Package: cygwin Version: 1.7.35-1 PTY of cygwin dies when master fd in parent process is closed while a child process keeps valid master fd.
To reproduce this problem: 1) Compile following C sources (Test Case 1, 2) 2) Execute them. Expected results are both: 01234567890 However, result of Test Case 2 is: Hungup while Test Case 1 is as expected. Difference between Test Case 1 and Test Case 2 is which process is worked in parent. In other words, master is in parent process in Test Case 1, while master is in child process in Test Case 2. I looked into cygwin source code, and found the cause. fhandler_pty_master::close() calls get_ttyp()->set_master_closed() if it is called from the process which opend the master. It is regardless whether other processes have the valid master handle. get_ttyp()->set_master_closed() should be called only when the last valid master handle among all processes is closed. Additionally, I am not sure whether SIGHUP should be generated when the master is closed. /***************/ /* Test Case 1 */ /***************/ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <termios.h> #include <sys/ioctl.h> #include <pty.h> #include <wait.h> int main() { int master, slave; pid_t pid; if ( openpty(&master, &slave, NULL, NULL, NULL) < 0) { perror("openpty()"); exit(EXIT_FAILURE); } pid = fork(); if (pid < 0) { perror("fork()"); exit(EXIT_FAILURE); } if (pid != 0) { /* Parent */ close(slave); write(master, "0123456789\n", 11); usleep(100000); /* wait until slave read() */ close(master); wait(NULL); } else { /* Child */ char buf[BUFSIZ]; int len; close(master); len = read(slave, buf, sizeof(buf)); write(STDOUT_FILENO, buf, len); close(slave); } return EXIT_SUCCESS; } /***************/ /* Test Case 2 */ /***************/ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <termios.h> #include <sys/ioctl.h> #include <pty.h> #include <wait.h> int main() { int master, slave; pid_t pid; if ( openpty(&master, &slave, NULL, NULL, NULL) < 0) { perror("openpty()"); exit(EXIT_FAILURE); } pid = fork(); if (pid < 0) { perror("fork()"); exit(EXIT_FAILURE); } if (pid == 0) { /* Child */ close(slave); write(master, "0123456789\n", 11); usleep(100000); /* wait until slave read() */ close(master); } else { /* Parent */ char buf[BUFSIZ]; int len; close(master); len = read(slave, buf, sizeof(buf)); write(STDOUT_FILENO, buf, len); close(slave); wait(NULL); } return EXIT_SUCCESS; } -- Takashi Yano <takashi.y...@nifty.ne.jp>
cygcheck.out
Description: Binary data
-- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple