Annotation of OpenXM/src/kxx/oxmain.c, Revision 1.26
1.26 ! takayama 1: /* $OpenXM: OpenXM/src/kxx/oxmain.c,v 1.25 2006/06/05 04:40:15 takayama Exp $ */
1.25 takayama 2: /* Note on IntelMac. [2006.06.05]
3: SIGINT does not seem to be blocked on the rosetta emulator of ppc
4: on the IntelMac's. "ox" should be universal binary.
5: A dirty hack to generate a universal binary of ox is as follows.
6: (1) Add -arch ppc -arch i386 to CFLAGS in src/kxx/Makefile
7: and src/kan96xx/plugin/Makefile
8: (2) Build ox
9: */
1.1 maekawa 10: /* nullserver01 */
11: #include <stdio.h>
1.4 takayama 12: #include <fcntl.h>
1.10 takayama 13: #include <unistd.h>
1.1 maekawa 14: #include <sys/types.h>
15: #include <sys/socket.h>
16: #include <sys/time.h>
1.23 takayama 17: #include <sys/resource.h>
1.1 maekawa 18: #include <netinet/in.h>
19: #include <netdb.h>
20: #include <signal.h>
21: #include <setjmp.h>
1.14 takayama 22: #include <stdlib.h>
1.1 maekawa 23: /* -lnsl -lsocket /usr/ucblib/libucb.a */
24: #include "ox_kan.h"
25: #include "serversm.h"
26:
1.4 takayama 27: #define SERVERNAME "ox_sm1"
1.1 maekawa 28:
1.14 takayama 29: extern char **environ;
1.1 maekawa 30: int OxCritical = 0;
31: int OxInterruptFlag = 0;
1.12 takayama 32: int OxTerminateMode = 0;
1.1 maekawa 33:
34: int SerialCurrentControl;
35:
36: int MyServerPid;
1.4 takayama 37: #define SERVERNAME_SIZE 4096
38: char ServerName[SERVERNAME_SIZE];
1.1 maekawa 39: int PacketMonitor = 0;
40: int Quiet = 0;
41:
42: int LocalMode = 1;
43: int NotifyPortnumber = 0;
1.4 takayama 44: int Do_not_use_control_stream_to_tell_no_server = 1;
1.24 takayama 45: int IgnoreSIGINT = 1;
1.4 takayama 46: static void errorToStartEngine(void);
47: static int findOxServer(char *server);
48: static void couldNotFind(char *s);
1.8 takayama 49: /* gcc -v -c hoge.c */
1.26 ! takayama 50: static void mywait(int m);
1.15 takayama 51:
52: void *sGC_malloc(int n) {
53: return (void *)malloc(n);
54: }
1.1 maekawa 55:
56: main(int argc, char *argv[]) {
57: int fd;
58: int size;
59: char sname[1024];
60: int tmp[1];
61: char *buf;
62: int i;
63: int fdControl = -1; int portControl = 1200;
64: int fdStream = -1; int portStream = 1300;
65: int reverse = 0;
66: extern int OpenedSocket;
67: char portfile[1024];
1.12 takayama 68: char *pass = NULL;
1.18 takayama 69: char *passControl = NULL;
70: char *passData = NULL;
1.4 takayama 71: int result;
1.9 takayama 72: int sleepingTime = 0;
1.22 takayama 73: int authEncoding=0;
74: FILE *fp;
75: char *stmp;
1.12 takayama 76: extern int OxTerminateMode;
1.1 maekawa 77:
1.26 ! takayama 78: int sighup[]={SIGHUP,-1};
! 79: block_signal(sighup); /* ignore x of xterm */
1.1 maekawa 80: strcpy(sname,"localhost");
81: strcpy(ServerName,SERVERNAME);
82: i = 1;
1.2 takayama 83: if (argc == 1) {
84: oxmainUsage();
1.12 takayama 85: exit(10);
1.2 takayama 86: }
1.1 maekawa 87: while (i<argc) {
88: if (strcmp(argv[i],"-host") == 0) {
89: i++;
90: if (i<argc) strcpy(sname,argv[i]);
91: }else if (strcmp(argv[i],"-data")==0) {
92: i++;
93: if (i<argc) sscanf(argv[i],"%d",&portStream);
94: }else if (strcmp(argv[i],"-control")==0) {
95: i++;
96: if (i<argc) sscanf(argv[i],"%d",&portControl);
97: }else if (strcmp(argv[i],"-ox") == 0) {
98: i++;
99: if (i<argc) strcpy(ServerName,argv[i]);
100: }else if (strcmp(argv[i],"-monitor") == 0) {
101: PacketMonitor = 1;
102: }else if (strcmp(argv[i],"-insecure") == 0) {
103: LocalMode = 0;
104: }else if (strcmp(argv[i],"-reverse") == 0) {
105: reverse = 1;
1.12 takayama 106: }else if (strcmp(argv[i],"-finish") == 0) {
107: OxTerminateMode = 1;
1.1 maekawa 108: }else if (strcmp(argv[i],"-portfile") == 0) {
109: i++;
110: if (i<argc) {
1.7 takayama 111: sscanf(argv[i],"%s",portfile);
112: portControl = 0;
113: portStream = 0;
114: NotifyPortnumber = 1;
1.1 maekawa 115: }
116: }else if (strcmp(argv[i],"-pass") == 0) {
117: i++;
118: if (i<argc) {
1.7 takayama 119: pass = argv[i];
1.1 maekawa 120: }
1.18 takayama 121: }else if (strcmp(argv[i],"-passData") == 0) {
122: i++;
123: if (i<argc) {
124: passData = argv[i];
125: }
126: }else if (strcmp(argv[i],"-passControl") == 0) {
127: i++;
128: if (i<argc) {
129: passControl = argv[i];
130: }
1.9 takayama 131: }else if (strcmp(argv[i],"-wait") == 0) {
132: i++;
133: if (i<argc) {
134: sscanf(argv[i],"%d",&sleepingTime);
135: }
1.22 takayama 136: }else if (strcmp(argv[i],"-authEncoding") == 0) {
137: i++;
138: if (strcmp(argv[i],"file") == 0) {
139: authEncoding = 1;
140: }else{
141: fprintf(stderr,"Unknown -authEncoding %s.\n",argv[i]);
142: oxmainUsage(); exit(10);
143: }
1.24 takayama 144: }else if (strcmp(argv[i],"-ignoreSIGINT") == 0) {
145: i++;
146: if (i<argc) {
1.25 takayama 147: sscanf(argv[i],"%d",&IgnoreSIGINT);
1.24 takayama 148: }
1.1 maekawa 149: }else {
150: fprintf(stderr,"Unknown option %s.\n",argv[i]);
151: oxmainUsage(); exit(10);
152: }
153: i++;
154: }
155:
1.4 takayama 156: if (Do_not_use_control_stream_to_tell_no_server) {
1.7 takayama 157: if (findOxServer(ServerName) < 0) {
158: fprintf(stderr,"Sleeping five seconds...\n");
159: sleep(5);
160: exit(-1);
161: }
1.9 takayama 162: }
163:
164: if (sleepingTime) {
165: fprintf(stderr,"Waiting to connect for %d seconds...\n",sleepingTime);
166: sleep(sleepingTime);
167: fprintf(stderr,"\nTrying to connect\n");
1.4 takayama 168: }
169:
1.18 takayama 170: if ((pass != NULL) && (passData == NULL)) {
171: passData = pass;
172: }
173: if ((pass != NULL) && (passControl == NULL)) {
174: passControl = pass;
175: }
176:
1.19 takayama 177: /* Decrypt passControl and passData, here. Lookup cryptmethod. */
1.22 takayama 178: if (authEncoding == 1) {
179: stmp = (char *)sGC_malloc(strlen(getenv("HOME"))+strlen(passControl)+
180: strlen(passData)+128);
181: sprintf(stmp,"%s/.openxm/tmp.opt/%s",(char *)getenv("HOME"),passControl);
182: fp = fopen(stmp,"r");
183: if (fp == NULL) { fprintf(stderr,"passControl file %s is not found.\n",stmp); exit(1);}
184: fgets(stmp,127,fp); passControl = stmp; fclose(fp);
185:
186: stmp = (char *)sGC_malloc(strlen(getenv("HOME"))+strlen(passControl)+
187: strlen(passData)+128);
188: sprintf(stmp,"%s/.openxm/tmp.opt/%s",(char *)getenv("HOME"),passData);
189: fp = fopen(stmp,"r");
190: if (fp == NULL) { fprintf(stderr,"passData file %s is not found.\n",stmp); exit(1);}
191: fgets(stmp,127,fp); passData = stmp; fclose(fp);
192: }
1.19 takayama 193:
1.1 maekawa 194: if (reverse) {
195: /* The order is very important. */
1.18 takayama 196: fdControl = socketConnectWithPass(sname,portControl,passControl);
197: fdStream = socketConnectWithPass(sname,portStream,passData);
1.1 maekawa 198:
199: fprintf(stderr,"Connected: control = %d, data = %d.\n",fdControl,fdStream);
1.7 takayama 200: result = 0;
1.5 takayama 201:
202:
1.20 takayama 203: if ((fdControl < 0) || (fdStream < 0)) {
204: fprintf(stderr,"Waiting for 10 seconds to show an error.\n");
205: sleep(10);
206: }
207:
1.1 maekawa 208: if (portControl != -1) {
209: MyServerPid = fork();
210: if (MyServerPid > 0 ) parentServerMain(fdControl,fdStream);
1.4 takayama 211: else result=childServerMain(fdControl,fdStream);
1.1 maekawa 212: }else{
1.4 takayama 213: result=childServerMain(fdControl,fdStream);
1.1 maekawa 214: }
1.4 takayama 215: /* This line will be never executed in case of success */
1.7 takayama 216: if (result < 0 ) {
217: errorToStartEngine();
218: }
1.1 maekawa 219: }
220:
221: /* non-reverse case. */
222: fprintf(stderr,"Hostname is %s \n",sname);
223: fprintf(stderr,"Port for data (-data) = %d \n",portStream);
224: fprintf(stderr,"Port for control message (-control) = %d \n",portControl);
225: fflush(NULL);
226:
227:
228: if (LocalMode) {
229: if (portControl != -1) {
230: fdControl = socketOpen(sname,portControl);
231: portControl = OpenedSocket;
232: if (NotifyPortnumber) {
1.7 takayama 233: oxWritePortFile(0,portControl,portfile);
1.1 maekawa 234: }
235: fdControl = socketAcceptLocal(fdControl);
236: fprintf(stderr,"\n control port %d : Connected.\n",portControl);
237: }
238: if (portStream != -1) {
239: fdStream = socketOpen(sname,portStream);
240: portStream = OpenedSocket;
241: if (NotifyPortnumber) {
1.7 takayama 242: oxWritePortFile(1,portStream,portfile);
1.1 maekawa 243: }
244: fdStream = socketAcceptLocal(fdStream);
245: fprintf(stderr,"\n stream port %d : Connected.\n",portStream);
246: }
247: }else{
248: if (portControl != -1) {
249: fdControl = socketOpen(sname,portControl);
250: portControl = OpenedSocket;
251: if (NotifyPortnumber) {
1.7 takayama 252: oxWritePortFile(0,portControl,portfile);
1.1 maekawa 253: }
254: fdControl = socketAccept(fdControl);
255: fprintf(stderr,"\n control port %d : Connected.\n",portControl);
256: }
257: if (portStream != -1) {
258: fdStream = socketOpen(sname,portStream);
259: portStream = OpenedSocket;
260: if (NotifyPortnumber) {
1.7 takayama 261: oxWritePortFile(1,portStream,portfile);
1.1 maekawa 262: }
263: fdStream = socketAccept(fdStream);
264: fprintf(stderr,"\n stream port %d : Connected.\n",portStream);
265: }
266: }
267:
1.19 takayama 268: if (passControl != NULL) {
269: char *s; int mm;
270: fprintf(stderr,"passControl\n");
271: mm = strlen(passControl);
272: s = (char *) malloc(mm+1);
273: if (s == NULL) {fprintf(stderr,"No more memory.\n"); exit(1); }
274: if (read(fdControl,s,mm+1) < 0) {
275: fprintf(stderr,"Read error to read passControl\n"); sleep(5); exit(1);
276: }
277: s[mm] = 0;
278: if (strcmp(s,passControl) != 0) {
279: fprintf(stderr,"s=%s and passControl=%s do not match.\n",s,passControl); sleep(5); exit(1);
280: }
281: free(s);
282: }
283: if (passData != NULL) {
284: char *s; int mm;
285: mm = strlen(passData);
286: fprintf(stderr,"passData\n");
287: s = (char *) malloc(mm+1);
288: if (s == NULL) {fprintf(stderr,"No more memory.\n"); exit(1); }
289: if (read(fdStream,s,mm+1) < 0) {
290: fprintf(stderr,"Read error to read passData\n");
291: errorToStartEngine();
292: }
293: if (strcmp(s,passData) != 0) {
294: fprintf(stderr,"s=%s and passData=%s do not match.\n",s,passData);
295: errorToStartEngine();
296: }
297: free(s);
298: }
1.1 maekawa 299:
1.20 takayama 300: if ((fdControl < 0) || (fdStream < 0)) {
301: fprintf(stderr,"Waiting for 10 seconds to show an error.\n");
302: sleep(10);
303: }
304:
305:
1.4 takayama 306: result = 0;
1.1 maekawa 307: if (portControl != -1) {
308: MyServerPid = fork();
309: if (MyServerPid > 0 ) parentServerMain(fdControl,fdStream);
1.4 takayama 310: else result = childServerMain(fdControl,fdStream);
1.1 maekawa 311: }else{
1.4 takayama 312: result = childServerMain(fdControl,fdStream);
1.1 maekawa 313: }
1.4 takayama 314: if (result < 0) errorToStartEngine();
315: }
1.1 maekawa 316:
1.4 takayama 317: static void errorToStartEngine(void) {
318: fprintf(stderr,"Failed to start the engine. Childing process is terminating.\n");
319: /* You have to tell to the control server that there is no engine.
1.7 takayama 320: And, the control server must tell the client that there is no
321: engine.
322: This part has not yet been implemented.
323: If you implement this, set Do_not_use_control_stream_to_tell_no_server to
324: zero.
325: */
1.20 takayama 326: sleep(10);
1.4 takayama 327: exit(-1);
1.1 maekawa 328: }
329:
330: oxmainUsage() {
331: fprintf(stderr,"Usage: \n");
332: fprintf(stderr," ox [-ox serverprogram -host name -data portnum -control portnum -monitor]\n");
1.18 takayama 333: fprintf(stderr," [-insecure -portfile fname -reverse -passControl xxxyyyzzz -passData pppqqqrrr]");
1.24 takayama 334: fprintf(stderr," [-finish] [-wait seconds] [-authEncoding [file]]");
335: fprintf(stderr," [-ignoreSIGINT [1|0]]");
1.1 maekawa 336: fprintf(stderr,"\n");
1.2 takayama 337: fprintf(stderr,"-reverse: ox server connects to the client.\n");
1.18 takayama 338: fprintf(stderr," The client must give a one time password to ox server to connect to the client with -pass* option.\n");
1.2 takayama 339: fprintf(stderr," The one time password can be seen by ps command, so you must not use this one time password system on an untrustful host.\n");
340: fprintf(stderr," The one time password should be sent by a safe communication line like ssh and the ox server should be started by ssh. Do not use rsh\n");
1.18 takayama 341: fprintf(stderr," (The option -pass is obsolete.)\n");
1.2 takayama 342: fprintf(stderr," If -reverse is not given, the client connect to the ox server\n");
343: fprintf(stderr," See OpenXM/src/SSkan/Doc/ox.sm1, /sm1connectr\n");
344: fprintf(stderr,"-insecure : \n");
345: fprintf(stderr," If you access to the server from a localhost, you do not need one time password. However, if you access outside of the localhost, a one time password is required. To turn off this restriction, -insecure option is used.\n");
1.4 takayama 346: fprintf(stderr,"\n");
347: fprintf(stderr,"If ox fails to find the serverprogram, it tries to look for it in /usr/local/OpenXM/bin and $OpenXM_HOME/bin.\n");
348: fprintf(stderr,"\n");
1.2 takayama 349: fprintf(stderr,"Example 1:\n");
1.3 takayama 350: fprintf(stderr,"(Start the ox server): dc1%% ox -ox ~/OpenXM/bin/ox_sm1 -host dc1.math.kobe-u.ac.jp -insecure -control 1200 -data 1300\n");
1.2 takayama 351: fprintf(stderr,"(client): sm1\n ");
352: fprintf(stderr," (ox.sm1) run ; \n");
1.1 maekawa 353: fprintf(stderr," sm1>[(dc1.math.kobe-u.ac.jp) 1300 1200] oxconnect /ox.ccc set\n");
1.2 takayama 354: fprintf(stderr,"Example 2:\n");
355: fprintf(stderr,"(Start the ox server): dc1%% ox -ox ~/OpenXM/bin/ox_sm1\n");
356: fprintf(stderr,"(client): dc1%% sm1\n ");
357: fprintf(stderr," (ox.sm1) run ; \n");
358: fprintf(stderr," sm1>[(localhost) 1300 1200] oxconnect /ox.ccc set\n");
1.1 maekawa 359: fprintf(stderr,"\n");
360: }
361:
362: parentServerMain(int fdControl, int fdStream) {
363: int id;
364: int mtag;
365: int size;
366: int n;
367: int r;
368: int message = 1;
369: int controlByteOrder;
1.12 takayama 370: extern OxTerminateMode;
1.26 ! takayama 371: extern void myServerExit(int m);
1.1 maekawa 372:
1.26 ! takayama 373: int sigchld[]={SIGCHLD,-1};
! 374: unblock_signal(sigchld);
1.12 takayama 375: if (OxTerminateMode) {
376: /*
377: OxTerminateMode cannot be used if you run ox by xterm -exec ox ...
378: */
379: if (fork()) {
380: close(fdControl); close(fdStream);
381: /* Parent */
382: exit(0); /*Tell the caller that launching is successfully finished.*/
383: }
384: }
385:
1.13 takayama 386: controlByteOrder = oxTellMyByteOrder(fdControl,fdControl);
1.1 maekawa 387: /* Set the network byte order. */
388: fprintf(stderr,"controlByteOrder=%x\n",controlByteOrder);
389:
1.26 ! takayama 390: int sigint[]={SIGINT,-1};
! 391: set_signal(sigint,myServerExit);
! 392: unblock_signal(sigint);
1.1 maekawa 393: while(1) {
394: mtag = oxfdGetOXheader(fdControl,&SerialCurrentControl);
395: /* get the message_tag */
396: /* message_body */
397: id = oxfdGetInt32(fdControl); /* get the function_id */
398: if (message) {printf("\n[control] control function_id is %d\n",id);}
399: switch( id ) {
400: case SM_control_kill:
401: if (message) printf("[control] control_kill\n");
402: oxSendResultOfControl(fdControl);
403: sleep(2);
1.26 ! takayama 404: myServerExit(0);
1.1 maekawa 405: break;
406: case SM_control_reset_connection:
407: if (message) printf("[control] control_reset_connection.\n");
408: if (message) printf("Sending the SIGUSR1 signal to %d: ",MyServerPid);
409: r=kill(MyServerPid,SIGUSR1);
410: if (message) printf("Result = %d\n",r);
411: fflush(NULL);
1.7 takayama 412: /* oxSendResultOfControlInt32(fdControl,0); */
1.1 maekawa 413: break;
414: default:
415: fprintf(stderr,"[control] Unknown control message.\n");
416: fprintf(stderr,"Shutdown the server.");
1.26 ! takayama 417: myServerExit(0);
1.1 maekawa 418: break;
419: }
420: }
421: }
422:
1.26 ! takayama 423: void myServerExit(int m) {
1.1 maekawa 424: printf("Sending the kill signal to the child.\n");
425: kill(MyServerPid,SIGKILL);
1.12 takayama 426: exit(0);
1.1 maekawa 427: }
428:
429: childServerMain(int fdControl, int fdStream) {
430: int i;
1.23 takayama 431: struct rlimit res;
1.1 maekawa 432: close(fdControl); /* close(0); dup(fdStream); */
433: dup2(fdStream,3);
434: dup2(fdStream,4);
1.4 takayama 435: /*close(0);
1.7 takayama 436: #include <sys/param.h>
437: for (i=5; i<NOFILE; i++) close(i);
438: */
1.4 takayama 439: if (!Do_not_use_control_stream_to_tell_no_server) {
1.7 takayama 440: if (findOxServer(ServerName) < 0) {
441: return(-1);
442: }
1.4 takayama 443: }
1.5 takayama 444: fprintf(stderr,"childServerMain: Starting the server %s\n",ServerName); fflush(NULL);
1.14 takayama 445:
446: /*
447: {
448: int i;
449: i=0;
450: while (environ[i] != NULL) {
451: fprintf(stderr,"%s ",environ[i++]);
452: }
453: fprintf(stderr,"\n");
454: }
455: */
456: /* bug: xterm of potato does not seem to pass the LD_LIBRARY_PATH.
457: So, the new gc does not work.
458: it is an workaround for OpenXM */
459: if (getenv("LD_LIBRARY_PATH") == (char *)NULL) {
460: char *s,*o;
461: fprintf(stderr,"Hmm... LD_LIBRARY_PATH does not seem to be set.\n");
462: o = getenv("OpenXM_HOME");
463: if (o == NULL) {
464: fprintf(stderr,"Giving up to set the LD_LIBRARY_PATH variable.\n");
465: }else{
466: s = (char *)malloc(strlen(o)+64);
467: sprintf(s,"LD_LIBRARY_PATH=%s/lib",o);
468: putenv(s);
469: }
470: }
1.23 takayama 471: getrlimit(RLIMIT_STACK,&res);
472: if (res.rlim_cur < 65536000) {
473: fprintf(stderr,"RLIMIT_STACK is increased to 65Mbytes by setrlimit.\n");
474: res.rlim_cur = 65536000;
475: setrlimit(RLIMIT_STACK,&res);
476: }
1.24 takayama 477:
1.26 ! takayama 478: int sigint[]={SIGINT,-1};
! 479: if (IgnoreSIGINT) { block_signal(sigint); fprintf(stderr,"SIGING\n");}
1.24 takayama 480:
1.1 maekawa 481: if (PacketMonitor) {
1.14 takayama 482: if (execle(ServerName,ServerName,"-monitor",NULL,environ)) {
1.1 maekawa 483: fprintf(stderr,"%s cannot be executed with -monitor.\n",ServerName);
1.7 takayama 484: fflush(NULL);
485: return(-1);
1.1 maekawa 486: }
487: }else {
1.14 takayama 488: if (execle(ServerName,ServerName,NULL,environ)) {
1.1 maekawa 489: fprintf(stderr,"%s cannot be executed.\n",ServerName);
1.7 takayama 490: fflush(NULL);
491: return(-1);
1.1 maekawa 492: }
493: }
1.4 takayama 494: /* never reached. */
1.1 maekawa 495: }
496:
497:
498: /* These are dummy. It is defined in stackmachine.c */
499: unlockCtrlCForOx() { ; }
500: restoreLockCtrlCForOx() { ; }
501:
1.4 takayama 502: static int findOxServer(char *server) {
503: char *p;
504: char *p2;
505: if (strlen(server) == 0) return(-1);
1.10 takayama 506: /* fd = open(server,O_RDONLY); */
1.11 ohara 507: if (access(server,X_OK&R_OK) == 0) {
1.7 takayama 508: fprintf(stderr,"Starting OX server : %s\n",server);
509: return(0);
1.4 takayama 510: }
511: if (server[0] == '/') {
1.7 takayama 512: couldNotFind(server);
513: return(-1);
1.4 takayama 514: }
515: fprintf(stderr,"The server %s was not found. Trying to find it under OpenXM/bin\n",server);
516: p = getenv("OpenXM_HOME");
517: if (p == NULL) {
518: p = "/usr/local/OpenXM";
519: }
520: p2 = (char *) malloc(sizeof(char)*(strlen(p)+strlen("/bin/")+3+strlen(server)));
521: if (p2 == NULL) { fprintf(stderr,"No more memory.\n"); exit(10); }
522: strcpy(p2,p); strcat(p2,"/bin/"); strcat(p2,server);
1.10 takayama 523: /* fd = open(p2,O_RDONLY); */
1.11 ohara 524: if (access(p2,X_OK&R_OK) == 0) {
1.7 takayama 525: fprintf(stderr,"Starting OX server : %s\n",p2);
526: if (strlen(p2) < SERVERNAME_SIZE) strcpy(server,p2);
527: else {
528: couldNotFind("Too long ox server name.");
529: return(-1);
530: }
531: return(0);
1.4 takayama 532: }
533: couldNotFind(p2);
534: return(-1);
535: }
1.1 maekawa 536:
1.4 takayama 537: static void couldNotFind(char *s) {
538: fprintf(stderr,"OX server %s could not be found.\n",s);
539: }
1.1 maekawa 540:
541:
1.26 ! takayama 542: static void mywait(int m) {
1.21 takayama 543: int status;
544: int pid;
545: int i,j;
546: /* signal(SIGCHLD,SIG_IGN); */
547: pid = wait(&status);
548: fprintf(stderr,"Control: child process %d is exiting.\n",pid);
549: fprintf(stderr,"Control: Shutting down the control server.\n");
550: sleep(2);
551: exit(0);
552: }
1.1 maekawa 553:
554:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>