Annotation of OpenXM/src/kan96xx/Kan/ext.c, Revision 1.13
1.13 ! takayama 1: /* $OpenXM: OpenXM/src/kan96xx/Kan/ext.c,v 1.12 2002/10/24 05:19:50 takayama Exp $ */
1.1 maekawa 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"
1.10 takayama 15: #include <ctype.h>
1.1 maekawa 16:
17: #define MYCP_SIZE 100
18: static int Mychildren[MYCP_SIZE];
19: static int Mycp = 0;
20: static void mywait() {
21: int status;
22: int pid;
23: int i,j;
24: signal(SIGCHLD,SIG_IGN);
25: pid = wait(&status);
26: fprintf(stderr,"Child process %d is exiting.\n",pid);
27: for (i=0; i<Mycp; i++) {
28: if (Mychildren[i] == pid) {
29: for (j=i; j<Mycp-1; j++) {
1.5 takayama 30: Mychildren[j] = Mychildren[j+1];
1.1 maekawa 31: }
32: if (Mycp > 0) Mycp--;
33: }
34: }
35: signal(SIGCHLD,mywait);
36: }
37:
38: #define SIZE_OF_ENVSTACK 5
1.9 takayama 39: #if defined(__CYGWIN__)
40: #define JMP_BUF sigjmp_buf
41: #else
42: #define JMP_BUF jmp_buf
43: #endif
44: static JMP_BUF EnvStack[SIZE_OF_ENVSTACK];
1.1 maekawa 45: static int Envp = 0;
1.9 takayama 46: static void pushEnv(JMP_BUF jb) {
1.1 maekawa 47: if (Envp < SIZE_OF_ENVSTACK) {
48: *(EnvStack[Envp]) = *jb;
49: Envp++;
50: }else{
51: fprintf(stderr,"Overflow of EnvStack.\n");
52: exit(2);
53: }
54: }
1.9 takayama 55: static void popEnv(JMP_BUF jbp) {
1.1 maekawa 56: if (Envp <= 0) {
57: fprintf(stderr,"Underflow of EnvStack.\n");
58: exit(3);
59: }else{
60: Envp--;
61: *jbp = *EnvStack[Envp];
62: }
63: }
64:
65: static char *ext_generateUniqueFileName(char *s)
66: {
67: char *t;
68: int i;
69: struct stat statbuf;
70: t = (char *)sGC_malloc(sizeof(char)*strlen(s)+4+2);
71: for (i=0; i<1000; i++) {
72: /* Give up if we failed for 1000 names. */
73: sprintf(t,"%s.%d",s,i);
74: /* if (phc_overwrite) return(t); */
75: if (stat(t,&statbuf) < 0) {
76: return(t);
77: }
78: }
79: errorKan1("%s\n","ext_generateUniqueFileName: could not generate a unique file name. Exhausted all the names.");
80: return(NULL);
81: }
82:
83: struct object Kextension(struct object obj)
84: {
85: char *key;
86: int size;
87: struct object keyo;
88: struct object rob = NullObject;
89: struct object obj1,obj2,obj3,obj4;
1.13 ! takayama 90: int m,i,pid, uid;
1.1 maekawa 91: int argListc, fdListc;
92: char *abc;
93: char *abc2;
94: extern struct context *CurrentContextp;
1.9 takayama 95: #if (__CYGWIN__)
96: extern sigjmp_buf EnvOfStackMachine;
97: #else
1.1 maekawa 98: extern jmp_buf EnvOfStackMachine;
1.9 takayama 99: #endif
1.1 maekawa 100: extern void ctrlC();
101: extern int SigIgn;
102: extern errno;
103: extern int DebugCMO;
104: extern int OXprintMessage;
105: struct stat buf;
106: char **argv;
107: FILE *fp;
1.3 takayama 108: void (*oldsig)();
109: extern SecureMode;
1.1 maekawa 110:
111: if (obj.tag != Sarray) errorKan1("%s\n","Kextension(): The argument must be an array.");
112: size = getoaSize(obj);
113: if (size < 1) errorKan1("%s\n","Kextension(): Empty array.");
114: keyo = getoa(obj,0);
115: if (keyo.tag != Sdollar) errorKan1("%s\n","Kextension(): No key word.");
116: key = KopString(keyo);
117:
118: /* branch by they key word. */
119: if (strcmp(key,"parse")==0) {
120: if (size != 2) errorKan1("%s\n","[(parse) string] extension.");
121: obj1 = getoa(obj,1);
122: if (obj1.tag != Sdollar) errorKan1("%s\n","[(parse) string] extension");
123:
124: pushEnv(EnvOfStackMachine);
125: m = KSexecuteString(obj1.lc.str);
126: /* This is critical area. If you catch ctrl-c here, program crashes. */
127: oldsig = signal(SIGINT,SIG_IGN);
128: popEnv(EnvOfStackMachine);
129: /* OK! We passed the critical area. */
130: signal(SIGINT,oldsig);
131: rob = KpoInteger(m);
132: }else if (strcmp(key,"getpid") == 0) {
133: rob = KpoInteger( (int) getpid() );
134: }else if (strcmp(key,"flush") == 0) {
135: /* fflush(NULL); */
136: fflush(stdout);
137: rob.tag = Snull;
138: }else if (strcmp(key,"chattrs")==0) {
139: if (size != 2) errorKan1("%s\n","[(chattrs) num] extension.");
140: obj1 = getoa(obj,1);
141: if (obj1.tag != Sinteger) errorKan1("%s\n","[(chattrs) num] extension.");
142: m = KopInteger(obj1);
143: if (!( m == 0 || m == PROTECT || m == ABSOLUTE_PROTECT))
144: errorKan1("%s\n","The number must be 0, 1 or 2.");
145: putUserDictionary2((char *)NULL,0,0,m | SET_ATTR_FOR_ALL_WORDS,
1.5 takayama 146: CurrentContextp->userDictionary);
1.1 maekawa 147: }else if (strcmp(key,"keywords")==0) {
148: if (size != 1) errorKan1("%s\n","[(keywords)] extension.");
149: rob = showSystemDictionary(1);
150: /* }else if (strcmp(key,"fork0")==0) {
1.5 takayama 151: if (size != 2) errorKan1("%s\n","[(fork0) sss] extension.");
152: m = fork();
153: if (m>0) { rob = KpoInteger(m); }
154: else {
155: system(KopString(getoa(obj,1))); exit(0);
156: } */
157: }else if (strcmp(key,"defaultPolyRing")==0) {
158: if (size != 2) errorKan1("%s\n","[(defaultPolyRing) n] extension.");
159: rob = KdefaultPolyRing(getoa(obj,1));
160: }else if (strcmp(key,"getenv")==0) {
161: if (size != 2) errorKan1("%s\n","[(getenv) envstr] extension.");
162: obj1 = getoa(obj,1);
163: if (obj1.tag != Sdollar) errorKan1("%s\n","[(getenv) envstr] extension");
164: abc = getenv(KopString(obj1));
1.10 takayama 165: #if defined(__CYGWIN__)
166: if (abc == NULL) {
1.11 takayama 167: abc2 = (char *)sGC_malloc(sizeof(char)*(strlen(KopString(obj1))+2));
1.10 takayama 168: strcpy(abc2,KopString(obj1));
169: for (i=0; i<strlen(abc2); i++) {
170: abc2[i] = toupper(abc2[i]);
171: }
172: abc = getenv(abc2);
173: }
174: #endif
1.5 takayama 175: if (abc == NULL) {
176: rob = NullObject;
177: }else{
178: abc2 = (char *)sGC_malloc(sizeof(char)*(strlen(abc)+2));
179: strcpy(abc2,abc);
180: rob = KpoString(abc2);
181: }
182: }else if (strcmp(key,"stat")==0) {
183: if (size != 2) errorKan1("%s\n","[(stat) fname] extension.");
184: obj1 = getoa(obj,1);
185: if (obj1.tag != Sdollar) errorKan1("%s\n","[(stat) fname] extension ; string fname.");
186: m = stat(KopString(obj1),&buf);
187: rob = newObjectArray(2);
188: if (m == -1) {
189: /* fail */
190: obj2 = NullObject;
191: putoa(rob,0,obj2);
192: obj3 = newObjectArray(2);
193: putoa(obj3,0,KpoString("error no"));
194: putoa(obj3,1,KpoInteger(errno));
195: putoa(rob,1,obj3);
196: }else{
197: /* success */
198: putoa(rob,0,KpoInteger(0));
199: obj3 = newObjectArray(1);
200: putoa(obj3,0,KpoInteger((int) buf.st_size));
201: putoa(rob,1,obj3); /* We have not yet read buf fully */
202: }
203: }else if (strcmp(key,"forkExec")==0) {
204: if (size != 4) errorKan1("%s\n","[(forkExec) argList fdList sigblock] extension.");
205: obj1 = getoa(obj,1);
206: if (obj1.tag != Sarray) errorKan1("%s\n","[(forkExec) argList fdList sigblock] extension. array argList.");
207: obj2 = getoa(obj,2);
208: if (obj2.tag != Sarray) errorKan1("%s\n","[(forkExec) argList fdList sigblock] extension. array fdList.");
209: obj3 = getoa(obj,3);
210: if (obj3.tag != Sinteger) errorKan1("%s\n","[(forkExec) argList fdList sigblock] extension. integer sigblock.");
1.7 takayama 211: m = KopInteger(obj3); /* m&1 : block ctrl-C. */
1.5 takayama 212: argListc = getoaSize(obj1);
213: fdListc = getoaSize(obj2);
1.6 takayama 214: if ((pid = fork()) > 0) {
1.5 takayama 215: /* parent */
1.7 takayama 216: if (m&2) {
1.6 takayama 217: /* Do not call singal to turn around a trouble on cygwin. BUG. */
218: }else{
219: signal(SIGCHLD,mywait); /* to kill Zombie */
220: }
221: Mychildren[Mycp++] = pid;
1.5 takayama 222: if (Mycp >= MYCP_SIZE-1) {
223: errorKan1("%s\n","Child process table is full.\n");
224: Mycp = 0;
225: }
1.6 takayama 226: rob = KpoInteger(pid);
1.5 takayama 227: /* Done */
228: }else{
229: /* Child */
230: for (i=0; i<fdListc; i++) {
231: /* close the specified files */
232: close(KopInteger(getoa(obj2,i)));
1.1 maekawa 233: }
1.5 takayama 234: /* execl */
1.7 takayama 235: if (m&1) {
1.5 takayama 236: {
237: sigset_t sss;
238: sigemptyset(&sss);
239: sigaddset(&sss,SIGINT);
240: sigprocmask(SIG_BLOCK,&sss,NULL);
241: }
1.1 maekawa 242: }
1.5 takayama 243: argv = (char **) sGC_malloc(sizeof(char *)*(argListc+1));
244: if (argv == NULL) {
245: fprintf(stderr," no more momory. forkExec --- exiting.\n");
246: _exit(10);
1.1 maekawa 247: }
1.5 takayama 248: for (i=0; i<argListc; i++) {
249: argv[i] = KopString(getoa(obj1,i));
250: argv[i+1] = NULL;
1.7 takayama 251: }
252:
253: if (m&4) {
254: fprintf(stderr,"execv %s\n",argv[0]);
255: sleep(5);
256: fprintf(stderr,">>>\n");
1.1 maekawa 257: }
1.5 takayama 258: execv(argv[0],argv);
259: /* This place will never be reached unless execv fails. */
260: fprintf(stderr,"forkExec fails: ");
261: for (i=0; i<argListc; i++) {
262: fprintf(stderr,"%s ",argv[i]);
263: }
264: fprintf(stderr,"\nExiting, but staying as Zombie.\n");
265: _exit(10);
266: }
267: }else if (strcmp(key,"getchild")==0) {
268: if (size != 1) errorKan1("%s\n","[(getchild)] extension.");
269: rob = newObjectArray(Mycp);
270: for (i=0; i<Mycp; i++) {
271: putoa(rob,i,KpoInteger(Mychildren[i]));
1.1 maekawa 272: }
1.5 takayama 273: }else if (strcmp(key,"getUniqueFileName")==0) {
274: if (size != 2) errorKan1("%s\n","[(getUniqueFileName) path] extension.");
275: obj1 = getoa(obj,1);
276: if (obj1.tag != Sdollar) errorKan1("%s\n","[(getUniqueFileName) path] extension. path must be a string.");
277: rob = KpoString(ext_generateUniqueFileName(KopString(obj1)));
278: }else if (strcmp(key,"outputObjectToFile")==0) {
279: if (size != 3) errorKan1("%s\n","[(outputObjectToFile) path obj] extension.");
280: obj1 = getoa(obj,1);
281: if (obj1.tag != Sdollar) errorKan1("%s\n","[(outputObjectToFile) path obj] extension. path must be a string.");
282: obj2 = getoa(obj,2);
283: fp = fopen(KopString(obj1),"w");
284: if (fp == NULL) errorKan1("%s\n","[(outputObjectToFile) path object] extension : could not open the path.");
285: printObject(obj2,0,fp);
286: fclose(fp);
287: rob = NullObject;
288: }else if (strcmp(key,"hilbert")==0) {
289: if (size != 3) errorKan1("%s\n","[(hilbert) obgb obvlist] extension.");
290: rob = hilberto(getoa(obj,1),getoa(obj,2));
1.13 ! takayama 291: }else if (strcmp(key,"nobody") == 0) {
! 292: uid = getuid();
! 293: if (uid == 0) {
! 294: #define NOBODY 65534
! 295: /* If I'm a super user, then change uid to nobody. */
! 296: if (setuid(NOBODY) != 0) {
! 297: fprintf(stderr,"Failed to change uid to nobody (%d)\n",NOBODY);
! 298: exit(10);
! 299: }
! 300: fprintf(stderr,"uid is changed to nobody (%d).\n",NOBODY);
! 301: rob.tag = Snull;
! 302: }
1.5 takayama 303: }else if (strcmp(key,"chattr")==0) {
304: if (size != 3) errorKan1("%s\n","[(chattr) num symbol] extension.");
305: obj1 = getoa(obj,1);
306: obj2 = getoa(obj,2);
307: if (obj1.tag != Sinteger) errorKan1("%s\n","[(chattr) num symbol] extension.");
308: if (obj2.tag != Sstring) errorKan1("%s\n","[(chattr) num symbol] extension.");
309: m = KopInteger(obj1);
310: if (!( m == 0 || m == PROTECT || m == ABSOLUTE_PROTECT))
311: errorKan1("%s\n","The number must be 0, 1 or 2.");
312: putUserDictionary2(obj2.lc.str,(obj2.rc.op->lc).ival,(obj2.rc.op->rc).ival,
313: m,CurrentContextp->userDictionary);
1.12 takayama 314: }else if (strcmp(key,"regionMatches")==0) {
315: if (size != 3) errorKan1("%s\n","[(regionMatches) str strArray] extension.");
316: obj1 = getoa(obj,1);
317: if (obj1.tag != Sdollar) errorKan1("%s\n","[(regionMatches) str strArray] extension. str must be a string.");
318: obj2 = getoa(obj,2);
319: if (obj2.tag != Sarray) errorKan1("%s\n","[(regionMatches) str strArray] extension. strArray must be an array.");
320: rob = KregionMatches(obj1,obj2);
1.8 takayama 321: }else if (strcmp(key,"ostype")==0) {
322: rob = newObjectArray(1);
323: /* Hard encode the OS type. */
324: #if defined(__CYGWIN__)
325: putoa(rob,0,KpoString("windows"));
326: #else
327: putoa(rob,0,KpoString("unix"));
328: #endif
1.5 takayama 329: }
1.1 maekawa 330: #include "plugin.hh"
331: else{
332: errorKan1("%s\n","Unknown tag for extension.");
333: }
334:
335:
336: return(rob);
1.12 takayama 337: }
338:
339: struct object KregionMatches(struct object sobj, struct object keyArray)
340: {
341: struct object rob;
342: int n,i,j,m,keyn;
343: char *s,*key;
344: rob = newObjectArray(3);
345: getoa(rob,0) = KpoInteger(-1);
346: getoa(rob,1) = NullObject;
347: getoa(rob,2) = NullObject;
348:
349: if (sobj.tag != Sdollar) return rob;
350: if (keyArray.tag != Sarray) return rob;
351: n = getoaSize(keyArray);
352: for (i=0; i<n; i++) {
353: if (getoa(keyArray,i).tag != Sdollar) { return rob; }
354: }
355:
356: s = KopString(sobj);
357: m = strlen(s);
358:
359: for (i=0; i<n; i++) {
360: key = KopString(getoa(keyArray,i));
361: keyn = strlen(key);
362: for (j=0; j<m; j++) {
363: if (strncmp(&(s[j]),key,keyn) == 0) {
364: getoa(rob,0) = KpoInteger(j);
365: getoa(rob,1) = KpoString(key);
366: getoa(rob,2) = KpoInteger(i);
367: return rob;
368: }
369: }
370: }
371: return rob;
1.1 maekawa 372: }
373:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>