From owner-freebsd-doc@FreeBSD.ORG Mon Jul 28 15:00:26 2003 Return-Path: Delivered-To: freebsd-doc@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 6439E37B401 for ; Mon, 28 Jul 2003 15:00:26 -0700 (PDT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2406343F85 for ; Mon, 28 Jul 2003 15:00:25 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.9/8.12.9) with ESMTP id h6SM0OUp014702 for ; Mon, 28 Jul 2003 15:00:24 -0700 (PDT) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.9/8.12.9/Submit) id h6SM0Oc9014701; Mon, 28 Jul 2003 15:00:24 -0700 (PDT) Resent-Date: Mon, 28 Jul 2003 15:00:24 -0700 (PDT) Resent-Message-Id: <200307282200.h6SM0Oc9014701@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-doc@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, William Sloan Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id DF6DE37B404 for ; Mon, 28 Jul 2003 14:52:33 -0700 (PDT) Received: from plague.ectogenic.com (mail0.ectogenic.com [207.154.88.12]) by mx1.FreeBSD.org (Postfix) with SMTP id C1FF543F75 for ; Mon, 28 Jul 2003 14:52:32 -0700 (PDT) (envelope-from wsloan@ectogenic.com) Received: from pox.ectogenic.com (pox.ectogenic.com [10.0.0.13]) by plague.ectogenic.com (8.12.8/8.12.8) with ESMTP id h6SLqRiq000995 (version=TLSv1/SSLv3 cipher=EDH-RSA-DES-CBC3-SHA bits=168 verify=NO) for ; Mon, 28 Jul 2003 14:52:27 -0700 Received: from pox.ectogenic.com (localhost.ectogenic.com [127.0.0.1]) by pox.ectogenic.com (8.12.9/8.12.9) with ESMTP id h6SLqQAH059662 for ; Mon, 28 Jul 2003 14:52:26 -0700 (PDT) (envelope-from wsloan@pox.ectogenic.com) Received: (from wsloan@localhost) by pox.ectogenic.com (8.12.9/8.12.9/Submit) id h6SLqQCo059661; Mon, 28 Jul 2003 14:52:26 -0700 (PDT) Message-Id: <200307282152.h6SLqQCo059661@pox.ectogenic.com> Date: Mon, 28 Jul 2003 14:52:26 -0700 (PDT) From: William Sloan To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Subject: docs/54995: Error in accept(2) man page X-BeenThere: freebsd-doc@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: William Sloan List-Id: Documentation project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 28 Jul 2003 22:00:26 -0000 >Number: 54995 >Category: docs >Synopsis: Error in accept(2) man page >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-doc >State: open >Quarter: >Keywords: >Date-Required: >Class: doc-bug >Submitter-Id: current-users >Arrival-Date: Mon Jul 28 15:00:24 PDT 2003 >Closed-Date: >Last-Modified: >Originator: William Sloan >Release: FreeBSD 5.1-RELEASE i386 >Organization: ectogenic.com >Environment: System: FreeBSD pox.ectogenic.com 5.1-RELEASE FreeBSD 5.1-RELEASE #0: Thu Jun 26 15:47:13 PDT 2003 root@yenlowang.wooferstar.net:/usr/src/sys/i386/compile/SMP i386 >Description: The accept(2) man pages states that the new socket has the same properties as the orginal socket. This appears not to be the case as the output from attached C program shows. Server Info: Status of socket 3 Server Info: Socket send timeout is 5 Server Info: Socket recv timeout is 5 Server Info: REUSEADDR flag is 4 Server Info: Linger options are 128 and 5 Server Info: Nonblocking IO is 4 Server Info: Async IO is 64 Server Info: close-on-exec flag is 1 Server Info: Pid owner is 59559 Server Info: After accept Server Info: Orignal socket Server Info: Status of socket 3 Server Info: Socket send timeout is 5 Server Info: Socket recv timeout is 5 Server Info: REUSEADDR flag is 4 Server Info: Linger options are 128 and 5 Server Info: Nonblocking IO is 4 Server Info: Async IO is 64 Server Info: close-on-exec flag is 1 Server Info: Pid owner is 59559 Server Info: Accepted socket Server Info: Status of socket 4 Server Info: Socket send timeout is 0 Server Info: Socket recv timeout is 0 Server Info: REUSEADDR flag is 4 Server Info: Linger options are 128 and 5 Server Info: Nonblocking IO is 4 Server Info: Async IO is 64 Server Info: close-on-exec flag is 0 Server Info: Pid owner is 59559 >How-To-Repeat: Compile and run the attached program and make a TCP connection to port 64000. Output like that of the previous section should show some properties changing across exec calls. #include #include #include #include #include #include #include #include #include #include #include #define SYSLOG_NAMES #include #define WILDCARD_ADDRESS "*" void logger (int level, char *s, ...) { int i = 0; va_list args; fprintf(stderr, "Server "); while (prioritynames[i].c_name != NULL) { if (level == prioritynames[i].c_val) { fprintf(stderr, "%c", toupper(prioritynames[i].c_name[0])); fprintf(stderr, "%s: ", &(prioritynames[i].c_name[1])); break; } i++; } va_start(args, s); vfprintf(stderr, s, args); va_end(args); return; } void set_socket_options(int socket) { int enable = 1, val; struct timeval timeout; struct linger linger_opts; bzero (&timeout, sizeof(timeout)); timeout.tv_sec = 5; if (setsockopt (socket, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout))) { logger(LOG_CRIT, "Could not set send timeout option\n"); exit(EXIT_FAILURE); } if (setsockopt (socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout))) { logger(LOG_CRIT, "Could not set recv timeout option\n"); exit(EXIT_FAILURE); } if (setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable))) { logger (LOG_CRIT, "Could not set reuse addr flag\n"); exit (EXIT_FAILURE); } linger_opts.l_onoff = 1; linger_opts.l_linger = 5; if (setsockopt(socket, SOL_SOCKET, SO_LINGER, &linger_opts, sizeof(linger_opts))) { logger (LOG_CRIT, "Could not set linger options\n"); exit(EXIT_FAILURE); } val = fcntl(socket, F_GETFL); val |= O_NONBLOCK; if (fcntl (socket, F_SETFL, val) == -1) { logger (LOG_CRIT, "Could not set nonblocking I/O because %s\n", strerror(errno)); exit (EXIT_FAILURE); } if (fcntl (socket, F_SETFD, FD_CLOEXEC) == -1) { logger (LOG_CRIT, "Could not set close on exec flag because %s\n", strerror(errno)); exit (EXIT_FAILURE); } if (fcntl (socket, F_SETOWN, getpid()) == -1) { logger (LOG_CRIT, "Could not set owner because %s\n", strerror(errno)); } val = fcntl(socket, F_GETFL); val |= O_ASYNC; if (fcntl (socket, F_SETFL, val) == -1) { logger (LOG_CRIT, "Could not set ASYNC because %s\n", strerror(errno)); exit (EXIT_FAILURE); } return; } void print_socket_options(int socket) { int val, enable; struct timeval timeout; struct linger linger_opts; logger (LOG_INFO, "Status of socket %d\n", socket); val = sizeof(timeout); if (getsockopt (socket, SOL_SOCKET, SO_SNDTIMEO, &timeout, &val)) { logger(LOG_CRIT, "Could not get send timeout option\n"); exit(EXIT_FAILURE); } logger (LOG_INFO, "Socket send timeout is %d\n", timeout.tv_sec); val = sizeof(timeout); if (getsockopt (socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, &val)) { logger(LOG_CRIT, "Could not get recv timeout option\n"); exit(EXIT_FAILURE); } logger (LOG_INFO, "Socket recv timeout is %d\n", timeout.tv_sec); val = sizeof(enable); if (getsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &enable, &val)) { logger (LOG_CRIT, "Could not get reuse addr flag\n"); exit (EXIT_FAILURE); } logger (LOG_INFO, "REUSEADDR flag is %d\n", enable); val = sizeof(linger_opts); if (getsockopt(socket, SOL_SOCKET, SO_LINGER, &linger_opts, &val)) { logger (LOG_CRIT, "Could not set linger options\n"); exit(EXIT_FAILURE); } logger (LOG_INFO, "Linger options are %d and %d\n", linger_opts.l_onoff, linger_opts.l_linger); val = fcntl(socket, F_GETFL); logger (LOG_INFO, "Nonblocking IO is %d\n", val & O_NONBLOCK); logger (LOG_INFO, "Async IO is %d\n", val & O_ASYNC); val = fcntl (socket, F_GETFD); logger (LOG_INFO, "close-on-exec flag is %d\n", val); val = fcntl (socket, F_GETOWN); logger (LOG_INFO, "Pid owner is %d\n", val); return; } int opensocket(char *address, int port, int timeout_sec, int linger_sec) { int s, enable; struct sockaddr_in name; if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) { logger(LOG_CRIT, "Could not open socket: %s\n", strerror(errno)); return s; } bzero (&name, sizeof(name)); set_socket_options(s); name.sin_family = AF_INET; if (strcmp(address, WILDCARD_ADDRESS) == 0) { name.sin_addr.s_addr = htonl(INADDR_ANY); } else { if ((name.sin_addr.s_addr = inet_addr(address)) == INADDR_NONE) { logger(LOG_CRIT, "Inet_addr failed: %s\n", strerror(errno)); exit (EXIT_FAILURE); } } name.sin_port = htons(port); if (bind(s, (struct sockaddr *)&name, sizeof(name)) == -1) { logger(LOG_CRIT, "Could not bind socket: %s\n", strerror(errno)); close(s); return -1; } if (listen(s, 4) == -1) { logger(LOG_CRIT, "Could not listen on socket: %s\n", strerror(errno)); close(s); return -1; } return s; } int main (void) { int s, ns, len; struct sockaddr addr; s = opensocket("*", 64000, 3, 5); print_socket_options(s); do { len = sizeof (addr); ns = accept(s, &addr, &len); } while ((ns == -1) && (errno == EWOULDBLOCK)); logger (LOG_INFO, "\nAfter accept\n"); logger (LOG_INFO, "Orignal socket\n"); print_socket_options(s); logger (LOG_INFO, "\nAccepted socket\n"); print_socket_options(ns); close (s); close(ns); } >Fix: Detail in the accept(2) man page which socket properties are changed durning an accept call. >Release-Note: >Audit-Trail: >Unformatted: