Hello,

I'm following this [tutorial](https://viewsourcecode.org/snaptoken/kilo/02.enteringRawMode.html#disable-ctrl-s-and-ctrl-q) and I'm having some trouble setting the flags.

I have this C program that works properly (exits as soon as I press `q` and `CTRL+C` does not kill it).

```
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include <termios.h>
#include <unistd.h>

struct termios orig_termios;

void disableRawMode() {
  tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios);
}

void enableRawMode() {
  tcgetattr(STDIN_FILENO, &orig_termios);
  atexit(disableRawMode);
  struct termios raw = orig_termios;
  raw.c_lflag &= ~(ECHO | ICANON | ISIG);
  tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
}

int main() {

  enableRawMode();

  char c;
  while (read(STDIN_FILENO, &c, 1) == 1 && c != 'q') {
    if (iscntrl(c)) {
      printf("%d\n", c);
    } else {
      printf("%d ('%c')\n", c, c);
    }
  }

  return 0;
}
```

I'm trying to write the equivalent program in D.

source/app.d
```
import adapter;
import core.stdc.stdlib : atexit;
import core.stdc.stdio : printf;
import core.stdc.ctype : iscntrl;

termios orig_termios;

extern (C)
{
        void disableRawMode() {
                tcsetattr(STDIN_FILENO, TCSANOW, &orig_termios);
        }
}

void enableRawMode() {
        tcgetattr(STDIN_FILENO, &orig_termios);
        atexit(&disableRawMode);

        termios raw = orig_termios;
        // TODO flags ICANON and ISIG do not work
        raw.c_lflag &= ~(ECHO | ICANON | ISIG);

        tcsetattr(STDIN_FILENO, TCSANOW, &raw);
}

int main()
{
        enableRawMode();

        char c;
        while (read(STDIN_FILENO, &c, 1) == 1 && c != 'q') {
                if (iscntrl(c)) {
                        printf("%d\n", c);
                } else {
                        printf("%d ('%c')\n", c, c);
                }
        }

        return 0;
}

```

source/adapter/package.d
```
module adapter;

public import adapter.termios;
public import adapter.unistd;
```


source/adapter/termios.d
```
module adapter.termios;

import std.typecons : Typedef;

// from termios.h, https://github.com/openbsd/src/blob/master/sys/sys/termios.h
enum int ECHO   = 0x00000008;
enum int ICANON = 0x00000100;
enum int ISIG   = 0x00000080;

enum int IXON   = 0x00000200;
enum int IEXTEN = 0x00000400;
enum int ICRNL  = 0x00000100;

enum int TCSANOW = 0;
enum int TCSADRAIN = 1;
enum int TCSAFLUSH = 2;

enum int NCCS = 20;

alias tcflag_t = Typedef!uint;
alias cc_t = Typedef!ubyte;
// alias speed_t = Typedef!uint;

struct termios {
        tcflag_t c_iflag;       /* input flags */
        tcflag_t c_oflag;       /* output flags */
        tcflag_t c_cflag;       /* control flags */
        tcflag_t c_lflag;       /* local flags */
        cc_t[NCCS] c_cc;        /* control chars */
        int c_ispeed;   /* input speed */
        int c_ospeed;   /* output speed */
};

extern (C) int tcgetattr(int, termios *);
extern (C) int tcsetattr(int, int, const termios *);

```

source/adapter/unistd.d
```
module adapter.unistd;

import core.sys.posix.sys.types : ssize_t;

// TODO fix import
enum int STDIN_FILENO = 0;
// import core.stdc.stdio : STDIN_FILENO;

// from unistd.h
extern (C) ssize_t read(int fildes, void *buf, size_t nbytes);
```

When I try to run it with `dub run` the only flag that appears to be set is `~(ECHO)`. It does exit when I press `CTRL+C` and it does not exit as soon as I press `q`, I must follow that with an `ENTER`.

Is there a better way to use `termios.h` inside D? Am I missing the point and there is a way to set these flags in D without using C libraries?

Reply via email to