Skip to content

Commit

Permalink
* nscd/nscd_helper.c (open_socket): Now takes request type and key
Browse files Browse the repository at this point in the history
	as parameter.  Construct request record.  Try sending request
	before the first poll use, it usually succeeds.  Adjust all
	callers.
	* nscd/nscd-client.h: Define MAXKEYLEN.
  • Loading branch information
Ulrich Drepper committed Jan 31, 2007
1 parent 8f9bf73 commit 58a2d52
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 52 deletions.
8 changes: 8 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
2007-01-31 Ulrich Drepper <drepper@redhat.com>

* nscd/nscd_helper.c (open_socket): Now takes request type and key
as parameter. Construct request record. Try sending request
before the first poll use, it usually succeeds. Adjust all
callers.
* nscd/nscd-client.h: Define MAXKEYLEN.

2007-01-31 Jakub Jelinek <jakub@redhat.com>

* nscd/nscd-client.h (__nscd_cache_search): Remove const qualifier
Expand Down
124 changes: 72 additions & 52 deletions nscd/nscd_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,16 +97,20 @@ __readvall (int fd, const struct iovec *iov, int iovcnt)


static int
open_socket (void)
open_socket (request_type type, const char *key, size_t keylen)
{
int sock = __socket (PF_UNIX, SOCK_STREAM, 0);
if (sock < 0)
return -1;

struct
{
request_header req;
char key[keylen];
} reqdata;

/* Make socket non-blocking. */
int fl = __fcntl (sock, F_GETFL);
if (fl != -1)
__fcntl (sock, F_SETFL, fl | O_NONBLOCK);
__fcntl (sock, F_SETFL, O_RDWR | O_NONBLOCK);

struct sockaddr_un sun;
sun.sun_family = AF_UNIX;
Expand All @@ -115,13 +119,56 @@ open_socket (void)
&& errno != EINPROGRESS)
goto out;

struct pollfd fds[1];
fds[0].fd = sock;
fds[0].events = POLLOUT | POLLERR | POLLHUP;
if (__poll (fds, 1, 5 * 1000) > 0)
/* Success. We do not check for success of the connect call here.
If it failed, the following operations will fail. */
return sock;
reqdata.req.version = NSCD_VERSION;
reqdata.req.type = type;
reqdata.req.key_len = keylen;

memcpy (reqdata.key, key, keylen);

bool first_try = true;
struct timeval tvend;
while (1)
{
#ifndef MSG_NOSIGNAL
# define MSG_NOSIGNAL 0
#endif
ssize_t wres = TEMP_FAILURE_RETRY (__send (sock, &reqdata,
sizeof (reqdata),
MSG_NOSIGNAL));
if (__builtin_expect (wres == (ssize_t) sizeof (reqdata), 1))
/* We managed to send the request. */
return sock;

if (wres != -1 || errno != EAGAIN)
/* Something is really wrong, no chance to continue. */
break;

/* The daemon is busy wait for it. */
int to;
if (first_try)
{
gettimeofday (&tvend, NULL);
tvend.tv_sec += 5;
to = 5 * 1000;
first_try = false;
}
else
{
struct timeval now;
gettimeofday (&now, NULL);
to = ((tvend.tv_sec - now.tv_sec) * 1000
+ (tvend.tv_usec - now.tv_usec) / 1000);
}

struct pollfd fds[1];
fds[0].fd = sock;
fds[0].events = POLLOUT | POLLERR | POLLHUP;
if (__poll (fds, 1, to) <= 0)
/* The connection timed out or broke down. */
break;

/* We try to write again. */
}

out:
close_not_cancel_no_status (sock);
Expand Down Expand Up @@ -181,36 +228,15 @@ get_mapping (request_type type, const char *key,
int saved_errno = errno;

int mapfd = -1;
char resdata[keylen];

/* Send the request. */
struct
{
request_header req;
char key[keylen];
} reqdata;

int sock = open_socket ();
/* Open a socket and send the request. */
int sock = open_socket (type, key, keylen);
if (sock < 0)
goto out;

reqdata.req.version = NSCD_VERSION;
reqdata.req.type = type;
reqdata.req.key_len = keylen;
memcpy (reqdata.key, key, keylen);

# ifndef MSG_NOSIGNAL
# define MSG_NOSIGNAL 0
# endif
if (__builtin_expect (TEMP_FAILURE_RETRY (__send (sock, &reqdata,
sizeof (reqdata),
MSG_NOSIGNAL))
!= sizeof (reqdata), 0))
/* We cannot even write the request. */
goto out_close2;

/* Room for the data sent along with the file descriptor. We expect
the key name back. */
# define resdata reqdata.key
struct iovec iov[1];
iov[0].iov_base = resdata;
iov[0].iov_len = keylen;
Expand Down Expand Up @@ -423,28 +449,22 @@ int
__nscd_open_socket (const char *key, size_t keylen, request_type type,
void *response, size_t responselen)
{
/* This should never happen and it is something the nscd daemon
enforces, too. He it helps to limit the amount of stack
used. */
if (keylen > MAXKEYLEN)
return -1;

int saved_errno = errno;

int sock = open_socket ();
int sock = open_socket (type, key, keylen);
if (sock >= 0)
{
request_header req;
req.version = NSCD_VERSION;
req.type = type;
req.key_len = keylen;

struct iovec vec[2];
vec[0].iov_base = &req;
vec[0].iov_len = sizeof (request_header);
vec[1].iov_base = (void *) key;
vec[1].iov_len = keylen;

ssize_t nbytes = TEMP_FAILURE_RETRY (__writev (sock, vec, 2));
if (nbytes == (ssize_t) (sizeof (request_header) + keylen)
/* Wait for data. */
&& wait_on_socket (sock) > 0)
/* Wait for data. */
if (wait_on_socket (sock) > 0)
{
nbytes = TEMP_FAILURE_RETRY (__read (sock, response, responselen));
ssize_t nbytes = TEMP_FAILURE_RETRY (__read (sock, response,
responselen));
if (nbytes == (ssize_t) responselen)
return sock;
}
Expand Down

0 comments on commit 58a2d52

Please sign in to comment.