diff options
-rw-r--r-- | ChangeLog.txt | 4 | ||||
-rw-r--r-- | enums/exit_status.in | 4 | ||||
-rw-r--r-- | ports/common/guts/execv.c | 4 | ||||
-rw-r--r-- | ports/unix/guts/dup.c | 2 | ||||
-rw-r--r-- | ports/unix/guts/dup2.c | 2 | ||||
-rw-r--r-- | pseudo.c | 12 | ||||
-rw-r--r-- | pseudo_client.c | 33 | ||||
-rw-r--r-- | pseudo_server.c | 20 | ||||
-rw-r--r-- | pseudo_util.c | 8 |
9 files changed, 54 insertions, 35 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt index 6031496..6cd3997 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,3 +1,7 @@ +2016-03-02: + * (seebs) more server launch rework and updates + * (seebs) make dup/dup2 less verbose in client + 2016-03-01: * (seebs) server launch reworking diff --git a/enums/exit_status.in b/enums/exit_status.in index e02b1bc..6be44d3 100644 --- a/enums/exit_status.in +++ b/enums/exit_status.in @@ -14,3 +14,7 @@ socket_path, "path allocation failure for server socket" socket_unlink, "couldn't unlink existing server socket" socket_bind, "couldn't bind server socket" socket_listen, "couldn't listen on server socket" +listen_fd, "server loop had no valid listen fd" +pseudo_loaded, "server couldn't get out of pseudo environment" +pseudo_prefix, "couldn't get valid pseudo prefix" +pseudo_invocation, "invalid server command arguments" diff --git a/ports/common/guts/execv.c b/ports/common/guts/execv.c index ba1ce65..6093e44 100644 --- a/ports/common/guts/execv.c +++ b/ports/common/guts/execv.c @@ -18,9 +18,9 @@ } pseudo_setupenv(); - if (pseudo_has_unload(NULL)) + if (pseudo_has_unload(NULL)) { pseudo_dropenv(); - + } /* if exec() fails, we may end up taking signals unexpectedly... * not much we can do about that. */ diff --git a/ports/unix/guts/dup.c b/ports/unix/guts/dup.c index f03c2ad..927b264 100644 --- a/ports/unix/guts/dup.c +++ b/ports/unix/guts/dup.c @@ -10,7 +10,7 @@ rc = real_dup(fd); save_errno = errno; - pseudo_debug(PDBGF_CLIENT, "dup: %d->%d\n", fd, rc); + pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "dup: %d->%d\n", fd, rc); pseudo_client_op(OP_DUP, 0, fd, rc, 0, 0); errno = save_errno; diff --git a/ports/unix/guts/dup2.c b/ports/unix/guts/dup2.c index cd335ac..8180039 100644 --- a/ports/unix/guts/dup2.c +++ b/ports/unix/guts/dup2.c @@ -10,7 +10,7 @@ /* close existing one first - this also causes the socket to the * server to get moved around if someone tries to overwrite it. */ - pseudo_debug(PDBGF_CLIENT, "dup2: %d->%d\n", oldfd, newfd); + pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "dup2: %d->%d\n", oldfd, newfd); pseudo_client_op(OP_CLOSE, 0, newfd, -1, 0, 0); rc = real_dup2(oldfd, newfd); save_errno = errno; @@ -113,12 +113,12 @@ main(int argc, char *argv[]) { sigprocmask(SIG_UNBLOCK, &blocked, &saved); if (ld_env && strstr(ld_env, "libpseudo")) { - pseudo_debug(PDBGF_SERVER, "can't run daemon with libpseudo in %s\n", PRELINK_LIBRARIES); + pseudo_debug(PDBGF_SERVER, "[server %d] can't run daemon with libpseudo in %s\n", getpid(), PRELINK_LIBRARIES); s = pseudo_get_value("PSEUDO_UNLOAD"); if (s) { pseudo_diag("pseudo: I can't seem to make %s go away. Sorry.\n", PRELINK_LIBRARIES); pseudo_diag("pseudo: %s: %s\n", PRELINK_LIBRARIES, ld_env); - exit(EXIT_FAILURE); + exit(PSEUDO_EXIT_PSEUDO_LOADED); } free(s); pseudo_set_value("PSEUDO_UNLOAD", "YES"); @@ -126,7 +126,7 @@ main(int argc, char *argv[]) { pseudo_dropenv(); /* Drop PRELINK_LIBRARIES */ execv(argv[0], argv); - exit(EXIT_FAILURE); + exit(PSEUDO_EXIT_PSEUDO_LOADED); } /* Be sure to clean PSEUDO_UNLOAD so if we're asked to run any @@ -258,7 +258,7 @@ main(int argc, char *argv[]) { if (!pseudo_get_prefix(argv[0])) { pseudo_diag("Can't figure out prefix. Set PSEUDO_PREFIX or invoke with full path.\n"); - exit(EXIT_FAILURE); + exit(PSEUDO_EXIT_PSEUDO_PREFIX); } /* move database */ @@ -339,13 +339,13 @@ main(int argc, char *argv[]) { if (opt_d && opt_f) { pseudo_diag("You cannot run a foregrounded daemon.\n"); - exit(EXIT_FAILURE); + exit(PSEUDO_EXIT_PSEUDO_INVOCATION); } if (opt_f || opt_d) { if (argc > optind) { pseudo_diag("pseudo: running program implies spawning background daemon.\n"); - exit(EXIT_FAILURE); + exit(PSEUDO_EXIT_PSEUDO_INVOCATION); } } else { char fullpath[pseudo_path_max()]; diff --git a/pseudo_client.c b/pseudo_client.c index 4d73598..5eca70c 100644 --- a/pseudo_client.c +++ b/pseudo_client.c @@ -938,15 +938,8 @@ client_spawn_server(void) { int status; FILE *fp; char * pseudo_pidfile; - char *old_value = pseudo_get_value("PSEUDO_UNLOAD"); - /* drop pseudo immediately so the fork/exec are lower-load. */ - pseudo_set_value("PSEUDO_UNLOAD", "YES"); if ((server_pid = fork()) != 0) { - /* restore PSEUDO_UNLOAD in caller */ - pseudo_set_value("PSEUDO_UNLOAD", old_value); - free(old_value); - if (server_pid == -1) { pseudo_diag("couldn't fork server: %s\n", strerror(errno)); return 1; @@ -1039,14 +1032,23 @@ client_spawn_server(void) { close(fd); } /* and now, execute the server */ - - pseudo_set_value("PSEUDO_UNLOAD", "YES"); - pseudo_setupenv(); - pseudo_dropenv(); /* drop PRELINK_LIBRARIES */ - pseudo_debug(PDBGF_CLIENT | PDBGF_SERVER | PDBGF_INVOKE, "calling execv on %s\n", argv[0]); - execv(argv[0], argv); + /* don't try to log this exec, because it'll cause the process + * that is supposed to be spawning the server to try to spawn + * a server. Whoops. This is because the exec wrapper doesn't + * respect antimagic, which I believe is intentional. + */ + pseudo_client_logging = 0; + + /* execve will call setupenv, then call dropenv if + * PSEUDO_UNLOAD is set. We call execve, not execv, due + * to unsetenv changing the responses given by getenv, + * but not changing the contents of the variable environ, + * in some cases. + */ + pseudo_set_value("PSEUDO_UNLOAD", "1"); + execve(argv[0], argv, environ); pseudo_diag("critical failure: exec of pseudo daemon failed: %s\n", strerror(errno)); exit(1); } @@ -1251,6 +1253,11 @@ pseudo_client_request(pseudo_msg_t *msg, size_t len, const char *path) { pseudo_msg_t *response = 0; int tries = 0; int rc; + extern char *program_invocation_short_name; + #if 0 + if (!strcmp(program_invocation_short_name, "pseudo")) + abort(); + #endif if (!msg) return 0; diff --git a/pseudo_server.c b/pseudo_server.c index f6806f3..12159e7 100644 --- a/pseudo_server.c +++ b/pseudo_server.c @@ -133,14 +133,12 @@ static sig_atomic_t got_sigalrm = 0; static void handle_sigusr1(int sig) { (void) sig; - pseudo_diag("sigusr1\n"); got_sigusr1 = 1; } static void handle_sigalrm(int sig) { (void) sig; - pseudo_diag("sigalrm\n"); got_sigalrm = 1; } @@ -157,7 +155,6 @@ pseudo_server_start(int daemonize) { /* parent process will wait for child process, or until it gets * SIGUSR1, or until too much time has passed. */ - pseudo_diag("server start: daemonize %d.\n", daemonize); if (daemonize) { int child; child = fork(); @@ -170,7 +167,6 @@ pseudo_server_start(int daemonize) { int status; int rc; int save_errno; - pseudo_diag("parent process, pid %d, doing setup.\n", getpid()); got_sigusr1 = 0; signal(SIGUSR1, handle_sigusr1); @@ -181,20 +177,21 @@ pseudo_server_start(int daemonize) { rc = waitpid(child, &status, WNOHANG); save_errno = errno; if (rc != child && !got_sigalrm && !got_sigusr1) { - struct timespec delay = { .tv_sec = 0, .tv_nsec = 100000000 }; + struct timespec delay = { .tv_sec = 0, .tv_nsec = 100000 }; nanosleep(&delay, NULL); ++tries; } } while (!got_sigalrm && !got_sigusr1 && rc != child); alarm(0); - pseudo_diag("pid waited: %d/%d [%d tries], status %d\n", rc, save_errno, tries, status); - pseudo_diag("usr1: %d alrm: %d\n", got_sigusr1, got_sigalrm); + pseudo_debug(PDBGF_SERVER, "pid waited: %d/%d [%d tries], status %d, usr1 %d, alrm %d\n", + rc, save_errno, tries, status, + got_sigusr1, got_sigalrm); if (got_sigusr1) { pseudo_debug(PDBGF_SERVER, "server says it's ready.\n"); exit(0); } - if (save_errno == EINTR) { + if (got_sigalrm) { pseudo_diag("Child process timeout after %d seconds.\n", PSEUDO_CHILD_PROCESS_TIMEOUT); exit(PSEUDO_EXIT_TIMEOUT); @@ -217,10 +214,13 @@ pseudo_server_start(int daemonize) { pseudo_diag("Child process exit status %d: %s\n", status, pseudo_exit_status_name(status)); + if (status == 0) { + pseudo_diag("Hang on, server should not have exited 0 without sending us sigusr1?\n"); + } exit(status); } pseudo_diag("Unknown exit status %d.\n", status); - exit(1); + exit(PSEUDO_EXIT_GENERAL); } else { /* detach from parent session */ setsid(); @@ -589,7 +589,7 @@ pseudo_server_loop(void) { pseudo_debug(PDBGF_SERVER, "server loop started.\n"); if (listen_fd < 0) { pseudo_diag("got into loop with no valid listen fd.\n"); - exit(1); + exit(PSEUDO_EXIT_LISTEN_FD); } pdb_log_msg(SEVERITY_INFO, NULL, NULL, NULL, "server started (pid %d)", getpid()); diff --git a/pseudo_util.c b/pseudo_util.c index 6e6345f..be07951 100644 --- a/pseudo_util.c +++ b/pseudo_util.c @@ -588,9 +588,14 @@ pseudo_evlog_internal(char *fmt, ...) { /* store pid in text form for prepending to messages */ void pseudo_new_pid() { +#if PSEUDO_PORT_LINUX + extern char *program_invocation_short_name; /* glibcism */ +#else + char *program_invocation_short_name = "unknown"; +#endif int pid = getpid(); pid_len = snprintf(pid_text, 32, "%d: ", pid); - pseudo_debug(PDBGF_PID, "new pid: %d\n", pid); + pseudo_debug(PDBGF_PID, "new pid: %d [%s]\n", pid, program_invocation_short_name); } /* helper function for pseudo_fix_path @@ -823,7 +828,6 @@ void pseudo_dropenv() { pseudo_diag("fatal: can't allocate new %s variable.\n", PRELINK_LIBRARIES); } if (ld_preload && strlen(ld_preload)) { - pseudo_diag("ld_preload without: <%s>\n", ld_preload); setenv(PRELINK_LIBRARIES, ld_preload, 1); } else { unsetenv(PRELINK_LIBRARIES); |