2281 |
return x; |
return x; |
2282 |
} |
} |
2283 |
|
|
2284 |
@(static defun socket (port &key host server async myaddr myport) |
static object |
2285 |
|
maccept(object x) { |
2286 |
|
|
2287 |
|
int fd,n; |
2288 |
|
struct sockaddr_in addr; |
2289 |
|
object server,host,port; |
2290 |
|
|
2291 |
|
if (type_of(x) != t_stream) |
2292 |
|
FEerror("~S is not a steam~%",1,x); |
2293 |
|
if (x->sm.sm_mode!=smm_two_way) |
2294 |
|
FEerror("~S is not a two-way steam~%",1,x); |
2295 |
|
fd=accept(SOCKET_STREAM_FD(STREAM_INPUT_STREAM(x)),(struct sockaddr *)&addr, &n); |
2296 |
|
if (fd <0) { |
2297 |
|
FEerror("Error ~S on accepting connection to ~S~%",2,make_simple_string(strerror(errno)),x); |
2298 |
|
x=Cnil; |
2299 |
|
} else { |
2300 |
|
server=STREAM_INPUT_STREAM(x)->sm.sm_object0->c.c_car; |
2301 |
|
host=STREAM_INPUT_STREAM(x)->sm.sm_object0->c.c_cdr->c.c_car; |
2302 |
|
port=STREAM_INPUT_STREAM(x)->sm.sm_object0->c.c_cdr->c.c_cdr->c.c_car; |
2303 |
|
x = make_two_way_stream |
2304 |
|
(make_socket_stream(fd,gcl_sm_input,server,host,port,Cnil), |
2305 |
|
make_socket_stream(fd,gcl_sm_output,server,host,port,Cnil)); |
2306 |
|
} |
2307 |
|
return x; |
2308 |
|
|
2309 |
|
} |
2310 |
|
|
2311 |
|
#ifdef BSD |
2312 |
|
#include <sys/types.h> |
2313 |
|
#include <sys/resource.h> |
2314 |
|
#include <signal.h> |
2315 |
|
|
2316 |
|
static void |
2317 |
|
rmc(int e,void *pid) { |
2318 |
|
|
2319 |
|
kill((int)pid,SIGTERM); |
2320 |
|
|
2321 |
|
} |
2322 |
|
#endif |
2323 |
|
|
2324 |
|
@(static defun socket (port &key host server async myaddr myport daemon) |
2325 |
/* |
/* |
2326 |
HOST is a string then connection is made to that |
HOST is a string then connection is made to that |
2327 |
ip or domain address. |
ip or domain address. |
2339 |
char buf1[500]; |
char buf1[500]; |
2340 |
char buf2[500]; |
char buf2[500]; |
2341 |
char *myaddrPtr=buf1,*hostPtr=buf2; |
char *myaddrPtr=buf1,*hostPtr=buf2; |
2342 |
|
object x; |
2343 |
@ |
@ |
2344 |
if (type_of(host) == t_string) { |
if (type_of(host) == t_string) { |
2345 |
hostPtr=lisp_copy_to_null_terminated(host,hostPtr,sizeof(buf1)); |
hostPtr=lisp_copy_to_null_terminated(host,hostPtr,sizeof(buf1)); |
2358 |
Iis_fixnum(port); |
Iis_fixnum(port); |
2359 |
inPort = (myport == Cnil ? 0 : fix(Iis_fixnum(myport))); |
inPort = (myport == Cnil ? 0 : fix(Iis_fixnum(myport))); |
2360 |
|
|
2361 |
fd = CreateSocket(fix(port),hostPtr,isServer,myaddrPtr,inPort,(async!=Cnil)); |
#ifdef BSD |
2362 |
|
if (isServer && daemon != Cnil) { |
2363 |
|
|
2364 |
{ object x; |
int pid,i; |
2365 |
x = make_two_way_stream |
struct rlimit r; |
2366 |
(make_socket_stream(fd,gcl_sm_input,server,host,port,async), |
struct sigaction sa; |
2367 |
make_socket_stream(fd,gcl_sm_output,server,host,port,async)); |
|
2368 |
@(return `x`); |
sa.sa_handler=SIG_IGN; |
2369 |
} |
sa.sa_flags=SA_NOCLDWAIT; |
2370 |
|
sigemptyset(&sa.sa_mask); |
2371 |
|
|
2372 |
|
sigaction(SIGCHLD,&sa,NULL); |
2373 |
|
|
2374 |
|
switch((pid=fork())) { |
2375 |
|
case -1: |
2376 |
|
FEerror("Cannot fork", 0); |
2377 |
|
break; |
2378 |
|
case 0: |
2379 |
|
|
2380 |
|
if (setsid()<0) |
2381 |
|
FEerror("setsid error", 0); |
2382 |
|
|
2383 |
|
if (daemon == sKpersistent) |
2384 |
|
switch(fork()) { |
2385 |
|
case -1: |
2386 |
|
FEerror("daemon fork error", 0); |
2387 |
|
break; |
2388 |
|
case 0: |
2389 |
|
break; |
2390 |
|
default: |
2391 |
|
exit(0); |
2392 |
|
break; |
2393 |
|
} |
2394 |
|
|
2395 |
|
memset(&r,0,sizeof(r)); |
2396 |
|
if (getrlimit(RLIMIT_NOFILE,&r)) |
2397 |
|
FEerror("Cannot get resourse usage",0); |
2398 |
|
|
2399 |
|
for (i=0;i<r.rlim_cur;i++) |
2400 |
|
close(i); |
2401 |
|
errno=0; |
2402 |
|
|
2403 |
|
if ((i=open("/dev/null",O_RDWR))==-1) |
2404 |
|
FEerror("Can't open /dev/null for stdin",0); |
2405 |
|
if ((i=dup(i))==-1) |
2406 |
|
FEerror("Can't dup",0); |
2407 |
|
if ((i=dup(i))==-1) |
2408 |
|
FEerror("Can't dup twice",0); |
2409 |
|
|
2410 |
|
if (chdir("/")) |
2411 |
|
FEerror("Cannot chdir to /",0); |
2412 |
|
|
2413 |
|
umask(0); |
2414 |
|
|
2415 |
|
fd = CreateSocket(fix(port),hostPtr,isServer,myaddrPtr,inPort,(async!=Cnil)); |
2416 |
|
|
2417 |
|
x = make_two_way_stream |
2418 |
|
(make_socket_stream(fd,gcl_sm_input,server,host,port,async), |
2419 |
|
make_socket_stream(fd,gcl_sm_output,server,host,port,async)); |
2420 |
|
|
2421 |
|
for (;;) { |
2422 |
|
|
2423 |
|
fd_set fds; |
2424 |
|
object y; |
2425 |
|
|
2426 |
|
FD_ZERO(&fds); |
2427 |
|
FD_SET(fd,&fds); |
2428 |
|
i=select(fd+1,&fds,NULL,NULL,NULL); |
2429 |
|
|
2430 |
|
if (i>0) { |
2431 |
|
|
2432 |
|
y=maccept(x); |
2433 |
|
|
2434 |
|
sigaction(SIGCHLD,&sa,NULL); |
2435 |
|
|
2436 |
|
switch((pid=fork())) { |
2437 |
|
case 0: |
2438 |
|
ifuncall1(server,y); |
2439 |
|
exit(0); |
2440 |
|
break; |
2441 |
|
case -1: |
2442 |
|
abort(); |
2443 |
|
break; |
2444 |
|
default: |
2445 |
|
close_stream(y); |
2446 |
|
break; |
2447 |
|
} |
2448 |
|
|
2449 |
|
} |
2450 |
|
} |
2451 |
|
break; |
2452 |
|
default: |
2453 |
|
if (daemon != sKpersistent) { |
2454 |
|
on_exit(rmc,(void *)pid); |
2455 |
|
x=make_fixnum(pid); |
2456 |
|
} else |
2457 |
|
x=Cnil; |
2458 |
|
break; |
2459 |
|
} |
2460 |
|
|
2461 |
|
} else |
2462 |
|
|
2463 |
|
#endif |
2464 |
|
|
2465 |
|
{ |
2466 |
|
fd = CreateSocket(fix(port),hostPtr,isServer,myaddrPtr,inPort,(async!=Cnil)); |
2467 |
|
|
2468 |
|
x = make_two_way_stream |
2469 |
|
(make_socket_stream(fd,gcl_sm_input,server,host,port,async), |
2470 |
|
make_socket_stream(fd,gcl_sm_output,server,host,port,async)); |
2471 |
|
|
2472 |
|
} |
2473 |
|
|
2474 |
|
@(return `x`); |
2475 |
|
|
2476 |
@) |
@) |
2477 |
|
|
2480 |
DEF_ORDINARY("ASYNC",sKasync,KEYWORD,""); |
DEF_ORDINARY("ASYNC",sKasync,KEYWORD,""); |
2481 |
DEF_ORDINARY("HOST",sKhost,KEYWORD,""); |
DEF_ORDINARY("HOST",sKhost,KEYWORD,""); |
2482 |
DEF_ORDINARY("SERVER",sKserver,KEYWORD,""); |
DEF_ORDINARY("SERVER",sKserver,KEYWORD,""); |
2483 |
|
DEF_ORDINARY("DAEMON",sKdaemon,KEYWORD,""); |
2484 |
|
DEF_ORDINARY("PERSISTENT",sKpersistent,KEYWORD,""); |
2485 |
DEF_ORDINARY("SOCKET",sSsocket,SI,""); |
DEF_ORDINARY("SOCKET",sSsocket,SI,""); |
2486 |
|
|
2487 |
|
|
2488 |
@(static defun accept (x) |
@(static defun accept (x) |
|
int fd,n; |
|
|
struct sockaddr_in addr; |
|
|
object server,host,port; |
|
2489 |
@ |
@ |
2490 |
if (type_of(x) != t_stream) |
x=maccept(x); |
|
FEerror("~S is not a steam~%",1,x); |
|
|
if (x->sm.sm_mode!=smm_two_way) |
|
|
FEerror("~S is not a two-way steam~%",1,x); |
|
|
fd=accept(SOCKET_STREAM_FD(STREAM_INPUT_STREAM(x)),(struct sockaddr *)&addr, &n); |
|
|
if (fd <0) { |
|
|
FEerror("Error ~S on accepting connection to ~S~%",1,make_simple_string(strerror(errno)),x); |
|
|
x=Cnil; |
|
|
} else { |
|
|
server=STREAM_INPUT_STREAM(x)->sm.sm_object0->c.c_car; |
|
|
host=STREAM_INPUT_STREAM(x)->sm.sm_object0->c.c_cdr->c.c_car; |
|
|
port=STREAM_INPUT_STREAM(x)->sm.sm_object0->c.c_cdr->c.c_cdr->c.c_car; |
|
|
x = make_two_way_stream |
|
|
(make_socket_stream(fd,gcl_sm_input,server,host,port,Cnil), |
|
|
make_socket_stream(fd,gcl_sm_output,server,host,port,Cnil)); |
|
|
} |
|
2491 |
@(return `x`); |
@(return `x`); |
|
|
|
|
|
|
2492 |
@) |
@) |
2493 |
|
|
2494 |
#endif /* HAVE_NSOCKET */ |
#endif /* HAVE_NSOCKET */ |