Compare commits

...
Author SHA1 Message Date
Alexandre Oliva d4139de660 2014-11-07 07:18:53 -02:00
Alexandre Oliva 91bbe17981 2014-11-07 07:18:53 -02:00
Alexandre Oliva bc3ac8b177 for ChangeLog
PR network/9981
	* sysdeps/posix/getaddrinfo.c (getaddrinfo): Do not sort
	AI_PASSIVE addresses.
2014-11-07 07:18:53 -02:00
Alexandre Oliva 7875573cbe drop address family conversions from /etc/hosts parser
for ChangeLog

	* nss/nss_files/files-hosts.c (LINE_PARSER): Drop all address
	family conversions.
2014-11-07 07:18:53 -02:00
Alexandre Oliva 393207b6a7 drop v4-to-v6 conversions of loopback addresses from /etc/hosts
for ChangeLog

	* nss/nss_files/files-hosts.c (LINE_PARSER): Drop family
	conversion of loopback addresses from IPv4 to IPv6.
2014-11-07 07:18:53 -02:00
Alexandre Oliva 2e8a3341f4 drop v6-to-v4 conversions of loopback addresses from /etc/hosts
for ChangeLog

	* nss/nss_files/files-hosts.c (LINE_PARSER): Drop family
	conversion of loopback addresses from IPv6 to IPv4.
2014-11-07 07:18:53 -02:00
Alexandre Oliva 901aad32ed resolv: skip leading dot in domain to search
This should only happen if the domain to search is the root,
represented as . rather than by an empty string.  Skipping it here
prevents libc_res_nquerydomain from duplicating the trailing dot,
which would cause the domain name compression to fail.

for  ChangeLog

	PR 16469
	* resolv/res_query.c (__libc_res_nsearch): Skip leading dot in
	search domain names.
2014-11-07 07:18:53 -02:00
Alexandre Oliva ba878d017e don't drop trailing dot in res_nquerydomain(..., name, NULL, ...)
If we drop it here, we will fail to detect a duplicate trailing dot
later on.  Retaining, OTOH, has no ill effects whatsoever, and it even
saves us the trouble of copying the domain name minus the trailing
dot, like we used to do.

for ChangeLog

	PR 16469
	* resolv/res_query.c (__libc_res_nquerydomain): Retain
        trailing dot.
	* NEWS: Fixes 16469.
