Mail Archives: cygwin/2013/02/05/01:40:05
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: | <CANjopZGmp+xaUg1Sn2FTmb77igMk8R=Lp9yBWyeDtDj3RP5R=g@mail.gmail.com>
|
Subject: | non-blocking accept() can hang.
|
From: | Tanaka Akira <akr AT fsij DOT org>
|
To: | cygwin AT cygwin DOT com
|
X-IsSubscribed: | yes
|
Mailing-List: | contact cygwin-help AT cygwin DOT com; run by ezmlm
|
List-Id: | <cygwin.cygwin.com>
|
List-Subscribe: | <mailto:cygwin-subscribe AT cygwin DOT com>
|
List-Archive: | <http://sourceware.org/ml/cygwin/>
|
List-Post: | <mailto:cygwin AT cygwin DOT com>
|
List-Help: | <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
|
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 <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/un.h>
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 <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/un.h>
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
- Raw text -