cons.c (2691B)
1 #include <errno.h> 2 #include <fcntl.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <string.h> 6 #include <sys/ioctl.h> 7 #include <sys/termios.h> 8 #include <sys/wait.h> 9 #include <unistd.h> 10 11 int device_open(); 12 int setparms(int fd, int baud); 13 int flush(int fd); 14 15 #define ERRLEN 128 16 char err[ERRLEN]; 17 #define BUFSIZE 16 18 19 int 20 main(void) 21 { 22 int fd; 23 int ret = 0; 24 int cret; 25 struct termios *term; 26 27 fd = device_open(); 28 if (fd < 0) { 29 fprintf(stderr, "can't open device: %s\n", strerror(errno)); 30 return 1; 31 } 32 if (setparms(fd, 115200) < 0) { 33 fprintf(stderr, "setparm: %s\n", err); 34 return 1; 35 } 36 37 if (flush(fd) < 0) { 38 fprintf(stderr, "flush: %s\n", strerror(errno)); 39 ret = errno; 40 goto defer; 41 } 42 43 if (fork() == 0) { 44 int n; 45 char buf[BUFSIZE]; 46 int ret = 0; 47 for (;;) { 48 n = read(0, buf, BUFSIZE); 49 if (n == 0) { 50 fprintf(stderr, "eof\n"); 51 break; 52 } else if (n < 0) { 53 fprintf(stderr, "read stdin: %s\n", strerror(errno)); 54 ret = 1; 55 break; 56 } 57 n = write(fd, buf, n); 58 if (n < 0) { 59 fprintf(stderr, "write to tty %s\n", strerror(errno)); 60 ret = 1; 61 break; 62 } 63 } 64 _exit(ret); 65 } 66 if (fork() == 0) { 67 int n; 68 char buf[BUFSIZE]; 69 int ret = 0; 70 for (;;) { 71 n = read(fd, buf, BUFSIZE); 72 if (n < 0) { 73 fprintf(stderr, "read tty: %s\n", strerror(errno)); 74 ret = 1; 75 break; 76 } 77 n = write(1, buf, n); 78 if (n < 0) { 79 fprintf(stderr, "write to stdout %s\n", strerror(errno)); 80 ret = 1; 81 break; 82 } 83 } 84 _exit(ret); 85 } 86 87 wait(&cret); 88 defer: 89 close(fd); 90 if (ret == 0) { 91 ret = cret; 92 } 93 return ret; 94 int n; 95 } 96 97 int 98 device_open() 99 { 100 int n; 101 int fd; 102 103 fd = open("/dev/ttyU0", O_RDWR|O_NDELAY|O_NOCTTY); 104 if (fd < 0) 105 return -1; 106 n = fcntl(fd, F_GETFL, 0); 107 fcntl(fd, F_SETFL, n&~O_NDELAY); 108 return fd; 109 } 110 111 int 112 setparms(int fd, int baud) 113 { 114 struct termios tty; 115 if (tcgetattr(fd, &tty) < 0) { 116 snprintf(err, ERRLEN, "tcgetattr: %s", strerror(errno)); 117 return -1; 118 } 119 if (cfsetospeed(&tty, (speed_t)baud) < 0) { 120 snprintf(err, ERRLEN, "cfsetospeed: %s", strerror(errno)); 121 return -1; 122 } 123 if (cfsetispeed(&tty, (speed_t)baud) < 0) { 124 snprintf(err, ERRLEN, "cfsetispeed: %s", strerror(errno)); 125 return -1; 126 } 127 tty.c_cflag = (tty.c_cflag&~CSIZE) | CS8; 128 tty.c_iflag = IGNBRK; 129 tty.c_lflag = 0; 130 tty.c_oflag = 0; 131 tty.c_cflag |= CLOCAL|CREAD; 132 tty.c_cc[VMIN] = 1; 133 tty.c_cc[VTIME] = 5; 134 tty.c_iflag &= ~(IXON|IXOFF|IXANY); // TODO: xon, xoff? 135 // TODO: parity 136 tty.c_cflag &= ~CSTOPB; // stop bit == 1 137 if (tcsetattr(fd, TCSANOW, &tty) < 0) { 138 snprintf(err, ERRLEN, "tcseattr: %s", strerror(errno)); 139 return -1; 140 } 141 // TODO: rs485 142 return 0; 143 } 144 145 int 146 flush(int fd) 147 { 148 int out = 0; 149 return ioctl(fd, TIOCFLUSH, &out); 150 }