Mercurial > dropbear
diff svr-chansession.c @ 1510:eb4c7052f51d coverity
merge coverity up to date
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sat, 17 Feb 2018 11:29:17 +0800 |
parents | 47f36d8565cf |
children | 79eef94ccea9 |
line wrap: on
line diff
--- a/svr-chansession.c Sat Feb 10 19:06:13 2018 +0800 +++ b/svr-chansession.c Sat Feb 17 11:29:17 2018 +0800 @@ -80,6 +80,55 @@ return chansess->exit.exitpid != -1; } +void svr_chansess_checksignal(void) { + int status; + pid_t pid; + + if (!ses.channel_signal_pending) { + return; + } + + while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { + unsigned int i; + struct exitinfo *ex = NULL; + TRACE(("sigchld handler: pid %d", pid)) + + ex = NULL; + /* find the corresponding chansess */ + for (i = 0; i < svr_ses.childpidsize; i++) { + if (svr_ses.childpids[i].pid == pid) { + TRACE(("found match session")); + ex = &svr_ses.childpids[i].chansess->exit; + break; + } + } + + /* If the pid wasn't matched, then we might have hit the race mentioned + * above. So we just store the info for the parent to deal with */ + if (ex == NULL) { + TRACE(("using lastexit")); + ex = &svr_ses.lastexit; + } + + ex->exitpid = pid; + if (WIFEXITED(status)) { + ex->exitstatus = WEXITSTATUS(status); + } + if (WIFSIGNALED(status)) { + ex->exitsignal = WTERMSIG(status); +#if !defined(AIX) && defined(WCOREDUMP) + ex->exitcore = WCOREDUMP(status); +#else + ex->exitcore = 0; +#endif + } else { + /* we use this to determine how pid exited */ + ex->exitsignal = -1; + } + + } +} + /* Handler for childs exiting, store the state for return to the client */ /* There's a particular race we have to watch out for: if the forked child @@ -89,63 +138,19 @@ * the parent when it runs. This work correctly at least in the case of a * single shell spawned (ie the usual case) */ static void sesssigchild_handler(int UNUSED(dummy)) { - - int status; - pid_t pid; - unsigned int i; struct sigaction sa_chld; - struct exitinfo *exit = NULL; const int saved_errno = errno; - /* Make channel handling code look for closed channels */ - ses.channel_signal_pending = 1; - TRACE(("enter sigchld handler")) - while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { - TRACE(("sigchld handler: pid %d", pid)) - - exit = NULL; - /* find the corresponding chansess */ - for (i = 0; i < svr_ses.childpidsize; i++) { - if (svr_ses.childpids[i].pid == pid) { - TRACE(("found match session")); - exit = &svr_ses.childpids[i].chansess->exit; - break; - } - } - - /* If the pid wasn't matched, then we might have hit the race mentioned - * above. So we just store the info for the parent to deal with */ - if (exit == NULL) { - TRACE(("using lastexit")); - exit = &svr_ses.lastexit; - } - exit->exitpid = pid; - if (WIFEXITED(status)) { - exit->exitstatus = WEXITSTATUS(status); - } - if (WIFSIGNALED(status)) { - exit->exitsignal = WTERMSIG(status); -#if !defined(AIX) && defined(WCOREDUMP) - exit->exitcore = WCOREDUMP(status); -#else - exit->exitcore = 0; -#endif - } else { - /* we use this to determine how pid exited */ - exit->exitsignal = -1; - } - - /* Make sure that the main select() loop wakes up */ - while (1) { - /* isserver is just a random byte to write. We can't do anything - about an error so should just ignore it */ - if (write(ses.signal_pipe[1], &ses.isserver, 1) == 1 - || errno != EINTR) { - break; - } + /* Make sure that the main select() loop wakes up */ + while (1) { + /* isserver is just a random byte to write. We can't do anything + about an error so should just ignore it */ + if (write(ses.signal_pipe[1], &ses.isserver, 1) == 1 + || errno != EINTR) { + break; } } @@ -658,7 +663,7 @@ } } if (issubsys) { -#ifdef SFTPSERVER_PATH +#if DROPBEAR_SFTPSERVER if ((cmdlen == 4) && strncmp(chansess->cmd, "sftp", 4) == 0) { m_free(chansess->cmd); chansess->cmd = m_strdup(SFTPSERVER_PATH); @@ -682,7 +687,7 @@ } -#ifdef LOG_COMMANDS +#if LOG_COMMANDS if (chansess->cmd) { dropbear_log(LOG_INFO, "User %s executing '%s'", ses.authstate.pw_name, chansess->cmd); @@ -769,7 +774,7 @@ pid_t pid; struct logininfo *li = NULL; -#ifdef DO_MOTD +#if DO_MOTD buffer * motdbuf = NULL; int len; struct stat sb; @@ -821,7 +826,7 @@ login_login(li); login_free_entry(li); -#ifdef DO_MOTD +#if DO_MOTD if (svr_opts.domotd && !chansess->cmd) { /* don't show the motd if ~/.hushlogin exists */ @@ -899,7 +904,7 @@ /* Clean up, drop to user privileges, set up the environment and execute * the command/shell. This function does not return. */ static void execchild(const void *user_data) { - struct ChanSess *chansess = user_data; + const struct ChanSess *chansess = user_data; char *usershell = NULL; /* with uClinux we'll have vfork()ed, so don't want to overwrite the