#define _XOPEN_SOURCE 600 #define _DEFAULT_SOURCE #include #include #include #include #include #include #include #include #include static int pty_make_raw(int ptym) { struct termios t; int err; err = tcgetattr(ptym, &t); if (err) return err; cfmakeraw(&t); return tcsetattr(ptym, TCSANOW, &t); } unsigned char data[65536]; unsigned char readbuf[65536]; int slavefd, slaveerr; size_t readsize; int cmp_mem(unsigned char *buf, unsigned char *buf2, size_t len, size_t pos) { size_t i; int rv = 0; for (i = 0; i < len; i++) { if (buf[i] != buf2[i]) { printf("Mismatch on byte %lu, expected 0x%2.2x, got 0x%2.2x\n", (long) (i + pos), buf[i], buf2[i]); fflush(stdout); rv = -1; break; } } return rv; } static void *read_thread(void *dummy) { ssize_t i; do { i = read(slavefd, readbuf + readsize, sizeof(readbuf) - readsize); if (i <= -1) { if (errno == EAGAIN) continue; if (errno == EIO) /* Remote close causes an EIO. */ return NULL; perror("read"); slaveerr = errno; return NULL; } if (i + readsize > sizeof(data)) { slaveerr = E2BIG; return NULL; } if (i && cmp_mem(data + readsize, readbuf + readsize, i, readsize)) { fprintf(stderr, "Data mismatch, starting at %ld, %ld bytes\n", (long) readsize, (long) i); assert(0); slaveerr = EBADMSG; return NULL; } readsize += i; } while (i != 0); return NULL; } int main(int argc, char *argv[]) { int ptym, err; char *slave; ssize_t i; pthread_t slavethr; for (i = 0; i < sizeof(data); i += 2) { data[i] = (i / 2) >> 8; data[i + 1] = i / 2; } ptym = posix_openpt(O_RDWR | O_NOCTTY); if (ptym == -1) { perror("posix_openpt"); exit(1); } if (fcntl(ptym, F_SETFL, O_NONBLOCK) == -1) { perror("fcntl ptym"); exit(1); } if (pty_make_raw(ptym)) { perror("pty_make_raw"); exit(1); } if (unlockpt(ptym) < 0) { perror("unlockpt"); exit(1); } slave = ptsname(ptym); slavefd = open(slave, O_RDWR); if (slavefd == -1) { perror("open"); exit(1); } err = pthread_create(&slavethr, NULL, read_thread, NULL); if (err) { fprintf(stderr, "pthread_create: %s\n", strerror(err)); exit(1); } i = write(ptym, data, sizeof(data)); if (i == -1) { perror("write"); exit(1); } close(ptym); pthread_join(slavethr, NULL); exit(0); }