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