Package: cygwin Version: 1.7.34-6 [Problem 1] TIOCKPT mode for PTY does not work properly when ONLCR flag is unset. When read() is called from master side, it seems working correctly only if the buffer size specified to read() is larger than the size of available data, otherwise it causes an internal error. To reproduce this problem, compile the following C source (Test Case 1) and execute it. The expected result is: 00 30 31 32 33 34 35 36 37 38 39 00 30 31 32 33 34 00 35 36 37 38 39 In cygwin 1.7.34-6, however, the result is: 00 30 31 32 33 34 35 36 37 38 39 0 [main] test_pty 3872 fhandler_pty_master::process_slave_output: internal error: 0 unexpected characters 00 30 31 32 33 34 0a 00 36 37 38 39 Furthermore, in the case that OPOST flag is unset, the result is: 00 30 31 32 33 34 35 36 37 38 39 00 30 31 32 33 34 35 00 36 37 38 39 In the latter case, length of data read out exceeds that specified to read(). I was looking into cygwin source code and found the PTY fails to count TIOCPKT control byte (TIOCPKT_DATA) into buffer length properly in fhandler_pty_master::process_slave_output(). [Problem 2] Moreover, I found another problem of TTY while testing the case. tcsetattr() affects data already written to TTY even if it is used with TCSADRAIN option. To reproduce this problem, compile the following C source (Test Case 2) and execute it. The expected result is: 0123456789 0123456789 because the first write() is without OPOST flag and the second write() is with OPOST flag. In cygwin 1.7.34-6, however, the result is: 0123456789 0123456789 This means that the second tcsetattr() is applied before the post-processing for the first write() is done. If usleep() currently commented-out is enabled, the result will be as expected. I was looking into cygwin source code again and found that this problem is caused since the processing for OPOST is done in a function fhandler_pty_master::process_slave_output() which is called by read-process. To fix this problem, the processing for OPOST should be done in write-process instead of read-process. Both problem above is essentially independent, but the patches for them are not independent. In other words, the patches for these problems touch same function. Therefore the bug reports for both problem are in this mail together. To fix these problems, I have made a patch (cygwin.patch) attached. I have confirmed both problem mentioned above have been gone with this patch. Please consider of adopting the patch I have proposed in the future release. /***************/ /* Test Case 1 */ /***************/ #include #include #include #include #include #include int main() { int master, slave; struct termios tt; int val = 1; int pkt = 0; char buf[BUFSIZ]; int len; if ( openpty(&master, &slave, NULL, NULL, NULL) < 0) { perror("openpty()"); exit(EXIT_FAILURE); } /* setup master */ if ( ioctl(master, FIONBIO, &val) < 0) { perror("ioctl(FIONBIO)"); exit(EXIT_FAILURE); } if ( ioctl(master, TIOCPKT, &val) < 0) { perror("ioctl(TIOCPKT)"); exit(EXIT_FAILURE); } else { pkt = 1; } /* setup slave */ tcgetattr(slave, &tt); tt.c_oflag &= ~ONLCR; // tt.c_oflag &= ~OPOST; tcsetattr(slave, TCSANOW, &tt); /* Case 1: No Error */ len = write(slave, "0123456789", 10); while (len>0) { int n = read(master, buf, 10+pkt); int i; if (n<=0) break; for (i=0; i0) { int n = read(master, buf, 5+pkt); int i; if (n<=0) break; for (i=0; i #include int main() { struct termios tt; tcgetattr(STDOUT_FILENO, &tt); tt.c_oflag &= ~OPOST; tcsetattr(STDOUT_FILENO, TCSANOW, &tt); write(STDOUT_FILENO, "0123456789\n", 11); /* usleep(100000); */ tt.c_oflag |= OPOST; tcsetattr(STDOUT_FILENO, TCSADRAIN, &tt); write(STDOUT_FILENO, "0123456789\n", 11); return 0; } -- Takashi Yano