Re: [PATCH] dired mg patch
It fixes the issue that if a filename has a space at the start of it, the point will stay in the first character column and not jump to the first non ' ' character in the filename. Yup, this looks good to me. However, it does seem to expose a bug in dired, that if a filename has a space at the start of it, mg doesn't find it if you try and open it. mg gives a message of (New File) and creates and empty buffer. But in the mean time, I think this change does make this diff more correct. Indeed. This looks like a flaw in d_makename, which seems to implement its own warpdot() :-) This should be changed to use our new function (and we could make use of NAME_FIELD). That fix, along with the one for dealing with shell metacharacters, should probably be a separate diff though.
Re: [PATCH] dired mg patch
However, it does seem to expose a bug in dired, that if a filename has a space at the start of it, mg doesn't find it if you try and open it. mg gives a message of (New File) and creates and empty buffer. But in the mean time, I think this change does make this diff more correct. Indeed. This looks like a flaw in d_makename, which seems to implement its own warpdot() :-) This should be changed to use our new function (and we could make use of NAME_FIELD). That fix, along with the one for dealing with shell metacharacters, should probably be a separate diff though. And here's that diff. Makename() uses warpdot(). I also refined warpdot to use NAME_FIELD and return (FALSE) if the field cannot be located (this is the change I anticipated earlier). This return value should make a couple conditions easier to understand. Then there's ls. Trying to escape shell metacharacters is one of the uglier things a program can do, if the alternative of passing the string directly to a program is available. Most of this code (fork exec) is already in dired.c in shell_command(). I took this code and put it into a separate function, d_exec(), and added some vararg magic. Using this function instead of popen() eliminates the issues with metachars while making dired_() quite a bit simpler. One bit I'm not particularly fond of is the first parameter of d_exec, which is used to prefix the lines with spaces (needed so the action chars like '!' fit on the line in front of ls output). On the principle of YAGNI, however, I did not implement a bigger hammer that would've let the caller read process lines one at a time; this would've involved more functions and state. I also added a few relevant comments. Index: dired.c === RCS file: /cvs/src/usr.bin/mg/dired.c,v retrieving revision 1.49 diff -u -p -r1.49 dired.c --- dired.c 29 Aug 2011 11:02:06 - 1.49 +++ dired.c 29 Aug 2011 13:54:10 - @@ -21,6 +21,7 @@ #include fcntl.h #include errno.h #include libgen.h +#include stdarg.h voiddired_init(void); static int dired(int, int); @@ -33,6 +34,7 @@ static int d_expunge(int, int); static int d_copy(int, int); static int d_del(int, int); static int d_rename(int, int); +static int d_exec(int, struct buffer *, const char *, const char *, ...); static int d_shell_command(int, int); static int d_create_directory(int, int); static int d_makename(struct line *, char *, size_t); @@ -483,14 +485,10 @@ reaper(int signo __attribute__((unused)) int d_shell_command(int f, int n) { - char command[512], fname[MAXPATHLEN], buf[BUFSIZ], *bufp, *cp; - int infd, fds[2]; - pid_tpid; - struct sigaction olda, newa; + char command[512], fname[MAXPATHLEN], *bufp; struct buffer *bp; struct mgwin*wp; - FILE*fin; - char sname[NFILEN]; + char sname[NFILEN]; bp = bfind(*Shell Command Output*, TRUE); if (bclear(bp) != TRUE) @@ -506,11 +504,61 @@ d_shell_command(int f, int n) bufp = eread(! on %s: , command, sizeof(command), EFNEW, sname); if (bufp == NULL) return (ABORT); - infd = open(fname, O_RDONLY); - if (infd == -1) { + + if (d_exec(0, bp, fname, sh, -c, command, NULL) != TRUE) + return (ABORT); + + if ((wp = popbuf(bp, WNONE)) == NULL) + return (ABORT); /* XXX - free the buffer?? */ + curwp = wp; + curbp = wp-w_bufp; + return (TRUE); +} + +/* + * Pipe input file to cmd and insert the command's output in the + * given buffer. Each line will be prefixed with the given + * number of spaces. + */ +static int +d_exec(int space, struct buffer *bp, const char *input, const char *cmd, ...) +{ + char buf[BUFSIZ]; + va_list ap; + struct sigaction olda, newa; + char**argv, *cp; + FILE*fin; + pid_tpid; + int infd, fds[2]; + int n; + + /* Find the number of arguments. */ + va_start(ap, cmd); + for (n = 2; va_arg(ap, char *) != NULL; n++) + ; + va_end(ap); + + /* Allocate and build the argv. */ + if ((argv = calloc(n, sizeof(*argv))) == NULL) { + ewprintf(Can't allocate argv : %s, strerror(errno)); + return (FALSE); + } + + n = 1; + argv[0] = (char *)cmd; + va_start(ap, cmd); + while ((argv[n] = va_arg(ap, char *)) != NULL) + n++; + va_end(ap); + + if (input == NULL) + input = /dev/null; + + if ((infd = open(input, O_RDONLY)) == -1) { ewprintf(Can't open input file : %s, strerror(errno)); return (FALSE); } + if (pipe(fds) == -1) { ewprintf(Can't create pipe : %s,
Re: [PATCH} dired mg patch
This fixes Nima's PR and mark's issue with filenames that start with a space. Index: src/usr.bin/mg/dired.c === RCS file: /cvs/src/usr.bin/mg/dired.c,v retrieving revision 1.48 diff -u -p -r1.48 dired.c --- src/usr.bin/mg/dired.c 23 Jan 2011 00:45:03 - 1.48 +++ src/usr.bin/mg/dired.c 29 Aug 2011 15:17:15 - @@ -36,6 +36,11 @@ static intd_rename(int, int); static int d_shell_command(int, int); static int d_create_directory(int, int); static int d_makename(struct line *, char *, size_t); +static int d_warpdot(char *); +static int d_forwpage(int, int); +static int d_backpage(int, int); +static int d_forwline(int, int); +static int d_backline(int, int); static void reaper(int); extern struct keymap_s helpmap, cXmap, metamap; @@ -57,15 +62,15 @@ static PF dirednul[] = { static PF diredcl[] = { reposition, /* ^L */ d_findfile, /* ^M */ - forwline, /* ^N */ + d_forwline, /* ^N */ rescan, /* ^O */ - backline, /* ^P */ + d_backline, /* ^P */ rescan, /* ^Q */ backisearch,/* ^R */ forwisearch,/* ^S */ rescan, /* ^T */ universal_argument, /* ^U */ - forwpage, /* ^V */ + d_forwpage, /* ^V */ rescan, /* ^W */ NULL/* ^X */ }; @@ -77,7 +82,7 @@ static PF diredcz[] = { rescan, /* ^] */ rescan, /* ^^ */ rescan, /* ^_ */ - forwline, /* SP */ + d_forwline, /* SP */ d_shell_command,/* ! */ rescan, /* */ rescan, /* # */ @@ -99,9 +104,9 @@ static PF diredc[] = { }; static PF diredn[] = { - forwline, /* n */ + d_forwline, /* n */ d_ffotherwindow,/* o */ - backline, /* p */ + d_backline, /* p */ rescan, /* q */ d_rename, /* r */ rescan, /* s */ @@ -116,13 +121,32 @@ static PF direddl[] = { d_undelbak /* del */ }; +static PF diredbp[] = { + d_backpage /* v */ +}; + +static PF dirednull[] = { + NULL +}; + #ifndefDIRED_XMAPS #defineNDIRED_XMAPS0 /* number of extra map sections */ #endif /* DIRED_XMAPS */ -static struct KEYMAPE (6 + NDIRED_XMAPS + IMAPEXT) diredmap = { - 6 + NDIRED_XMAPS, - 6 + NDIRED_XMAPS + IMAPEXT, +static struct KEYMAPE (1 + IMAPEXT) d_backpagemap = { + 1, + 1 + IMAPEXT, + rescan, + { + { + 'v', 'v', diredbp, NULL + } + } +}; + +static struct KEYMAPE (7 + NDIRED_XMAPS + IMAPEXT) diredmap = { + 7 + NDIRED_XMAPS, + 7 + NDIRED_XMAPS + IMAPEXT, rescan, { #ifndef NO_HELP @@ -138,6 +162,10 @@ static struct KEYMAPE (6 + NDIRED_XMAPS CCHR('L'), CCHR('X'), diredcl, (KEYMAP *) cXmap }, { + CCHR('['), CCHR('['), dirednull, (KEYMAP *) + d_backpagemap + }, + { CCHR('Z'), '+', diredcz, (KEYMAP *) metamap }, { @@ -165,8 +193,12 @@ dired_init(void) funmap_add(d_findfile, dired-find-file); funmap_add(d_ffotherwindow, dired-find-file-other-window); funmap_add(d_del, dired-flag-file-deleted); + funmap_add(d_forwline, dired-next-line); funmap_add(d_otherwindow, dired-other-window); + funmap_add(d_backline, dired-previous-line); funmap_add(d_rename, dired-rename-file); + funmap_add(d_backpage, dired-scroll-down); + funmap_add(d_forwpage, dired-scroll-up); funmap_add(d_undel, dired-unflag); maps_add((KEYMAP *)diredmap, dired); dobindkey(fundamental_map, dired, ^Xd); @@ -563,13 +595,13 @@ d_create_directory(int f, int n) return (showbuffer(bp, curwp, WFFULL | WFMODE)); } -#define NAME_FIELD 8 static int d_makename(struct line *lp, char *fn, size_t len) { - int i; + int i, col; char*p, *ep; + col = 0; if (strlcpy(fn, curbp-b_fname, len) = len) return (FALSE); @@ -577,21 +609,98 @@ d_makename(struct line *lp, char *fn, si return (ABORT); ep = lp-l_text + llength(lp); p++; /* skip action letter, if any */ - for (i = 0; i NAME_FIELD; i++) { - while (p ep isspace(*p)) - p++; - while (p
Re: [PATCH] dired mg patch
This diff works fine. Not using metacharacters and passing it as argv is the proper fix. Escaping shell metacharacters isn't the proper way. Warpdot() is also a little bit safer now. It addresses some of the issues I was a bit worried about. This should go in !
APC Smart-UPS 2200 con poco uso - Escucho 0fertas
APC Smart-UPS 2200VA USB Serial RM 2U 230V $ 2200 Consulte respondiendo el presente mensaje Salida Capacidad de Potencia de Salida 1980 Vatios / 2200 VA / Max Potencia Configurable1980 Vatios / 2200 VA Voltaje de salida nominal 230V / Nota de voltaje de salida Configurable a una tensioacute;n nominal de salida de 220 : 230 o 240 / Distorsioacute;nde Voltaje de Salida Menos del 3% / Frecuencia de salida (sincronizado paraprincipales) 47-53 Hz para 50 Hz nominal,57 - 63 Hz para 60 Hz nominal /Tipo de forma de onda Onda senoidal / Conexiones de salida (8) IEC 320 C13 / (1) IEC 320 C19 / (2) IEC Jumpers Entrada Voltaje Nominal de Entrada 230V / Frecuencia de entrada 50/60 Hz +/- 3 Hz(deteccioacute;n automaacute;tica) / Tipo de Conexioacute;n de Entrada/ IEC-320 C20 / Schuko CEE 7 / EU1-16P / British BS1363A Rango de voltaje de entrada En operaciones principales 160 - 286V / Rango de voltaje ajustable paraoperaciones principales 151 - 302V Bateriacute;as y tiempo de autonomiacute;a Tipo de bateriacute;a Bateriacute;a libre de mantenimiento sellada alplomo con electrolito suspendido : a prueba de fugas / Tiempo tiacute;picode recarga 3 hour(s) / Cartucho de bateriacute;a de repuesto RBC43 / Cantidad de RBCtrade; 1 Comunicaciones Gestioacute;n Puerto Interfaz DB-9 RS-232,SmartSlot,USB / Interfaces SmartSlottrade; disponibles 1 / Panel de Control Diodos luminosos de Estado, con barras graficas decarga y bateriacute;a e Indicadores de En Red : Bateriacute;a activada: Cambiar Bateriacute;a : y Sobrecarga / Alarma Acuacute;stica Alarmaen caso de funcionar con bateriacute;as : alarma especial de bateriacute;abaja : Retardos configurables / Desconexioacute;n de Emergencia (EPO) Siacute;/ Proteccioacute;n y Filtro contra Picos de Voltaje / Medicioacute;n deEnergiacute;a de Picos de Voltaje (Julios ) 480 Julios / Filtro Filtracioacute;n multipolar permanente de ruido : Paso de tensioacute;n ante pico de voltage 0.3% IEEE : tiempo de reaccioacute;n de bloqueo cero : acorde con UL 1449 Descripcioacute;n fiacute;sica Altura maacute;xima 89.00 mm / Anchura maacute;xima 483.00 mm / Profundidadmaacute;xima 660.00 mm / Altura del bastidor 2U / Peso neto 43.64 KG /Peso de enviacute;o 51.50 KG / Altura de Enviacute;o 260.00 mm / Anchurade Enviacute;o 600.00 mm / Profundidad de enviacute;o 980.00 mm / Color Negro / Unidades en Palet 8.00 Descripcioacute;n medioambiental Temperatura de trabajo 0 - 40 deg;C / Humedad Relativa de Trabajo 0 - 95% / Elevacioacute;n de Trabajo 0-3000 metros / Temperatura de Almacenamiento-15 - 45 deg;C / Humedad Relativa de Almacenamiento 0 - 95% / Elevacioacute;nde Almacenamiento 0-15000 metros / Ruido perceptible a 1 metro desde lasuperficie de la unidad 47.00 dBA / Disipacioacute;n teacute;rmica online300.00 BTU/h Conformidad Aceptaciones Ciclo C,CE,EN 50091-1,EN 50091-2,GOST,VDE / Cumplimiento medioambientalRoHS 7b Exemption,China RoHS
quotacheck(8) and duid
...at present do not seem to go together nicely: # tail -n 1 /etc/fstab 73123067c3dc34d4.a /data ffs rw,userquota,groupquota 1 1 # /sbin/quotacheck /data quotacheck: 73123067c3dc34d4.a: No such file or directory Would the attached diff be acceptable? It appears to solve my issue, working with both the /dev/sd0a and duid forms. Note that (for unchanged fstab and patch applied), using quotacheck with the then-current physical device (sd0a) complains. # /sbin/quotacheck /dev/sd0a /dev/sd0a not found in /etc/fstab Hardly surprising, since it's indeed not in fstab; I suppose it's overkill to add logic for this. In case the diff gets mangled in transit, alternatively try: http://pastebin.com/VRN8wZX6 Regards, Rogier Index: Makefile === RCS file: /cvs/src/sbin/quotacheck/Makefile,v retrieving revision 1.6 diff -u -r1.6 Makefile --- Makefile21 Sep 1997 11:37:57 - 1.6 +++ Makefile29 Aug 2011 23:20:47 - @@ -6,4 +6,7 @@ MAN= quotacheck.8 .PATH: ${.CURDIR}/../fsck +LDADD+=-lutil +DPADD+=${LIBUTIL} + .include bsd.prog.mk Index: quotacheck.c === RCS file: /cvs/src/sbin/quotacheck/quotacheck.c,v retrieving revision 1.25 diff -u -r1.25 quotacheck.c --- quotacheck.c27 Oct 2009 23:59:34 - 1.25 +++ quotacheck.c29 Aug 2011 23:20:47 - @@ -50,6 +50,7 @@ #include grp.h #include errno.h #include unistd.h +#include util.h #include stdio.h #include stdlib.h #include string.h @@ -263,13 +264,14 @@ ino_t ino, inosused; pid_t pid; char *cp; + char *realdev; switch (pid = fork()) { case -1:/* error */ warn(fork); return 1; case 0: /* child */ - if ((fi = open(fsname, O_RDONLY, 0)) 0) + if ((fi = opendev(fsname, O_RDONLY, 0, realdev)) 0) err(1, %s, fsname); sync(); dev_bsize = 1;
Re: [PATCH] dired mg patch
And here's that diff. [..] It never hurts to re-read a diff before going to bed. Indeed, I forgot to free argv (execlp uses alloca). The number of things to clean up after one thing fails is almost getting out of hand, and at least the fork() case wasn't handled properly. In this new revision of d_exec, argv and all the fds are checked and freed (only) at the end of the function, if necessary. That's where we jump to, should anything fail. The rest of the diff is as before. Index: dired.c === RCS file: /cvs/src/usr.bin/mg/dired.c,v retrieving revision 1.49 diff -u -p -r1.49 dired.c --- dired.c 29 Aug 2011 11:02:06 - 1.49 +++ dired.c 29 Aug 2011 23:27:09 - @@ -21,6 +21,7 @@ #include fcntl.h #include errno.h #include libgen.h +#include stdarg.h voiddired_init(void); static int dired(int, int); @@ -33,6 +34,7 @@ static int d_expunge(int, int); static int d_copy(int, int); static int d_del(int, int); static int d_rename(int, int); +static int d_exec(int, struct buffer *, const char *, const char *, ...); static int d_shell_command(int, int); static int d_create_directory(int, int); static int d_makename(struct line *, char *, size_t); @@ -483,14 +485,10 @@ reaper(int signo __attribute__((unused)) int d_shell_command(int f, int n) { - char command[512], fname[MAXPATHLEN], buf[BUFSIZ], *bufp, *cp; - int infd, fds[2]; - pid_tpid; - struct sigaction olda, newa; + char command[512], fname[MAXPATHLEN], *bufp; struct buffer *bp; struct mgwin*wp; - FILE*fin; - char sname[NFILEN]; + char sname[NFILEN]; bp = bfind(*Shell Command Output*, TRUE); if (bclear(bp) != TRUE) @@ -506,68 +504,124 @@ d_shell_command(int f, int n) bufp = eread(! on %s: , command, sizeof(command), EFNEW, sname); if (bufp == NULL) return (ABORT); - infd = open(fname, O_RDONLY); - if (infd == -1) { + + if (d_exec(0, bp, fname, sh, -c, command, NULL) != TRUE) + return (ABORT); + + if ((wp = popbuf(bp, WNONE)) == NULL) + return (ABORT); /* XXX - free the buffer?? */ + curwp = wp; + curbp = wp-w_bufp; + return (TRUE); +} + +/* + * Pipe input file to cmd and insert the command's output in the + * given buffer. Each line will be prefixed with the given + * number of spaces. + */ +static int +d_exec(int space, struct buffer *bp, const char *input, const char *cmd, ...) +{ + char buf[BUFSIZ]; + va_list ap; + struct sigaction olda, newa; + char**argv = NULL, *cp; + FILE*fin; + int fds[2] = { -1, -1 }; + int infd = -1; + int ret = (ABORT), n; + pid_tpid; + + if (sigaction(SIGCHLD, NULL, olda) == -1) + return (ABORT); + + /* Find the number of arguments. */ + va_start(ap, cmd); + for (n = 2; va_arg(ap, char *) != NULL; n++) + ; + va_end(ap); + + /* Allocate and build the argv. */ + if ((argv = calloc(n, sizeof(*argv))) == NULL) { + ewprintf(Can't allocate argv : %s, strerror(errno)); + goto out; + } + + n = 1; + argv[0] = (char *)cmd; + va_start(ap, cmd); + while ((argv[n] = va_arg(ap, char *)) != NULL) + n++; + va_end(ap); + + if (input == NULL) + input = /dev/null; + + if ((infd = open(input, O_RDONLY)) == -1) { ewprintf(Can't open input file : %s, strerror(errno)); - return (FALSE); + goto out; } + if (pipe(fds) == -1) { ewprintf(Can't create pipe : %s, strerror(errno)); - close(infd); - return (FALSE); + goto out; } newa.sa_handler = reaper; newa.sa_flags = 0; - if (sigaction(SIGCHLD, newa, olda) == -1) { - close(infd); - close(fds[0]); - close(fds[1]); - return (ABORT); + if (sigaction(SIGCHLD, newa, NULL) == -1) + goto out; + + if ((pid = fork()) == -1) { + ewprintf(Can't fork); + goto out; } - pid = fork(); + switch (pid) { - case -1: - ewprintf(Can't fork); - return (ABORT); - case 0: + case 0: /* Child */ close(fds[0]); dup2(infd, STDIN_FILENO); dup2(fds[1], STDOUT_FILENO); dup2(fds[1], STDERR_FILENO); - execl(/bin/sh, sh, -c, bufp, (char *)NULL); + execvp(argv[0], argv); exit(1); break; - default: + default: /* Parent */
Re: quotacheck(8) and duid
On Tue, Aug 30, 2011 at 01:25, Rogier Krieger rkrie...@gmail.com wrote: Would the attached diff be acceptable? Sorry, no real point in adding a variable that is not really used. I should've read the man page more thoroughly. New diff, without that junk. Also at http://pastebin.com/bRiUuX1J Index: Makefile === RCS file: /cvs/src/sbin/quotacheck/Makefile,v retrieving revision 1.6 diff -u -r1.6 Makefile --- Makefile21 Sep 1997 11:37:57 - 1.6 +++ Makefile30 Aug 2011 02:59:22 - @@ -6,4 +6,7 @@ MAN= quotacheck.8 .PATH: ${.CURDIR}/../fsck +LDADD+=-lutil +DPADD+=${LIBUTIL} + .include bsd.prog.mk Index: quotacheck.c === RCS file: /cvs/src/sbin/quotacheck/quotacheck.c,v retrieving revision 1.25 diff -u -r1.25 quotacheck.c --- quotacheck.c27 Oct 2009 23:59:34 - 1.25 +++ quotacheck.c30 Aug 2011 02:59:22 - @@ -50,6 +50,7 @@ #include grp.h #include errno.h #include unistd.h +#include util.h #include stdio.h #include stdlib.h #include string.h @@ -269,7 +270,7 @@ warn(fork); return 1; case 0: /* child */ - if ((fi = open(fsname, O_RDONLY, 0)) 0) + if ((fi = opendev(fsname, O_RDONLY, 0, NULL)) 0) err(1, %s, fsname); sync(); dev_bsize = 1;
Re: [PATCH] dired mg patch
The latest diff has no issues so far. I just added the error message in case execvp() fails. Index: src/usr.bin/mg/dired.c === RCS file: /cvs/src/usr.bin/mg/dired.c,v retrieving revision 1.49 diff -u -p -r1.49 dired.c --- src/usr.bin/mg/dired.c 29 Aug 2011 11:02:06 - 1.49 +++ src/usr.bin/mg/dired.c 30 Aug 2011 03:39:11 - @@ -21,6 +21,7 @@ #include fcntl.h #include errno.h #include libgen.h +#include stdarg.h voiddired_init(void); static int dired(int, int); @@ -33,6 +34,7 @@ static int d_expunge(int, int); static int d_copy(int, int); static int d_del(int, int); static int d_rename(int, int); +static int d_exec(int, struct buffer *, const char *, const char *, ...); static int d_shell_command(int, int); static int d_create_directory(int, int); static int d_makename(struct line *, char *, size_t); @@ -483,14 +485,10 @@ reaper(int signo __attribute__((unused)) int d_shell_command(int f, int n) { - char command[512], fname[MAXPATHLEN], buf[BUFSIZ], *bufp, *cp; - int infd, fds[2]; - pid_tpid; - struct sigaction olda, newa; + char command[512], fname[MAXPATHLEN], *bufp; struct buffer *bp; struct mgwin*wp; - FILE*fin; - char sname[NFILEN]; + char sname[NFILEN]; bp = bfind(*Shell Command Output*, TRUE); if (bclear(bp) != TRUE) @@ -506,68 +504,125 @@ d_shell_command(int f, int n) bufp = eread(! on %s: , command, sizeof(command), EFNEW, sname); if (bufp == NULL) return (ABORT); - infd = open(fname, O_RDONLY); - if (infd == -1) { + + if (d_exec(0, bp, fname, sh, -c, command, NULL) != TRUE) + return (ABORT); + + if ((wp = popbuf(bp, WNONE)) == NULL) + return (ABORT); /* XXX - free the buffer?? */ + curwp = wp; + curbp = wp-w_bufp; + return (TRUE); +} + +/* + * Pipe input file to cmd and insert the command's output in the + * given buffer. Each line will be prefixed with the given + * number of spaces. + */ +static int +d_exec(int space, struct buffer *bp, const char *input, const char *cmd, ...) +{ + char buf[BUFSIZ]; + va_list ap; + struct sigaction olda, newa; + char**argv = NULL, *cp; + FILE*fin; + int fds[2] = { -1, -1 }; + int infd = -1; + int ret = (ABORT), n; + pid_tpid; + + if (sigaction(SIGCHLD, NULL, olda) == -1) + return (ABORT); + + /* Find the number of arguments. */ + va_start(ap, cmd); + for (n = 2; va_arg(ap, char *) != NULL; n++) + ; + va_end(ap); + + /* Allocate and build the argv. */ + if ((argv = calloc(n, sizeof(*argv))) == NULL) { + ewprintf(Can't allocate argv : %s, strerror(errno)); + goto out; + } + + n = 1; + argv[0] = (char *)cmd; + va_start(ap, cmd); + while ((argv[n] = va_arg(ap, char *)) != NULL) + n++; + va_end(ap); + + if (input == NULL) + input = /dev/null; + + if ((infd = open(input, O_RDONLY)) == -1) { ewprintf(Can't open input file : %s, strerror(errno)); - return (FALSE); + goto out; } + if (pipe(fds) == -1) { ewprintf(Can't create pipe : %s, strerror(errno)); - close(infd); - return (FALSE); + goto out; } newa.sa_handler = reaper; newa.sa_flags = 0; - if (sigaction(SIGCHLD, newa, olda) == -1) { - close(infd); - close(fds[0]); - close(fds[1]); - return (ABORT); + if (sigaction(SIGCHLD, newa, NULL) == -1) + goto out; + + if ((pid = fork()) == -1) { + ewprintf(Can't fork); + goto out; } - pid = fork(); + switch (pid) { - case -1: - ewprintf(Can't fork); - return (ABORT); - case 0: + case 0: /* Child */ close(fds[0]); dup2(infd, STDIN_FILENO); dup2(fds[1], STDOUT_FILENO); dup2(fds[1], STDERR_FILENO); - execl(/bin/sh, sh, -c, bufp, (char *)NULL); + if (execvp(argv[0], argv) == -1) + printf(cmd error: %s, strerror(errno)); exit(1); break; - default: + default: /* Parent */ close(infd); close(fds[1]); - fin = fdopen(fds[0], r); - if (fin == NULL)/* r is surely a valid mode! */ - panic(can't happen); + infd = fds[1] = -1; + if ((fin =