From owner-svn-src-stable-10@freebsd.org Tue Jul 31 00:37:27 2018 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 9D0BC10663F5; Tue, 31 Jul 2018 00:37:27 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 40F268F2A3; Tue, 31 Jul 2018 00:37:27 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 0350243DD; Tue, 31 Jul 2018 00:37:27 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w6V0bQsK099925; Tue, 31 Jul 2018 00:37:26 GMT (envelope-from markj@FreeBSD.org) Received: (from markj@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w6V0bPlm099916; Tue, 31 Jul 2018 00:37:25 GMT (envelope-from markj@FreeBSD.org) Message-Id: <201807310037.w6V0bPlm099916@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: markj set sender to markj@FreeBSD.org using -f From: Mark Johnston Date: Tue, 31 Jul 2018 00:37:25 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r336953 - in stable: 10/usr.bin/mail 11/usr.bin/mail X-SVN-Group: stable-10 X-SVN-Commit-Author: markj X-SVN-Commit-Paths: in stable: 10/usr.bin/mail 11/usr.bin/mail X-SVN-Commit-Revision: 336953 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 31 Jul 2018 00:37:28 -0000 Author: markj Date: Tue Jul 31 00:37:25 2018 New Revision: 336953 URL: https://svnweb.freebsd.org/changeset/base/336953 Log: Revert r335693, r335694, r335695 by eadler. They cause mail(1) to crash in certain scenarios. PR: 230196 Reported by: Pete French Modified: stable/10/usr.bin/mail/cmd1.c stable/10/usr.bin/mail/cmd2.c stable/10/usr.bin/mail/cmd3.c stable/10/usr.bin/mail/edit.c stable/10/usr.bin/mail/extern.h stable/10/usr.bin/mail/fio.c stable/10/usr.bin/mail/getname.c stable/10/usr.bin/mail/popen.c Directory Properties: stable/10/ (props changed) Changes in other areas also in this revision: Modified: stable/11/usr.bin/mail/cmd1.c stable/11/usr.bin/mail/cmd2.c stable/11/usr.bin/mail/cmd3.c stable/11/usr.bin/mail/edit.c stable/11/usr.bin/mail/extern.h stable/11/usr.bin/mail/fio.c stable/11/usr.bin/mail/getname.c stable/11/usr.bin/mail/popen.c Directory Properties: stable/11/ (props changed) Modified: stable/10/usr.bin/mail/cmd1.c ============================================================================== --- stable/10/usr.bin/mail/cmd1.c Tue Jul 31 00:34:39 2018 (r336952) +++ stable/10/usr.bin/mail/cmd1.c Tue Jul 31 00:37:25 2018 (r336953) @@ -439,7 +439,7 @@ folders(void) } if ((cmd = value("LISTER")) == NULL) cmd = "ls"; - (void)run_command(cmd, 0, -1, -1, dirname, NULL); + (void)run_command(cmd, 0, -1, -1, dirname, NULL, NULL); return (0); } Modified: stable/10/usr.bin/mail/cmd2.c ============================================================================== --- stable/10/usr.bin/mail/cmd2.c Tue Jul 31 00:34:39 2018 (r336952) +++ stable/10/usr.bin/mail/cmd2.c Tue Jul 31 00:37:25 2018 (r336953) @@ -130,9 +130,8 @@ hitit: * so we can discard when the user quits. */ int -save(void *v) +save(char str[]) { - char *str = v; return (save1(str, 1, "save", saveignore)); } @@ -141,9 +140,8 @@ save(void *v) * Copy a message to a file without affected its saved-ness */ int -copycmd(void *v) +copycmd(char str[]) { - char *str = v; return (save1(str, 0, "copy", saveignore)); } Modified: stable/10/usr.bin/mail/cmd3.c ============================================================================== --- stable/10/usr.bin/mail/cmd3.c Tue Jul 31 00:34:39 2018 (r336952) +++ stable/10/usr.bin/mail/cmd3.c Tue Jul 31 00:37:25 2018 (r336953) @@ -79,7 +79,7 @@ dosh(char *str __unused) if ((sh = value("SHELL")) == NULL) sh = _PATH_CSHELL; - (void)run_command(sh, 0, -1, -1, NULL); + (void)run_command(sh, 0, -1, -1, NULL, NULL, NULL); (void)signal(SIGINT, sigint); printf("\n"); return (0); @@ -102,7 +102,7 @@ bangexp(char *str, size_t strsize) n = sizeof(bangbuf); while (*cp != '\0') { if (*cp == '!') { - if (n < (int)strlen(lastbang)) { + if (n < strlen(lastbang)) { overf: printf("Command buffer overflow\n"); return (-1); Modified: stable/10/usr.bin/mail/edit.c ============================================================================== --- stable/10/usr.bin/mail/edit.c Tue Jul 31 00:34:39 2018 (r336952) +++ stable/10/usr.bin/mail/edit.c Tue Jul 31 00:37:25 2018 (r336953) @@ -180,7 +180,7 @@ run_editor(FILE *fp, off_t size, int type, int readonl nf = NULL; if ((edit = value(type == 'e' ? "EDITOR" : "VISUAL")) == NULL) edit = type == 'e' ? _PATH_EX : _PATH_VI; - if (run_command(edit, 0, -1, -1, tempname, NULL) < 0) { + if (run_command(edit, 0, -1, -1, tempname, NULL, NULL) < 0) { (void)rm(tempname); goto out; } Modified: stable/10/usr.bin/mail/extern.h ============================================================================== --- stable/10/usr.bin/mail/extern.h Tue Jul 31 00:34:39 2018 (r336952) +++ stable/10/usr.bin/mail/extern.h Tue Jul 31 00:37:25 2018 (r336953) @@ -49,7 +49,7 @@ char *copyin(char *, char **); char *detract(struct name *, int); char *expand(char *); char *getdeadletter(void); -char *getname(uid_t); +char *getname(int); char *hfield(const char *, struct message *); FILE *infix(struct header *, FILE *); char *ishfield(char [], char *, const char *); @@ -95,7 +95,7 @@ void collhup(int); void collint(int); void collstop(int); void commands(void); -int copycmd(void *v); +int copycmd(char []); int core(void); int count(struct name *); int delete(int []); @@ -130,7 +130,7 @@ int getfold(char *, int); int gethfield(FILE *, char [], int, char **); int getmsglist(char *, int *, int); int getrawlist(char [], char **, int); -uid_t getuserid(char []); +int getuserid(char []); int grabh(struct header *, int); int group(char **); void hangup(int); @@ -198,8 +198,8 @@ int respond(int *); int retfield(char *[]); int rexit(int); int rm(char *); -int run_command(char *, sigset_t *, int, int, ...); -int save(void *v); +int run_command(char *, sigset_t *, int, int, char *, char *, char *); +int save(char []); int save1(char [], int, const char *, struct ignoretab *); void savedeadletter(FILE *); int saveigfield(char *[]); @@ -223,7 +223,7 @@ void sort(char **); int source(char **); void spreserve(void); void sreset(void); -int start_command(char *, sigset_t *, int, int, ...); +int start_command(char *, sigset_t *, int, int, char *, char *, char *); void statusput(struct message *, FILE *, char *); void stop(int); int stouch(int []); Modified: stable/10/usr.bin/mail/fio.c ============================================================================== --- stable/10/usr.bin/mail/fio.c Tue Jul 31 00:34:39 2018 (r336952) +++ stable/10/usr.bin/mail/fio.c Tue Jul 31 00:37:25 2018 (r336953) @@ -235,7 +235,7 @@ makemessage(FILE *f, int omsgCount) size -= (omsgCount + 1) * sizeof(struct message); (void)fflush(f); (void)lseek(fileno(f), (off_t)sizeof(*message), 0); - if (read(fileno(f), (void *)&message[omsgCount], size) != size) + if (read(fileno(f), (char *)&message[omsgCount], size) != size) errx(1, "Message temporary file corrupted"); message[msgCount].m_size = 0; message[msgCount].m_lines = 0; Modified: stable/10/usr.bin/mail/getname.c ============================================================================== --- stable/10/usr.bin/mail/getname.c Tue Jul 31 00:34:39 2018 (r336952) +++ stable/10/usr.bin/mail/getname.c Tue Jul 31 00:37:25 2018 (r336953) @@ -45,7 +45,7 @@ __FBSDID("$FreeBSD$"); * Search the passwd file for a uid. Return name on success, NULL on failure. */ char * -getname(uid_t uid) +getname(int uid) { struct passwd *pw; @@ -58,7 +58,7 @@ getname(uid_t uid) * Convert the passed name to a user id and return it. Return -1 * on error. */ -uid_t +int getuserid(char name[]) { struct passwd *pw; Modified: stable/10/usr.bin/mail/popen.c ============================================================================== --- stable/10/usr.bin/mail/popen.c Tue Jul 31 00:34:39 2018 (r336952) +++ stable/10/usr.bin/mail/popen.c Tue Jul 31 00:37:25 2018 (r336953) @@ -38,8 +38,6 @@ __FBSDID("$FreeBSD$"); #include "rcv.h" #include #include -#include -#include #include "extern.h" #define READ 0 @@ -48,23 +46,22 @@ __FBSDID("$FreeBSD$"); struct fp { FILE *fp; int pipe; - pid_t pid; + int pid; struct fp *link; }; static struct fp *fp_head; struct child { - pid_t pid; + int pid; char done; char free; int status; struct child *link; }; -static struct child *child, *child_freelist = NULL; - +static struct child *child; +static struct child *findchild(int); static void delchild(struct child *); -static pid_t file_pid(FILE *); -static pid_t start_commandv(char *, sigset_t *, int, int, va_list); +static int file_pid(FILE *); FILE * Fopen(const char *path, const char *mode) @@ -93,7 +90,6 @@ Fdopen(int fd, const char *mode) int Fclose(FILE *fp) { - unregister_file(fp); return (fclose(fp)); } @@ -103,7 +99,7 @@ Popen(char *cmd, const char *mode) { int p[2]; int myside, hisside, fd0, fd1; - pid_t pid; + int pid; sigset_t nset; FILE *fp; @@ -113,15 +109,15 @@ Popen(char *cmd, const char *mode) (void)fcntl(p[WRITE], F_SETFD, 1); if (*mode == 'r') { myside = p[READ]; - hisside = fd0 = fd1 = p[WRITE]; + fd0 = -1; + hisside = fd1 = p[WRITE]; } else { myside = p[WRITE]; hisside = fd0 = p[READ]; fd1 = -1; } (void)sigemptyset(&nset); - pid = start_command(value("SHELL"), &nset, fd0, fd1, "-c", cmd, NULL); - if (pid < 0) { + if ((pid = start_command(cmd, &nset, fd0, fd1, NULL, NULL, NULL)) < 0) { (void)close(p[READ]); (void)close(p[WRITE]); return (NULL); @@ -162,7 +158,7 @@ close_all_files(void) } void -register_file(FILE *fp, int pipe, pid_t pid) +register_file(FILE *fp, int pipe, int pid) { struct fp *fpp; @@ -190,7 +186,7 @@ unregister_file(FILE *fp) /*NOTREACHED*/ } -pid_t +int file_pid(FILE *fp) { struct fp *p; @@ -204,17 +200,30 @@ file_pid(FILE *fp) /* * Run a command without a shell, with optional arguments and splicing - * of stdin (-1 means none) and stdout. The command name can be a sequence - * of words. + * of stdin and stdout. The command name can be a sequence of words. * Signals must be handled by the caller. - * "nset" contains the signals to ignore in the new process. - * SIGINT is enabled unless it's in "nset". + * "Mask" contains the signals to ignore in the new process. + * SIGINT is enabled unless it's in the mask. */ -static pid_t -start_commandv(char *cmd, sigset_t *nset, int infd, int outfd, va_list args) +/*VARARGS4*/ +int +run_command(char *cmd, sigset_t *mask, int infd, int outfd, char *a0, + char *a1, char *a2) { - pid_t pid; + int pid; + if ((pid = start_command(cmd, mask, infd, outfd, a0, a1, a2)) < 0) + return (-1); + return (wait_command(pid)); +} + +/*VARARGS4*/ +int +start_command(char *cmd, sigset_t *mask, int infd, int outfd, char *a0, + char *a1, char *a2) +{ + int pid; + if ((pid = fork()) < 0) { warn("fork"); return (-1); @@ -223,10 +232,11 @@ start_commandv(char *cmd, sigset_t *nset, int infd, in char *argv[100]; int i = getrawlist(cmd, argv, sizeof(argv) / sizeof(*argv)); - while ((argv[i++] = va_arg(args, char *))) - ; - argv[i] = NULL; - prepare_child(nset, infd, outfd); + if ((argv[i++] = a0) != NULL && + (argv[i++] = a1) != NULL && + (argv[i++] = a2) != NULL) + argv[i] = NULL; + prepare_child(mask, infd, outfd); execvp(argv[0], argv); warn("%s", argv[0]); _exit(1); @@ -234,32 +244,6 @@ start_commandv(char *cmd, sigset_t *nset, int infd, in return (pid); } -int -run_command(char *cmd, sigset_t *nset, int infd, int outfd, ...) -{ - pid_t pid; - va_list args; - - va_start(args, outfd); - pid = start_commandv(cmd, nset, infd, outfd, args); - va_end(args); - if (pid < 0) - return -1; - return wait_command(pid); -} - -int -start_command(char *cmd, sigset_t *nset, int infd, int outfd, ...) -{ - va_list args; - int r; - - va_start(args, outfd); - r = start_commandv(cmd, nset, infd, outfd, args); - va_end(args); - return r; -} - void prepare_child(sigset_t *nset, int infd, int outfd) { @@ -284,7 +268,7 @@ prepare_child(sigset_t *nset, int infd, int outfd) } int -wait_command(pid_t pid) +wait_command(int pid) { if (wait_child(pid) < 0) { @@ -295,7 +279,7 @@ wait_command(pid_t pid) } static struct child * -findchild(pid_t pid, int dont_alloc) +findchild(int pid) { struct child **cpp; @@ -303,16 +287,9 @@ findchild(pid_t pid, int dont_alloc) cpp = &(*cpp)->link) ; if (*cpp == NULL) { - if (dont_alloc) - return(NULL); - if (child_freelist) { - *cpp = child_freelist; - child_freelist = (*cpp)->link; - } else { - *cpp = malloc(sizeof(struct child)); - if (*cpp == NULL) - err(1, "malloc"); - } + *cpp = malloc(sizeof(struct child)); + if (*cpp == NULL) + err(1, "Out of memory"); (*cpp)->pid = pid; (*cpp)->done = (*cpp)->free = 0; (*cpp)->link = NULL; @@ -328,22 +305,19 @@ delchild(struct child *cp) for (cpp = &child; *cpp != cp; cpp = &(*cpp)->link) ; *cpp = cp->link; - cp->link = child_freelist; - child_freelist = cp; + (void)free(cp); } /*ARGSUSED*/ void sigchild(int signo __unused) { - pid_t pid; + int pid; int status; struct child *cp; - int save_errno; - save_errno = errno; while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { - cp = findchild(pid, 1); + cp = findchild(pid); if (cp->free) delchild(cp); else { @@ -351,7 +325,6 @@ sigchild(int signo __unused) cp->status = status; } } - errno = save_errno; } int wait_status; @@ -360,51 +333,41 @@ int wait_status; * Wait for a specific child to die. */ int -wait_child(pid_t pid) +wait_child(int pid) { - struct child *cp; sigset_t nset, oset; - pid_t rv = 0; + struct child *cp; (void)sigemptyset(&nset); (void)sigaddset(&nset, SIGCHLD); - (void)sigprocmask(SIG_BLOCK, &nset, &oset); - /* - * If we have not already waited on the pid (via sigchild) - * wait on it now. Otherwise, use the wait status stashed - * by sigchild. - */ - cp = findchild(pid, 1); - if (cp == NULL || !cp->done) - rv = waitpid(pid, &wait_status, 0); - else - wait_status = cp->status; - if (cp != NULL) - delchild(cp); + (void)sigprocmask(SIG_BLOCK, &nset, &oset); + + cp = findchild(pid); + + while (!cp->done) + (void)sigsuspend(&oset); + wait_status = cp->status; + delchild(cp); (void)sigprocmask(SIG_SETMASK, &oset, NULL); - if (rv == -1 || (WIFEXITED(wait_status) && WEXITSTATUS(wait_status))) - return -1; - else - return 0; + return ((WIFEXITED(wait_status) && WEXITSTATUS(wait_status)) ? -1 : 0); } /* * Mark a child as don't care. */ void -free_child(pid_t pid) +free_child(int pid) { - struct child *cp; sigset_t nset, oset; + struct child *cp = findchild(pid); (void)sigemptyset(&nset); (void)sigaddset(&nset, SIGCHLD); - (void)sigprocmask(SIG_BLOCK, &nset, &oset); - if ((cp = findchild(pid, 0)) != NULL) { - if (cp->done) - delchild(cp); - else - cp->free = 1; - } + (void)sigprocmask(SIG_BLOCK, &nset, &oset); + + if (cp->done) + delchild(cp); + else + cp->free = 1; (void)sigprocmask(SIG_SETMASK, &oset, NULL); }