1 /* $Id: xsystem.c,v 1.13 1992/02/24 06:59:13 serow Exp serow $
2 * like system("cmd") but return with exit code of "cmd"
3 * for Turbo-C/MS-C/LSI-C
4 * This code is in the public domain.
5 *
6 * $Log: xsystem.c,v $
7 * Revision 1.13 1992/02/24 06:59:13 serow
8 * *** empty log message ***
9 *
10 * Revision 1.12 1991/04/09 08:48:20 serow
11 * ignore new line at command line tail
12 *
13 * Revision 1.11 1991/03/12 07:12:50 serow
14 * CMDLINE
15 *
16 * Revision 1.10 91/02/24 05:10:14 serow
17 * 2>&1
18 *
19 * Revision 1.9 91/02/22 07:01:17 serow
20 * NEAR for ms-c
21 *
22 */
23 /* modified for djgpp v2.01 1997.1.29 by K.Okabe */
24 /* Last modified 2000.1.29 by K.Okabe */
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <fcntl.h>
29 #include <io.h>
30 #include <process.h>
31 #include <dos.h>
32 /* patch 1997.1.27 by K.Okabe */
33 #include <limits.h>
34 #include <errno.h>
35 #ifdef __GO32__
36 #include <dpmi.h>
37 #include <go32.h>
38 #include <sys/farptr.h>
39 #include <unistd.h>
40 #endif
41 /* end of patch */
42 /* patch 1998.8.4 by K.Okabe */
43 #ifdef WIN32
44 #include <mbctype.h>
45 #endif
46 /* end of patch */
47
48
49 #ifndef USECMDLINE
50 #define USECMDLINE 0
51 #endif
52
53 /* patch 1997.1.27 by K.Okabe */
54 #ifndef PATH_MAX
55 #define PATH_MAX 128
56 #endif
57 /* end of patch */
58
59 extern char *mktemp(char *);
60
61 #define UCH(c) ((unsigned char)(c))
62 #if 1 /* patch 1997.1.28 by K.Okabe */
63 #define isk1(c) dbcs_bitset_member(UCH(c))
64 #else
65 #define isk1(c) ((0x81<=UCH(c)&&UCH(c)<=0x9F)||(0xE0<=UCH(c)&&UCH(c)<=0xFC))
66 #endif
67 #define isq(c) ((c) == '"')
68 #define isspc(c) ((c) == ' ' || (c) == '\t')
69 #define issep(c) (isspc(c) || (c) == '"' || (c) == '\'' || (c) == '<' || (c) == '>' || (c) == '\0')
70 #define issep2(c) (issep(c) || (c) == '.' || (c) == '\\' || (c) == '/')
71 #define isdeg(c) ('0' <= (c) && (c) <= '9')
72
73 #if (defined (_MSC_VER) || defined (__TURBOC__)) && !defined (WIN32)
74 /* MS-C */
75 #define NEAR _near
76 #else
77 #define NEAR
78 #endif
79
80 /* patch 1997.4.2 by K.Okabe */
81 #if defined (GAWK) && !defined (__GO32__) && !defined(WIN32)
82 extern int os_open (const char *, int, ...);
83 #define open os_open
84 #endif
85 /* end of patch */
86
87 /* patch 1997.1.27 by K.Okabe */
88 #ifdef __GNUC__
89 #define ALLOCA(n) __builtin_alloca((n))
90 #define FREE(p)
91 #else
92 #define ALLOCA(n) xmalloc((n))
93 #define FREE(p) free((p))
94 #endif
95
96 #if defined(DJGPP) && ((DJGPP > 2) || (DJGPP == 2 && DJGPP_MINOR >= 1))
97 #define SPAWN(cmd,arg) djgpp201_spawn((cmd), (arg))
98 #define CMDLEN_LIMIT 125
99
100 extern char **environ;
101
102 static int NEAR
djgpp201_spawn(const char * cmd,const char * arg)103 djgpp201_spawn(const char *cmd, const char *arg)
104 {
105 if (strlen(arg) > CMDLEN_LIMIT) {
106 errno = E2BIG;
107 return -1;
108 }
109 return _dos_exec(cmd, arg, environ);
110 }
111 #else
112 #define SPAWN(cmd,arg) spawnl(P_WAIT, (cmd), (cmd), (arg), (char *) 0)
113 #endif
114
115 #if defined(DJGPP) && DJGPP >= 2
116 #define REGS __dpmi_regs
117 #define INTDOS(regs) __dpmi_int(0x21, &(regs))
118 #define INTDOSX(regs,segs) __dpmi_int(0x21, &(regs))
119 #else
120 #define REGS union REGS
121 #define INTDOS(regs) intdos(&(regs), &(regs))
122 #define INTDOSX(regs,segs) intdosx(&(regs), &(regs), &(segs))
123 #endif
124 #ifdef __GO32__
125 #define OFFSET unsigned
126 #define MAKE_OFFSET(seg,off) ((OFFSET) (((seg) << 4) + (off)))
127 #define PEEKB(off) _farpeekb(_go32_info_block.selector_for_linear_memory, (off))
128 #else
129 #define OFFSET unsigned char far *
130 #define MAKE_OFFSET(seg,off) \
131 ((OFFSET) (((unsigned long) ((seg) + ((unsigned) (off) >> 4)) << 16) | (unsigned) ((off) & 15)))
132 #define PEEKB(off) (*(off))
133 #endif
134
135 #define CHARBITS 8
136
137 #define dbcs_bitset_access(n,op) \
138 (dbcs_table[(unsigned) (n) / CHARBITS] op (1 << ((n) & (CHARBITS - 1))))
139
140 #define dbcs_bitset_member(n) dbcs_bitset_access(n, &)
141 #define dbcs_bitset_enjoin(n) dbcs_bitset_access(n, |=)
142
143 static unsigned char dbcs_table[(1 << CHARBITS) / CHARBITS];
144
145 static void NEAR
init_dbcs()146 init_dbcs()
147 {
148 /* patch 1998.8.5 by K.Okabe */
149 #if defined(WIN32)
150 int c;
151
152 static int done = 0;
153
154 if (done)
155 return;
156
157 done = 1;
158 memset(dbcs_table, 0, sizeof(dbcs_table));
159 for (c = 0; c < 256; c++)
160 if (_ismbblead(c))
161 dbcs_bitset_enjoin(c);
162 #else
163 /* end of patch */
164 #if defined(DJGPP) && DJGPP >= 2
165 #define SEG_DS regs.x.ds
166 #else
167 #define SEG_DS segs.ds
168 struct SREGS segs;
169 #endif
170 REGS regs;
171 OFFSET offset;
172
173 static int done = 0;
174
175 if (done)
176 return;
177
178 done = 1;
179 memset(dbcs_table, 0, sizeof(dbcs_table));
180 SEG_DS = regs.x.si = 0;
181 regs.x.ax = 0x6300;
182 INTDOSX(regs, segs);
183 offset = MAKE_OFFSET(SEG_DS, regs.x.si);
184 if (offset == (OFFSET) 0)
185 return;
186
187 for (;;) {
188 int lo, hi, c;
189
190 lo = (unsigned char) PEEKB(offset);
191 offset++;
192 hi = (unsigned char) PEEKB(offset);
193 offset++;
194 if (lo == 0 && hi == 0)
195 break;
196
197 for (c = lo; c <= hi; c++)
198 dbcs_bitset_enjoin(c);
199 }
200 #endif
201 }
202 /* end of patch */
203
204 typedef struct _proc {
205 struct _proc *next;
206 char *line;
207 char *cmd;
208 char *arg;
209 char *inf;
210 int infmod;
211 char *outf;
212 int outfmod;
213 /* patch 1997.1.27 by K.Okabe */
214 char *errf;
215 int errfmod;
216 /* end of patch */
217 int ored[10];
218 int sred[10];
219 } PRO;
220
221 static PRO *p1 = 0;
222
223 static char *NEAR
xmalloc(size_t n)224 xmalloc(size_t n)
225 {
226 char *bp;
227
228 if ((bp = calloc(1, n)) == (char *) 0) {
229 write(2, "xsystem: Out of memory.!\n", 25);
230 exit(1);
231 }
232 return bp;
233 }
234
235 static char *NEAR
xrealloc(void * p,size_t n)236 xrealloc(void *p, size_t n)
237 {
238 char *bp;
239
240 if ((bp = realloc(p, n)) == (char *) 0) {
241 write(2, "xsystem: Out of memory!.\n", 25);
242 exit(1);
243 }
244 return bp;
245 }
246
247 static int NEAR
iscommandcommand(char * s)248 iscommandcommand(char *s)
249 {
250 static char *cmdtab[]=
251 {
252 "dir", "type", "rem", "ren", "rename", "erase", "del",
253 "copy", "pause", "date", "time", "ver", "vol",
254 "cd", "chdir", "md", "mkdir", "rd", "rmdir", "break",
255 "verify", "set", "prompt", "path", "exit", "ctty", "echo",
256 "if", "for", "cls", "goto", "shift"
257 };
258 int i, l, lc;
259
260 l = strlen(s);
261 for (i = 0; i < sizeof(cmdtab) / sizeof(cmdtab[0]); i++) {
262 if (stricmp(s, cmdtab[i]) == 0)
263 return 1;
264 lc = strlen(cmdtab[i]);
265 if (lc < l && strnicmp(s, cmdtab[i], lc) == 0 && issep2(s[lc]))
266 return 1;
267 }
268 return 0;
269 }
270
271 static int NEAR
getswchar(void)272 getswchar(void)
273 {
274 #ifdef WIN32
275 return '/';
276 #else
277 REGS reg;
278
279 reg.x.ax = 0x3700;
280 INTDOS(reg);
281 return reg.h.dl;
282 #endif
283 }
284
285 static int NEAR
csystem(PRO * p)286 csystem(PRO * p)
287 {
288 char *cmp;
289 char SW[3];
290 int rc;
291
292 #ifdef GAWK /* patch 1997.1.27 by K.Okabe */
293 cmp = getenv("SHELL");
294 if (! cmp)
295 cmp = getenv("COMSPEC");
296 if (! cmp)
297 return -2;
298 #else
299 if ((cmp = getenv("COMSPEC")) == 0)
300 return -2;
301 #endif
302 SW[0] = getswchar();
303 SW[1] = 'c';
304 SW[2] = 0;
305 #if 1 /* patch 1997.1.27 by K.Okabe */
306 {
307 char *cmdline = (char *) ALLOCA(strlen(p->cmd) + strlen(p->arg) + 4);
308 if (strpbrk(p->cmd, "\t ")) {
309 cmdline[0] = '"';
310 strcat(strcpy(cmdline + 1, p->cmd), "\"");
311 } else
312 strcpy(cmdline, p->cmd);
313 strcat(strcat(cmdline, " "), p->arg);
314 rc = spawnl(P_WAIT, cmp, cmp, SW, cmdline, (char *) 0);
315 FREE(cmdline);
316 }
317 #else
318 rc = spawnl(P_WAIT, cmp, cmp, SW, p->cmd, p->arg, (char *) 0);
319 #endif
320 return rc < 0 ? -2 : rc;
321 }
322
323 static PRO *NEAR
pars1c(char * s)324 pars1c(char *s)
325 {
326 PRO *pp;
327 char *fnp;
328 int ms, mi;
329 int fs, fi, inpf;
330 int q;
331
332 pp = (PRO *) xmalloc(sizeof(PRO));
333 for (q = 0; q < sizeof(pp->ored) / sizeof(pp->ored[0]); q++)
334 pp->ored[q] = q;
335 while (isspc(*s))
336 s++;
337 pp->line = strdup(s);
338 pp->cmd = xmalloc(ms = 8);
339 mi = 0;
340 #if 1 /* patch 1997.1.28 by K.Okabe */
341 if ((q = *s == '"'))
342 s++;
343 while (q ? *s != '"' && *s != '\0' : ! issep(*s)) {
344 if (mi >= ms - 1)
345 pp->cmd = xrealloc(pp->cmd, ms += 8);
346 pp->cmd[mi++] = *s++;
347 }
348 if (q && *s == '"')
349 s++;
350 #else
351 while (!issep(*s)) {
352 if (mi >= ms - 1)
353 pp->cmd = xrealloc(pp->cmd, ms += 8);
354 pp->cmd[mi++] = *s++;
355 }
356 #endif
357 pp->cmd[mi] = '\0';
358 q = 0;
359 pp->arg = xmalloc(ms = 32);
360 if (isspc(*s))
361 s++;
362 mi = 0;
363 while (*s) {
364 if (mi >= ms - 1) {
365 pp->arg = xrealloc(pp->arg, ms += 32);
366 }
367 if (q == 0) {
368 /* patch 1997.1.28 by K.Okabe */
369 int errf = 0;
370 /* end of patch */
371 inpf = 0;
372 if ((mi == 0 || isspc(s[-1])) &&
373 isdeg(s[0]) && s[1] == '>' &&
374 s[2] == '&' && isdeg(s[3])) {
375
376 pp->ored[s[0] & 15] = s[3] & 15;
377 s += 4;
378 continue;
379 } else if (s[0] == '<') {
380 if (pp->inf == 0) {
381 pp->infmod = O_RDONLY;
382 }
383 inpf = 1;
384 } else if (s[0] == '>' && s[1] == '>') {
385 if (pp->outf == 0) {
386 pp->outfmod = O_WRONLY | O_CREAT | O_APPEND;
387 }
388 s++;
389 } else if (s[0] == '>') {
390 if (pp->outf == 0) {
391 pp->outfmod = O_WRONLY | O_CREAT | O_TRUNC;
392 }
393 /* patch 1997.1.28 by K.Okabe */
394 } else if ((mi == 0 || isspc(s[-1])) && s[0] == '1' && s[1] == '>') {
395 if (s[2] == '>') {
396 if (pp->outf == 0) {
397 pp->outfmod = O_WRONLY | O_CREAT | O_APPEND;
398 }
399 s += 2;
400 } else {
401 if (pp->outf == 0) {
402 pp->outfmod = O_WRONLY | O_CREAT | O_TRUNC;
403 }
404 s++;
405 }
406 } else if ((mi == 0 || isspc(s[-1])) && s[0] == '2' && s[1] == '>') {
407 if (s[2] == '>') {
408 if (pp->errf == 0) {
409 pp->errfmod = O_WRONLY | O_CREAT | O_APPEND;
410 }
411 s += 2;
412 } else {
413 if (pp->errf == 0) {
414 pp->errfmod = O_WRONLY | O_CREAT | O_TRUNC;
415 }
416 s++;
417 }
418 errf = 1;
419 /* end of patch */
420 } else {
421 if (*s == '"')
422 q = !q;
423 pp->arg[mi++] = *s++;
424 continue;
425 }
426 fnp = xmalloc(fs = 16);
427 fi = 0;
428 s++;
429 while (isspc(*s))
430 s++;
431 while (!issep(*s)) {
432 if (fi >= fs - 1)
433 fnp = xrealloc(fnp, fs += 16);
434 fnp[fi++] = *s++;
435 }
436 fnp[fi] = 0;
437 if (inpf) {
438 if (pp->inf == 0)
439 pp->inf = fnp;
440 /* patch 1997.1.28 by K.Okabe */
441 } else if (errf) {
442 if (pp->errf == 0)
443 pp->errf = fnp;
444 /* end of patch */
445 } else {
446 if (pp->outf == 0)
447 pp->outf = fnp;
448 }
449 } else if (s[0] == '"') {
450 q = !q;
451 pp->arg[mi++] = *s++;
452 } else {
453 pp->arg[mi++] = *s++;
454 }
455 }
456 /* patch 1997.1.28 by K.Okabe */
457 while (mi > 0 && isspc(pp->arg[mi - 1]))
458 mi--;
459 /* end of patch */
460 pp->arg[mi] = '\0';
461 return pp;
462 }
463
464 static PRO *NEAR
pars(char * s)465 pars(char *s)
466 {
467 char *lb;
468 int li, ls, q;
469 int c;
470 PRO *pp;
471
472 lb = xmalloc(ls = 128); /* about */
473 li = q = 0;
474 p1 = 0;
475
476 for (;;) {
477 c = *s++;
478 if (li >= ls - 3)
479 lb = xrealloc(lb, ls += 128);
480 if (isk1(c) && *s) {
481 lb[li++] = c;
482 lb[li++] = *s++;
483 } else if ((!q && c == '|') || c == '\0' || (c == '\n' && *s == '\0')) {
484 lb[li++] = '\0';
485 if (p1 == 0) {
486 pp = p1 = pars1c(lb);
487 } else {
488 pp->next = pars1c(lb);
489 pp = pp->next;
490 }
491 li = 0;
492 if (c == '\0' || (c == '\n' && *s == '\0'))
493 break;
494 #if 0 /* patch 1997.1.27 by K.Okabe */
495 } else if (c == '\\') {
496 lb[li++] = c;
497 if (*s) {
498 if (isk1(*s))
499 lb[li++] = *s++;
500 lb[li++] = *s++;
501 }
502 #endif
503 } else if (c == '"') {
504 q = !q;
505 lb[li++] = c;
506 } else {
507 lb[li++] = c;
508 }
509 }
510 free(lb);
511 return p1;
512 }
513
514 static int NEAR
try3(char * cnm,PRO * p)515 try3(char *cnm, PRO * p)
516 {
517 char cmdb[PATH_MAX];
518 int rc;
519
520 strcat(strcpy(cmdb, cnm), ".com");
521 if ((rc = open(cmdb, O_RDONLY)) >= 0) {
522 close(rc);
523 return SPAWN(cmdb, p->arg);
524 }
525 strcat(strcpy(cmdb, cnm), ".exe");
526 if ((rc = open(cmdb, O_RDONLY)) >= 0) {
527 close(rc);
528 return SPAWN(cmdb, p->arg);
529 }
530 strcat(strcpy(cmdb, cnm), ".bat");
531 if ((rc = open(cmdb, O_RDONLY)) >= 0) {
532 close(rc);
533 return csystem(p);
534 }
535 return -1;
536 }
537
538 static int NEAR
pgo(PRO * p)539 pgo(PRO * p)
540 {
541 char *s;
542 char *extp = 0;
543 char cmdb[PATH_MAX];
544 char *ep;
545 int rc, lc;
546
547 s = p->cmd + strlen(p->cmd) - 1;
548 while (p->cmd <= s && *s != '\\' && *s != '/' && *s != ':') {
549 if (*s == '.')
550 extp = s;
551 s--;
552 }
553 if (iscommandcommand(p->cmd) || (extp && stricmp(extp, ".bat") == 0))
554 return csystem(p);
555
556 if (s < p->cmd) { /* cmd has no PATH nor Drive */
557 ep = getenv("PATH");
558 strcpy(cmdb, p->cmd);
559 for (;;) {
560 if (extp) { /* has extention */
561 if ((rc = open(cmdb, O_RDONLY)) >= 0) {
562 close(rc);
563 rc = SPAWN(cmdb, p->arg);
564 }
565 } else {
566 rc = try3(cmdb, p);
567 }
568 if (rc >= 0)
569 return rc;
570
571 if (ep && *ep) {
572 int i;
573 for (i = 0; *ep != ';' && *ep != '\0'; ep++, i++)
574 lc = cmdb[i] = *ep;
575 if (*ep == ';')
576 ep++;
577 if (i > 0 && lc != ':' && lc != '\\' && lc != '/')
578 cmdb[i++] = '\\';
579 cmdb[i] = 0;
580 strcat(cmdb, p->cmd);
581 } else {
582 if (rc == -2)
583 return rc;
584 return -1;
585 }
586 }
587 } else { /* has PATH or Drive */
588 if (extp) { /* has extention */
589 if ((rc = open(p->cmd, O_RDONLY)) >= 0) {
590 close(rc);
591 return SPAWN(p->cmd, p->arg);
592 }
593 return -1;
594 } else {
595 return try3(p->cmd, p);
596 }
597 }
598 }
599
600 static char *NEAR
tmpf(char * tp)601 tmpf(char *tp)
602 {
603 char tplate[PATH_MAX];
604 char *ev;
605 int i;
606
607 #ifdef __GO32__
608 ev = getenv("TMPDIR");
609 if (! ev)
610 ev = getenv("TMP");
611 #else
612 ev = getenv("TMP");
613 #endif
614 if (ev != 0) {
615 strcpy(tplate, ev);
616 i = strlen(ev);
617 if (i && ev[i - 1] != '\\' && ev[i - 1] != '/')
618 strcat(tplate, "\\");
619 } else {
620 tplate[0] = 0;
621 }
622 strcat(tplate, tp);
623 return strdup(mktemp(tplate));
624 }
625
626 static int NEAR
redopen(char * fn,int md,int sfd)627 redopen(char *fn, int md, int sfd)
628 {
629 int rc;
630 int fd;
631
632 if ((fd = open(fn, md, 0666)) != -1) {
633 if (md & O_APPEND)
634 lseek(fd, 0L, SEEK_END);
635 rc = dup(sfd);
636 if (fd != sfd) {
637 dup2(fd, sfd);
638 close(fd);
639 }
640 return rc;
641 }
642 return -1;
643 }
644
645 static int NEAR
redclose(int fd,int sfd)646 redclose(int fd, int sfd)
647 {
648 if (fd != -1) {
649 dup2(fd, sfd);
650 close(fd);
651 }
652 return -1;
653 }
654
655 static void NEAR
redswitch(PRO * p)656 redswitch(PRO * p)
657 {
658 int d;
659
660 for (d = 0; d < sizeof(p->ored) / sizeof(p->ored[0]); d++) {
661 if (d != p->ored[d]) {
662 p->sred[d] = dup(d);
663 dup2(p->ored[d], d);
664 }
665 }
666 }
667 static void NEAR
redunswitch(PRO * p)668 redunswitch(PRO * p)
669 {
670 int d;
671
672 for (d = 0; d < sizeof(p->ored) / sizeof(p->ored[0]); d++) {
673 if (d != p->ored[d]) {
674 dup2(p->sred[d], d);
675 close(p->sred[d]);
676 }
677 }
678 }
679
680 /* patch 1997.1.31 by K.Okabe */
681 static int
is_unixy_shell(const char * shell)682 is_unixy_shell(const char *shell)
683 {
684 static const char *shells[] = {
685 "SH",
686 "SH16",
687 "SH32",
688 "KSH",
689 "ZSH",
690 "BASH",
691 0
692 };
693 char shellexe[16];
694 const char *p;
695 int i;
696
697 for (p = shell; *p != '\0'; p++)
698 if (*p == ':' || *p == '/' || *p == '\\')
699 shell = p + 1;
700 for (i = 0; shells[i]; i++) {
701 if (stricmp(shell, shells[i]) == 0)
702 return 1;
703 strcpy(shellexe, shells[i]);
704 strcat(shellexe, ".EXE");
705 if (stricmp(shell, shellexe) == 0)
706 return 1;
707 }
708 return 0;
709 }
710 /* end of patch */
711
712 int
xsystem(char * cmd)713 xsystem(char *cmd)
714 {
715 PRO *p, *pn;
716 char *pof, *pif, *pxf;
717 int psstdin, psstdout;
718 int rdstdin, rdstdout;
719 /* patch 1997.1.27 by K.Okabe */
720 int rdstderr;
721 /* end of patch */
722 int rc = 0;
723 #if USECMDLINE
724 static char *cmdline = 0;
725 char *oldcmdline;
726 #endif
727
728 #if defined(GAWK) && defined(OS2) && (_MSC_VER != 510) /* patch 1997.2.20 by K.Okabe */
729 if (_osmode == OS2_MODE)
730 return system(cmd);
731 #endif
732
733 /* patch 1997.1.31 by K.Okabe */
734 {
735 char *shell = (char *) 0;
736 #ifdef GAWK
737 shell = getenv("AWKSHELL");
738 if (! shell)
739 shell = getenv("SHELL");
740 #endif
741 if (! shell)
742 shell = getenv("COMSPEC");
743 if (shell && is_unixy_shell(shell)) {
744 #if defined(DJGPP) && ((DJGPP > 2) || (DJGPP == 2 && DJGPP_MINOR >= 1))
745 rc = spawnl(P_WAIT, shell, shell, "-c", cmd, (char *) 0);
746 #else
747 char *quoted_cmd, *p;
748 quoted_cmd = (char *) ALLOCA(strlen(cmd) * 2 + 3);
749 p = quoted_cmd;
750 *p++ = '"';
751 while (*cmd != '\0') {
752 if (*cmd == '"')
753 *p++ = '\\';
754 *p++ = *cmd++;
755 }
756 *p++ = '"';
757 *p = '\0';
758 rc = spawnl(P_WAIT, shell, shell, "-c", quoted_cmd, (char *) 0);
759 FREE(quoted_cmd);
760 #endif
761 return rc < 0 ? 0xff00 : (rc << 8) & 0xff00 ;
762 }
763 }
764 init_dbcs();
765 /* end of patch */
766
767 pof = pif = pxf = 0;
768 p = pars(cmd);
769 pof = tmpf("p1XXXXXX");
770 pif = tmpf("p2XXXXXX");
771 psstdin = psstdout = rdstdin = rdstdout = -1;
772 /* patch 1997.1.27 by K.Okabe */
773 rdstderr = -1;
774 /* end of patch */
775 while (p) {
776 #if USECMDLINE
777 if (!getenv("NOCMDLINE")) {
778 oldcmdline = cmdline;
779 cmdline = xmalloc(strlen(p->cmd) + strlen(p->arg) + 10);
780 strcat(strcat(strcat(strcpy(cmdline, "CMDLINE="), p->cmd), " "), p->arg);
781 putenv(cmdline);
782 if (oldcmdline)
783 free(oldcmdline);
784 }
785 #endif
786 if (p->next)
787 psstdout = redopen(pof, O_WRONLY | O_CREAT | O_TRUNC, 1);
788 if (p->inf)
789 rdstdin = redopen(p->inf, p->infmod, 0);
790 if (p->outf)
791 rdstdout = redopen(p->outf, p->outfmod, 1);
792 /* patch 1997.1.27 by K.Okabe */
793 if (p->errf)
794 rdstderr = redopen(p->errf, p->errfmod, 2);
795 /* end of patch */
796 redswitch(p);
797 rc = pgo(p);
798 redunswitch(p);
799 rdstdin = redclose(rdstdin, 0);
800 rdstdout = redclose(rdstdout, 1);
801 /* patch 1997.1.27 by K.Okabe */
802 rdstderr = redclose(rdstderr, 2);
803 /* end of patch */
804 psstdout = redclose(psstdout, 1);
805 psstdin = redclose(psstdin, 0);
806 if ((p = p->next) != 0) {
807 pxf = pif;
808 pif = pof;
809 pof = pxf;
810 psstdin = redopen(pif, O_RDONLY, 0);
811 }
812 }
813 unlink(pif);
814 free(pif);
815 unlink(pof);
816 free(pof);
817 for (pn = p = p1; p; p = pn) {
818 pn = p->next;
819 if (p->line)
820 free(p->line);
821 if (p->cmd)
822 free(p->cmd);
823 if (p->arg)
824 free(p->arg);
825 if (p->inf)
826 free(p->inf);
827 if (p->outf)
828 free(p->outf);
829 free(p);
830 }
831 if (rc == -2)
832 return 127;
833 return rc < 0 ? 0xFF00 : (rc << 8) & 0xFF00;
834 }
835
836 #ifdef TEST
837 #include <stdio.h>
838
839 void
main()840 main()
841 {
842 char lb[128];
843 while (gets(lb)) {
844 printf("\nreturn %04X\n", xsystem(lb));
845 }
846 }
847 #endif /* TEST */
848