Mercurial > emacs
comparison src/process.c @ 52516:0ca23eb697b9
(Fset_process_sentinel): Add sentinel to childp plist
for network process.
(socket_options): Add `:' prefix to option names. Add optbit field.
(set_socket_option): Remove no_error arg and special handling of s < 0.
Return 1<<optbit for known option, 0 for unknown.
Do not interpret 0 as false for boolean option (only nil).
Pass failed option and value to report_file_error.
(Fset_network_process_options): Replaced by Fset_network_process_option.
(Fset_network_process_option): New function to set just one option.
(Fmake_network_process): Allow :coding arg to be a cons.
Allow :server arg to be an integer specifying backlog size.
Remove :options arg, and allow options to be specified directly
as :KEY, VALUE pairs. Parse these options before binding socket.
As before, :reuseaddr t is default for a server process, but this
can now be disabled by specifying :reuseaddr nil.
(Fnetwork_interface_info): Rename from Fget_network_interface_info.
(init_process): Availability of network options is now checked with
simpler syntax (featurep 'make-network-process :OPTION); use loop to
setup features.
(syms_of_process): Fix defsubr's for the replaced functions.
| author | Kim F. Storm <storm@cua.dk> |
|---|---|
| date | Tue, 16 Sep 2003 23:05:24 +0000 |
| parents | 256a27a47af1 |
| children | fd2be6cea0e7 |
comparison
equal
deleted
inserted
replaced
| 52515:14b2402877fc | 52516:0ca23eb697b9 |
|---|---|
| 963 The sentinel is called as a function when the process changes state. | 963 The sentinel is called as a function when the process changes state. |
| 964 It gets two arguments: the process, and a string describing the change. */) | 964 It gets two arguments: the process, and a string describing the change. */) |
| 965 (process, sentinel) | 965 (process, sentinel) |
| 966 register Lisp_Object process, sentinel; | 966 register Lisp_Object process, sentinel; |
| 967 { | 967 { |
| 968 struct Lisp_Process *p; | |
| 969 | |
| 968 CHECK_PROCESS (process); | 970 CHECK_PROCESS (process); |
| 969 XPROCESS (process)->sentinel = sentinel; | 971 p = XPROCESS (process); |
| 972 | |
| 973 p->sentinel = sentinel; | |
| 974 if (NETCONN1_P (p)) | |
| 975 p->childp = Fplist_put (p->childp, QCsentinel, sentinel); | |
| 970 return sentinel; | 976 return sentinel; |
| 971 } | 977 } |
| 972 | 978 |
| 973 DEFUN ("process-sentinel", Fprocess_sentinel, Sprocess_sentinel, | 979 DEFUN ("process-sentinel", Fprocess_sentinel, Sprocess_sentinel, |
| 974 1, 1, 0, | 980 1, 1, 0, |
| 2306 | 2312 |
| 2307 static struct socket_options { | 2313 static struct socket_options { |
| 2308 /* The name of this option. Should be lowercase version of option | 2314 /* The name of this option. Should be lowercase version of option |
| 2309 name without SO_ prefix. */ | 2315 name without SO_ prefix. */ |
| 2310 char *name; | 2316 char *name; |
| 2311 /* Length of name. */ | |
| 2312 int nlen; | |
| 2313 /* Option level SOL_... */ | 2317 /* Option level SOL_... */ |
| 2314 int optlevel; | 2318 int optlevel; |
| 2315 /* Option number SO_... */ | 2319 /* Option number SO_... */ |
| 2316 int optnum; | 2320 int optnum; |
| 2317 enum { SOPT_UNKNOWN, SOPT_BOOL, SOPT_INT, SOPT_STR, SOPT_LINGER } opttype; | 2321 enum { SOPT_UNKNOWN, SOPT_BOOL, SOPT_INT, SOPT_STR, SOPT_LINGER } opttype; |
| 2322 enum { OPIX_NONE=0, OPIX_MISC=1, OPIX_REUSEADDR=2 } optbit; | |
| 2318 } socket_options[] = | 2323 } socket_options[] = |
| 2319 { | 2324 { |
| 2320 #ifdef SO_BINDTODEVICE | 2325 #ifdef SO_BINDTODEVICE |
| 2321 { "bindtodevice", 12, SOL_SOCKET, SO_BINDTODEVICE, SOPT_STR }, | 2326 { ":bindtodevice", SOL_SOCKET, SO_BINDTODEVICE, SOPT_STR, OPIX_MISC }, |
| 2322 #endif | 2327 #endif |
| 2323 #ifdef SO_BROADCAST | 2328 #ifdef SO_BROADCAST |
| 2324 { "broadcast", 9, SOL_SOCKET, SO_BROADCAST, SOPT_BOOL }, | 2329 { ":broadcast", SOL_SOCKET, SO_BROADCAST, SOPT_BOOL, OPIX_MISC }, |
| 2325 #endif | 2330 #endif |
| 2326 #ifdef SO_DONTROUTE | 2331 #ifdef SO_DONTROUTE |
| 2327 { "dontroute", 9, SOL_SOCKET, SO_DONTROUTE, SOPT_BOOL }, | 2332 { ":dontroute", SOL_SOCKET, SO_DONTROUTE, SOPT_BOOL, OPIX_MISC }, |
| 2328 #endif | 2333 #endif |
| 2329 #ifdef SO_KEEPALIVE | 2334 #ifdef SO_KEEPALIVE |
| 2330 { "keepalive", 9, SOL_SOCKET, SO_KEEPALIVE, SOPT_BOOL }, | 2335 { ":keepalive", SOL_SOCKET, SO_KEEPALIVE, SOPT_BOOL, OPIX_MISC }, |
| 2331 #endif | 2336 #endif |
| 2332 #ifdef SO_LINGER | 2337 #ifdef SO_LINGER |
| 2333 { "linger", 6, SOL_SOCKET, SO_LINGER, SOPT_LINGER }, | 2338 { ":linger", SOL_SOCKET, SO_LINGER, SOPT_LINGER, OPIX_MISC }, |
| 2334 #endif | 2339 #endif |
| 2335 #ifdef SO_OOBINLINE | 2340 #ifdef SO_OOBINLINE |
| 2336 { "oobinline", 9, SOL_SOCKET, SO_OOBINLINE, SOPT_BOOL }, | 2341 { ":oobinline", SOL_SOCKET, SO_OOBINLINE, SOPT_BOOL, OPIX_MISC }, |
| 2337 #endif | 2342 #endif |
| 2338 #ifdef SO_PRIORITY | 2343 #ifdef SO_PRIORITY |
| 2339 { "priority", 8, SOL_SOCKET, SO_PRIORITY, SOPT_INT }, | 2344 { ":priority", SOL_SOCKET, SO_PRIORITY, SOPT_INT, OPIX_MISC }, |
| 2340 #endif | 2345 #endif |
| 2341 #ifdef SO_REUSEADDR | 2346 #ifdef SO_REUSEADDR |
| 2342 { "reuseaddr", 9, SOL_SOCKET, SO_REUSEADDR, SOPT_BOOL }, | 2347 { ":reuseaddr", SOL_SOCKET, SO_REUSEADDR, SOPT_BOOL, OPIX_REUSEADDR }, |
| 2343 #endif | 2348 #endif |
| 2344 { 0, 0, 0, 0, SOPT_UNKNOWN } | 2349 { 0, 0, 0, SOPT_UNKNOWN, OPIX_NONE } |
| 2345 }; | 2350 }; |
| 2346 | 2351 |
| 2347 /* Process list of socket options OPTS on socket S. | 2352 /* Set option OPT to value VAL on socket S. |
| 2348 Only check if options are supported is S < 0. | 2353 |
| 2349 If NO_ERROR is non-zero, continue silently if an option | 2354 Returns (1<<socket_options[OPT].optbit) if option is known, 0 otherwise. |
| 2350 cannot be set. | 2355 Signals an error if setting a known option fails. |
| 2351 | 2356 */ |
| 2352 Each element specifies one option. An element is either a string | |
| 2353 "OPTION=VALUE" or a cons (OPTION . VALUE) where OPTION is a string | |
| 2354 or a symbol. */ | |
| 2355 | 2357 |
| 2356 static int | 2358 static int |
| 2357 set_socket_options (s, opts, no_error) | 2359 set_socket_option (s, opt, val) |
| 2358 int s; | 2360 int s; |
| 2359 Lisp_Object opts; | 2361 Lisp_Object opt, val; |
| 2360 int no_error; | 2362 { |
| 2361 { | 2363 char *name; |
| 2362 if (!CONSP (opts)) | 2364 struct socket_options *sopt; |
| 2363 opts = Fcons (opts, Qnil); | 2365 int ret = 0; |
| 2364 | 2366 |
| 2365 while (CONSP (opts)) | 2367 CHECK_SYMBOL (opt); |
| 2366 { | 2368 |
| 2367 Lisp_Object opt; | 2369 name = (char *) SDATA (SYMBOL_NAME (opt)); |
| 2368 Lisp_Object val; | 2370 for (sopt = socket_options; sopt->name; sopt++) |
| 2369 char *name, *arg; | 2371 if (strcmp (name, sopt->name) == 0) |
| 2370 struct socket_options *sopt; | 2372 break; |
| 2371 int ret = 0; | 2373 |
| 2372 | 2374 switch (sopt->opttype) |
| 2373 opt = XCAR (opts); | 2375 { |
| 2374 opts = XCDR (opts); | 2376 case SOPT_BOOL: |
| 2375 | 2377 { |
| 2376 name = 0; | 2378 int optval; |
| 2377 val = Qt; | 2379 optval = NILP (val) ? 0 : 1; |
| 2378 if (CONSP (opt)) | 2380 ret = setsockopt (s, sopt->optlevel, sopt->optnum, |
| 2379 { | 2381 &optval, sizeof (optval)); |
| 2380 val = XCDR (opt); | 2382 break; |
| 2381 opt = XCAR (opt); | |
| 2382 } | |
| 2383 if (STRINGP (opt)) | |
| 2384 name = (char *) SDATA (opt); | |
| 2385 else if (SYMBOLP (opt)) | |
| 2386 name = (char *) SDATA (SYMBOL_NAME (opt)); | |
| 2387 else { | |
| 2388 error ("Mal-formed option list"); | |
| 2389 return 0; | |
| 2390 } | 2383 } |
| 2391 | 2384 |
| 2392 if (strncmp (name, "no", 2) == 0) | 2385 case SOPT_INT: |
| 2393 { | 2386 { |
| 2394 val = Qnil; | 2387 int optval; |
| 2395 name += 2; | 2388 if (INTEGERP (val)) |
| 2396 } | 2389 optval = XINT (val); |
| 2397 | 2390 else |
| 2398 arg = 0; | 2391 error ("Bad option value for %s", name); |
| 2399 for (sopt = socket_options; sopt->name; sopt++) | 2392 ret = setsockopt (s, sopt->optlevel, sopt->optnum, |
| 2400 if (strncmp (name, sopt->name, sopt->nlen) == 0) | 2393 &optval, sizeof (optval)); |
| 2401 { | 2394 break; |
| 2402 if (name[sopt->nlen] == 0) | 2395 } |
| 2403 break; | 2396 |
| 2404 if (name[sopt->nlen] == '=') | 2397 case SOPT_STR: |
| 2405 { | 2398 { |
| 2406 arg = name + sopt->nlen + 1; | 2399 char *arg; |
| 2407 break; | 2400 |
| 2408 } | 2401 if (NILP (val)) |
| 2409 } | 2402 arg = ""; |
| 2410 | 2403 else if (STRINGP (val)) |
| 2411 switch (sopt->opttype) | 2404 arg = (char *) SDATA (val); |
| 2412 { | 2405 else if (XSYMBOL (val)) |
| 2413 case SOPT_BOOL: | 2406 arg = (char *) SDATA (SYMBOL_NAME (val)); |
| 2414 { | 2407 else |
| 2415 int optval; | 2408 error ("Bad option value for %s", name); |
| 2416 if (s < 0) | 2409 ret = setsockopt (s, sopt->optlevel, sopt->optnum, |
| 2417 return 1; | 2410 arg, strlen (arg)); |
| 2418 if (arg) | 2411 } |
| 2419 optval = (*arg == '0' || *arg == 'n') ? 0 : 1; | |
| 2420 else if (INTEGERP (val)) | |
| 2421 optval = XINT (val) == 0 ? 0 : 1; | |
| 2422 else | |
| 2423 optval = NILP (val) ? 0 : 1; | |
| 2424 ret = setsockopt (s, sopt->optlevel, sopt->optnum, | |
| 2425 &optval, sizeof (optval)); | |
| 2426 break; | |
| 2427 } | |
| 2428 | |
| 2429 case SOPT_INT: | |
| 2430 { | |
| 2431 int optval; | |
| 2432 if (arg) | |
| 2433 optval = atoi(arg); | |
| 2434 else if (INTEGERP (val)) | |
| 2435 optval = XINT (val); | |
| 2436 else | |
| 2437 error ("Bad option argument for %s", name); | |
| 2438 if (s < 0) | |
| 2439 return 1; | |
| 2440 ret = setsockopt (s, sopt->optlevel, sopt->optnum, | |
| 2441 &optval, sizeof (optval)); | |
| 2442 break; | |
| 2443 } | |
| 2444 | |
| 2445 case SOPT_STR: | |
| 2446 { | |
| 2447 if (!arg) | |
| 2448 { | |
| 2449 if (NILP (val)) | |
| 2450 arg = ""; | |
| 2451 else if (STRINGP (val)) | |
| 2452 arg = (char *) SDATA (val); | |
| 2453 else if (XSYMBOL (val)) | |
| 2454 arg = (char *) SDATA (SYMBOL_NAME (val)); | |
| 2455 else | |
| 2456 error ("Invalid argument to %s option", name); | |
| 2457 } | |
| 2458 ret = setsockopt (s, sopt->optlevel, sopt->optnum, | |
| 2459 arg, strlen (arg)); | |
| 2460 } | |
| 2461 | 2412 |
| 2462 #ifdef SO_LINGER | 2413 #ifdef SO_LINGER |
| 2463 case SOPT_LINGER: | 2414 case SOPT_LINGER: |
| 2464 { | 2415 { |
| 2465 struct linger linger; | 2416 struct linger linger; |
| 2466 | 2417 |
| 2467 linger.l_onoff = 1; | 2418 linger.l_onoff = 1; |
| 2468 linger.l_linger = 0; | 2419 linger.l_linger = 0; |
| 2469 | 2420 if (INTEGERP (val)) |
| 2470 if (s < 0) | 2421 linger.l_linger = XINT (val); |
| 2471 return 1; | 2422 else |
| 2472 | 2423 linger.l_onoff = NILP (val) ? 0 : 1; |
| 2473 if (arg) | 2424 ret = setsockopt (s, sopt->optlevel, sopt->optnum, |
| 2474 { | 2425 &linger, sizeof (linger)); |
| 2475 if (*arg == 'n' || *arg == 't' || *arg == 'y') | 2426 break; |
| 2476 linger.l_onoff = (*arg == 'n') ? 0 : 1; | 2427 } |
| 2477 else | 2428 #endif |
| 2478 linger.l_linger = atoi(arg); | 2429 |
| 2479 } | 2430 default: |
| 2480 else if (INTEGERP (val)) | 2431 return 0; |
| 2481 linger.l_linger = XINT (val); | 2432 } |
| 2482 else | 2433 |
| 2483 linger.l_onoff = NILP (val) ? 0 : 1; | 2434 if (ret < 0) |
| 2484 ret = setsockopt (s, sopt->optlevel, sopt->optnum, | 2435 report_file_error ("Cannot set network option", |
| 2485 &linger, sizeof (linger)); | 2436 Fcons (opt, Fcons (val, Qnil))); |
| 2486 break; | 2437 return (1 << sopt->optbit); |
| 2487 } | 2438 } |
| 2488 #endif | 2439 |
| 2489 default: | 2440 |
| 2490 if (s < 0) | 2441 DEFUN ("set-network-process-option", |
| 2491 return 0; | 2442 Fset_network_process_option, Sset_network_process_option, |
| 2492 if (no_error) | 2443 3, 4, 0, |
| 2493 continue; | 2444 doc: /* For network process PROCESS set option OPTION to value VALUE. |
| 2494 error ("Unsupported option: %s", name); | 2445 See `make-network-process' for a list of options and values. |
| 2495 } | 2446 If optional fourth arg NO-ERROR is non-nil, don't signal an error if |
| 2496 if (ret < 0 && ! no_error) | 2447 OPTION is not a supported option, return nil instead; otherwise return t. */) |
| 2497 report_file_error ("Cannot set network option: %s", opt); | 2448 (process, option, value, no_error) |
| 2498 } | 2449 Lisp_Object process, option, value; |
| 2499 return 1; | 2450 Lisp_Object no_error; |
| 2500 } | 2451 { |
| 2501 | 2452 int s, i; |
| 2502 DEFUN ("set-network-process-options", | 2453 |
| 2503 Fset_network_process_options, Sset_network_process_options, | |
| 2504 1, MANY, 0, | |
| 2505 doc: /* Set one or more options for network process PROCESS. | |
| 2506 Each option is either a string "OPT=VALUE" or a cons (OPT . VALUE). | |
| 2507 A boolean value is false if it either zero or nil, true otherwise. | |
| 2508 | |
| 2509 The following options are known. Consult the relevant system manual | |
| 2510 pages for more information. | |
| 2511 | |
| 2512 bindtodevice=NAME -- bind to interface NAME, or remove binding if nil. | |
| 2513 broadcast=BOOL -- Allow send and receive of datagram broadcasts. | |
| 2514 dontroute=BOOL -- Only send to directly connected hosts. | |
| 2515 keepalive=BOOL -- Send keep-alive messages on network stream. | |
| 2516 linger=BOOL or TIMEOUT -- Send queued messages before closing. | |
| 2517 oobinline=BOOL -- Place out-of-band data in receive data stream. | |
| 2518 priority=INT -- Set protocol defined priority for sent packets. | |
| 2519 reuseaddr=BOOL -- Allow reusing a recently used address. | |
| 2520 | |
| 2521 usage: (set-network-process-options PROCESS &rest OPTIONS) */) | |
| 2522 (nargs, args) | |
| 2523 int nargs; | |
| 2524 Lisp_Object *args; | |
| 2525 { | |
| 2526 Lisp_Object process; | |
| 2527 Lisp_Object opts; | |
| 2528 | |
| 2529 process = args[0]; | |
| 2530 CHECK_PROCESS (process); | 2454 CHECK_PROCESS (process); |
| 2531 if (nargs > 1 && XINT (XPROCESS (process)->infd) >= 0) | 2455 |
| 2532 { | 2456 s = XINT (XPROCESS (process)->infd); |
| 2533 opts = Flist (nargs, args); | 2457 if (s < 0) |
| 2534 set_socket_options (XINT (XPROCESS (process)->infd), opts, 0); | 2458 error ("Process is not running"); |
| 2535 } | 2459 |
| 2536 return process; | 2460 if (set_socket_option (s, option, value)) |
| 2537 } | 2461 return Qt; |
| 2462 | |
| 2463 if (NILP (no_error)) | |
| 2464 error ("Unknown or unsupported option"); | |
| 2465 | |
| 2466 return Qnil; | |
| 2467 } | |
| 2468 | |
| 2538 | 2469 |
| 2539 /* A version of request_sigio suitable for a record_unwind_protect. */ | 2470 /* A version of request_sigio suitable for a record_unwind_protect. */ |
| 2540 | 2471 |
| 2541 Lisp_Object | 2472 Lisp_Object |
| 2542 unwind_request_sigio (dummy) | 2473 unwind_request_sigio (dummy) |
| 2612 where F is the family number and AV is a vector containing the socket | 2543 where F is the family number and AV is a vector containing the socket |
| 2613 address data with one element per address data byte. Do not rely on | 2544 address data with one element per address data byte. Do not rely on |
| 2614 this format in portable code, as it may depend on implementation | 2545 this format in portable code, as it may depend on implementation |
| 2615 defined constants, data sizes, and data structure alignment. | 2546 defined constants, data sizes, and data structure alignment. |
| 2616 | 2547 |
| 2617 :coding CODING -- CODING is coding system for this process. | 2548 :coding CODING -- If CODING is a symbol, it specifies the coding |
| 2618 | 2549 system used for both reading and writing for this process. If CODING |
| 2619 :options OPTIONS -- Set the specified options for the network process. | 2550 is a cons (DECODING . ENCODING), DECODING is used for reading, and |
| 2620 See `set-network-process-options' for details. | 2551 ENCODING is used for writing. |
| 2621 | 2552 |
| 2622 :nowait BOOL -- If BOOL is non-nil for a stream type client process, | 2553 :nowait BOOL -- If BOOL is non-nil for a stream type client process, |
| 2623 return without waiting for the connection to complete; instead, the | 2554 return without waiting for the connection to complete; instead, the |
| 2624 sentinel function will be called with second arg matching "open" (if | 2555 sentinel function will be called with second arg matching "open" (if |
| 2625 successful) or "failed" when the connect completes. Default is to use | 2556 successful) or "failed" when the connect completes. Default is to use |
| 2649 is the server process, CLIENT is the new process for the connection, | 2580 is the server process, CLIENT is the new process for the connection, |
| 2650 and MESSAGE is a string. | 2581 and MESSAGE is a string. |
| 2651 | 2582 |
| 2652 :plist PLIST -- Install PLIST as the new process' initial plist. | 2583 :plist PLIST -- Install PLIST as the new process' initial plist. |
| 2653 | 2584 |
| 2654 :server BOOL -- if BOOL is non-nil, create a server process for the | 2585 :server QLEN -- if QLEN is non-nil, create a server process for the |
| 2655 specified FAMILY, SERVICE, and connection type (stream or datagram). | 2586 specified FAMILY, SERVICE, and connection type (stream or datagram). |
| 2656 Default is a client process. | 2587 If QLEN is an integer, it is used as the max. length of the server's |
| 2657 | 2588 pending connection queue (also known as the backlog); the default |
| 2658 A server process will listen for and accept connections from | 2589 queue length is 5. Default is to create a client process. |
| 2659 clients. When a client connection is accepted, a new network process | 2590 |
| 2660 is created for the connection with the following parameters: | 2591 The following network options can be specified for this connection: |
| 2592 | |
| 2593 :bindtodevice NAME -- bind to interface NAME. | |
| 2594 :broadcast BOOL -- Allow send and receive of datagram broadcasts. | |
| 2595 :dontroute BOOL -- Only send to directly connected hosts. | |
| 2596 :keepalive BOOL -- Send keep-alive messages on network stream. | |
| 2597 :linger BOOL or TIMEOUT -- Send queued messages before closing. | |
| 2598 :oobinline BOOL -- Place out-of-band data in receive data stream. | |
| 2599 :priority INT -- Set protocol defined priority for sent packets. | |
| 2600 :reuseaddr BOOL -- Allow reusing a recently used local address | |
| 2601 (this is allowed by default for a server process). | |
| 2602 | |
| 2603 Consult the relevant system programmer's manual pages for more | |
| 2604 information on using these options. | |
| 2605 | |
| 2606 | |
| 2607 A server process will listen for and accept connections from clients. | |
| 2608 When a client connection is accepted, a new network process is created | |
| 2609 for the connection with the following parameters: | |
| 2610 | |
| 2661 - The client's process name is constructed by concatenating the server | 2611 - The client's process name is constructed by concatenating the server |
| 2662 process' NAME and a client identification string. | 2612 process' NAME and a client identification string. |
| 2663 - If the FILTER argument is non-nil, the client process will not get a | 2613 - If the FILTER argument is non-nil, the client process will not get a |
| 2664 separate process buffer; otherwise, the client's process buffer is a newly | 2614 separate process buffer; otherwise, the client's process buffer is a newly |
| 2665 created buffer named after the server process' BUFFER name or process | 2615 created buffer named after the server process' BUFFER name or process |
| 2716 Lisp_Object QCaddress; /* one of QClocal or QCremote */ | 2666 Lisp_Object QCaddress; /* one of QClocal or QCremote */ |
| 2717 Lisp_Object tem; | 2667 Lisp_Object tem; |
| 2718 Lisp_Object name, buffer, host, service, address; | 2668 Lisp_Object name, buffer, host, service, address; |
| 2719 Lisp_Object filter, sentinel; | 2669 Lisp_Object filter, sentinel; |
| 2720 int is_non_blocking_client = 0; | 2670 int is_non_blocking_client = 0; |
| 2721 int is_server = 0; | 2671 int is_server = 0, backlog = 5; |
| 2722 int socktype; | 2672 int socktype; |
| 2723 int family = -1; | 2673 int family = -1; |
| 2724 | 2674 |
| 2725 if (nargs == 0) | 2675 if (nargs == 0) |
| 2726 return Qnil; | 2676 return Qnil; |
| 2753 not available, since a blocked Emacs is not useful. */ | 2703 not available, since a blocked Emacs is not useful. */ |
| 2754 #if defined(TERM) || (!defined(O_NONBLOCK) && !defined(O_NDELAY)) | 2704 #if defined(TERM) || (!defined(O_NONBLOCK) && !defined(O_NDELAY)) |
| 2755 error ("Network servers not supported"); | 2705 error ("Network servers not supported"); |
| 2756 #else | 2706 #else |
| 2757 is_server = 1; | 2707 is_server = 1; |
| 2708 if (INTEGERP (tem)) | |
| 2709 backlog = XINT (tem); | |
| 2758 #endif | 2710 #endif |
| 2759 } | 2711 } |
| 2760 | 2712 |
| 2761 /* Make QCaddress an alias for :local (server) or :remote (client). */ | 2713 /* Make QCaddress an alias for :local (server) or :remote (client). */ |
| 2762 QCaddress = is_server ? QClocal : QCremote; | 2714 QCaddress = is_server ? QClocal : QCremote; |
| 3005 count1 = SPECPDL_INDEX (); | 2957 count1 = SPECPDL_INDEX (); |
| 3006 s = -1; | 2958 s = -1; |
| 3007 | 2959 |
| 3008 for (lres = res; lres; lres = lres->ai_next) | 2960 for (lres = res; lres; lres = lres->ai_next) |
| 3009 { | 2961 { |
| 2962 int optn, optbits; | |
| 2963 | |
| 3010 s = socket (lres->ai_family, lres->ai_socktype, lres->ai_protocol); | 2964 s = socket (lres->ai_family, lres->ai_socktype, lres->ai_protocol); |
| 3011 if (s < 0) | 2965 if (s < 0) |
| 3012 { | 2966 { |
| 3013 xerrno = errno; | 2967 xerrno = errno; |
| 3014 continue; | 2968 continue; |
| 3038 #endif | 2992 #endif |
| 3039 | 2993 |
| 3040 /* Make us close S if quit. */ | 2994 /* Make us close S if quit. */ |
| 3041 record_unwind_protect (close_file_unwind, make_number (s)); | 2995 record_unwind_protect (close_file_unwind, make_number (s)); |
| 3042 | 2996 |
| 2997 /* Parse network options in the arg list. | |
| 2998 We simply ignore anything which isn't a known option (including other keywords). | |
| 2999 An error is signalled if setting a known option fails. */ | |
| 3000 for (optn = optbits = 0; optn < nargs-1; optn += 2) | |
| 3001 optbits |= set_socket_option (s, args[optn], args[optn+1]); | |
| 3002 | |
| 3043 if (is_server) | 3003 if (is_server) |
| 3044 { | 3004 { |
| 3045 /* Configure as a server socket. */ | 3005 /* Configure as a server socket. */ |
| 3006 | |
| 3007 /* SO_REUSEADDR = 1 is default for server sockets; must specify | |
| 3008 explicit :reuseaddr key to override this. */ | |
| 3046 #ifdef HAVE_LOCAL_SOCKETS | 3009 #ifdef HAVE_LOCAL_SOCKETS |
| 3047 if (family != AF_LOCAL) | 3010 if (family != AF_LOCAL) |
| 3048 #endif | 3011 #endif |
| 3049 { | 3012 if (!(optbits & (1 << OPIX_REUSEADDR))) |
| 3050 int optval = 1; | 3013 { |
| 3051 if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval)) | 3014 int optval = 1; |
| 3052 report_file_error ("Cannot set reuse option on server socket.", Qnil); | 3015 if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval)) |
| 3053 } | 3016 report_file_error ("Cannot set reuse option on server socket.", Qnil); |
| 3017 } | |
| 3054 | 3018 |
| 3055 if (bind (s, lres->ai_addr, lres->ai_addrlen)) | 3019 if (bind (s, lres->ai_addr, lres->ai_addrlen)) |
| 3056 report_file_error ("Cannot bind server socket", Qnil); | 3020 report_file_error ("Cannot bind server socket", Qnil); |
| 3057 | 3021 |
| 3058 #ifdef HAVE_GETSOCKNAME | 3022 #ifdef HAVE_GETSOCKNAME |
| 3067 contact = Fplist_put (contact, QCservice, service); | 3031 contact = Fplist_put (contact, QCservice, service); |
| 3068 } | 3032 } |
| 3069 } | 3033 } |
| 3070 #endif | 3034 #endif |
| 3071 | 3035 |
| 3072 if (socktype == SOCK_STREAM && listen (s, 5)) | 3036 if (socktype == SOCK_STREAM && listen (s, backlog)) |
| 3073 report_file_error ("Cannot listen on server socket", Qnil); | 3037 report_file_error ("Cannot listen on server socket", Qnil); |
| 3074 | 3038 |
| 3075 break; | 3039 break; |
| 3076 } | 3040 } |
| 3077 | 3041 |
| 3203 report_file_error ("make server process failed", contact); | 3167 report_file_error ("make server process failed", contact); |
| 3204 else | 3168 else |
| 3205 report_file_error ("make client process failed", contact); | 3169 report_file_error ("make client process failed", contact); |
| 3206 } | 3170 } |
| 3207 | 3171 |
| 3208 tem = Fplist_get (contact, QCoptions); | |
| 3209 if (!NILP (tem)) | |
| 3210 set_socket_options (s, tem, 1); | |
| 3211 | |
| 3212 #endif /* not TERM */ | 3172 #endif /* not TERM */ |
| 3213 | 3173 |
| 3214 inch = s; | 3174 inch = s; |
| 3215 outch = s; | 3175 outch = s; |
| 3216 | 3176 |
| 3288 /* Qt denotes we have not yet called Ffind_operation_coding_system. */ | 3248 /* Qt denotes we have not yet called Ffind_operation_coding_system. */ |
| 3289 Lisp_Object coding_systems = Qt; | 3249 Lisp_Object coding_systems = Qt; |
| 3290 Lisp_Object args[5], val; | 3250 Lisp_Object args[5], val; |
| 3291 | 3251 |
| 3292 if (!NILP (tem)) | 3252 if (!NILP (tem)) |
| 3293 val = XCAR (XCDR (tem)); | 3253 { |
| 3254 val = XCAR (XCDR (tem)); | |
| 3255 if (CONSP (val)) | |
| 3256 val = XCAR (val); | |
| 3257 } | |
| 3294 else if (!NILP (Vcoding_system_for_read)) | 3258 else if (!NILP (Vcoding_system_for_read)) |
| 3295 val = Vcoding_system_for_read; | 3259 val = Vcoding_system_for_read; |
| 3296 else if ((!NILP (buffer) && NILP (XBUFFER (buffer)->enable_multibyte_characters)) | 3260 else if ((!NILP (buffer) && NILP (XBUFFER (buffer)->enable_multibyte_characters)) |
| 3297 || (NILP (buffer) && NILP (buffer_defaults.enable_multibyte_characters))) | 3261 || (NILP (buffer) && NILP (buffer_defaults.enable_multibyte_characters))) |
| 3298 /* We dare not decode end-of-line format by setting VAL to | 3262 /* We dare not decode end-of-line format by setting VAL to |
| 3320 val = Qnil; | 3284 val = Qnil; |
| 3321 } | 3285 } |
| 3322 p->decode_coding_system = val; | 3286 p->decode_coding_system = val; |
| 3323 | 3287 |
| 3324 if (!NILP (tem)) | 3288 if (!NILP (tem)) |
| 3325 val = XCAR (XCDR (tem)); | 3289 { |
| 3290 val = XCAR (XCDR (tem)); | |
| 3291 if (CONSP (val)) | |
| 3292 val = XCDR (val); | |
| 3293 } | |
| 3326 else if (!NILP (Vcoding_system_for_write)) | 3294 else if (!NILP (Vcoding_system_for_write)) |
| 3327 val = Vcoding_system_for_write; | 3295 val = Vcoding_system_for_write; |
| 3328 else if (NILP (current_buffer->enable_multibyte_characters)) | 3296 else if (NILP (current_buffer->enable_multibyte_characters)) |
| 3329 val = Qnil; | 3297 val = Qnil; |
| 3330 else | 3298 else |
| 3488 { IFF_DYNAMIC, "dynamic" }, | 3456 { IFF_DYNAMIC, "dynamic" }, |
| 3489 #endif | 3457 #endif |
| 3490 { 0, 0 } | 3458 { 0, 0 } |
| 3491 }; | 3459 }; |
| 3492 | 3460 |
| 3493 DEFUN ("get-network-interface-info", Fget_network_interface_info, Sget_network_interface_info, 1, 1, 0, | 3461 DEFUN ("network-interface-info", Fnetwork_interface_info, Snetwork_interface_info, 1, 1, 0, |
| 3494 doc: /* Return information about network interface named IFNAME. | 3462 doc: /* Return information about network interface named IFNAME. |
| 3495 The return value is a list (ADDR BCAST NETMASK HWADDR FLAGS), | 3463 The return value is a list (ADDR BCAST NETMASK HWADDR FLAGS), |
| 3496 where ADDR is the layer 3 address, BCAST is the layer 3 broadcast address, | 3464 where ADDR is the layer 3 address, BCAST is the layer 3 broadcast address, |
| 3497 NETMASK is the layer 3 network mask, HWADDR is the layer 2 addres, and | 3465 NETMASK is the layer 3 network mask, HWADDR is the layer 2 addres, and |
| 3498 FLAGS is the current flags of the interface. */) | 3466 FLAGS is the current flags of the interface. */) |
| 6538 #endif | 6506 #endif |
| 6539 | 6507 |
| 6540 #ifdef HAVE_SOCKETS | 6508 #ifdef HAVE_SOCKETS |
| 6541 { | 6509 { |
| 6542 Lisp_Object subfeatures = Qnil; | 6510 Lisp_Object subfeatures = Qnil; |
| 6511 struct socket_options *sopt; | |
| 6512 | |
| 6543 #define ADD_SUBFEATURE(key, val) \ | 6513 #define ADD_SUBFEATURE(key, val) \ |
| 6544 subfeatures = Fcons (Fcons (key, Fcons (val, Qnil)), subfeatures) | 6514 subfeatures = Fcons (Fcons (key, Fcons (val, Qnil)), subfeatures) |
| 6545 | 6515 |
| 6546 #ifdef NON_BLOCKING_CONNECT | 6516 #ifdef NON_BLOCKING_CONNECT |
| 6547 ADD_SUBFEATURE (QCnowait, Qt); | 6517 ADD_SUBFEATURE (QCnowait, Qt); |
| 6556 ADD_SUBFEATURE (QCservice, Qt); | 6526 ADD_SUBFEATURE (QCservice, Qt); |
| 6557 #endif | 6527 #endif |
| 6558 #if !defined(TERM) && (defined(O_NONBLOCK) || defined(O_NDELAY)) | 6528 #if !defined(TERM) && (defined(O_NONBLOCK) || defined(O_NDELAY)) |
| 6559 ADD_SUBFEATURE (QCserver, Qt); | 6529 ADD_SUBFEATURE (QCserver, Qt); |
| 6560 #endif | 6530 #endif |
| 6561 #ifdef SO_BINDTODEVICE | 6531 |
| 6562 ADD_SUBFEATURE (QCoptions, intern ("bindtodevice")); | 6532 for (sopt = socket_options; sopt->name; sopt++) |
| 6563 #endif | 6533 subfeatures = Fcons (intern (sopt->name), subfeatures); |
| 6564 #ifdef SO_BROADCAST | 6534 |
| 6565 ADD_SUBFEATURE (QCoptions, intern ("broadcast")); | |
| 6566 #endif | |
| 6567 #ifdef SO_DONTROUTE | |
| 6568 ADD_SUBFEATURE (QCoptions, intern ("dontroute")); | |
| 6569 #endif | |
| 6570 #ifdef SO_KEEPALIVE | |
| 6571 ADD_SUBFEATURE (QCoptions, intern ("keepalive")); | |
| 6572 #endif | |
| 6573 #ifdef SO_LINGER | |
| 6574 ADD_SUBFEATURE (QCoptions, intern ("linger")); | |
| 6575 #endif | |
| 6576 #ifdef SO_OOBINLINE | |
| 6577 ADD_SUBFEATURE (QCoptions, intern ("oobinline")); | |
| 6578 #endif | |
| 6579 #ifdef SO_PRIORITY | |
| 6580 ADD_SUBFEATURE (QCoptions, intern ("priority")); | |
| 6581 #endif | |
| 6582 #ifdef SO_REUSEADDR | |
| 6583 ADD_SUBFEATURE (QCoptions, intern ("reuseaddr")); | |
| 6584 #endif | |
| 6585 Fprovide (intern ("make-network-process"), subfeatures); | 6535 Fprovide (intern ("make-network-process"), subfeatures); |
| 6586 } | 6536 } |
| 6587 #endif /* HAVE_SOCKETS */ | 6537 #endif /* HAVE_SOCKETS */ |
| 6588 } | 6538 } |
| 6589 | 6539 |
| 6701 defsubr (&Sset_process_plist); | 6651 defsubr (&Sset_process_plist); |
| 6702 defsubr (&Slist_processes); | 6652 defsubr (&Slist_processes); |
| 6703 defsubr (&Sprocess_list); | 6653 defsubr (&Sprocess_list); |
| 6704 defsubr (&Sstart_process); | 6654 defsubr (&Sstart_process); |
| 6705 #ifdef HAVE_SOCKETS | 6655 #ifdef HAVE_SOCKETS |
| 6706 defsubr (&Sset_network_process_options); | 6656 defsubr (&Sset_network_process_option); |
| 6707 defsubr (&Smake_network_process); | 6657 defsubr (&Smake_network_process); |
| 6708 defsubr (&Sformat_network_address); | 6658 defsubr (&Sformat_network_address); |
| 6709 #ifdef SIOCGIFCONF | 6659 #ifdef SIOCGIFCONF |
| 6710 defsubr (&Snetwork_interface_list); | 6660 defsubr (&Snetwork_interface_list); |
| 6711 #endif | 6661 #endif |
| 6712 #if defined(SIOCGIFADDR) || defined(SIOCGIFHWADDR) || defined(SIOCGIFFLAGS) | 6662 #if defined(SIOCGIFADDR) || defined(SIOCGIFHWADDR) || defined(SIOCGIFFLAGS) |
| 6713 defsubr (&Sget_network_interface_info); | 6663 defsubr (&Snetwork_interface_info); |
| 6714 #endif | 6664 #endif |
| 6715 #endif /* HAVE_SOCKETS */ | 6665 #endif /* HAVE_SOCKETS */ |
| 6716 #ifdef DATAGRAM_SOCKETS | 6666 #ifdef DATAGRAM_SOCKETS |
| 6717 defsubr (&Sprocess_datagram_address); | 6667 defsubr (&Sprocess_datagram_address); |
| 6718 defsubr (&Sset_process_datagram_address); | 6668 defsubr (&Sset_process_datagram_address); |
