mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-30 22:43:12 +03:00
* 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:
@ -1,5 +1,11 @@
|
|||||||
2008-07-24 Ulrich Drepper <drepper@redhat.com>
|
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.
|
* Versions.def (glibc): Add GLIBC_2.9.
|
||||||
* io/Makefile (routines): Add dup3 and pipe2.
|
* io/Makefile (routines): Add dup3 and pipe2.
|
||||||
* io/Versions [glibc] (GLIBC_2.9): Add dup3 and pipe2.
|
* io/Versions [glibc] (GLIBC_2.9): Add dup3 and pipe2.
|
||||||
|
@ -234,6 +234,14 @@ static int inotify_fd = -1;
|
|||||||
static int resolv_conf_descr = -1;
|
static int resolv_conf_descr = -1;
|
||||||
#endif
|
#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. */
|
/* Number of times clients had to wait. */
|
||||||
unsigned long int client_queued;
|
unsigned long int client_queued;
|
||||||
|
|
||||||
@ -517,9 +525,15 @@ nscd_init (void)
|
|||||||
|
|
||||||
#ifdef HAVE_INOTIFY
|
#ifdef HAVE_INOTIFY
|
||||||
/* Use inotify to recognize changed files. */
|
/* Use inotify to recognize changed files. */
|
||||||
inotify_fd = inotify_init ();
|
inotify_fd = inotify_init1 (IN_NONBLOCK);
|
||||||
if (inotify_fd != -1)
|
# ifndef __ASSUME_IN_NONBLOCK
|
||||||
fcntl (inotify_fd, F_SETFL, O_NONBLOCK);
|
if (inotify_fd == -1 && errno == ENOSYS)
|
||||||
|
{
|
||||||
|
inotify_fd = inotify_init ();
|
||||||
|
if (inotify_fd != -1)
|
||||||
|
fcntl (inotify_fd, F_SETFL, O_NONBLOCK);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (size_t cnt = 0; cnt < lastdb; ++cnt)
|
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. */
|
/* 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)
|
if (sock < 0)
|
||||||
{
|
{
|
||||||
dbg_log (_("cannot open socket: %s"), strerror (errno));
|
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);
|
exit (errno == EACCES ? 4 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We don't want to get stuck on accept. */
|
#ifndef __ASSUME_SOCK_CLOEXEC
|
||||||
int fl = fcntl (sock, F_GETFL);
|
if (have_sock_cloexec < 0)
|
||||||
if (fl == -1 || fcntl (sock, F_SETFL, fl | O_NONBLOCK) == -1)
|
|
||||||
{
|
{
|
||||||
dbg_log (_("cannot change socket to nonblocking mode: %s"),
|
/* We don't want to get stuck on accept. */
|
||||||
strerror (errno));
|
int fl = fcntl (sock, F_GETFL);
|
||||||
exit (1);
|
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. */
|
/* The descriptor needs to be closed on exec. */
|
||||||
if (paranoia && fcntl (sock, F_SETFD, FD_CLOEXEC) == -1)
|
if (paranoia && fcntl (sock, F_SETFD, FD_CLOEXEC) == -1)
|
||||||
{
|
{
|
||||||
dbg_log (_("cannot set socket to close on exec: %s"),
|
dbg_log (_("cannot set socket to close on exec: %s"),
|
||||||
strerror (errno));
|
strerror (errno));
|
||||||
exit (1);
|
exit (1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Set permissions for the socket. */
|
/* Set permissions for the socket. */
|
||||||
chmod (_PATH_NSCDSOCKET, DEFFILEMODE);
|
chmod (_PATH_NSCDSOCKET, DEFFILEMODE);
|
||||||
@ -1576,10 +1609,15 @@ nscd_run_worker (void *p)
|
|||||||
/* We are done with the list. */
|
/* We are done with the list. */
|
||||||
pthread_mutex_unlock (&readylist_lock);
|
pthread_mutex_unlock (&readylist_lock);
|
||||||
|
|
||||||
/* We do not want to block on a short read or so. */
|
#ifndef __ASSUME_SOCK_CLOEXEC
|
||||||
int fl = fcntl (fd, F_GETFL);
|
if (have_sock_cloexec < 0)
|
||||||
if (fl == -1 || fcntl (fd, F_SETFL, fl | O_NONBLOCK) == -1)
|
{
|
||||||
goto close_and_out;
|
/* 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. */
|
/* Now read the request. */
|
||||||
request_header req;
|
request_header req;
|
||||||
@ -1779,7 +1817,24 @@ main_loop_poll (void)
|
|||||||
if (conns[0].revents != 0)
|
if (conns[0].revents != 0)
|
||||||
{
|
{
|
||||||
/* We have a new incoming connection. Accept the connection. */
|
/* 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. */
|
/* Use the descriptor if we have not reached the limit. */
|
||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
|
@ -497,3 +497,12 @@
|
|||||||
#if __LINUX_KERNEL_VERSION >= 0x02061b
|
#if __LINUX_KERNEL_VERSION >= 0x02061b
|
||||||
# define __ASSUME_AT_EXECFN 1
|
# define __ASSUME_AT_EXECFN 1
|
||||||
#endif
|
#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
|
||||||
|
Reference in New Issue
Block a user