summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2001-11-14 21:49:30 +0000
committerJeremy Allison <jra@samba.org>2001-11-14 21:49:30 +0000
commitb30f0baf7a31687780c16b9866ee90655599fec3 (patch)
tree84456076206f925a2a4739122b0788267201e033
parent5d97ab9df86af7004572f227f47bd74a0830833d (diff)
downloadsamba-b30f0baf7a31687780c16b9866ee90655599fec3.tar.gz
samba-b30f0baf7a31687780c16b9866ee90655599fec3.tar.bz2
samba-b30f0baf7a31687780c16b9866ee90655599fec3.zip
Make signal handling safer (handle EINTR on read/write/accept), don't
call slprintf within a signal handler. Jeremy. (This used to be commit a9f7974cb8e266ce87d2979fa107bf7ebbb98b70)
-rw-r--r--source3/nsswitch/winbindd.c90
1 files changed, 52 insertions, 38 deletions
diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c
index fb3309ec33..0d13b70442 100644
--- a/source3/nsswitch/winbindd.c
+++ b/source3/nsswitch/winbindd.c
@@ -82,7 +82,7 @@ static void do_print_winbindd_status(void)
winbindd_status();
winbindd_idmap_status();
winbindd_cache_status();
- winbindd_cm_status();
+ winbindd_cm_status();
}
/* Flush client cache */
@@ -96,35 +96,36 @@ static void do_flush_caches(void)
/* Handle the signal by unlinking socket and exiting */
-static void termination_handler(int signum)
+static void terminate(void)
{
pstring path;
/* Remove socket file */
-
snprintf(path, sizeof(path), "%s/%s",
WINBINDD_SOCKET_DIR, WINBINDD_SOCKET_NAME);
unlink(path);
-
exit(0);
}
+static BOOL do_sigterm;
+
+static void termination_handler(int signum)
+{
+ do_sigterm = True;
+}
+
static BOOL print_winbindd_status;
static void sigusr1_handler(int signum)
{
- BlockSignals(True, SIGUSR1);
print_winbindd_status = True;
- BlockSignals(False, SIGUSR1);
}
static BOOL do_sighup;
static void sighup_handler(int signum)
{
- BlockSignals(True, SIGHUP);
do_sighup = True;
- BlockSignals(False, SIGHUP);
}
/* Create winbindd socket */
@@ -324,8 +325,12 @@ static void new_connection(int accept_sock)
/* Accept connection */
len = sizeof(sunaddr);
- if ((sock = accept(accept_sock, (struct sockaddr *)&sunaddr, &len))
- == -1)
+
+ do {
+ sock = accept(accept_sock, (struct sockaddr *)&sunaddr, &len);
+ } while (sock == -1 && errno == EINTR);
+
+ if (sock == -1)
return;
DEBUG(6,("accepted socket %d\n", sock));
@@ -399,8 +404,10 @@ static void client_read(struct winbindd_cli_state *state)
/* Read data */
- n = read(state->sock, state->read_buf_len + (char *)&state->request,
- sizeof(state->request) - state->read_buf_len);
+ do {
+ n = read(state->sock, state->read_buf_len + (char *)&state->request,
+ sizeof(state->request) - state->read_buf_len);
+ } while (n == -1 && errno == EINTR);
DEBUG(10,("client_read: read %d bytes. Need %d more for a full request.\n", n,
sizeof(state->request) - n - state->read_buf_len ));
@@ -447,7 +454,9 @@ static void client_write(struct winbindd_cli_state *state)
state->write_buf_len;
}
- num_written = write(state->sock, data, state->write_buf_len);
+ do {
+ num_written = write(state->sock, data, state->write_buf_len);
+ } while (num_written == -1 && errno == EINTR);
DEBUG(10,("client_write: wrote %d bytes.\n", num_written ));
@@ -547,7 +556,8 @@ static void process_loop(int accept_sock)
/* Select requires we know the highest fd used */
- if (state->sock > maxfd) maxfd = state->sock;
+ if (state->sock > maxfd)
+ maxfd = state->sock;
/* Add fd for reading */
@@ -562,28 +572,12 @@ static void process_loop(int accept_sock)
state = state->next;
}
- /* Check signal handling things */
-
- if (do_sighup) {
-
- /* Flush winbindd cache */
-
- do_flush_caches();
- reload_services_file(True);
-
- do_sighup = False;
- }
-
- if (print_winbindd_status) {
- do_print_winbindd_status();
- print_winbindd_status = False;
- }
-
/* Call select */
selret = select(maxfd + 1, &r_fds, &w_fds, NULL, &timeout);
- if (selret == 0) continue;
+ if (selret == 0)
+ continue;
if ((selret == -1 && errno != EINTR) || selret == 0) {
@@ -653,6 +647,26 @@ static void process_loop(int accept_sock)
client_write(state);
}
}
+
+ /* Check signal handling things */
+
+ if (do_sigterm)
+ terminate();
+
+ if (do_sighup) {
+
+ /* Flush winbindd cache */
+
+ do_flush_caches();
+ reload_services_file(True);
+
+ do_sighup = False;
+ }
+
+ if (print_winbindd_status) {
+ do_print_winbindd_status();
+ print_winbindd_status = False;
+ }
}
}
@@ -668,7 +682,7 @@ int main(int argc, char **argv)
BOOL interactive = False;
int opt, new_debuglevel = -1;
- /* Initialise for running in non-root mode */
+ /* Initialise for running in non-root mode */
sec_init();
@@ -682,7 +696,7 @@ int main(int argc, char **argv)
while ((opt = getopt(argc, argv, "id:s:")) != EOF) {
switch (opt) {
- /* Don't become a daemon */
+ /* Don't become a daemon */
case 'i':
interactive = True;
@@ -736,11 +750,11 @@ int main(int argc, char **argv)
secrets_init();
- /* Get list of domains we look up requests for. This includes the
- domain which we are a member of as well as any trusted
- domains. */
+ /* Get list of domains we look up requests for. This includes the
+ domain which we are a member of as well as any trusted
+ domains. */
- get_domain_info();
+ get_domain_info();
ZERO_STRUCT(server_state);