as seen in cron, make the popen replacement nicer. this also repairs two
abuses of comma operators and an unnecessary function pointer.
Index: extern.h
===================================================================
RCS file: /cvs/src/libexec/ftpd/extern.h,v
retrieving revision 1.18
diff -u -p -r1.18 extern.h
--- extern.h 4 Mar 2012 04:05:15 -0000 1.18
+++ extern.h 4 Oct 2015 09:35:33 -0000
@@ -67,8 +67,8 @@ void cwd(char *);
void delete(char *);
void dologout(int);
void fatal(char *);
-int ftpd_pclose(FILE *);
-FILE *ftpd_popen(char *, char *);
+int ftpd_pclose(FILE *, pid_t);
+FILE *ftpd_popen(char *, char *, pid_t *);
int get_line(char *, int, FILE *);
void ftpdlogwtmp(char *, char *, char *);
void lreply(int, const char *, ...);
Index: ftpd.c
===================================================================
RCS file: /cvs/src/libexec/ftpd/ftpd.c,v
retrieving revision 1.208
diff -u -p -r1.208 ftpd.c
--- ftpd.c 1 Sep 2015 06:50:53 -0000 1.208
+++ ftpd.c 4 Oct 2015 09:38:41 -0000
@@ -1160,18 +1160,18 @@ retrieve(char *cmd, char *name)
{
FILE *fin, *dout;
struct stat st;
- int (*closefunc)(FILE *);
+ pid_t pid;
time_t start;
if (cmd == 0) {
- fin = fopen(name, "r"), closefunc = fclose;
+ fin = fopen(name, "r");
st.st_size = 0;
} else {
char line[BUFSIZ];
(void) snprintf(line, sizeof(line), cmd, name);
name = line;
- fin = ftpd_popen(line, "r"), closefunc = ftpd_pclose;
+ fin = ftpd_popen(line, "r", &pid);
st.st_size = -1;
st.st_blksize = BUFSIZ;
}
@@ -1226,9 +1226,12 @@ done:
if (pdata >= 0)
(void) close(pdata);
pdata = -1;
- if (cmd == 0)
+ if (cmd == 0) {
LOGBYTES("get", name, byte_count);
- (*closefunc)(fin);
+ fclose(fin);
+ } else {
+ ftpd_pclose(fin, pid);
+ }
}
void
@@ -1771,10 +1774,11 @@ statfilecmd(char *filename)
FILE *fin;
int c;
int atstart;
+ pid_t pid;
char line[LINE_MAX];
(void)snprintf(line, sizeof(line), "/bin/ls -lgA %s", filename);
- fin = ftpd_popen(line, "r");
+ fin = ftpd_popen(line, "r", &pid);
if (fin == NULL) {
reply(451, "Local resource failure");
return;
@@ -1785,13 +1789,13 @@ statfilecmd(char *filename)
if (c == '\n') {
if (ferror(stdout)){
perror_reply(421, "control connection");
- (void) ftpd_pclose(fin);
+ (void) ftpd_pclose(fin, pid);
dologout(1);
/* NOTREACHED */
}
if (ferror(fin)) {
perror_reply(551, filename);
- (void) ftpd_pclose(fin);
+ (void) ftpd_pclose(fin, pid);
return;
}
(void) putc('\r', stdout);
@@ -1801,7 +1805,7 @@ statfilecmd(char *filename)
(void) putc(c, stdout);
atstart = (c == '\n');
}
- (void) ftpd_pclose(fin);
+ (void) ftpd_pclose(fin, pid);
reply(211, "End of Status");
}
Index: popen.c
===================================================================
RCS file: /cvs/src/libexec/ftpd/popen.c,v
retrieving revision 1.24
diff -u -p -r1.24 popen.c
--- popen.c 8 Mar 2010 19:34:44 -0000 1.24
+++ popen.c 4 Oct 2015 09:35:03 -0000
@@ -56,14 +56,11 @@
* may create a pipe to a hidden program as a side effect of a list or dir
* command.
*/
-static pid_t *pids;
-static int fds;
-
#define MAX_ARGV 100
#define MAX_GARGV 1000
FILE *
-ftpd_popen(char *program, char *type)
+ftpd_popen(char *program, char *type, pid_t *pidptr)
{
char *cp;
FILE *iop;
@@ -74,12 +71,6 @@ ftpd_popen(char *program, char *type)
if ((*type != 'r' && *type != 'w') || type[1])
return (NULL);
- if (!pids) {
- if ((fds = getdtablesize()) <= 0)
- return (NULL);
- if ((pids = calloc(fds, sizeof(pid_t))) == NULL)
- return (NULL);
- }
if (pipe(pdes) < 0)
return (NULL);
@@ -160,7 +151,7 @@ ftpd_popen(char *program, char *type)
iop = fdopen(pdes[1], type);
(void)close(pdes[0]);
}
- pids[fileno(iop)] = pid;
+ *pidptr = pid;
pfree: for (argc = 1; gargv[argc] != NULL; argc++)
free(gargv[argc]);
@@ -169,29 +160,22 @@ pfree: for (argc = 1; gargv[argc] != NUL
}
int
-ftpd_pclose(FILE *iop)
+ftpd_pclose(FILE *iop, pid_t pid)
{
int fdes, status;
- pid_t pid;
+ pid_t rv;
sigset_t sigset, osigset;
- /*
- * pclose returns -1 if stream is not associated with a
- * `popened' command, or, if already `pclosed'.
- */
- if (pids == 0 || pids[fdes = fileno(iop)] == 0)
- return (-1);
(void)fclose(iop);
sigemptyset(&sigset);
sigaddset(&sigset, SIGINT);
sigaddset(&sigset, SIGQUIT);
sigaddset(&sigset, SIGHUP);
sigprocmask(SIG_BLOCK, &sigset, &osigset);
- while ((pid = waitpid(pids[fdes], &status, 0)) < 0 && errno == EINTR)
+ while ((rv = waitpid(pid, &status, 0)) < 0 && errno == EINTR)
continue;
sigprocmask(SIG_SETMASK, &osigset, NULL);
- pids[fdes] = 0;
- if (pid < 0)
+ if (rv < 0)
return (-1);
if (WIFEXITED(status))
return (WEXITSTATUS(status));