Annotation of OpenXM_contrib2/asir2000/io/ox_launch.c, Revision 1.16
1.3 noro 1: /*
2: * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED
3: * All rights reserved.
4: *
5: * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
6: * non-exclusive and royalty-free license to use, copy, modify and
7: * redistribute, solely for non-commercial and non-profit purposes, the
8: * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
9: * conditions of this Agreement. For the avoidance of doubt, you acquire
10: * only a limited right to use the SOFTWARE hereunder, and FLL or any
11: * third party developer retains all rights, including but not limited to
12: * copyrights, in and to the SOFTWARE.
13: *
14: * (1) FLL does not grant you a license in any way for commercial
15: * purposes. You may use the SOFTWARE only for non-commercial and
16: * non-profit purposes only, such as academic, research and internal
17: * business use.
18: * (2) The SOFTWARE is protected by the Copyright Law of Japan and
19: * international copyright treaties. If you make copies of the SOFTWARE,
20: * with or without modification, as permitted hereunder, you shall affix
21: * to all such copies of the SOFTWARE the above copyright notice.
22: * (3) An explicit reference to this SOFTWARE and its copyright owner
23: * shall be made on your publication or presentation in any form of the
24: * results obtained by use of the SOFTWARE.
25: * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
1.4 noro 26: * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
1.3 noro 27: * for such modification or the source code of the modified part of the
28: * SOFTWARE.
29: *
30: * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
31: * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
32: * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
33: * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
34: * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
35: * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
36: * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
37: * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
38: * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
39: * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
40: * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
41: * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
42: * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
43: * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
44: * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
45: * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
46: * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
1.16 ! noro 47: * $OpenXM: OpenXM_contrib2/asir2000/io/ox_launch.c,v 1.15 2001/10/09 01:36:21 noro Exp $
1.3 noro 48: */
1.2 noro 49: #include <setjmp.h>
50: #include <signal.h>
51: #include <fcntl.h>
1.1 noro 52: #include "ca.h"
53: #include "com.h"
54: #include "ox.h"
55: #if defined(VISUAL)
1.7 noro 56: #include <stdlib.h>
1.1 noro 57: #include <windows.h>
58: #include <io.h>
59: #include <fcntl.h>
60: #include <process.h>
61: #else
62: #include <sys/file.h>
63: #include <sys/types.h>
64: #include <sys/stat.h>
65: #include <pwd.h>
66: #endif
67:
68: #if defined(SYSV)
69: #include <unistd.h>
70: #endif
71:
72: #if defined(VISUAL)
73: HANDLE hIntr,hReset,hKill;
74: #endif
75:
76: static void put_log(char *);
77: static int which_command(char *,char *);
78: static int search_command(char *);
1.10 noro 79: static int ox_spawn(char *,int,char *,int);
1.1 noro 80: static void launch_error(char *);
1.15 noro 81: static void ox_io_init(int);
1.1 noro 82: static void push_one(Obj);
83: static Obj pop_one();
84: static void do_cmd(int);
1.13 noro 85: static void terminate_server();
1.1 noro 86:
87: static Obj *asir_OperandStack;
88: static int asir_OperandStackPtr;
89:
90: static char hostname[BUFSIZ];
91: static int sindex;
92: static struct sockaddr_in peer;
93: static int cpid;
94:
95: static void put_log(str)
96: char *str;
97: {
98: static FILE *logfile;
99:
100: if ( !logfile )
101: logfile = fopen("/tmp/ox_log","w");
102: fprintf(logfile,"%s\n",str);
103: fflush(logfile);
104: }
105:
106: #if !defined(VISUAL)
107: static int which_command(com,file)
108: char *com,*file;
109: {
110: char *c,*s;
111: int len;
112: char dir[BUFSIZ],path[BUFSIZ];
113:
114: for ( s = (char *)getenv("PATH"); s; ) {
115: c = (char *)index(s,':');
116: if ( c ) {
117: len = c-s;
118: strncpy(dir,s,len); s = c+1; dir[len] = 0;
119: } else {
120: strcpy(dir,s); s = 0;
121: }
122: sprintf(path,"%s/%s",dir,com);
123: if ( search_command(path) ) {
124: strcpy(file,path); return 1;
125: }
126: }
127: file[0] = 0; return 0;
128: }
129:
130: static int search_command(file)
131: char *file;
132: {
133: struct stat buf;
134:
135: if ( stat(file,&buf) || (buf.st_mode & S_IFDIR) )
136: return 0;
137: if ( access(file,X_OK) )
138: return 0;
139: else
140: return 1;
141: }
142: #endif
143:
144: /*
145: argv[1] : host to connect
146: argv[2] : if 1, call try_bind_listen and try_accept
147: if 0, call try_connect
148: argv[3] : control_port
149: argv[4] : server_port
150: argv[5] : server
151: argv[6] : display or "0"
1.10 noro 152: argv[7] : if exists, it should be "-nolog"
1.1 noro 153: */
154:
155: void launch_main(argc,argv)
156: int argc;
157: char **argv;
158: {
1.15 noro 159: #if !defined(VISUAL)
160: Obj p;
1.1 noro 161: char *name;
162: char buf[BUFSIZ];
1.15 noro 163: #endif
164: int id;
165: Obj obj;
1.1 noro 166: int cs,ss;
167: unsigned int cmd;
1.10 noro 168: int use_unix,accept_client,nolog;
1.1 noro 169: char *control_port_str,*server_port_str;
170: char *rhost,*server,*dname;
171:
172: GC_init(); nglob_init();
173: gethostname(hostname,BUFSIZ);
174: rhost = argv[1];
175: use_unix = !strcmp(rhost,".") ? 1 : 0;
176: accept_client = atoi(argv[2]) ? 1 : 0;
177: control_port_str = argv[3];
178: server_port_str = argv[4];
179: server = argv[5];
180: dname = argv[6];
1.10 noro 181: nolog = argc > 7 ? 1 : 0;
1.1 noro 182:
183: #if defined(VISUAL)
184: init_socket();
185: #endif
186:
187: signal(SIGINT,SIG_IGN);
188: #if defined(SIGUSR1)
189: signal(SIGUSR1,SIG_IGN);
190: #endif
1.13 noro 191: #if defined(SIGTERM)
192: signal(SIGTERM,terminate_server);
193: #endif
1.1 noro 194:
195: if ( accept_client ) {
196: cs = try_bind_listen(use_unix,control_port_str);
197: ss = try_bind_listen(use_unix,server_port_str);
198: cs = try_accept(use_unix,cs);
199: ss = try_accept(use_unix,ss);
200: } else {
201: cs = try_connect(use_unix,rhost,control_port_str);
202: ss = try_connect(use_unix,rhost,server_port_str);
203: }
204: ox_io_init(cs);
205: if ( cs < 0 || ss < 0 )
206: launch_error("cannot connect to the client");
1.10 noro 207: cpid = ox_spawn(server,ss,dname,nolog);
1.1 noro 208:
209: while ( 1 ) {
210: ox_recv(sindex,&id,&obj);
211: switch ( id ) {
212: case OX_COMMAND:
213: cmd = ((USINT)obj)->body;
214: do_cmd(cmd);
215: break;
216: case OX_DATA:
217: push_one(obj);
218: break;
219: case OX_SYNC_BALL:
220: break;
221: default:
222: break;
223: }
224: }
225: }
226:
227: #if defined(VISUAL)
228: static void do_cmd(cmd)
229: int cmd;
230: {
231: USINT t;
232:
233: switch ( cmd ) {
234: case SM_shutdown:
235: SetEvent(hKill);
1.8 noro 236: ExitProcess(0);
237: break;
1.1 noro 238: case SM_control_intr:
239: SetEvent(hIntr);
240: break;
241: case SM_control_kill:
242: SetEvent(hKill);
243: break;
244: case SM_control_reset_connection:
245: MKUSINT(t,0);
246: ox_send_data(sindex,t);
247: SetEvent(hReset);
248: break;
249: default:
250: break;
251: }
252: }
253: #else
254: static void do_cmd(cmd)
255: int cmd;
256: {
257: USINT t;
258: int id,cindex;
259: int bport,sport;
260: int bs,bs0;
261: int status;
262: STRING prog,dname;
263:
264: switch ( cmd ) {
265: case SM_shutdown:
266: kill(cpid,SIGKILL);
267: exit(0); break;
268: case SM_control_intr:
269: kill(cpid,SIGINT);
270: break;
271: case SM_control_kill:
272: kill(cpid,SIGKILL);
273: break;
274: case SM_control_reset_connection:
275: MKUSINT(t,0);
276: ox_send_data(sindex,t);
277: kill(cpid,SIGUSR1);
278: break;
279: default:
280: break;
281: }
282: }
283: #endif
284:
1.10 noro 285: static int ox_spawn(prog,bs,dname,nolog)
1.1 noro 286: char *prog;
287: int bs;
288: char *dname;
1.10 noro 289: int nolog;
1.1 noro 290: {
291: #if defined(VISUAL)
292: char *av[BUFSIZ];
293: char sock_id[BUFSIZ],ox_intr[BUFSIZ],ox_reset[BUFSIZ],ox_kill[BUFSIZ];
294: char AsirExe[BUFSIZ];
1.15 noro 295: int hProc;
1.1 noro 296: STRING rootdir;
297: int mypid;
1.7 noro 298: int newbs;
1.1 noro 299:
1.7 noro 300: DuplicateHandle(GetCurrentProcess(),(HANDLE)bs,
301: GetCurrentProcess(),(HANDLE *)&newbs,
302: 0,TRUE,DUPLICATE_SAME_ACCESS);
303: close(bs);
304: bs = newbs;
305:
1.1 noro 306: mypid = GetCurrentProcessId();
307: sprintf(ox_intr,"ox_intr_%d",mypid);
308: sprintf(ox_reset,"ox_reset_%d",mypid);
309: sprintf(ox_kill,"ox_kill_%d",mypid);
310: hIntr = CreateEvent(NULL,TRUE,FALSE,ox_intr);
311: hReset = CreateEvent(NULL,TRUE,FALSE,ox_reset);
312: hKill = CreateEvent(NULL,TRUE,FALSE,ox_kill);
313: sprintf(sock_id,"%d",bs);
314: av[0] = prog;
315: av[1] = sock_id;
1.7 noro 316: av[2] = dname; /* if dname == "1" then a message window is opened */
317: av[3] = ox_intr;
318: av[4] = ox_reset;
319: av[5] = ox_kill;
320: av[6] = NULL;
1.1 noro 321: Pget_rootdir(&rootdir);
1.9 noro 322: sprintf(AsirExe,"%s\\bin\\engine.exe",BDY(rootdir));
1.7 noro 323: _fileinfo = 1;
1.1 noro 324: hProc = _spawnv(_P_NOWAIT,AsirExe,av);
325: return (int)hProc;
326: #else /* VISUAL */
327: int b,s,i;
328: struct hostent *hp;
329: int pid;
330: char wname[BUFSIZ];
331: char buf[BUFSIZ];
1.5 noro 332: char errcode;
1.1 noro 333:
334: pid = fork();
335: if ( pid )
336: return pid;
337: else {
338: setpgid(0,getpid());
1.16 ! noro 339: if ( bs != 3 && dup2(bs,3) != 3 )
1.1 noro 340: exit(1);
1.16 ! noro 341: if ( bs != 4 && dup2(bs,4) != 4 )
1.1 noro 342: exit(1);
343: {
1.16 ! noro 344: #if defined(linux) || defined(__NeXT__) || defined(ultrix) || defined(__CYGWIN__)
1.1 noro 345: #include <sys/param.h>
346: close(0);
347: for ( i = 5; i < NOFILE; i++ )
348: close(i);
349: #else
350: #include <sys/resource.h>
351: struct rlimit rl;
352:
353: getrlimit(RLIMIT_NOFILE,&rl);
354: close(0);
355: for ( i = 5; i < rl.rlim_cur; i++ )
356: close(i);
357: #endif
358: }
1.12 noro 359: if ( !nolog && !strcmp(dname,"1" ) ) /* XXX: for ssh */
1.6 noro 360: execl(prog,prog,0);
1.10 noro 361: else if ( nolog || !strcmp(dname,"0") ) {
1.1 noro 362: FILE *null;
363:
364: null = fopen("/dev/null","wb");
365: dup2(fileno(null),1);
366: dup2(fileno(null),2);
1.12 noro 367: if ( !strcmp(dname,"1") ) {
368: /* XXX */
369: putenv("DISPLAY=");
370: execl(prog,prog,0);
371: } else if ( strcmp(dname,"0") )
1.11 noro 372: execl(prog,prog,"-display",dname,0);
373: else {
1.10 noro 374: putenv("DISPLAY=");
375: execl(prog,prog,0);
1.11 noro 376: }
1.6 noro 377: } else
378: execl(prog,prog,"-display",dname,0);
1.5 noro 379: /* On failure */
380: errcode = 2;
381: write(4,&errcode,1);
382: exit(1);
1.1 noro 383: }
384: #endif
385: }
386:
387: static void launch_error(s)
388: char *s;
389: {
390: exit(0);
391: }
392:
1.15 noro 393: static void ox_io_init(sock)
1.1 noro 394: int sock;
395: {
396: endian_init();
397: /* server mode */
398: sindex = get_iofp(sock,0,1);
399: asir_OperandStack = (Obj *)CALLOC(BUFSIZ,sizeof(Obj));
400: asir_OperandStackPtr = -1;
401: }
402:
403: static void push_one(obj)
404: Obj obj;
405: {
406: if ( !obj || OID(obj) != O_VOID )
407: asir_OperandStack[++asir_OperandStackPtr] = obj;
408: }
409:
410: static Obj pop_one() {
411: if ( asir_OperandStackPtr >= 0 ) {
412: return asir_OperandStack[asir_OperandStackPtr--];
413: }
1.13 noro 414: }
415:
1.15 noro 416: static void terminate_server(int sig)
1.13 noro 417: {
1.14 noro 418: #if defined(SIGKILL)
1.13 noro 419: kill(cpid,SIGKILL);
1.14 noro 420: #endif
1.13 noro 421: exit(0);
1.1 noro 422: }
423:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>