#ifdef HAVE_BSD_AUTH_H
char *login_style;
#endif /* HAVE_BSD_AUTH_H */
+sigaction_t saved_sa_int, saved_sa_quit, saved_sa_tstp, saved_sa_chld;
void (*set_perms) __P((int));
int sudo_mode;
int pwflag;
char **new_environ;
- sigaction_t sa, saved_sa_int, saved_sa_quit, saved_sa_tstp, saved_sa_chld;
+ sigaction_t sa;
extern int printmatches;
extern char **environ;
warn("unable to change directory to %s", runas_pw->pw_dir);
}
+ if (sudo_mode & MODE_EDIT)
+ exit(sudo_edit(NewArgc, NewArgv));
+
/* Restore signal handlers before we exec. */
(void) sigaction(SIGINT, &saved_sa_int, NULL);
(void) sigaction(SIGQUIT, &saved_sa_quit, NULL);
(void) sigaction(SIGTSTP, &saved_sa_tstp, NULL);
(void) sigaction(SIGCHLD, &saved_sa_chld, NULL);
- if (sudo_mode & MODE_EDIT)
- exit(sudo_edit(NewArgc, NewArgv));
-
#ifndef PROFILING
if ((sudo_mode & MODE_BACKGROUND) && fork() > 0)
exit(0);
#endif /* HAVE_ERR_H */
#include <ctype.h>
#include <pwd.h>
+#include <signal.h>
#include <errno.h>
#include <fcntl.h>
static const char rcsid[] = "$Sudo$";
#endif /* lint */
+extern sigaction_t saved_sa_int, saved_sa_quit, saved_sa_tstp, saved_sa_chld;
+
/*
* Wrapper to allow users to edit privileged files with their own uid.
*/
char **argv;
{
ssize_t nread, nwritten;
- pid_t pid;
+ pid_t kidpid, pid;
const char *tmpdir;
char **nargv, **ap, *editor, *cp;
char buf[BUFSIZ];
int i, ac, ofd, tfd, nargc, rval;
+ sigaction_t sa;
struct stat sb;
struct tempfile {
char *tfile;
nargv[ac++] = tf[i++].tfile;
nargv[ac] = NULL;
+ /* We wait for our own children and can be suspended. */
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+ sa.sa_handler = SIG_DFL;
+ (void) sigaction(SIGCHLD, &sa, NULL);
+ (void) sigaction(SIGTSTP, &saved_sa_tstp, NULL);
+
/*
* Fork and exec the editor as with the invoking user's creds.
*/
- pid = fork();
- if (pid == -1) {
+ kidpid = fork();
+ if (kidpid == -1) {
warn("fork");
goto cleanup;
- } else if (pid == 0) {
+ } else if (kidpid == 0) {
/* child */
+ (void) sigaction(SIGINT, &saved_sa_int, NULL);
+ (void) sigaction(SIGQUIT, &saved_sa_quit, NULL);
+ (void) sigaction(SIGCHLD, &saved_sa_chld, NULL);
set_perms(PERM_FULL_USER);
execvp(nargv[0], nargv);
warn("unable to execute %s", nargv[0]);
_exit(127);
}
- /* In parent, wait for child to finish. */
+ /* Anxious parent, waiting for letters home from camp... */
+ do {
#ifdef sudo_waitpid
- pid = sudo_waitpid(pid, &i, 0);
+ pid = sudo_waitpid(kidpid, &i, WUNTRACED);
#else
- pid = wait(&i);
+ pid = wait(&i);
#endif
- rval = pid == -1 ? -1 : (i >> 8);
+ if (pid == kidpid) {
+ if (WIFSTOPPED(i))
+ kill(getpid(), WSTOPSIG(i));
+ else
+ break;
+ }
+ } while (pid != -1 || errno == EINTR);
+ if (pid == -1 || !WIFEXITED(i))
+ rval = 1;
+ else
+ rval = WEXITSTATUS(i);
/* Copy contents of temp files to real ones */
for (i = 0; i < argc - 1; i++) {