From 8ccf22f93431a2f8c77de708cd3b15325c8fe0f4 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Fri, 25 Jul 2008 17:06:50 +0000 Subject: [PATCH] * include/rpc/clnt.h: Declare __libc_clntudp_bufcreate and __libc_clntudp_bufcreate_internal. * include/sys/socket.h: Declare __have_sock_cloexec. * socket/Makefile (aux): Add have_sock_cloexec. * socket/have_sock_cloexec.c: New file. * sunrpc/clnt_udp.h (clntudp_bufcreate): Now a wrapper around __libc_clntudp_bufcreate. (__libc_clntudp_bufcreate): Former implementation of clntudp_bufcreate which takes an additional parameter. Create socket with non-blocking mode and close-on-exec flag set, if wanted. * sunrpc/Versions: Export __libc_clntudp_bufcreate@GLIBC_PRIVATE. * nis/ypclnt.c (yp_bind_client_create): Use __libc_clntpudp_bufcreate instead of clntudp_create. The socket has already the close-on-exec flag set if SOCK_CLOEXEC is defined. --- ChangeLog | 17 +++++++++ include/rpc/clnt.h | 12 +++++++ include/sys/socket.h | 8 +++++ nis/ypclnt.c | 17 +++++++-- nptl/ChangeLog | 13 ++++++- nptl/sysdeps/unix/sysv/linux/mq_notify.c | 29 +++++++++++++-- socket/Makefile | 2 ++ socket/have_sock_cloexec.c | 24 +++++++++++++ sunrpc/Versions | 3 ++ sunrpc/clnt_udp.c | 60 +++++++++++++++++++++++++++----- 10 files changed, 169 insertions(+), 16 deletions(-) create mode 100644 socket/have_sock_cloexec.c diff --git a/ChangeLog b/ChangeLog index c46770a8ff..56c0415cc9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2008-07-25 Ulrich Drepper + + * include/rpc/clnt.h: Declare __libc_clntudp_bufcreate and + __libc_clntudp_bufcreate_internal. + * include/sys/socket.h: Declare __have_sock_cloexec. + * socket/Makefile (aux): Add have_sock_cloexec. + * socket/have_sock_cloexec.c: New file. + * sunrpc/clnt_udp.h (clntudp_bufcreate): Now a wrapper around + __libc_clntudp_bufcreate. + (__libc_clntudp_bufcreate): Former implementation of clntudp_bufcreate + which takes an additional parameter. Create socket with non-blocking + mode and close-on-exec flag set, if wanted. + * sunrpc/Versions: Export __libc_clntudp_bufcreate@GLIBC_PRIVATE. + * nis/ypclnt.c (yp_bind_client_create): Use __libc_clntpudp_bufcreate + instead of clntudp_create. The socket has already the close-on-exec + flag set if SOCK_CLOEXEC is defined. + 2008-07-24 Ulrich Drepper * sysdeps/unix/sysv/linux/kernel-features.h: Define diff --git a/include/rpc/clnt.h b/include/rpc/clnt.h index 1e72e22bcb..75d88a65ca 100644 --- a/include/rpc/clnt.h +++ b/include/rpc/clnt.h @@ -21,6 +21,18 @@ extern CLIENT *clntudp_bufcreate_internal (struct sockaddr_in *__raddr, struct timeval __wait_resend, int *__sockp, u_int __sendsz, u_int __recvsz) attribute_hidden; +extern CLIENT *__libc_clntudp_bufcreate (struct sockaddr_in *__raddr, + u_long __program, u_long __version, + struct timeval __wait_resend, + int *__sockp, u_int __sendsz, + u_int __recvsz, int __flags); +extern CLIENT *__libc_clntudp_bufcreate_internal (struct sockaddr_in *__raddr, + u_long __program, + u_long __version, + struct timeval __wait_resend, + int *__sockp, u_int __sendsz, + u_int __recvsz, int __flags) + attribute_hidden; extern CLIENT *clntunix_create_internal (struct sockaddr_un *__raddr, u_long __program, u_long __version, int *__sockp, u_int __sendsz, diff --git a/include/sys/socket.h b/include/sys/socket.h index 0a226726aa..df892783a0 100644 --- a/include/sys/socket.h +++ b/include/sys/socket.h @@ -153,4 +153,12 @@ extern int __libc_sa_len_internal (sa_family_t __af) attribute_hidden; # define __connect(fd, addr, len) INTUSE(__connect) (fd, addr, len) #endif +#ifdef SOCK_CLOEXEC +extern int __have_sock_cloexec; +/* At lot of other functionality became available at the same time as + SOCK_CLOEXEC. Avoid defining separate variables for all of them + unless it is really necessary. */ +# define __have_paccept __have_sock_cloexec +#endif + #endif diff --git a/nis/ypclnt.c b/nis/ypclnt.c index 7d0091bd26..aaf4eb6e59 100644 --- a/nis/ypclnt.c +++ b/nis/ypclnt.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2001, 2002, 2003, 2004, 2005, 2006 +/* Copyright (C) 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk , 1996. @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -69,14 +70,24 @@ yp_bind_client_create (const char *domain, dom_binding *ysd, ysd->dom_domain[YPMAXDOMAIN] = '\0'; ysd->dom_socket = RPC_ANYSOCK; - ysd->dom_client = clntudp_create (&ysd->dom_server_addr, YPPROG, YPVERS, - UDPTIMEOUT, &ysd->dom_socket); +#ifdef SOCK_CLOEXEC +# define xflags SOCK_CLOEXEC +#else +# define xflags 0 +#endif + ysd->dom_client = __libc_clntudp_bufcreate (&ysd->dom_server_addr, YPPROG, + YPVERS, UDPTIMEOUT, + &ysd->dom_socket, + UDPMSGSIZE, UDPMSGSIZE, + xflags); if (ysd->dom_client != NULL) { +#ifndef SOCK_CLOEXEC /* If the program exits, close the socket */ if (fcntl (ysd->dom_socket, F_SETFD, FD_CLOEXEC) == -1) perror ("fcntl: F_SETFD"); +#endif } } diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 744f90d786..27ced1aedb 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,14 @@ +2008-07-25 Ulrich Drepper + + * sysdeps/unix/sysv/linux/mq_notify.c (init_mq_netlink): Use + SOCK_CLOEXEC if possible. + +2008-05-29 Ulrich Drepper + + * Makefile (tests): Add tst-rwlock2a. + * tst-rwlock2.c: Use TYPE macro to decide what rwlock type to use. + * tst-rwlock2a.c: New file. + 2008-06-12 Ulrich Drepper * sysdeps/pthread/pthread.h: Remove inadvertant checkin. @@ -76,7 +87,7 @@ 2008-03-27 Ulrich Drepper - * sysdeps/unix/sysv/linux/bits/local_lim.h: Undefined ARG_MAX if + * sysdeps/unix/sysv/linux/bits/local_lim.h: Undefine ARG_MAX if has defined it. * sysdeps/unix/sysv/linux/alpha/bits/local_lim.h: Likewise. * sysdeps/unix/sysv/linux/ia64/bits/local_lim.h: Likewise. diff --git a/nptl/sysdeps/unix/sysv/linux/mq_notify.c b/nptl/sysdeps/unix/sysv/linux/mq_notify.c index 2ec11bf686..1be452a0e0 100644 --- a/nptl/sysdeps/unix/sysv/linux/mq_notify.c +++ b/nptl/sysdeps/unix/sysv/linux/mq_notify.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2004, 2005 Free Software Foundation, Inc. +/* Copyright (C) 2004, 2005, 2008 Free Software Foundation, Inc. This file is part of the GNU C Library. Contribute by Ulrich Drepper , 2004. @@ -29,6 +29,7 @@ #include #include #include +#include #ifdef __NR_mq_notify @@ -152,18 +153,40 @@ reset_once (void) static void init_mq_netlink (void) { +#ifdef SOCK_CLOEXEC +# ifndef __ASSUME_SOCK_CLOEXEC + static int have_sock_cloexec; +# else +# define have_sock_cloexec 1 +# endif +#else +# define have_sock_cloexec -1 +# define SOCK_CLOEXEC 0 +#endif + /* This code might be called a second time after fork(). The file descriptor is inherited from the parent. */ if (netlink_socket == -1) { /* Just a normal netlink socket, not bound. */ - netlink_socket = socket (AF_NETLINK, SOCK_RAW, 0); + if (have_sock_cloexec) + { + netlink_socket = socket (AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, 0); +#if defined SOCK_CLOEXEC && !defined __ASSUME_SOCK_CLOEXEC + if (have_sock_cloexec == 0) + have_sock_cloexec = (netlink_socket != -1 || errno != EINVAL + ? 1 : -1); +#endif + } + if (have_sock_cloexec < 0) + netlink_socket = socket (AF_NETLINK, SOCK_RAW, 0); /* No need to do more if we have no socket. */ if (netlink_socket == -1) return; /* Make sure the descriptor is closed on exec. */ - if (fcntl (netlink_socket, F_SETFD, FD_CLOEXEC) != 0) + if (have_sock_cloexec < 0 + && fcntl (netlink_socket, F_SETFD, FD_CLOEXEC) != 0) goto errout; } diff --git a/socket/Makefile b/socket/Makefile index e1c9ec0fad..e7fa589e65 100644 --- a/socket/Makefile +++ b/socket/Makefile @@ -29,6 +29,8 @@ routines := accept bind connect getpeername getsockname getsockopt \ setsockopt shutdown socket socketpair isfdtype opensock \ sockatmark paccept +aux := have_sock_cloexec + distribute := ifreq.h include ../Rules diff --git a/socket/have_sock_cloexec.c b/socket/have_sock_cloexec.c new file mode 100644 index 0000000000..22dccdf722 --- /dev/null +++ b/socket/have_sock_cloexec.c @@ -0,0 +1,24 @@ +/* Copyright (C) 2008 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include + +#if defined SOCK_CLOEXEC && !defined __ASSUME_SOCK_CLOEXEC +int __have_sock_cloexec; +#endif diff --git a/sunrpc/Versions b/sunrpc/Versions index cddf188766..d2d8e81ac0 100644 --- a/sunrpc/Versions +++ b/sunrpc/Versions @@ -116,4 +116,7 @@ libc { GLIBC_2.3.4 { xdr_quad_t; xdr_u_quad_t; } + GLIBC_PRIVATE { + __libc_clntudp_bufcreate; + } } diff --git a/sunrpc/clnt_udp.c b/sunrpc/clnt_udp.c index 634313211d..e3a68129ec 100644 --- a/sunrpc/clnt_udp.c +++ b/sunrpc/clnt_udp.c @@ -54,12 +54,15 @@ static char sccsid[] = "@(#)clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro"; #ifdef USE_IN_LIBIO # include #endif +#include #ifdef IP_RECVERR #include #include #endif +#include + extern bool_t xdr_opaque_auth (XDR *, struct opaque_auth *); extern u_long _create_xid (void); @@ -121,9 +124,9 @@ struct cu_data * sent and received. */ CLIENT * -clntudp_bufcreate (struct sockaddr_in *raddr, u_long program, u_long version, - struct timeval wait, int *sockp, u_int sendsz, - u_int recvsz) +__libc_clntudp_bufcreate (struct sockaddr_in *raddr, u_long program, + u_long version, struct timeval wait, int *sockp, + u_int sendsz, u_int recvsz, int flags) { CLIENT *cl; struct cu_data *cu = NULL; @@ -178,8 +181,32 @@ clntudp_bufcreate (struct sockaddr_in *raddr, u_long program, u_long version, { int dontblock = 1; - *sockp = __socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (*sockp < 0) +#ifdef SOCK_NONBLOCK +# ifndef __ASSUME_SOCK_CLOEXEC + if (__have_sock_cloexec >= 0) +# endif + { + *sockp = __socket (AF_INET, SOCK_DGRAM|SOCK_NONBLOCK|flags, + IPPROTO_UDP); +# ifndef __ASSUME_SOCK_CLOEXEC + if (__have_sock_cloexec == 0) + __have_sock_cloexec = *sockp >= 0 || errno != EINVAL ? 1 : -1; +# endif + } +#endif +#ifndef __ASSUME_SOCK_CLOEXEC +# ifdef SOCK_CLOEXEC + if (__have_sock_cloexec < 0) +# endif + { + *sockp = __socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); +# ifdef SOCK_CLOEXEC + if (flags & SOCK_CLOEXEC) + fcntl (*sockp, F_SETFD, FD_CLOEXEC); +# endif + } +#endif + if (__builtin_expect (*sockp < 0, 0)) { struct rpc_createerr *ce = &get_rpc_createerr (); ce->cf_stat = RPC_SYSTEMERROR; @@ -188,8 +215,13 @@ clntudp_bufcreate (struct sockaddr_in *raddr, u_long program, u_long version, } /* attempt to bind to prov port */ (void) bindresvport (*sockp, (struct sockaddr_in *) 0); - /* the sockets rpc controls are non-blocking */ - (void) __ioctl (*sockp, FIONBIO, (char *) &dontblock); +#ifndef __ASSUME_SOCK_CLOEXEC +# ifdef SOCK_CLOEXEC + if (__have_sock_cloexec < 0) +# endif + /* the sockets rpc controls are non-blocking */ + (void) __ioctl (*sockp, FIONBIO, (char *) &dontblock); +#endif #ifdef IP_RECVERR { int on = 1; @@ -212,6 +244,16 @@ fooy: mem_free ((caddr_t) cl, sizeof (CLIENT)); return (CLIENT *) NULL; } +INTDEF (__libc_clntudp_bufcreate) + +CLIENT * +clntudp_bufcreate (struct sockaddr_in *raddr, u_long program, u_long version, + struct timeval wait, int *sockp, u_int sendsz, + u_int recvsz) +{ + return INTUSE(__libc_clntudp_bufcreate) (raddr, program, version, wait, + sockp, sendsz, recvsz, 0); +} INTDEF (clntudp_bufcreate) CLIENT * @@ -222,8 +264,8 @@ clntudp_create (raddr, program, version, wait, sockp) struct timeval wait; int *sockp; { - return INTUSE(clntudp_bufcreate) (raddr, program, version, wait, sockp, - UDPMSGSIZE, UDPMSGSIZE); + return INTUSE(__libc_clntudp_bufcreate) (raddr, program, version, wait, + sockp, UDPMSGSIZE, UDPMSGSIZE, 0); } INTDEF (clntudp_create) -- 2.11.4.GIT