All pastes #1055298 Raw Edit

setting ONLCR on a pty

public c v1 · immutable
#1055298 ·published 2008-06-24 20:46 UTC
rendered paste body
/* Open a pty, fork a child that frobs the pty's settings then   exec()s, and see what we get back in a short conversation with the   child. */#include <errno.h>#include <fcntl.h>#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/wait.h>#include <termios.h>#include <unistd.h>void * lose (char *s){  fprintf(stderr, "%d\n", errno);  fprintf(stderr, "%s: %s\n", s, strerror(errno));  exit(1);}/* set some flags on a terminal */int set_noecho (int fd) {  struct termios  stermios;  if (tcgetattr(fd, &stermios) < 0) return 0;  stermios.c_lflag &= ~(ECHO | ECHONL);  stermios.c_iflag &= ~(BRKINT);  stermios.c_iflag |= (ICANON|ICRNL);  stermios.c_oflag |= (OPOST|ONLCR); /* We want CR/LF-terminated lines. */  stermios.c_cc[VERASE]=0177;  if (tcsetattr(fd, TCSANOW, &stermios) < 0) return 0;  return 1;}/* For some reason, I need to declare this... */extern char *ptsname();/* Open a pty with a pipe(2)-like interface. */int open_pty(int fildes[2]){  /* pty mumbojumbo */  int mtrfd = open("/dev/ptmx", O_RDWR, 0);  char *pts;  int slvfd;  if (mtrfd == -1) return -1;  if (grantpt(mtrfd) != 0) return -1;  if (unlockpt(mtrfd) != 0) return -1;  if ((pts = ptsname(mtrfd)) == NULL) return -1;  slvfd = open(pts, O_RDWR, 0666);  if (slvfd == -1) return -1;    fildes[0] = mtrfd;  fildes[1] = slvfd;  return 0;}/* yes, this is written somewhat strangely. */int main (int argc, char **argv) {  int fds[2];  pid_t pid;  (open_pty(fds) == 0) || lose("open_pty");  /* make a test file. */  (system("echo foo > openpty.test") == 0) || lose("system");  pid = fork();  if (pid < -1) lose("fork");  if (pid == 0) {    dup2(fds[1], 0);    (set_noecho(0) != 0) || lose("set_noecho");    dup2(fds[1], 1);    dup2(fds[1], 2);    close(fds[1]);    execl("/bin/ed", "/bin/ed", "openpty.test", NULL);  } else {    FILE *f;    int status;    (f = fdopen(fds[0], "w+")) || lose("fdopen");    printf("%d\n", fgetc(f));    printf("%d\n", fgetc(f));    printf("%d\n", fgetc(f));    fprintf(f, "q\n");    fflush(f);    wait(&status);    (unlink("openpty.test")==0) || lose("unlink");  }}/*Expected output (which I get on Linux and NetBSD)521310What I get on Solaris:521052That is, the child's terminal isn't converting newlines to CR/LFs.*/