Annotation of OpenXM/src/kan96xx/Kan/shell.c, Revision 1.16
1.16 ! takayama 1: /* $OpenXM: OpenXM/src/kan96xx/Kan/shell.c,v 1.15 2012/10/29 02:51:41 takayama Exp $ */
1.1 takayama 2: #include <stdio.h>
1.14 ohara 3: #include <string.h>
1.1 takayama 4: #include <sys/types.h>
5: #include <sys/stat.h>
6: #include <fcntl.h>
7: #include <stdlib.h>
8: #include <unistd.h>
9: #include <sys/wait.h>
10: #include "datatype.h"
11: #include "stackm.h"
12: #include "extern.h"
13: #include "extern2.h"
14: #include <signal.h>
15: #include "plugin.h"
16: #include "kclass.h"
17: #include <ctype.h>
18: #include "ox_pathfinder.h"
19:
1.2 takayama 20: static struct object KoxShell_test1(struct object ob);
1.3 takayama 21: static struct object oxsExecuteBlocked(struct object ob);
22: static struct object oxsSetenv(struct object ob);
23: static char *oxsIsURI(char *s);
24: static char *oxsURIgetVarName(char *s);
25: static char *oxsURIgetExtension(char *s);
1.5 takayama 26: static char *oxsURIgetFileName(char *s);
27: static char *oxsRemoveOpt(char *s);
28: static char *oxsGetOpt(char *s);
1.3 takayama 29: static char *oxsVarToFile(char *v,char *extension,char *comamnd,int tmp);
30: static int oxsFileToVar(char *v,char *fname);
31: static char **oxsBuildArgv(struct object ob);
1.5 takayama 32: static char **oxsBuildArgvRedirect(char **argv);
1.3 takayama 33: static struct object testmain(struct object ob);
34:
35: #define mymalloc(n) sGC_malloc(n)
36: #define nomemory(n) errorKan1("%s\n","No more memory in shell.c");
37:
38: #define MAXFILES 256
39: static char *AfterReadFile[MAXFILES];
40: static char *AfterSetVar[MAXFILES];
41: static int AfterPt=0;
42: static char *AfterDeleteFile[MAXFILES];
43: static int AfterD=0;
1.2 takayama 44:
1.8 takayama 45: static int KeepTmpFiles = 0;
1.5 takayama 46:
47: extern int OX_P_stdin;
48: extern int OX_P_stdout;
49: extern int OX_P_stderr;
50:
1.2 takayama 51: struct object KoxShell(struct object ob) {
52: return KoxShell_test1(ob);
53: }
54:
1.3 takayama 55: /* A temporary help system */
56: void KoxShellHelp(char *key,FILE *fp) {
1.7 takayama 57: char *keys[]={"command","export","keep_tmp_files",
58: "killall","redirect","which","@@@@gatekeeper"};
1.3 takayama 59: int i;
60: #define HSIZE 20
61: char *s[HSIZE];
62: if (key == NULL) {
1.6 takayama 63: fprintf(fp,"\n");
1.3 takayama 64: for (i=0; strcmp(keys[i],"@@@@gatekeeper") != 0; i++) {
1.6 takayama 65: fprintf(fp,"%s\n",keys[i]);
66: KoxShellHelp(keys[i],fp);
67: fprintf(fp,"\n",keys[i]);
68: }
69: return;
1.3 takayama 70: }
71: for (i=0; i<HSIZE; i++) s[i] = NULL;
72: if (strcmp(key,"export")==0) {
1.6 takayama 73: s[0] = "export env_name = value";
74: s[1] = "export env_name = ";
75: s[2] = "Example: [(export) (PATH) (=) (/usr/new/bin:${PATH})] oxshell";
76: s[3] = NULL;
1.3 takayama 77: }else if (strcmp(key,"which")==0) {
1.6 takayama 78: s[0] = "which cmd_name";
79: s[1] = "which cmd_name path";
80: s[2] = "Example: [(which) (ls)] oxshell";
1.3 takayama 81: s[3] = NULL;
82: }else if (strcmp(key,"command")==0) {
1.6 takayama 83: s[0] = "Executing a command";
84: s[1] = "cmdname arg1 arg2 ... ";
85: s[2] = "Example 1: /afo (Hello! ) def [(cat) (stringIn://afo)] oxshell";
86: s[3] = "Example 2: [(polymake) (stringInOut://afo.poly) (FACETS)] oxshell";
1.16 ! takayama 87: s[4] = "A temporary file afo.poly* with the contents of the variable afo.poly is generated under $TMP and \"polymake $TMP FACETS\" will be executed. cf. kan96xx/trans/doPolymake.sm1, Doc/oxshell.oxw, Doc/changelog-ja.tex";
! 88: s[5] = "Example 3: [(ls) (-l) (>) (stringOut://ff)] oxshell";
! 89: s[6] = NULL;
1.5 takayama 90: }else if (strcmp(key,"redirect")==0) {
1.6 takayama 91: s[0] = "The following redirect operators are implemented.";
92: s[1] = "< > 2>";
93: s[2] = "Example 1: [(ls) (hoge) (2>) (stringOut://afo)] oxshell\n afo ::";
94: s[3] = "Example 2: [(cp) ] addStdoutStderr oxshell\n [@@@stdout @@@stderr] ::";
1.5 takayama 95: s[4] = NULL;
1.7 takayama 96: }else if (strcmp(key,"killall")==0) {
97: s[0] = "Kill all the processes envoked by oxshell";
98: s[1] = NULL;
99: }else if (strcmp(key,"keep_tmp_files")==0) {
100: s[0] = "keep_tmp_files value";
101: s[1] = "If value is zero, then temporary files are removed after execution.";
1.15 takayama 102: s[2] = "Example 1: [(keep_tmp_files) (1)] oxshell ; temporary files will be kept in /tmp or $TMP or ...";
103: s[3] = NULL;
1.3 takayama 104: }else{
105: }
106: i = 0;
107: while (s[i] != NULL) {
1.6 takayama 108: fprintf(fp,"%s\n",s[i++]);
1.3 takayama 109: }
110: }
111:
112:
1.2 takayama 113: static struct object KoxShell_test1(struct object ob) {
114: /* A simple shell. It does not implement a parser. */
1.13 takayama 115: struct object rob = OINIT;
1.2 takayama 116: char *cmd;
117: char *arg1,*arg2;
118: int i,n;
119: rob = NullObject; cmd = NULL; arg1=NULL; arg2=NULL;
120: if (ob.tag != Sarray) errorKan1("%s\n","KoxShell requires an array as an argument.");
121: n = getoaSize(ob);
122: for (i=0; i<n; i++) {
1.6 takayama 123: if (getoa(ob,i).tag != Sdollar) errorKan1("%s\n","KoxShell requires an array of string as an argument.");
1.2 takayama 124: }
125:
126: if (n == 0) return(rob);
127: cmd = KopString(getoa(ob,0));
1.3 takayama 128: if (strcmp(cmd,"testmain")==0) {
129: rob = testmain(ob);
130: }else if (strcmp(cmd,"which")==0) {
1.6 takayama 131: if (n == 2) {
1.12 takayama 132: pathFinderErrorVerbose(0);
1.6 takayama 133: rob = KoxWhich(getoa(ob,1),KpoInteger(0));
1.12 takayama 134: pathFinderErrorVerbose(-1);
1.6 takayama 135: }else if (n==3) {
1.12 takayama 136: pathFinderErrorVerbose(0);
1.6 takayama 137: rob = KoxWhich(getoa(ob,1),getoa(ob,2));
1.12 takayama 138: pathFinderErrorVerbose(-1);
1.6 takayama 139: }else{
140: errorKan1("%s\n","shell: << which command-name >> or << which command-name path >>");
141: }
142: return(rob);
1.2 takayama 143: }else if (strcmp(cmd,"export")==0) {
1.6 takayama 144: rob=oxsSetenv(ob);
1.7 takayama 145: }else if (strcmp(cmd,"keep_tmp_files")==0) {
146: if (n != 2) errorKan1("%s\n","shell: << keep_tmp_files value >>");
147: if (strcmp("0",KopString(getoa(ob,1))) == 0) {
148: KeepTmpFiles = 0;
149: }else{
150: KeepTmpFiles = 1;
151: }
152: rob = KpoInteger(KeepTmpFiles);
153: }else if (strcmp(cmd,"killall")==0) {
154: /* It is called from ctrl-C hook of oxrfc103.sm1 */
155: fprintf(stderr,"Killing all child processes (oxshell) ...");
156: rob = KpoInteger(oxKillAll());
157: fprintf(stderr,"\nDone.\n");
1.2 takayama 158: }else{
1.6 takayama 159: rob = oxsExecuteBlocked(ob);
1.2 takayama 160: }
161: return(rob);
162: }
1.1 takayama 163:
164: /* Functions for ox_shell */
165: struct object KoxWhich(struct object cmdo,struct object patho) {
1.13 takayama 166: struct object rob = OINIT;
1.1 takayama 167: char *sss;
168: rob = NullObject;
169: if (cmdo.tag != Sdollar) errorKan1("%s\n","KoxWhich(str-obj,str-obj)");
170: if (patho.tag == Sdollar) {
171: sss=oxWhich(KopString(cmdo),KopString(patho));
172: if (sss != NULL) rob=KpoString(sss);
173: else{
174: sss=getCommandPath(KopString(cmdo));
175: if (sss != NULL) rob=KpoString(sss);
176: }
177: }else{
178: sss=getCommandPath(KopString(cmdo));
179: if (sss != NULL) rob=KpoString(sss);
180: }
181: return(rob);
182: }
183:
1.10 takayama 184: static int mysetenv(char *name, char *value, int overwrite);
185: static int myunsetenv(char *name);
186: static int mysetenv(char *name, char *value, int overwrite) {
187: char *s;
188: char *orig;
189: s = (char *)getenv(name);
190: if ((s == NULL) || overwrite) {
1.11 takayama 191: s = (char *) mymalloc(strlen(name)+strlen(value)+5);
1.10 takayama 192: if (s == 0) { fprintf(stderr,"No more memory.\n"); exit(10); }
193: strcpy(s,name);
194: strcat(s,"="); strcat(s,value);
195: return(putenv(s));
196: }
197: return (0);
198: }
199:
200: /* bug on Solaris. It does not unsetenv.
201: libc4, libc5, glibc. It does unsetenv. */
202: static myunsetenv(char *name) {
203: return(putenv(name));
204: }
205:
1.3 takayama 206: /* Example. [(export) (PATH) (=) (/usr/new/bin:$PATH)] */
207: static struct object oxsSetenv(struct object ob) {
1.13 takayama 208: struct object rob = OINIT;
1.3 takayama 209: int i,n;
210: char *envp;
211: char *new;
212: int r;
213: rob = NullObject;
214: if (ob.tag != Sarray) errorKan1("%s\n","oxsSetenv requires an array of srings.");
215: n = getoaSize(ob);
216: if ((n != 4) && (n != 3)) errorKan1("%s\n","oxsSetenv requires an array of srings. Length must be 3 or 4.");
217: for (i=0; i<n; i++) {
1.6 takayama 218: if (getoa(ob,i).tag != Sdollar) errorKan1("%s\n","oxsSetenv requires an array of srings. Length must be 3 or 4.");
1.3 takayama 219: }
220:
221: if (strcmp(KopString(getoa(ob,2)),"=") != 0) {
1.6 takayama 222: errorKan1("%s\n","oxsSetenv, example [(export) (PATH) (=) (/usr/new/bin:$PATH)] oxshell");
1.3 takayama 223: }
224: envp = KopString(getoa(ob,1));
225: if (n == 4) {
1.6 takayama 226: new = KopString(getoa(ob,3));
227: /* printf("%s\n",new); */
228: new = oxEvalEnvVar(new);
229: /* printf("%s\n",new); */
1.10 takayama 230: r = mysetenv(envp,new,1);
1.3 takayama 231: }else{
1.10 takayama 232: myunsetenv(envp); r = 0;
233: /* bug: On Solaris, unsetenv will not work. */
1.3 takayama 234: }
235: if (r != 0) errorKan1("%s\n","setenv failed.");
236: new = (char *) getenv(envp);
237: if (new != NULL) {
1.6 takayama 238: rob = KpoString((char *) getenv(envp));
1.3 takayama 239: }
240: return(rob);
241: }
242:
243: /* s="stringIn://abc.poly" ==> stringIn
244: s="stringInOut://abc.poly" ==> stringInOut
245: */
246: char *oxsIsURI(char *s) {
247: int n,i,j;
248: char *u;
249: if (s == NULL) return((char *)NULL);
1.5 takayama 250: s = oxsRemoveOpt(s);
1.3 takayama 251: n = strlen(s);
252: for (i=0; i<n-3;i++) {
253: if ((s[i] == ':') && (s[i+1] == '/') && (s[i+2] == '/')) {
254: u = (char *) mymalloc(i+1);
255: if (u == NULL) nomemory(1);
256: u[0]=0;
257: for (j=0; j<i; j++) {
258: u[j] = s[j]; u[j+1]=0;
259: }
260: return(u);
261: }
262: }
263: return(NULL);
264: }
1.1 takayama 265:
1.3 takayama 266: /* s="stringIn://abc.poly" ==> abc
267: s="stringInOut://abc.poly" ==> abc
268: s="stringInOut://abc" ==> abc
269: */
270: char *oxsURIgetVarName(char *s) {
271: int n,i,j;
272: char *u;
273: if (s == NULL) return((char *)NULL);
1.5 takayama 274: s = oxsRemoveOpt(s);
1.3 takayama 275: n = strlen(s);
276: for (i=0; i<n-3;i++) {
277: if ((s[i] == ':') && (s[i+1] == '/') && (s[i+2] == '/')) {
278: u = (char *) mymalloc(n-i+1);
279: if (u == NULL) nomemory(1);
280: u[0]=0;
281: for (j=i+3; j<n; j++) {
282: if (s[j] == '.') break;
283: u[j-i-3] = s[j]; u[j-i-3+1]=0;
284: }
285: return(u);
286: }
287: }
288: return(NULL);
289: }
290:
291: /* s="stringIn://abc.poly" ==> poly
292: s="stringInOut://abc.poly" ==> poly
293: s="stringInOut://abc" ==> NULL
294: */
295: char *oxsURIgetExtension(char *s) {
296: int n,i,j,k;
297: char *u;
298: if (s == NULL) return((char *)NULL);
1.5 takayama 299: s = oxsRemoveOpt(s);
1.3 takayama 300: n = strlen(s);
301: for (i=0; i<n-3;i++) {
302: if ((s[i] == ':') && (s[i+1] == '/') && (s[i+2] == '/')) {
303: for (j=i+3; j<n; j++) {
304: if (s[j] == '.') {
305: u = (char *) mymalloc(n-j+2);
306: if (u == NULL) nomemory(1);
307: u[0]=0;
308: for (k=j+1; k<n; k++) {
309: u[k-j-1] = s[k]; u[k-j] = 0;
310: }
311: return(u);
312: }
313: }
314: }
315: }
316: return(NULL);
317: }
318:
1.5 takayama 319: /* stringInOut://abc.poly=:file://pqr.txt */
320: static char *oxsRemoveOpt(char *s) {
321: int n,i,j;
322: char *u;
323: if (s == NULL) return((char *)NULL);
324: n = strlen(s);
325: for (i=0; i<n-1;i++) {
326: if ((s[i] == '=') && (s[i+1] == ':')) {
327: u = (char *) mymalloc(i+1);
328: if (u == NULL) nomemory(1);
329: u[0]=0;
330: for (j=0; j<i; j++) {
331: u[j] = s[j]; u[j+1]=0;
332: }
333: return(u);
334: }
335: }
336: return(s);
337: }
338:
339: /* stringInOut://abc.poly=:file://pqr.txt */
340: /* stringInOut://abc.poly */
341: char *oxsGetOpt(char *s) {
342: int n,i,j;
343: char *u;
344: if (s == NULL) return((char *)NULL);
345: n = strlen(s);
346: for (i=0; i<n-1;i++) {
347: if ((s[i] == '=') && (s[i+1] == ':')) {
348: u = (char *) mymalloc(n-i+1);
349: if (u == NULL) nomemory(1);
350: u[0]=0;
351: for (j=i+2; j<n; j++) {
352: u[j-i-2] = s[j]; u[j-i-2+1]=0;
353: }
354: return(u);
355: }
356: }
357: return(NULL);
358: }
359:
360: char *oxsURIgetFileName(char *s) {
361: int n,i,j;
362: char *u;
363: if (s == NULL) return((char *)NULL);
364: s = oxsRemoveOpt(s);
365: n = strlen(s);
366: for (i=0; i<n-3;i++) {
367: if ((s[i] == ':') && (s[i+1] == '/') && (s[i+2] == '/')) {
368: u = (char *) mymalloc(n-i+1);
369: if (u == NULL) nomemory(1);
370: u[0]=0;
371: for (j=i+3; j<n; j++) {
372: u[j-i-3] = s[j]; u[j-i-3+1]=0;
373: }
374: return(u);
375: }
376: }
377: return(NULL);
378: }
379:
380:
1.3 takayama 381: static struct object testmain(struct object ob) {
1.13 takayama 382: struct object rob = OINIT;
1.3 takayama 383: char *s;
1.13 takayama 384: struct object ot = OINIT;
1.3 takayama 385: char **av;
386: int i;
387: rob = NullObject;
388:
389: /* Try sm1 -s " /hoge (hogehoge) def [(testmain)] oxshell afo message " */
390:
391: ot = newObjectArray(3);
392: getoa(ot,0)=KpoString("cat");
393: getoa(ot,1)=KpoString("stringInOut://hoge.poly");
394: getoa(ot,2)=KpoString("${HOME}/t.t");
395: av=oxsBuildArgv(ot);
396: for (i=0; av[i] != NULL; i++) {
1.6 takayama 397: printf("%s\n",av[i]);
1.3 takayama 398: }
399: printf("------------------------------\n");
400:
401: s=oxsVarToFile("hoge","poly","polymake",0);
402: printf("%s\n",s);
403: oxsFileToVar("afo",s);
404: return(rob);
405: }
406:
407: char *oxsVarToFile(char *v,char *ext,char *command,int usetmp) {
408: char *fname;
409: int winname;
410: FILE *fp;
411: int n,i,prevc,c;
412: char *prog;
1.13 takayama 413: struct object vv = OINIT;
1.3 takayama 414:
415: /*bug; winname must be automatically set by looking at command.
416: If command is win32-native-application, then winname=1; else winname=0.
417: For example, if command=="gnuplot32" then winmame=1; else winname=0;
418: */
419: winname = 0;
420:
421: fname = generateTMPfileName2(v,ext,usetmp,winname);
422: if (fname == NULL) errorKan1("%s\n","generateTMPfileName2() is failed.");
423: if (v == NULL) errorKan1("%s\n","oxsVarToFile(), v is NULL.");
424: vv = KfindUserDictionary(v);
425: if (vv.tag != Sdollar) errorKan1("%s\n","oxsVarToFile(), value is not a string object or the object is not found in the dictionary.");
426: prog = KopString(vv);
427:
428: fp = fopen(fname,"w");
429: if (fp == NULL) errorKan1("%s\n","oxsVarToFile(), fail to open a file.");
430: n = strlen(prog);
431: prevc = 0;
432: for (i=0; i<n ; i++) {
1.6 takayama 433: c = prog[i];
434: if (winname) {
435: if ((c == '\n') && (prevc != 0xd)) {
436: fputc(0xd,fp); fputc(c,fp);
437: }
438: }else{
439: fputc(c,fp);
440: }
441: prevc = c;
1.3 takayama 442: }
443: if (fclose(fp) != 0) errorKan1("%s\n","oxsVarToFile(), fail to close the file.");
444:
445: return(fname);
446: }
447:
448: int oxsFileToVar(char *v,char *fname) {
449: FILE *fp;
450: char *s, *sold;
451: int limit;
452: int c,i;
453:
1.9 takayama 454: if (v == NULL) {
455: /* errorKan1("%s\n","oxsFileToVar(), v is NULL."); */
456: fprintf(stderr,"oxsFileToVar(), v is NULL.");
457: return(-1);
458: }
1.3 takayama 459: limit = 1024;
460: fp = fopen(fname,"r");
461: if (fp == NULL) {
1.6 takayama 462: fprintf(stderr,"Filename=%s\n",fname);
1.9 takayama 463: /* errorKan1("%s\n","oxsFileToVar(), the file cannot be opened."); */
464: fprintf(stderr,"oxsFileToVar(), the file cannot be opened.");
465: return(-1);
1.3 takayama 466: }
467: s = (char *)mymalloc(limit);
468: if (s == NULL) errorKan1("%s\n","No more memory in oxsFileToVar().");
469:
470: i = 0;
471: while ((c=fgetc(fp)) != EOF) {
1.6 takayama 472: s[i] = c; s[i+1] = 0;
473: if (i > limit - 10) {
474: sold = s; limit *= 2;
475: s = (char *)mymalloc(limit);
476: if (s == NULL) errorKan1("%s\n","No more memory in oxsFileToVar().");
477: strcpy(s,sold);
478: }
1.3 takayama 479: i++;
480: }
481: fclose(fp);
482:
483: KputUserDictionary(v,KpoString(s));
484: return(0);
485: }
486:
487: static char **oxsBuildArgv(struct object ob) {
488: int n,i;
489: char **argv;
490: char *s;
491: char *type;
492: char *ext, *v;
493: int usetmp=1;
494: int win=0;
1.13 takayama 495: struct object ocmd = OINIT;
1.3 takayama 496:
497: /* bug: win variable must be properly set on windows native. */
498:
499: if (ob.tag != Sarray) errorKan1("%s\n","oxsBuildArgv() requires an array as an argument.");
500: n = getoaSize(ob);
501: for (i=0; i<n; i++) {
1.6 takayama 502: if (getoa(ob,i).tag != Sdollar) errorKan1("%s\n","oxsBuildArgv() requires an array of string as an argument.");
1.3 takayama 503: }
504:
505: argv = (char **) mymalloc(sizeof(char *)*(n+2));
506: argv[0] = (char *)NULL;
507: if (n == 0) return(argv);
508:
509: s = KopString(getoa(ob,0));
510: s = oxEvalEnvVar(s);
1.4 takayama 511: ocmd = KoxWhich(KpoString(s),KpoInteger(0));
512: if (ocmd.tag != Sdollar) {
1.6 takayama 513: argv[0] = NULL;
1.4 takayama 514: }else{
1.6 takayama 515: argv[0] = KopString(ocmd);
1.4 takayama 516: }
1.3 takayama 517: argv[1] = (char *)NULL;
518: if (argv[0] == NULL) {
1.6 takayama 519: fprintf(stderr,"cmdname=%s\n",s);
520: errorKan1("%s\n","oxsBuildArgv() Command is not found.\n");
1.3 takayama 521: }
522: for (i=1; i<n; i++) {
1.6 takayama 523: argv[i] = argv[i+1] = NULL;
524: s = KopString(getoa(ob,i));
525: s = oxEvalEnvVar(s);
526: type = oxsIsURI(s);
527: if (type == NULL) {
528: argv[i] = s;
529: }else{
530: /* Case when argv[i] is like "stringInOut:abc.poly" */
531: v = oxsURIgetVarName(s);
532: ext = oxsURIgetExtension(s);
533: if (strcmp(type,"stringIn") == 0) {
534: argv[i] = oxsVarToFile(v,ext,argv[0],usetmp);
535: AfterDeleteFile[AfterD++] = argv[i];
536: }else if (strcmp(type,"stringInOut") == 0) {
537: argv[i] = oxsVarToFile(v,ext,argv[0],usetmp);
538: AfterDeleteFile[AfterD++] = argv[i];
539: AfterReadFile[AfterPt] = argv[i];
540: AfterSetVar[AfterPt] = v;
541: AfterPt++;
542: if (AfterPt >= MAXFILES) {
543: AfterPt=0;
544: errorKan1("%s\n","oxsBuildArgv(), Too may files to open.");
545: }
546: }else if (strcmp(type,"stringOut") == 0) {
547: argv[i] = generateTMPfileName2(v,ext,usetmp,win);
548: AfterDeleteFile[AfterD++] = argv[i];
549: AfterReadFile[AfterPt] = argv[i];
550: AfterSetVar[AfterPt] = v;
551: AfterPt++;
552: if (AfterPt >= MAXFILES) {
553: AfterPt=0;
554: errorKan1("%s\n","oxsBuildArgv(), Too may files to open.");
555: }
556: }else {
557: errorKan1("%s\n","This URI type has not yet been implemented.");
558: }
559: if (AfterD >= MAXFILES) {
560: AfterD=0;
561: errorKan1("%s\n","oxsBuildArgv(), Too may files to open.");
562: }
563: }
1.3 takayama 564: }
565: return(argv);
566: }
567:
568:
569: static struct object oxsExecuteBlocked(struct object ob)
570: {
571: int r,i,n;
572: char **argv;
1.9 takayama 573: int errorf;
1.3 takayama 574:
575: argv = oxsBuildArgv(ob);
1.5 takayama 576: argv = oxsBuildArgvRedirect(argv);
1.3 takayama 577: r=oxForkExecBlocked(argv); /* bug: what happen when NoX? */
578: /*
579: if (1) {
1.6 takayama 580: for (i=0; argv[i] != NULL; i++) {
581: fprintf(stderr,"argv[%d]=%s\n",i,argv[i]);
582: }
583: errorKan1("%s\n","ForkExecBlocked failed.");
1.3 takayama 584: }
585: */
1.9 takayama 586: errorf=0;
1.3 takayama 587: if (AfterPt > 0) {
1.6 takayama 588: for (i=0; i< AfterPt; i++) {
1.9 takayama 589: if (oxsFileToVar(AfterSetVar[i],AfterReadFile[i]) != 0) {
590: errorf=1;
591: }
1.6 takayama 592: }
1.3 takayama 593: }
594: AfterPt = 0;
595:
596: if (AfterD > 0) {
1.6 takayama 597: for (i=0; i< AfterD; i++) {
598: if (!KeepTmpFiles) {
599: oxDeleteFile(AfterDeleteFile[i]);
1.5 takayama 600: }
1.6 takayama 601: }
1.3 takayama 602: }
603: AfterD = 0;
1.9 takayama 604: if (errorf) errorKan1("%s\n","Some errors in oxsFileToVar().");
1.3 takayama 605:
606: return(KpoInteger(r));
1.5 takayama 607: }
608:
609: static char **oxsBuildArgvRedirect(char **argv) {
610: char **newargv;
611: int n,i,j;
612: FILE *fp;
613: char *fname;
614:
615: n = 0; while (argv[n] != NULL) n++;
616: newargv = (char **) mymalloc(sizeof(char *)*(n+1));
617: for (i=0; i<=n; i++) newargv[i]=(char *)NULL;
618: j=0;
619: /* bug: Critical area, do not make an interruption. */
620: for (i=0; i<n; i++) {
1.6 takayama 621: if (strcmp(argv[i],"<")==0) {
622: fname=argv[i+1];
623: OX_P_stdin = open(fname,O_RDONLY);
624: if (OX_P_stdin < 0) {
625: OX_P_stdin = -1;
626: oxResetRedirect();
627: errorKan1("%s\n","oxsBuildArgvRedirect fails to open the input file.");
628: }
1.5 takayama 629: i++;
1.6 takayama 630: }else if (strcmp(argv[i],">")==0) {
631: fname = argv[i+1];
632: fp == NULL;
633: if (fname != NULL) {
634: fp = fopen(fname,"w");
635: }
1.5 takayama 636: if (fp == NULL) {
1.6 takayama 637: oxResetRedirect();
638: errorKan1("%s\n","oxsBuildArgvRedirect, cannot open the output file.\n");
639: }
640: fclose(fp); /* touch */
641: OX_P_stdout = open(fname,O_WRONLY);
642: i++;
643: }else if (strcmp(argv[i],"2>") == 0) {
644: fname = argv[i+1];
645: fp == NULL;
646: if (fname != NULL) {
647: fp = fopen(fname,"w");
648: }
1.5 takayama 649: if (fp == NULL) {
1.6 takayama 650: oxResetRedirect();
651: errorKan1("%s\n","oxsBuildArgvRedirect, cannot open the output (stderr) file.\n");
652: }
653: fclose(fp); /* touch */
654: OX_P_stderr = open(fname,O_WRONLY);
655: i++;
656: }else{
657: newargv[j++] = argv[i];
658: }
1.5 takayama 659: }
660: return( newargv );
1.3 takayama 661: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>