X-Recipient: archive-cygwin AT delorie DOT com X-SWARE-Spam-Status: No, hits=-3.7 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,FREEMAIL_FROM,KHOP_RCVD_TRUST,RCVD_IN_DNSWL_LOW,RCVD_IN_HOSTKARMA_YE X-Spam-Check-By: sourceware.org MIME-Version: 1.0 X-Received: by 10.49.24.132 with SMTP id u4mr22066992qef.55.1360046379471; Mon, 04 Feb 2013 22:39:39 -0800 (PST) Date: Tue, 5 Feb 2013 15:39:39 +0900 Message-ID: Subject: non-blocking accept() can hang. From: Tanaka Akira To: cygwin AT cygwin DOT com Content-Type: text/plain; charset=ISO-8859-1 X-IsSubscribed: yes Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Hi. I found that non-blocking accept() can hang. The following test program shows the problem. % uname -mrsv CYGWIN_NT-5.1 1.7.17(0.262/5/3) 2012-10-19 14:39 i686 % cat tst-nonblocking.c #include #include #include #include #include #include #include #include void set_nonblock(int fd) { int ret; ret = fcntl(fd, F_GETFL); if (ret == -1) { perror("fcntl(F_GETFL)"); exit(EXIT_FAILURE); } ret |= O_NONBLOCK; ret = fcntl(fd, F_SETFL, ret); if (ret == -1) { perror("fcntl(F_SETFL)"); exit(EXIT_FAILURE); } } int main(int argc, char *argv[]) { int s, c, ret; struct sockaddr_un addr; socklen_t addrlen; unlink("socketfile"); addrlen = sizeof(addr); memset(&addr, '\0', addrlen); addr.sun_family = AF_UNIX; strcpy(addr.sun_path, "socketfile"); s = socket(AF_UNIX, SOCK_STREAM, 0); if (s == -1) { perror("socket(server)"); exit(EXIT_FAILURE); } set_nonblock(s); ret = bind(s, (struct sockaddr *)&addr, addrlen); if (ret == -1) { perror("bind"); exit(EXIT_FAILURE); } ret = listen(s, SOMAXCONN); if (ret == -1) { perror("listen"); exit(EXIT_FAILURE); } c = socket(AF_UNIX, SOCK_STREAM, 0); if (c == -1) { perror("socket(client)"); exit(EXIT_FAILURE); } set_nonblock(c); ret = connect(c, (struct sockaddr *)&addr, addrlen); if (ret == -1 && errno == EINPROGRESS) { perror("connect"); } else if (ret == -1) { perror("connect"); exit(EXIT_FAILURE); } ret = accept(s, NULL, 0); if (ret == -1) { perror("accept"); exit(EXIT_FAILURE); } return EXIT_SUCCESS; } % gcc -Wall tst-nonblocking.c -o tst-nonblocking % ./tst-nonblocking connect: Operation now in progress (^C and ^Z is not effective. I used Windows task manager to kill the process.) I found this problem when I investigate why the following program blocks. The following program doesn't use O_NONBLOCK but other OS (GNU/Linux, FreeBSD, NetBSD, OpenBSD and SunOS) doesn't block. Is it intentional behavior? % cat tst-blocking.c #include #include #include #include #include #include #include #include int main(int argc, char *argv[]) { int s, c, ret; struct sockaddr_un addr; socklen_t addrlen; unlink("socketfile"); addrlen = sizeof(addr); memset(&addr, '\0', addrlen); addr.sun_family = AF_UNIX; strcpy(addr.sun_path, "socketfile"); s = socket(AF_UNIX, SOCK_STREAM, 0); if (s == -1) { perror("socket(server)"); exit(EXIT_FAILURE); } ret = bind(s, (struct sockaddr *)&addr, addrlen); if (ret == -1) { perror("bind"); exit(EXIT_FAILURE); } ret = listen(s, SOMAXCONN); if (ret == -1) { perror("listen"); exit(EXIT_FAILURE); } c = socket(AF_UNIX, SOCK_STREAM, 0); if (c == -1) { perror("socket(client)"); exit(EXIT_FAILURE); } ret = connect(c, (struct sockaddr *)&addr, addrlen); if (ret == -1 && errno == EINPROGRESS) { perror("connect"); } else if (ret == -1) { perror("connect"); exit(EXIT_FAILURE); } return EXIT_SUCCESS; } % gcc -Wall tst-nonblocking.c -o tst-nonblocking % ./tst-blocking (^C can interrupt the process.) -- Tanaka Akira -- 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