2014-11-07 07:18:53 -02:00
Alexandre Oliva ff9a1b7dce Do not continue in nss_db_getservbyname 2014-11-07 07:18:53 -02:00
Alexandre Oliva 6286965b02 create all sockets with SOCK_CLOEXEC 2014-11-07 07:18:52 -02:00
Alexandre Oliva c83b8a8717 introduce internal function to ease poll retry with timeout 2014-11-05 02:54:45 -02:00
27 changed files with 373 additions and 301 deletions
+2 -2
View File
@@ -9,8 +9,8 @@ Version 2.21
* The following bugs are resolved with this release:
6652, 12926, 14138, 14171, 15215, 15884, 17266, 17344, 17363, 17370,
17371, 17411, 17460, 17485, 17501, 17508, 17522.
6652, 12926, 14138, 14171, 15215, 15884, 16649, 17266, 17344, 17363,
17370, 17371, 17411, 17460, 17485, 17501, 17508, 17522.
Version 2.20
+105
View File
@@ -0,0 +1,105 @@
/* Copyright (C) 2014 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, see
<http://www.gnu.org/licenses/>. */
#ifndef _SOCKET_CLOEXEC_H
#define _SOCKET_CLOEXEC_H
#include <stdbool.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
/* Like socket, but with SOCK_CLOEXEC set if available. If it's not,
try to set the FD_CLOEXEC flag, and if that fails, close the socket
and fail unless __tolerant. */
static inline int
__socket_cloexec (int __domain, int __type, int __protocol, bool __tolerant)
{
int __ret;
#ifdef SOCK_CLOEXEC
# ifdef __ASSUME_SOCK_CLOEXEC
int __have_sock_cloexec = 1;
# endif /* __ASSUME_SOCK_CLOEXEC */
if (__have_sock_cloexec >= 0)
{
__ret = __socket (__domain, __type | SOCK_CLOEXEC, __protocol);
if (__have_sock_cloexec == 0)
__have_sock_cloexec = (__ret == -1 && errno == EINVAL ? -1 : 1);
if (__have_sock_cloexec > 0)
return __ret;
}
#endif /* SOCK_CLOEXEC */
__ret = __socket (__domain, __type, __protocol);
if ((__ret >= 0 && __fcntl (__ret, F_SETFD, FD_CLOEXEC) < 0) && !__tolerant)
{
__close (__ret);
__ret = -1;
}
return __ret;
}
/* Like socket, but with SOCK_CLOEXEC and SOCK_NONBLOCK set if
SOCK_CLOEXEC is available. SOCK_NONBLOCK is supported iff
SOCK_CLOEXEC is.
If SOCK_CLOEXEC is not supported, try to set the FD_CLOEXEC flag,
and if that fails, close the socket and fail unless __tolerant.
If SOCK_NONBLOCK is not supported, try to set the O_NONBLOCK flag,
and if that fails, close the socket and fail REGARDLESS of
__tolerant. */
static inline int
__socket_cloexec_nonblock (int __domain, int __type, int __protocol,
bool __tolerant)
{
int __ret;
#ifdef SOCK_NONBLOCK
# ifdef __ASSUME_SOCK_CLOEXEC
int __have_sock_cloexec = 1;
# endif /* __ASSUME_SOCK_CLOEXEC */
if (__have_sock_cloexec >= 0)
{
__ret = __socket (__domain, __type | SOCK_CLOEXEC | SOCK_NONBLOCK,
__protocol);
if (__have_sock_cloexec == 0)
__have_sock_cloexec = (__ret == -1 && errno == EINVAL ? -1 : 1);
if (__have_sock_cloexec > 0)
return __ret;
}
#endif /* SOCK_NONBLOCK */
__ret = __socket (__domain, __type, __protocol);
if (__ret >= 0)
{
int __fl = __fcntl (__ret, F_GETFL);
if (__fl == -1
|| __fcntl (__ret, F_SETFL, __fl | O_NONBLOCK) < 0
|| (__fcntl (__ret, F_SETFD, FD_CLOEXEC) < 0 && !__tolerant))
{
__close (__ret);
__ret = -1;
}
}
return __ret;
}
#pragma poison __socket
#pragma poison socket
#endif /* _SOCKET_CLOEXEC_H */
+41 -1
View File
@@ -6,6 +6,46 @@ extern int __poll (struct pollfd *__fds, unsigned long int __nfds,
int __timeout);
libc_hidden_proto (__poll)
libc_hidden_proto (ppoll)
#endif
#include <errno.h>
#include <sys/time.h>
static inline int
__poll_noeintr (struct pollfd *__fds, unsigned long int __nfds,
int __timeout)
{
int __ret = __poll (__fds, __nfds, __timeout);
if (__ret == -1 && __glibc_unlikely (errno == EINTR))
{
/* Handle the case where the poll() call is interrupted by a
signal. We cannot just use TEMP_FAILURE_RETRY since it might
lead to infinite loops. We can't tell how long poll has
already waited, and we can't assume the existence of a
higher-precision clock, but that's ok-ish: the timeout is a
lower bound, we just have to make sure we don't wait
indefinitely. */
struct timeval __now;
(void) __gettimeofday (&__now, NULL);
long int __end = __now.tv_sec * 1000 + __timeout
+ (__now.tv_usec + 500) / 1000;
while (1)
{
__ret = __poll (__fds, __nfds, __timeout);
if (__ret != -1 || errno != EINTR)
break;
/* Recompute the timeout time. */
(void) __gettimeofday (&__now, NULL);
__timeout = __end - __now.tv_sec * 1000
- (__now.tv_usec + 500) / 1000;
}
}
return __ret;
}
#endif /* _ISOMAC */
#endif
+1 -2
View File
@@ -215,8 +215,7 @@ internal_nis_do_callback (struct dir_binding *bptr, netobj *cookie,
my_pollfd[i].revents = 0;
}
switch (i = TEMP_FAILURE_RETRY (__poll (my_pollfd, svc_max_pollfd,
25*1000)))
switch (i = __poll_noeintr (my_pollfd, svc_max_pollfd, 25*1000))
{
case -1:
return NIS_CBERROR;
+17 -41
View File
@@ -233,12 +233,7 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
bool alloca_used = false;
dataset = NULL;
/* If the record contains more than one IP address (used for
load balancing etc) don't cache the entry. This is something
the current cache handling cannot handle and it is more than
questionable whether it is worthwhile complicating the cache
handling just for handling such a special case. */
if (he == NULL && h_addr_list_cnt == 1)
if (he == NULL)
dataset = (struct dataset *) mempool_alloc (db, total + req->key_len,
1);
@@ -312,33 +307,29 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
/* The data has not changed. We will just bump the
timeout value. Note that the new record has been
allocated on the stack and need not be freed. */
assert (h_addr_list_cnt == 1);
dh->ttl = dataset->head.ttl;
dh->timeout = dataset->head.timeout;
++dh->nreloads;
}
else
{
if (h_addr_list_cnt == 1)
/* We have to create a new record. Just allocate
appropriate memory and copy it. */
struct dataset *newp
= (struct dataset *) mempool_alloc (db,
total + req->key_len,
1);
if (newp != NULL)
{
/* We have to create a new record. Just allocate
appropriate memory and copy it. */
struct dataset *newp
= (struct dataset *) mempool_alloc (db,
total + req->key_len,
1);
if (newp != NULL)
{
/* Adjust pointers into the memory block. */
addresses = (char *) newp + (addresses
- (char *) dataset);
aliases = (char *) newp + (aliases - (char *) dataset);
assert (key_copy != NULL);
key_copy = (char *) newp + (key_copy - (char *) dataset);
/* Adjust pointers into the memory block. */
addresses = (char *) newp + (addresses
- (char *) dataset);
aliases = (char *) newp + (aliases - (char *) dataset);
assert (key_copy != NULL);
key_copy = (char *) newp + (key_copy - (char *) dataset);
dataset = memcpy (newp, dataset, total + req->key_len);
alloca_used = false;
}
dataset = memcpy (newp, dataset, total + req->key_len);
alloca_used = false;
}
/* Mark the old record as obsolete. */
@@ -386,13 +377,7 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
}
/* Add the record to the database. But only if it has not been
stored on the stack.
If the record contains more than one IP address (used for
load balancing etc) don't cache the entry. This is something
the current cache handling cannot handle and it is more than
questionable whether it is worthwhile complicating the cache
handling just for handling such a special case. */
stored on the stack. */
if (! alloca_used)
{
/* If necessary, we also propagate the data to disk. */
@@ -405,15 +390,6 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
+ total + req->key_len, MS_ASYNC);
}
/* NB: the following code is really complicated. It has
seemlingly duplicated code paths which do the same. The
problem is that we always must add the hash table entry
with the FIRST flag set first. Otherwise we get dangling
pointers in case memory allocation fails. */
assert (hst->h_addr_list[1] == NULL);
/* Avoid adding names if more than one address is available. See
above for more info. */
assert (req->type == GETHOSTBYNAME
|| req->type == GETHOSTBYNAMEv6
|| req->type == GETHOSTBYADDR
+1 -23
View File
@@ -53,29 +53,7 @@ wait_on_socket (int sock, long int usectmo)
struct pollfd fds[1];
fds[0].fd = sock;
fds[0].events = POLLIN | POLLERR | POLLHUP;
int n = __poll (fds, 1, usectmo);
if (n == -1 && __builtin_expect (errno == EINTR, 0))
{
/* Handle the case where the poll() call is interrupted by a
signal. We cannot just use TEMP_FAILURE_RETRY since it might
lead to infinite loops. */
struct timeval now;
(void) __gettimeofday (&now, NULL);
long int end = now.tv_sec * 1000 + usectmo + (now.tv_usec + 500) / 1000;
long int timeout = usectmo;
while (1)
{
n = __poll (fds, 1, timeout);
if (n != -1 || errno != EINTR)
break;
/* Recompute the timeout time. */
(void) __gettimeofday (&now, NULL);
timeout = end - (now.tv_sec * 1000 + (now.tv_usec + 500) / 1000);
}
}
return n;
return __poll_noeintr (fds, 1, usectmo);
}
+6 -3
View File
@@ -191,6 +191,12 @@ enum nss_status \
char *p = memcpy (buffer, valstr, len); \
\
int err = parse_line (p, result, data, buflen, errnop EXTRA_ARGS); \
\
/* Advance before break_if_match, lest it uses continue to skip
to the next entry. */ \
if ((hidx += hval2) >= header->dbs[i].hashsize) \
hidx -= header->dbs[i].hashsize; \
\
if (err > 0) \
{ \
status = NSS_STATUS_SUCCESS; \
@@ -203,9 +209,6 @@ enum nss_status \
status = NSS_STATUS_TRYAGAIN; \
break; \
} \
\
if ((hidx += hval2) >= header->dbs[i].hashsize) \
hidx -= header->dbs[i].hashsize; \
} \
\
if (status == NSS_STATUS_NOTFOUND) \
+5 -26
View File
@@ -57,33 +57,12 @@ LINE_PARSER
if (inet_pton (af == AF_UNSPEC ? AF_INET : af, addr, entdata->host_addr)
> 0)
af = af == AF_UNSPEC ? AF_INET : af;
else if (af == AF_UNSPEC
&& inet_pton (AF_INET6, addr, entdata->host_addr) > 0)
af = AF_INET6;
else
{
if (af == AF_INET6 && (flags & AI_V4MAPPED) != 0
&& inet_pton (AF_INET, addr, entdata->host_addr) > 0)
map_v4v6_address ((char *) entdata->host_addr,
(char *) entdata->host_addr);
else if (af == AF_INET
&& inet_pton (AF_INET6, addr, entdata->host_addr) > 0)
{
if (IN6_IS_ADDR_V4MAPPED (entdata->host_addr))
memcpy (entdata->host_addr, entdata->host_addr + 12, INADDRSZ);
else if (IN6_IS_ADDR_LOOPBACK (entdata->host_addr))
{
in_addr_t localhost = htonl (INADDR_LOOPBACK);
memcpy (entdata->host_addr, &localhost, sizeof (localhost));
}
else
/* Illegal address: ignore line. */
return 0;
}
else if (af == AF_UNSPEC
&& inet_pton (AF_INET6, addr, entdata->host_addr) > 0)
af = AF_INET6;
else
/* Illegal address: ignore line. */
return 0;
}
/* Illegal address: ignore line. */
return 0;
/* We always return entries of the requested form. */
result->h_addrtype = af;
+5 -2
View File
@@ -44,8 +44,11 @@ DB_LOOKUP (servbyname, ':',
{
/* Must match both protocol (if specified) and name. */
if (proto != NULL && strcmp (result->s_proto, proto))
continue;
LOOKUP_NAME (s_name, s_aliases)
/* A continue statement here breaks nss_db, because it
bypasses advancing to the next db entry, and it
doesn't make nss_files any more efficient. */;
else
LOOKUP_NAME (s_name, s_aliases)
},
const char *name, const char *proto)
+2 -1
View File
@@ -41,6 +41,7 @@
#include <sys/ioctl.h>
#include <unistd.h>
#include <netinet/in.h>
#include <socket-cloexec.h>
#include <bits/libc-lock.h>
#include "ifreq.h"
#include "res_hconf.h"
@@ -410,7 +411,7 @@ _res_hconf_reorder_addrs (struct hostent *hp)
/* Initialize interface table. */
/* The SIOCGIFNETMASK ioctl will only work on an AF_INET socket. */
sd = __socket (AF_INET, SOCK_DGRAM, 0);
sd = __socket_cloexec (AF_INET, SOCK_DGRAM, 0, true);
if (sd < 0)
return;
+6 -12
View File
@@ -413,13 +413,15 @@ __libc_res_nsearch(res_state statp,
for (domain = (const char * const *)statp->dnsrch;
*domain && !done;
domain++) {
const char *dname = domain[0];
searched = 1;
if (domain[0][0] == '\0' ||
(domain[0][0] == '.' && domain[0][1] == '\0'))
if (dname[0] == '.')
dname++;
if (dname[0] == '\0')
root_on_list++;
ret = __libc_res_nquerydomain(statp, name, *domain,
ret = __libc_res_nquerydomain(statp, name, dname,
class, type,
answer, anslen, answerp,
answerp2, nanswerp2,
@@ -561,10 +563,6 @@ __libc_res_nquerydomain(res_state statp,
name, domain?domain:"<Nil>", class, type);
#endif
if (domain == NULL) {
/*
* Check for trailing '.';
* copy without '.' if present.
*/
n = strlen(name);
/* Decrement N prior to checking it against MAXDNAME
@@ -575,11 +573,7 @@ __libc_res_nquerydomain(res_state statp,
RES_SET_H_ERRNO(statp, NO_RECOVERY);
return (-1);
}
if (name[n] == '.') {
strncpy(nbuf, name, n);
nbuf[n] = '\0';
} else
longname = name;
longname = name;
} else {
n = strlen(name);
d = strlen(domain);
+8 -7
View File
@@ -17,6 +17,7 @@
#include <stdio.h>
#include <sys/socket.h>
#include <socket-cloexec.h>
#include <bits/libc-lock.h>
/* Return a socket of any type. The socket can be used in subsequent
@@ -32,7 +33,7 @@ __opensock (void)
if (sock_af != -1)
{
fd = __socket (sock_af, SOCK_DGRAM, 0);
fd = __socket_cloexec (sock_af, SOCK_DGRAM, 0, true);
if (fd != -1)
return fd;
}
@@ -40,28 +41,28 @@ __opensock (void)
__libc_lock_lock (lock);
if (sock_af != -1)
fd = __socket (sock_af, SOCK_DGRAM, 0);
fd = __socket_cloexec (sock_af, SOCK_DGRAM, 0, true);
if (fd == -1)
{
#ifdef AF_INET
fd = __socket (sock_af = AF_INET, SOCK_DGRAM, 0);
fd = __socket_cloexec (sock_af = AF_INET, SOCK_DGRAM, 0, true);
#endif
#ifdef AF_INET6
if (fd < 0)
fd = __socket (sock_af = AF_INET6, SOCK_DGRAM, 0);
fd = __socket_cloexec (sock_af = AF_INET6, SOCK_DGRAM, 0, true);
#endif
#ifdef AF_IPX
if (fd < 0)
fd = __socket (sock_af = AF_IPX, SOCK_DGRAM, 0);
fd = __socket_cloexec (sock_af = AF_IPX, SOCK_DGRAM, 0, true);
#endif
#ifdef AF_AX25
if (fd < 0)
fd = __socket (sock_af = AF_AX25, SOCK_DGRAM, 0);
fd = __socket_cloexec (sock_af = AF_AX25, SOCK_DGRAM, 0, true);
#endif
#ifdef AF_APPLETALK
if (fd < 0)
fd = __socket (sock_af = AF_APPLETALK, SOCK_DGRAM, 0);
fd = __socket_cloexec (sock_af = AF_APPLETALK, SOCK_DGRAM, 0, true);
#endif
}
+2 -1
View File
@@ -52,6 +52,7 @@
#include <rpc/rpc.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <socket-cloexec.h>
#include <rpc/pmap_clnt.h>
#include <wchar.h>
@@ -146,7 +147,7 @@ clnttcp_create (struct sockaddr_in *raddr, u_long prog, u_long vers,
*/
if (*sockp < 0)
{
*sockp = __socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
*sockp = __socket_cloexec (AF_INET, SOCK_STREAM, IPPROTO_TCP, true);
(void) bindresvport (*sockp, (struct sockaddr_in *) 0);
if ((*sockp < 0)
|| (__connect (*sockp, (struct sockaddr *) raddr,
+1 -4
View File
@@ -378,9 +378,8 @@ send_again:
anyup = 0;
for (;;)
{
switch (__poll (&fd, 1, milliseconds))
switch (__poll_noeintr (&fd, 1, milliseconds))
{
case 0:
if (anyup == 0)
{
@@ -407,8 +406,6 @@ send_again:
* updated.
*/
case -1:
if (errno == EINTR)
continue;
cu->cu_error.re_errno = errno;
return (cu->cu_error.re_status = RPC_CANTRECV);
}
+10 -15
View File
@@ -53,6 +53,7 @@
#include <sys/uio.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <socket-cloexec.h>
#include <rpc/pmap_clnt.h>
#include <wchar.h>
@@ -132,7 +133,7 @@ clntunix_create (struct sockaddr_un *raddr, u_long prog, u_long vers,
*/
if (*sockp < 0)
{
*sockp = __socket (AF_UNIX, SOCK_STREAM, 0);
*sockp = __socket_cloexec (AF_UNIX, SOCK_STREAM, 0, true);
len = strlen (raddr->sun_path) + sizeof (raddr->sun_family) + 1;
if (*sockp < 0
|| __connect (*sockp, (struct sockaddr *) raddr, len) < 0)
@@ -551,22 +552,16 @@ readunix (char *ctptr, char *buf, int len)
fd.fd = ct->ct_sock;
fd.events = POLLIN;
while (TRUE)
switch (__poll_noeintr (&fd, 1, milliseconds))
{
switch (__poll (&fd, 1, milliseconds))
{
case 0:
ct->ct_error.re_status = RPC_TIMEDOUT;
return -1;
case 0:
ct->ct_error.re_status = RPC_TIMEDOUT;
return -1;
case -1:
if (errno == EINTR)
continue;
ct->ct_error.re_status = RPC_CANTRECV;
ct->ct_error.re_errno = errno;
return -1;
}
break;
case -1:
ct->ct_error.re_status = RPC_CANTRECV;
ct->ct_error.re_errno = errno;
return -1;
}
switch (len = __msgread (ct->ct_sock, buf, len))
{
+2 -1
View File
@@ -38,6 +38,7 @@
#include <rpc/pmap_prot.h>
#include <rpc/pmap_clnt.h>
#include <sys/socket.h>
#include <socket-cloexec.h>
/*
* Create a socket that is locally bound to a non-reserve port. For
@@ -48,7 +49,7 @@ int
internal_function
__get_socket (struct sockaddr_in *saddr)
{
int so = __socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
int so = __socket_cloexec (AF_INET, SOCK_STREAM, IPPROTO_TCP, true);
if (so < 0)
return -1;
+2 -1
View File
@@ -42,6 +42,7 @@
#include <rpc/pmap_rmt.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <socket-cloexec.h>
#include <stdio.h>
#include <errno.h>
#undef _POSIX_SOURCE /* Ultrix <sys/param.h> needs --roland@gnu */
@@ -238,7 +239,7 @@ clnt_broadcast (prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
* initialization: create a socket, a broadcast address, and
* preserialize the arguments into a send buffer.
*/
if ((sock = __socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
if ((sock = __socket_cloexec (AF_INET, SOCK_DGRAM, IPPROTO_UDP, true)) < 0)
{
perror (_("Cannot create socket for broadcast rpc"));
stat = RPC_CANTSEND;
+3 -4
View File
@@ -45,6 +45,7 @@
#include <sys/types.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <socket-cloexec.h>
#include <sys/time.h>
#include <rpc/auth_des.h>
#include <errno.h>
@@ -84,7 +85,7 @@ rtime (struct sockaddr_in *addrp, struct rpc_timeval *timep,
else
type = SOCK_DGRAM;
s = __socket (AF_INET, type, 0);
s = __socket_cloexec (AF_INET, type, 0, true);
if (s < 0)
return (-1);
@@ -102,9 +103,7 @@ rtime (struct sockaddr_in *addrp, struct rpc_timeval *timep,
milliseconds = (timeout->tv_sec * 1000) + (timeout->tv_usec / 1000);
fd.fd = s;
fd.events = POLLIN;
do
res = __poll (&fd, 1, milliseconds);
while (res < 0 && errno == EINTR);
res = __poll_noeintr (&fd, 1, milliseconds);
if (res <= 0)
{
if (res == 0)
+1 -3
View File
@@ -83,11 +83,9 @@ svc_run (void)
my_pollfd[i].revents = 0;
}
switch (i = __poll (my_pollfd, max_pollfd, -1))
switch (i = __poll_noeintr (my_pollfd, max_pollfd, -1))
{
case -1:
if (errno == EINTR)
continue;
perror (_("svc_run: - poll failed"));
break;
case 0:
+14 -19
View File
@@ -58,6 +58,7 @@
#include <libintl.h>
#include <rpc/rpc.h>
#include <sys/socket.h>
#include <socket-cloexec.h>
#include <sys/poll.h>
#include <errno.h>
#include <stdlib.h>
@@ -159,7 +160,8 @@ svctcp_create (int sock, u_int sendsize, u_int recvsize)
if (sock == RPC_ANYSOCK)
{
if ((sock = __socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
if ((sock = __socket_cloexec (AF_INET, SOCK_STREAM, IPPROTO_TCP,
true)) < 0)
{
perror (_("svc_tcp.c - tcp socket creation problem"));
return (SVCXPRT *) NULL;
@@ -317,26 +319,19 @@ readtcp (char *xprtptr, char *buf, int len)
int milliseconds = 35 * 1000;
struct pollfd pollfd;
do
pollfd.fd = sock;
pollfd.events = POLLIN;
switch (__poll_noeintr (&pollfd, 1, milliseconds))
{
pollfd.fd = sock;
pollfd.events = POLLIN;
switch (__poll (&pollfd, 1, milliseconds))
{
case -1:
if (errno == EINTR)
continue;
/*FALLTHROUGH*/
case 0:
goto fatal_err;
default:
if ((pollfd.revents & POLLERR) || (pollfd.revents & POLLHUP)
|| (pollfd.revents & POLLNVAL))
goto fatal_err;
break;
}
case -1:
case 0:
goto fatal_err;
default:
if ((pollfd.revents & POLLERR) || (pollfd.revents & POLLHUP)
|| (pollfd.revents & POLLNVAL))
goto fatal_err;
break;
}
while ((pollfd.revents & POLLIN) == 0);
if ((len = __read (sock, buf, len)) > 0)
return len;
+3 -1
View File
@@ -55,6 +55,7 @@
#include <string.h>
#include <rpc/rpc.h>
#include <sys/socket.h>
#include <socket-cloexec.h>
#include <errno.h>
#include <libintl.h>
@@ -132,7 +133,8 @@ svcudp_bufcreate (sock, sendsz, recvsz)
if (sock == RPC_ANYSOCK)
{
if ((sock = __socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
if ((sock = __socket_cloexec (AF_INET, SOCK_DGRAM, IPPROTO_UDP,
true)) < 0)
{
perror (_("svcudp_create: socket creation problem"));
return (SVCXPRT *) NULL;
+13 -19
View File
@@ -58,6 +58,7 @@
#include <rpc/rpc.h>
#include <rpc/svc.h>
#include <sys/socket.h>
#include <socket-cloexec.h>
#include <sys/uio.h>
#include <sys/poll.h>
#include <errno.h>
@@ -157,7 +158,7 @@ svcunix_create (int sock, u_int sendsize, u_int recvsize, char *path)
if (sock == RPC_ANYSOCK)
{
if ((sock = __socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
if ((sock = __socket_cloexec (AF_UNIX, SOCK_STREAM, 0, true)) < 0)
{
perror (_("svc_unix.c - AF_UNIX socket creation problem"));
return (SVCXPRT *) NULL;
@@ -419,26 +420,19 @@ readunix (char *xprtptr, char *buf, int len)
int milliseconds = 35 * 1000;
struct pollfd pollfd;
do
pollfd.fd = sock;
pollfd.events = POLLIN;
switch (__poll_noeintr (&pollfd, 1, milliseconds))
{
pollfd.fd = sock;
pollfd.events = POLLIN;
switch (__poll (&pollfd, 1, milliseconds))
{
case -1:
if (errno == EINTR)
continue;
/*FALLTHROUGH*/
case 0:
goto fatal_err;
default:
if ((pollfd.revents & POLLERR) || (pollfd.revents & POLLHUP)
|| (pollfd.revents & POLLNVAL))
goto fatal_err;
break;
}
case -1:
case 0:
goto fatal_err;
default:
if ((pollfd.revents & POLLERR) || (pollfd.revents & POLLHUP)
|| (pollfd.revents & POLLNVAL))
goto fatal_err;
break;
}
while ((pollfd.revents & POLLIN) == 0);
if ((len = __msgread (sock, buf, len)) > 0)
return len;
+2 -1
View File
@@ -19,6 +19,7 @@
#include <ifaddrs.h>
#include <net/if.h>
#include <sys/socket.h>
#include <socket-cloexec.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdlib.h>
@@ -37,7 +38,7 @@ getifaddrs (struct ifaddrs **ifap)
/* This implementation handles only IPv4 interfaces.
The various ioctls below will only work on an AF_INET socket.
Some different mechanism entirely must be used for IPv6. */
int fd = __socket (AF_INET, SOCK_DGRAM, 0);
int fd = __socket_cloexec (AF_INET, SOCK_DGRAM, 0, true);
struct ifreq *ifreqs;
int nifs;
+114 -109
View File
@@ -52,6 +52,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <net/if.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <socket-cloexec.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/un.h>
@@ -565,113 +566,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
int no_more;
int old_res_options;
/* If we do not have to look for IPv6 addresses or the canonical
name, use the simple, old functions, which do not support
IPv6 scope ids, nor retrieving the canonical name. */
if (req->ai_family == AF_INET
&& (req->ai_flags & AI_CANONNAME) == 0)
{
/* Allocate additional room for struct host_data. */
size_t tmpbuflen = (512 + MAX_NR_ALIASES * sizeof(char*)
+ 16 * sizeof(char));
assert (tmpbuf == NULL);
tmpbuf = alloca_account (tmpbuflen, alloca_used);
int rc;
struct hostent th;
struct hostent *h;
int herrno;
while (1)
{
rc = __gethostbyname2_r (name, AF_INET, &th, tmpbuf,
tmpbuflen, &h, &herrno);
if (rc != ERANGE || herrno != NETDB_INTERNAL)
break;
if (!malloc_tmpbuf
&& __libc_use_alloca (alloca_used + 2 * tmpbuflen))
tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen,
2 * tmpbuflen,
alloca_used);
else
{
char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL,
2 * tmpbuflen);
if (newp == NULL)
{
result = -EAI_MEMORY;
goto free_and_return;
}
tmpbuf = newp;
malloc_tmpbuf = true;
tmpbuflen = 2 * tmpbuflen;
}
}
if (rc == 0)
{
if (h != NULL)
{
int i;
/* We found data, count the number of addresses. */
for (i = 0; h->h_addr_list[i]; ++i)
;
if (i > 0 && *pat != NULL)
--i;
if (__libc_use_alloca (alloca_used
+ i * sizeof (struct gaih_addrtuple)))
addrmem = alloca_account (i * sizeof (struct gaih_addrtuple),
alloca_used);
else
{
addrmem = malloc (i
* sizeof (struct gaih_addrtuple));
if (addrmem == NULL)
{
result = -EAI_MEMORY;
goto free_and_return;
}
malloc_addrmem = true;
}
/* Now convert it into the list. */
struct gaih_addrtuple *addrfree = addrmem;
for (i = 0; h->h_addr_list[i]; ++i)
{
if (*pat == NULL)
{
*pat = addrfree++;
(*pat)->scopeid = 0;
}
(*pat)->next = NULL;
(*pat)->family = AF_INET;
memcpy ((*pat)->addr, h->h_addr_list[i],
h->h_length);
pat = &((*pat)->next);
}
}
}
else
{
if (herrno == NETDB_INTERNAL)
{
__set_h_errno (herrno);
result = -EAI_SYSTEM;
}
else if (herrno == TRY_AGAIN)
result = -EAI_AGAIN;
else
/* We made requests but they turned out no data.
The name is known, though. */
result = -EAI_NODATA;
goto free_and_return;
}
goto process_list;
}
#ifdef USE_NSCD
if (__nss_not_use_nscd_hosts > 0
&& ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY)
@@ -805,6 +699,113 @@ gaih_inet (const char *name, const struct gaih_service *service,
}
#endif
/* If we do not have to look for IPv6 addresses or the canonical
name, use the simple, old functions, which do not support
IPv6 scope ids, nor retrieving the canonical name. */
if (req->ai_family == AF_INET
&& (req->ai_flags & AI_CANONNAME) == 0)
{
/* Allocate additional room for struct host_data. */
size_t tmpbuflen = (512 + MAX_NR_ALIASES * sizeof(char*)
+ 16 * sizeof(char));
assert (tmpbuf == NULL);
tmpbuf = alloca_account (tmpbuflen, alloca_used);
int rc;
struct hostent th;
struct hostent *h;
int herrno;
while (1)
{
rc = __gethostbyname2_r (name, AF_INET, &th, tmpbuf,
tmpbuflen, &h, &herrno);
if (rc != ERANGE || herrno != NETDB_INTERNAL)
break;
if (!malloc_tmpbuf
&& __libc_use_alloca (alloca_used + 2 * tmpbuflen))
tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen,
2 * tmpbuflen,
alloca_used);
else
{
char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL,
2 * tmpbuflen);
if (newp == NULL)
{
result = -EAI_MEMORY;
goto free_and_return;
}
tmpbuf = newp;
malloc_tmpbuf = true;
tmpbuflen = 2 * tmpbuflen;
}
}
if (rc == 0)
{
if (h != NULL)
{
int i;
/* We found data, count the number of addresses. */
for (i = 0; h->h_addr_list[i]; ++i)
;
if (i > 0 && *pat != NULL)
--i;
if (__libc_use_alloca (alloca_used
+ i * sizeof (struct gaih_addrtuple)))
addrmem = alloca_account (i * sizeof (struct gaih_addrtuple),
alloca_used);
else
{
addrmem = malloc (i
* sizeof (struct gaih_addrtuple));
if (addrmem == NULL)
{
result = -EAI_MEMORY;
goto free_and_return;
}
malloc_addrmem = true;
}
/* Now convert it into the list. */
struct gaih_addrtuple *addrfree = addrmem;
for (i = 0; h->h_addr_list[i]; ++i)
{
if (*pat == NULL)
{
*pat = addrfree++;
(*pat)->scopeid = 0;
}
(*pat)->next = NULL;
(*pat)->family = AF_INET;
memcpy ((*pat)->addr, h->h_addr_list[i],
h->h_length);
pat = &((*pat)->next);
}
}
}
else
{
if (herrno == NETDB_INTERNAL)
{
__set_h_errno (herrno);
result = -EAI_SYSTEM;
}
else if (herrno == TRY_AGAIN)
result = -EAI_AGAIN;
else
/* We made requests but they turned out no data.
The name is known, though. */
result = -EAI_NODATA;
goto free_and_return;
}
goto process_list;
}
if (__nss_hosts_database == NULL)
no_more = __nss_database_lookup ("hosts", NULL,
"dns [!UNAVAIL=return] files",
@@ -2434,7 +2435,11 @@ getaddrinfo (const char *name, const char *service,
return EAI_FAMILY;
}
if (naddrs > 1)
/* We don't want to sort the localhost addresses used for passive
binding; if the caller asked for both address types, we want to
return IPv6+IPv4 before IPv4, because if we bind to IPv4 first,
the IPv6 bind will fail. */
if (naddrs > 1 && (name || (hints->ai_flags & AI_PASSIVE) == 0))
{
/* Read the config file. */
__libc_once_define (static, once);
@@ -2512,7 +2517,7 @@ getaddrinfo (const char *name, const char *service,
close_retry:
close_not_cancel_no_status (fd);
af = q->ai_family;
fd = __socket (af, SOCK_DGRAM, IPPROTO_IP);
fd = __socket_cloexec (af, SOCK_DGRAM, IPPROTO_IP, true);
}
else
{
+3 -1
View File
@@ -28,6 +28,8 @@
#include <net/if.h>
#include <net/if_arp.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <socket-cloexec.h>
#include <asm/types.h>
#include <linux/netlink.h>
@@ -40,7 +42,7 @@ void
__check_native (uint32_t a1_index, int *a1_native,
uint32_t a2_index, int *a2_native)
{
int fd = __socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
int fd = __socket_cloexec (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE, true);
struct sockaddr_nl nladdr;
memset (&nladdr, '\0', sizeof (nladdr));
+2 -1
View File
@@ -26,6 +26,7 @@
#include <unistd.h>
#include <stdint.h>
#include <sys/socket.h>
#include <socket-cloexec.h>
#include <asm/types.h>
#include <linux/netlink.h>
@@ -353,7 +354,7 @@ __check_pf (bool *seen_ipv4, bool *seen_ipv6,
}
else
{
int fd = __socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
int fd = __socket_cloexec (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE, true);
if (__glibc_likely (fd >= 0))
{
+2 -1
View File
@@ -29,6 +29,7 @@
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <socket-cloexec.h>
#include <sysdep.h>
#include <time.h>
#include <unistd.h>
@@ -251,7 +252,7 @@ __netlink_open (struct netlink_handle *h)
{
struct sockaddr_nl nladdr;
h->fd = __socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
h->fd = __socket_cloexec (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE, true);
if (h->fd < 0)
goto out;