Date: Mon, 28 Jul 2003 14:52:26 -0700 (PDT) From: William Sloan <wsloan@ectogenic.com> To: FreeBSD-gnats-submit@FreeBSD.org Subject: docs/54995: Error in accept(2) man page Message-ID: <200307282152.h6SLqQCo059661@pox.ectogenic.com> Resent-Message-ID: <200307282200.h6SM0Oc9014701@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>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 <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <errno.h> #include <unistd.h> #include <fcntl.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define SYSLOG_NAMES #include <syslog.h> #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:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200307282152.h6SLqQCo059661>