* sysdeps/unix/sysv/linux/kernel-features.h: Define

__ASSUME_PACCEPT, __ASSUME_IN_NONBLOCK, and __ASSUME_PACCEPT if
	appropriate.
	* nscd/connections.c: Avoid fcntl calls to set close-on-exec flag and
	non-blocking mode by using socket, paccept, and inotify_init1.
This commit is contained in:
Ulrich Drepper 2008-07-25 05:30:10 +00:00
parent bdcebfc4c7
commit 3ff2c948be
3 changed files with 92 additions and 22 deletions

View File

@ -1,5 +1,11 @@
2008-07-24 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/kernel-features.h: Define
__ASSUME_PACCEPT, __ASSUME_IN_NONBLOCK, and __ASSUME_PACCEPT if
appropriate.
* nscd/connections.c: Avoid fcntl calls to set close-on-exec flag and
non-blocking mode by using socket, paccept, and inotify_init1.
* Versions.def (glibc): Add GLIBC_2.9.
* io/Makefile (routines): Add dup3 and pipe2.
* io/Versions [glibc] (GLIBC_2.9): Add dup3 and pipe2.

View File

@ -234,6 +234,14 @@ static int inotify_fd = -1;
static int resolv_conf_descr = -1;
#endif
#ifndef __ASSUME_SOCK_CLOEXEC
/* Negative if SOCK_CLOEXEC is not supported, positive if it is, zero
before be know the result. */
static int have_sock_cloexec;
/* The paccept syscall was introduced at the same time as SOCK_CLOEXEC. */
# define have_paccept have_sock_cloexec
#endif
/* Number of times clients had to wait. */
unsigned long int client_queued;
@ -517,9 +525,15 @@ nscd_init (void)
#ifdef HAVE_INOTIFY
/* Use inotify to recognize changed files. */
inotify_fd = inotify_init ();
if (inotify_fd != -1)
fcntl (inotify_fd, F_SETFL, O_NONBLOCK);
inotify_fd = inotify_init1 (IN_NONBLOCK);
# ifndef __ASSUME_IN_NONBLOCK
if (inotify_fd == -1 && errno == ENOSYS)
{
inotify_fd = inotify_init ();
if (inotify_fd != -1)
fcntl (inotify_fd, F_SETFL, O_NONBLOCK);
}
# endif
#endif
for (size_t cnt = 0; cnt < lastdb; ++cnt)
@ -860,7 +874,21 @@ cannot set socket to close on exec: %s; disabling paranoia mode"),
}
/* Create the socket. */
sock = socket (AF_UNIX, SOCK_STREAM, 0);
#ifndef __ASSUME_SOCK_CLOEXEC
sock = -1;
if (have_sock_cloexec >= 0)
#endif
{
sock = socket (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
#ifdef __ASSUME_SOCK_CLOEXEC
if (have_sock_cloexec == 0)
have_sock_cloexec = sock != -1 || errno != EINVAL ? 1 : -1;
#endif
}
#ifndef __ASSUME_SOCK_CLOEXEC
if (have_sock_cloexec < 0)
sock = socket (AF_UNIX, SOCK_STREAM, 0);
#endif
if (sock < 0)
{
dbg_log (_("cannot open socket: %s"), strerror (errno));
@ -876,22 +904,27 @@ cannot set socket to close on exec: %s; disabling paranoia mode"),
exit (errno == EACCES ? 4 : 1);
}
/* We don't want to get stuck on accept. */
int fl = fcntl (sock, F_GETFL);
if (fl == -1 || fcntl (sock, F_SETFL, fl | O_NONBLOCK) == -1)
#ifndef __ASSUME_SOCK_CLOEXEC
if (have_sock_cloexec < 0)
{
dbg_log (_("cannot change socket to nonblocking mode: %s"),
strerror (errno));
exit (1);
}
/* We don't want to get stuck on accept. */
int fl = fcntl (sock, F_GETFL);
if (fl == -1 || fcntl (sock, F_SETFL, fl | O_NONBLOCK) == -1)
{
dbg_log (_("cannot change socket to nonblocking mode: %s"),
strerror (errno));
exit (1);
}
/* The descriptor needs to be closed on exec. */
if (paranoia && fcntl (sock, F_SETFD, FD_CLOEXEC) == -1)
{
dbg_log (_("cannot set socket to close on exec: %s"),
strerror (errno));
exit (1);
/* The descriptor needs to be closed on exec. */
if (paranoia && fcntl (sock, F_SETFD, FD_CLOEXEC) == -1)
{
dbg_log (_("cannot set socket to close on exec: %s"),
strerror (errno));
exit (1);
}
}
#endif
/* Set permissions for the socket. */
chmod (_PATH_NSCDSOCKET, DEFFILEMODE);
@ -1576,10 +1609,15 @@ nscd_run_worker (void *p)
/* We are done with the list. */
pthread_mutex_unlock (&readylist_lock);
/* We do not want to block on a short read or so. */
int fl = fcntl (fd, F_GETFL);
if (fl == -1 || fcntl (fd, F_SETFL, fl | O_NONBLOCK) == -1)
goto close_and_out;
#ifndef __ASSUME_SOCK_CLOEXEC
if (have_sock_cloexec < 0)
{
/* We do not want to block on a short read or so. */
int fl = fcntl (fd, F_GETFL);
if (fl == -1 || fcntl (fd, F_SETFL, fl | O_NONBLOCK) == -1)
goto close_and_out;
}
#endif
/* Now read the request. */
request_header req;
@ -1779,7 +1817,24 @@ main_loop_poll (void)
if (conns[0].revents != 0)
{
/* We have a new incoming connection. Accept the connection. */
int fd = TEMP_FAILURE_RETRY (accept (sock, NULL, NULL));
int fd;
#ifndef __ASSUME_PACCEPT
fd = -1;
if (have_paccept >= 0)
#endif
{
fd = TEMP_FAILURE_RETRY (paccept (sock, NULL, NULL, NULL,
SOCK_NONBLOCK));
#ifndef __ASSUME_PACCEPT
if (have_paccept == 0)
have_paccept = fd != -1 || errno != ENOSYS ? 1 : -1;
#endif
}
#ifndef __ASSUME_PACCEPT
if (have_paccept < 0)
fd = TEMP_FAILURE_RETRY (accept (sock, NULL, NULL));
#endif
/* Use the descriptor if we have not reached the limit. */
if (fd >= 0)

View File

@ -497,3 +497,12 @@
#if __LINUX_KERNEL_VERSION >= 0x02061b
# define __ASSUME_AT_EXECFN 1
#endif
/* Support for various CLOEXEC and NONBLOCK flags was added for x86 and
x86-64 in 2.6.27. */
#if __LINUX_KERNEL_VERSION >= 0x02061b \
&& (defined __i386__ || defined __x86_64__)
# define __ASSUME_SOCK_CLOEXEC 1
# define __ASSUME_IN_NONBLOCK 1
# define __ASSUME_PACCEPT 1
#endif