Mercurial > hg > xemacs-beta
comparison src/process-unix.c @ 440:8de8e3f6228a r21-2-28
Import from CVS: tag r21-2-28
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:33:38 +0200 |
parents | 3ecd8885ac67 |
children | abe6d1db359e |
comparison
equal
deleted
inserted
replaced
439:357dd071b03c | 440:8de8e3f6228a |
---|---|
25 `open-network-stream-internal' and `open-multicast-group-internal'. */ | 25 `open-network-stream-internal' and `open-multicast-group-internal'. */ |
26 | 26 |
27 /* This file has been split into process.c and process-unix.c by | 27 /* This file has been split into process.c and process-unix.c by |
28 Kirill M. Katsnelson <kkm@kis.ru>, so please bash him and not | 28 Kirill M. Katsnelson <kkm@kis.ru>, so please bash him and not |
29 the original author(s) */ | 29 the original author(s) */ |
30 | |
31 /* The IPv6 support is derived from the code for GNU Emacs-20.3 | |
32 written by Wolfgang S. Rupprecht */ | |
30 | 33 |
31 #include <config.h> | 34 #include <config.h> |
32 | 35 |
33 #if !defined (NO_SUBPROCESSES) | 36 #if !defined (NO_SUBPROCESSES) |
34 | 37 |
308 } | 311 } |
309 | 312 |
310 | 313 |
311 #ifdef HAVE_SOCKETS | 314 #ifdef HAVE_SOCKETS |
312 | 315 |
316 #if !(defined(HAVE_GETADDRINFO) && defined(HAVE_GETNAMEINFO)) | |
313 static int | 317 static int |
314 get_internet_address (Lisp_Object host, struct sockaddr_in *address, | 318 get_internet_address (Lisp_Object host, struct sockaddr_in *address, |
315 Error_behavior errb) | 319 Error_behavior errb) |
316 { | 320 { |
317 struct hostent *host_info_ptr = NULL; | 321 struct hostent *host_info_ptr = NULL; |
363 * (IN_ADDR *) &address->sin_addr = numeric_addr; | 367 * (IN_ADDR *) &address->sin_addr = numeric_addr; |
364 } | 368 } |
365 | 369 |
366 return 1; | 370 return 1; |
367 } | 371 } |
372 #endif /* !(HAVE_GETADDRINFO && HAVE_GETNAMEINFO) */ | |
368 | 373 |
369 static void | 374 static void |
370 set_socket_nonblocking_maybe (int fd, int port, CONST char* proto) | 375 set_socket_nonblocking_maybe (int fd, int port, CONST char* proto) |
371 { | 376 { |
372 #ifdef PROCESS_IO_BLOCKING | 377 #ifdef PROCESS_IO_BLOCKING |
403 | 408 |
404 /* Compute the Lisp form of the process status from | 409 /* Compute the Lisp form of the process status from |
405 the numeric status that was returned by `wait'. */ | 410 the numeric status that was returned by `wait'. */ |
406 | 411 |
407 static void | 412 static void |
408 update_status_from_wait_code (struct Lisp_Process *p, int *w_fmh) | 413 update_status_from_wait_code (Lisp_Process *p, int *w_fmh) |
409 { | 414 { |
410 /* C compiler lossage when attempting to pass w directly */ | 415 /* C compiler lossage when attempting to pass w directly */ |
411 int w = *w_fmh; | 416 int w = *w_fmh; |
412 | 417 |
413 if (WIFSTOPPED (w)) | 418 if (WIFSTOPPED (w)) |
518 if (block_sigchld) | 523 if (block_sigchld) |
519 EMACS_UNBLOCK_SIGNAL (SIGCHLD); | 524 EMACS_UNBLOCK_SIGNAL (SIGCHLD); |
520 } | 525 } |
521 | 526 |
522 /* For any processes that have changed status and are recorded | 527 /* For any processes that have changed status and are recorded |
523 and such, update the corresponding struct Lisp_Process. | 528 and such, update the corresponding Lisp_Process. |
524 We separate this from record_exited_processes() so that | 529 We separate this from record_exited_processes() so that |
525 we never have to call this function from within a signal | 530 we never have to call this function from within a signal |
526 handler. We block SIGCHLD in case record_exited_processes() | 531 handler. We block SIGCHLD in case record_exited_processes() |
527 is called from a signal handler. */ | 532 is called from a signal handler. */ |
528 | 533 |
647 /* | 652 /* |
648 * Allocate and initialize Lisp_Process->process_data | 653 * Allocate and initialize Lisp_Process->process_data |
649 */ | 654 */ |
650 | 655 |
651 static void | 656 static void |
652 unix_alloc_process_data (struct Lisp_Process *p) | 657 unix_alloc_process_data (Lisp_Process *p) |
653 { | 658 { |
654 p->process_data = xnew (struct unix_process_data); | 659 p->process_data = xnew (struct unix_process_data); |
655 | 660 |
656 UNIX_DATA(p)->connected_via_filedesc_p = 0; | 661 UNIX_DATA(p)->connected_via_filedesc_p = 0; |
657 UNIX_DATA(p)->infd = -1; | 662 UNIX_DATA(p)->infd = -1; |
663 /* | 668 /* |
664 * Mark any Lisp objects in Lisp_Process->process_data | 669 * Mark any Lisp objects in Lisp_Process->process_data |
665 */ | 670 */ |
666 | 671 |
667 static void | 672 static void |
668 unix_mark_process_data (struct Lisp_Process *proc) | 673 unix_mark_process_data (Lisp_Process *proc) |
669 { | 674 { |
670 mark_object (UNIX_DATA(proc)->tty_name); | 675 mark_object (UNIX_DATA(proc)->tty_name); |
671 } | 676 } |
672 | 677 |
673 /* | 678 /* |
691 * handles are generally represented by void* type, but are | 696 * handles are generally represented by void* type, but are |
692 * of type int (file descriptors) for UNIX | 697 * of type int (file descriptors) for UNIX |
693 */ | 698 */ |
694 | 699 |
695 static void | 700 static void |
696 unix_init_process_io_handles (struct Lisp_Process *p, void* in, void* out, int flags) | 701 unix_init_process_io_handles (Lisp_Process *p, void* in, void* out, int flags) |
697 { | 702 { |
698 UNIX_DATA(p)->infd = (int)in; | 703 UNIX_DATA(p)->infd = (int)in; |
699 } | 704 } |
700 | 705 |
701 /* | 706 /* |
707 * which fits into Lisp_Int. No return value indicates an error, the method | 712 * which fits into Lisp_Int. No return value indicates an error, the method |
708 * must signal an error instead. | 713 * must signal an error instead. |
709 */ | 714 */ |
710 | 715 |
711 static int | 716 static int |
712 unix_create_process (struct Lisp_Process *p, | 717 unix_create_process (Lisp_Process *p, |
713 Lisp_Object *argv, int nargv, | 718 Lisp_Object *argv, int nargv, |
714 Lisp_Object program, Lisp_Object cur_dir) | 719 Lisp_Object program, Lisp_Object cur_dir) |
715 { | 720 { |
716 /* This function rewritten by ben@xemacs.org. */ | 721 /* This function rewritten by ben@xemacs.org. */ |
717 | 722 |
921 CHECK_STRING (argv[i]); | 926 CHECK_STRING (argv[i]); |
922 new_argv[i + 1] = (char *) XSTRING_DATA (argv[i]); | 927 new_argv[i + 1] = (char *) XSTRING_DATA (argv[i]); |
923 } | 928 } |
924 new_argv[i + 1] = 0; | 929 new_argv[i + 1] = 0; |
925 | 930 |
926 GET_C_STRING_FILENAME_DATA_ALLOCA (cur_dir, current_dir); | 931 TO_EXTERNAL_FORMAT (LISP_STRING, cur_dir, |
932 C_STRING_ALLOCA, current_dir, | |
933 Qfile_name); | |
927 | 934 |
928 child_setup (xforkin, xforkout, xforkout, new_argv, current_dir); | 935 child_setup (xforkin, xforkout, xforkout, new_argv, current_dir); |
929 } | 936 } |
930 | 937 |
931 } /**** End of child code ****/ | 938 } /**** End of child code ****/ |
980 } | 987 } |
981 | 988 |
982 /* Return nonzero if this process is a ToolTalk connection. */ | 989 /* Return nonzero if this process is a ToolTalk connection. */ |
983 | 990 |
984 static int | 991 static int |
985 unix_tooltalk_connection_p (struct Lisp_Process *p) | 992 unix_tooltalk_connection_p (Lisp_Process *p) |
986 { | 993 { |
987 return UNIX_DATA(p)->connected_via_filedesc_p; | 994 return UNIX_DATA(p)->connected_via_filedesc_p; |
988 } | 995 } |
989 | 996 |
990 /* This is called to set process' virtual terminal size */ | 997 /* This is called to set process' virtual terminal size */ |
991 | 998 |
992 static int | 999 static int |
993 unix_set_window_size (struct Lisp_Process* p, int cols, int rows) | 1000 unix_set_window_size (Lisp_Process* p, int cols, int rows) |
994 { | 1001 { |
995 return set_window_size (UNIX_DATA(p)->infd, cols, rows); | 1002 return set_window_size (UNIX_DATA(p)->infd, cols, rows); |
996 } | 1003 } |
997 | 1004 |
998 /* | 1005 /* |
1003 * The method is called only for real child processes. | 1010 * The method is called only for real child processes. |
1004 */ | 1011 */ |
1005 | 1012 |
1006 #ifdef HAVE_WAITPID | 1013 #ifdef HAVE_WAITPID |
1007 static void | 1014 static void |
1008 unix_update_status_if_terminated (struct Lisp_Process* p) | 1015 unix_update_status_if_terminated (Lisp_Process* p) |
1009 { | 1016 { |
1010 int w; | 1017 int w; |
1011 #ifdef SIGCHLD | 1018 #ifdef SIGCHLD |
1012 EMACS_BLOCK_SIGNAL (SIGCHLD); | 1019 EMACS_BLOCK_SIGNAL (SIGCHLD); |
1013 #endif | 1020 #endif |
1029 #ifdef SIGCHLD | 1036 #ifdef SIGCHLD |
1030 static void | 1037 static void |
1031 unix_reap_exited_processes (void) | 1038 unix_reap_exited_processes (void) |
1032 { | 1039 { |
1033 int i; | 1040 int i; |
1034 struct Lisp_Process *p; | 1041 Lisp_Process *p; |
1035 | 1042 |
1036 #ifndef OBNOXIOUS_SYSV_SIGCLD_BEHAVIOR | 1043 #ifndef OBNOXIOUS_SYSV_SIGCLD_BEHAVIOR |
1037 record_exited_processes (1); | 1044 record_exited_processes (1); |
1038 #endif | 1045 #endif |
1039 | 1046 |
1128 unix_send_process (Lisp_Object proc, struct lstream* lstream) | 1135 unix_send_process (Lisp_Object proc, struct lstream* lstream) |
1129 { | 1136 { |
1130 /* Use volatile to protect variables from being clobbered by longjmp. */ | 1137 /* Use volatile to protect variables from being clobbered by longjmp. */ |
1131 SIGTYPE (*volatile old_sigpipe) (int) = 0; | 1138 SIGTYPE (*volatile old_sigpipe) (int) = 0; |
1132 volatile Lisp_Object vol_proc = proc; | 1139 volatile Lisp_Object vol_proc = proc; |
1133 struct Lisp_Process *volatile p = XPROCESS (proc); | 1140 Lisp_Process *volatile p = XPROCESS (proc); |
1134 | 1141 |
1135 if (!SETJMP (send_process_frame)) | 1142 if (!SETJMP (send_process_frame)) |
1136 { | 1143 { |
1137 /* use a reasonable-sized buffer (somewhere around the size of the | 1144 /* use a reasonable-sized buffer (somewhere around the size of the |
1138 stream buffer) so as to avoid inundating the stream with blocked | 1145 stream buffer) so as to avoid inundating the stream with blocked |
1234 * | 1241 * |
1235 * The UNIX version guards this by ignoring possible SIGPIPE. | 1242 * The UNIX version guards this by ignoring possible SIGPIPE. |
1236 */ | 1243 */ |
1237 | 1244 |
1238 static USID | 1245 static USID |
1239 unix_deactivate_process (struct Lisp_Process *p) | 1246 unix_deactivate_process (Lisp_Process *p) |
1240 { | 1247 { |
1241 SIGTYPE (*old_sigpipe) (int) = 0; | 1248 SIGTYPE (*old_sigpipe) (int) = 0; |
1242 USID usid; | 1249 USID usid; |
1243 | 1250 |
1244 if (UNIX_DATA(p)->infd >= 0) | 1251 if (UNIX_DATA(p)->infd >= 0) |
1273 int current_group, int nomsg) | 1280 int current_group, int nomsg) |
1274 { | 1281 { |
1275 int gid; | 1282 int gid; |
1276 int no_pgrp = 0; | 1283 int no_pgrp = 0; |
1277 int kill_retval; | 1284 int kill_retval; |
1278 struct Lisp_Process *p = XPROCESS (proc); | 1285 Lisp_Process *p = XPROCESS (proc); |
1279 | 1286 |
1280 if (!UNIX_DATA(p)->pty_flag) | 1287 if (!UNIX_DATA(p)->pty_flag) |
1281 current_group = 0; | 1288 current_group = 0; |
1282 | 1289 |
1283 /* If we are using pgrps, get a pgrp number and make it negative. */ | 1290 /* If we are using pgrps, get a pgrp number and make it negative. */ |
1393 /* | 1400 /* |
1394 * Return TTY name used to communicate with subprocess | 1401 * Return TTY name used to communicate with subprocess |
1395 */ | 1402 */ |
1396 | 1403 |
1397 static Lisp_Object | 1404 static Lisp_Object |
1398 unix_get_tty_name (struct Lisp_Process *p) | 1405 unix_get_tty_name (Lisp_Process *p) |
1399 { | 1406 { |
1400 return UNIX_DATA (p)->tty_name; | 1407 return UNIX_DATA (p)->tty_name; |
1401 } | 1408 } |
1402 | 1409 |
1403 /* | 1410 /* |
1408 | 1415 |
1409 #ifdef HAVE_SOCKETS | 1416 #ifdef HAVE_SOCKETS |
1410 static Lisp_Object | 1417 static Lisp_Object |
1411 unix_canonicalize_host_name (Lisp_Object host) | 1418 unix_canonicalize_host_name (Lisp_Object host) |
1412 { | 1419 { |
1420 #if defined(HAVE_GETADDRINFO) && defined(HAVE_GETNAMEINFO) | |
1421 struct addrinfo hints, *res; | |
1422 static char addrbuf[NI_MAXHOST]; | |
1423 Lisp_Object canonname; | |
1424 int retval; | |
1425 char *ext_host; | |
1426 | |
1427 xzero (hints); | |
1428 hints.ai_flags = AI_CANONNAME; | |
1429 hints.ai_family = AF_UNSPEC; | |
1430 hints.ai_socktype = SOCK_STREAM; | |
1431 hints.ai_protocol = 0; | |
1432 TO_EXTERNAL_FORMAT (LISP_STRING, host, C_STRING_ALLOCA, ext_host, Qnative); | |
1433 retval = getaddrinfo (ext_host, NULL, &hints, &res); | |
1434 if (retval != 0) | |
1435 { | |
1436 char *gai_error; | |
1437 | |
1438 TO_INTERNAL_FORMAT (C_STRING, gai_strerror (retval), | |
1439 C_STRING_ALLOCA, gai_error, | |
1440 Qnative); | |
1441 maybe_error (Qprocess, ERROR_ME_NOT, | |
1442 "%s \"%s\"", gai_error, XSTRING_DATA (host)); | |
1443 canonname = host; | |
1444 } | |
1445 else | |
1446 { | |
1447 int gni = getnameinfo (res->ai_addr, res->ai_addrlen, | |
1448 addrbuf, sizeof(addrbuf), | |
1449 NULL, 0, NI_NUMERICHOST); | |
1450 canonname = gni ? host : build_ext_string (addrbuf, Qnative); | |
1451 | |
1452 freeaddrinfo (res); | |
1453 } | |
1454 | |
1455 return canonname; | |
1456 #else /* ! HAVE_GETADDRINFO */ | |
1413 struct sockaddr_in address; | 1457 struct sockaddr_in address; |
1414 | 1458 |
1415 if (!get_internet_address (host, &address, ERROR_ME_NOT)) | 1459 if (!get_internet_address (host, &address, ERROR_ME_NOT)) |
1416 return host; | 1460 return host; |
1417 | 1461 |
1418 if (address.sin_family == AF_INET) | 1462 if (address.sin_family == AF_INET) |
1419 return build_string (inet_ntoa (address.sin_addr)); | 1463 return build_string (inet_ntoa (address.sin_addr)); |
1420 else | 1464 else |
1421 /* #### any clue what to do here? */ | 1465 /* #### any clue what to do here? */ |
1422 return host; | 1466 return host; |
1467 #endif /* ! HAVE_GETADDRINFO */ | |
1423 } | 1468 } |
1424 | 1469 |
1425 /* open a TCP network connection to a given HOST/SERVICE. Treated | 1470 /* open a TCP network connection to a given HOST/SERVICE. Treated |
1426 exactly like a normal process when reading and writing. Only | 1471 exactly like a normal process when reading and writing. Only |
1427 differences are in status display and process deletion. A network | 1472 differences are in status display and process deletion. A network |
1430 | 1475 |
1431 static void | 1476 static void |
1432 unix_open_network_stream (Lisp_Object name, Lisp_Object host, Lisp_Object service, | 1477 unix_open_network_stream (Lisp_Object name, Lisp_Object host, Lisp_Object service, |
1433 Lisp_Object protocol, void** vinfd, void** voutfd) | 1478 Lisp_Object protocol, void** vinfd, void** voutfd) |
1434 { | 1479 { |
1435 struct sockaddr_in address; | |
1436 int inch; | 1480 int inch; |
1437 int outch; | 1481 int outch; |
1438 volatile int s; | 1482 volatile int s; |
1439 volatile int port; | 1483 volatile int port; |
1440 volatile int retry = 0; | 1484 volatile int retry = 0; |
1444 | 1488 |
1445 if (!EQ (protocol, Qtcp) && !EQ (protocol, Qudp)) | 1489 if (!EQ (protocol, Qtcp) && !EQ (protocol, Qudp)) |
1446 error ("Unsupported protocol \"%s\"", | 1490 error ("Unsupported protocol \"%s\"", |
1447 string_data (symbol_name (XSYMBOL (protocol)))); | 1491 string_data (symbol_name (XSYMBOL (protocol)))); |
1448 | 1492 |
1449 if (INTP (service)) | 1493 { |
1450 port = htons ((unsigned short) XINT (service)); | 1494 #if defined(HAVE_GETADDRINFO) && defined(HAVE_GETNAMEINFO) |
1451 else | 1495 struct addrinfo hints, *res; |
1452 { | 1496 struct addrinfo * volatile lres; |
1453 struct servent *svc_info; | 1497 char *portstring; |
1454 CHECK_STRING (service); | 1498 volatile int xerrno = 0; |
1455 | 1499 volatile int failed_connect = 0; |
1456 if (EQ (protocol, Qtcp)) | 1500 char *ext_host; |
1501 /* | |
1502 * Caution: service can either be a string or int. | |
1503 * Convert to a C string for later use by getaddrinfo. | |
1504 */ | |
1505 if (INTP (service)) | |
1506 { | |
1507 char portbuf[128]; | |
1508 snprintf (portbuf, sizeof (portbuf), "%ld", (long) XINT (service)); | |
1509 portstring = portbuf; | |
1510 port = htons ((unsigned short) XINT (service)); | |
1511 } | |
1512 else | |
1513 { | |
1514 CHECK_STRING (service); | |
1515 TO_EXTERNAL_FORMAT (LISP_STRING, service, | |
1516 C_STRING_ALLOCA, portstring, | |
1517 Qnative); | |
1518 port = 0; | |
1519 } | |
1520 | |
1521 xzero (hints); | |
1522 hints.ai_flags = 0; | |
1523 hints.ai_family = AF_UNSPEC; | |
1524 if (EQ (protocol, Qtcp)) | |
1525 hints.ai_socktype = SOCK_STREAM; | |
1526 else /* EQ (protocol, Qudp) */ | |
1527 hints.ai_socktype = SOCK_DGRAM; | |
1528 hints.ai_protocol = 0; | |
1529 TO_EXTERNAL_FORMAT (LISP_STRING, host, C_STRING_ALLOCA, ext_host, Qnative); | |
1530 retval = getaddrinfo (ext_host, portstring, &hints, &res); | |
1531 if (retval != 0) | |
1532 { | |
1533 char *gai_error; | |
1534 | |
1535 TO_INTERNAL_FORMAT (C_STRING, gai_strerror (retval), | |
1536 C_STRING_ALLOCA, gai_error, | |
1537 Qnative); | |
1538 error ("%s/%s %s", XSTRING_DATA (host), portstring, gai_error); | |
1539 } | |
1540 | |
1541 /* address loop */ | |
1542 for (lres = res; lres ; lres = lres->ai_next) | |
1543 { | |
1544 if (EQ (protocol, Qtcp)) | |
1545 s = socket (lres->ai_family, SOCK_STREAM, 0); | |
1546 else /* EQ (protocol, Qudp) */ | |
1547 s = socket (lres->ai_family, SOCK_DGRAM, 0); | |
1548 | |
1549 if (s < 0) | |
1550 continue; | |
1551 | |
1552 /* Turn off interrupts here -- see comments below. There used to | |
1553 be code which called bind_polling_period() to slow the polling | |
1554 period down rather than turn it off, but that seems rather | |
1555 bogus to me. Best thing here is to use a non-blocking connect | |
1556 or something, to check for QUIT. */ | |
1557 | |
1558 /* Comments that are not quite valid: */ | |
1559 | |
1560 /* Kernel bugs (on Ultrix at least) cause lossage (not just EINTR) | |
1561 when connect is interrupted. So let's not let it get interrupted. | |
1562 Note we do not turn off polling, because polling is only used | |
1563 when not interrupt_input, and thus not normally used on the systems | |
1564 which have this bug. On systems which use polling, there's no way | |
1565 to quit if polling is turned off. */ | |
1566 | |
1567 /* Slow down polling. Some kernels have a bug which causes retrying | |
1568 connect to fail after a connect. */ | |
1569 | |
1570 slow_down_interrupts (); | |
1571 | |
1572 loop: | |
1573 | |
1574 /* A system call interrupted with a SIGALRM or SIGIO comes back | |
1575 here, with can_break_system_calls reset to 0. */ | |
1576 SETJMP (break_system_call_jump); | |
1577 if (QUITP) | |
1578 { | |
1579 speed_up_interrupts (); | |
1580 REALLY_QUIT; | |
1581 /* In case something really weird happens ... */ | |
1582 slow_down_interrupts (); | |
1583 } | |
1584 | |
1585 /* Break out of connect with a signal (it isn't otherwise possible). | |
1586 Thus you don't get screwed with a hung network. */ | |
1587 can_break_system_calls = 1; | |
1588 retval = connect (s, lres->ai_addr, lres->ai_addrlen); | |
1589 can_break_system_calls = 0; | |
1590 if (retval == -1) | |
1591 { | |
1592 xerrno = errno; | |
1593 if (errno != EISCONN) | |
1594 { | |
1595 if (errno == EINTR) | |
1596 goto loop; | |
1597 if (errno == EADDRINUSE && retry < 20) | |
1598 { | |
1599 /* A delay here is needed on some FreeBSD systems, | |
1600 and it is harmless, since this retrying takes time anyway | |
1601 and should be infrequent. | |
1602 `sleep-for' allowed for quitting this loop with interrupts | |
1603 slowed down so it can't be used here. Async timers should | |
1604 already be disabled at this point so we can use `sleep'. */ | |
1605 sleep (1); | |
1606 retry++; | |
1607 goto loop; | |
1608 } | |
1609 } | |
1610 | |
1611 failed_connect = 1; | |
1612 close (s); | |
1613 | |
1614 speed_up_interrupts (); | |
1615 | |
1616 continue; | |
1617 } | |
1618 | |
1619 if (port == 0) | |
1620 { | |
1621 int gni; | |
1622 char servbuf[NI_MAXSERV]; | |
1623 | |
1624 if (EQ (protocol, Qtcp)) | |
1625 gni = getnameinfo (lres->ai_addr, lres->ai_addrlen, | |
1626 NULL, 0, servbuf, sizeof(servbuf), | |
1627 NI_NUMERICSERV); | |
1628 else /* EQ (protocol, Qudp) */ | |
1629 gni = getnameinfo (lres->ai_addr, lres->ai_addrlen, | |
1630 NULL, 0, servbuf, sizeof(servbuf), | |
1631 NI_NUMERICSERV | NI_DGRAM); | |
1632 | |
1633 if (gni == 0) | |
1634 port = strtol (servbuf, NULL, 10); | |
1635 } | |
1636 | |
1637 break; | |
1638 } /* address loop */ | |
1639 | |
1640 speed_up_interrupts (); | |
1641 | |
1642 freeaddrinfo (res); | |
1643 if (s < 0) | |
1644 { | |
1645 errno = xerrno; | |
1646 | |
1647 if (failed_connect) | |
1648 report_file_error ("connection failed", list2 (host, name)); | |
1649 else | |
1650 report_file_error ("error creating socket", list1 (name)); | |
1651 } | |
1652 #else /* ! HAVE_GETADDRINFO */ | |
1653 struct sockaddr_in address; | |
1654 | |
1655 if (INTP (service)) | |
1656 port = htons ((unsigned short) XINT (service)); | |
1657 else | |
1658 { | |
1659 struct servent *svc_info; | |
1660 CHECK_STRING (service); | |
1661 | |
1662 if (EQ (protocol, Qtcp)) | |
1457 svc_info = getservbyname ((char *) XSTRING_DATA (service), "tcp"); | 1663 svc_info = getservbyname ((char *) XSTRING_DATA (service), "tcp"); |
1458 else /* EQ (protocol, Qudp) */ | 1664 else /* EQ (protocol, Qudp) */ |
1459 svc_info = getservbyname ((char *) XSTRING_DATA (service), "udp"); | 1665 svc_info = getservbyname ((char *) XSTRING_DATA (service), "udp"); |
1460 | 1666 |
1461 if (svc_info == 0) | 1667 if (svc_info == 0) |
1462 error ("Unknown service \"%s\"", XSTRING_DATA (service)); | 1668 error ("Unknown service \"%s\"", XSTRING_DATA (service)); |
1463 port = svc_info->s_port; | 1669 port = svc_info->s_port; |
1464 } | 1670 } |
1465 | 1671 |
1466 get_internet_address (host, &address, ERROR_ME); | 1672 get_internet_address (host, &address, ERROR_ME); |
1467 address.sin_port = port; | 1673 address.sin_port = port; |
1468 | 1674 |
1469 if (EQ (protocol, Qtcp)) | 1675 if (EQ (protocol, Qtcp)) |
1470 s = socket (address.sin_family, SOCK_STREAM, 0); | 1676 s = socket (address.sin_family, SOCK_STREAM, 0); |
1471 else /* EQ (protocol, Qudp) */ | 1677 else /* EQ (protocol, Qudp) */ |
1472 s = socket (address.sin_family, SOCK_DGRAM, 0); | 1678 s = socket (address.sin_family, SOCK_DGRAM, 0); |
1473 | 1679 |
1474 if (s < 0) | 1680 if (s < 0) |
1475 report_file_error ("error creating socket", list1 (name)); | 1681 report_file_error ("error creating socket", list1 (name)); |
1476 | 1682 |
1477 /* Turn off interrupts here -- see comments below. There used to | 1683 /* Turn off interrupts here -- see comments below. There used to |
1478 be code which called bind_polling_period() to slow the polling | 1684 be code which called bind_polling_period() to slow the polling |
1479 period down rather than turn it off, but that seems rather | 1685 period down rather than turn it off, but that seems rather |
1480 bogus to me. Best thing here is to use a non-blocking connect | 1686 bogus to me. Best thing here is to use a non-blocking connect |
1481 or something, to check for QUIT. */ | 1687 or something, to check for QUIT. */ |
1482 | 1688 |
1483 /* Comments that are not quite valid: */ | 1689 /* Comments that are not quite valid: */ |
1484 | 1690 |
1485 /* Kernel bugs (on Ultrix at least) cause lossage (not just EINTR) | 1691 /* Kernel bugs (on Ultrix at least) cause lossage (not just EINTR) |
1486 when connect is interrupted. So let's not let it get interrupted. | 1692 when connect is interrupted. So let's not let it get interrupted. |
1487 Note we do not turn off polling, because polling is only used | 1693 Note we do not turn off polling, because polling is only used |
1488 when not interrupt_input, and thus not normally used on the systems | 1694 when not interrupt_input, and thus not normally used on the systems |
1489 which have this bug. On systems which use polling, there's no way | 1695 which have this bug. On systems which use polling, there's no way |
1490 to quit if polling is turned off. */ | 1696 to quit if polling is turned off. */ |
1491 | 1697 |
1492 /* Slow down polling. Some kernels have a bug which causes retrying | 1698 /* Slow down polling. Some kernels have a bug which causes retrying |
1493 connect to fail after a connect. */ | 1699 connect to fail after a connect. */ |
1494 | 1700 |
1495 slow_down_interrupts (); | 1701 slow_down_interrupts (); |
1496 | 1702 |
1497 loop: | 1703 loop: |
1498 | 1704 |
1499 /* A system call interrupted with a SIGALRM or SIGIO comes back | 1705 /* A system call interrupted with a SIGALRM or SIGIO comes back |
1500 here, with can_break_system_calls reset to 0. */ | 1706 here, with can_break_system_calls reset to 0. */ |
1501 SETJMP (break_system_call_jump); | 1707 SETJMP (break_system_call_jump); |
1502 if (QUITP) | 1708 if (QUITP) |
1503 { | 1709 { |
1504 speed_up_interrupts (); | 1710 speed_up_interrupts (); |
1505 REALLY_QUIT; | 1711 REALLY_QUIT; |
1506 /* In case something really weird happens ... */ | 1712 /* In case something really weird happens ... */ |
1507 slow_down_interrupts (); | 1713 slow_down_interrupts (); |
1508 } | 1714 } |
1509 | 1715 |
1510 /* Break out of connect with a signal (it isn't otherwise possible). | 1716 /* Break out of connect with a signal (it isn't otherwise possible). |
1511 Thus you don't get screwed with a hung network. */ | 1717 Thus you don't get screwed with a hung network. */ |
1512 can_break_system_calls = 1; | 1718 can_break_system_calls = 1; |
1513 retval = connect (s, (struct sockaddr *) &address, sizeof (address)); | 1719 retval = connect (s, (struct sockaddr *) &address, sizeof (address)); |
1514 can_break_system_calls = 0; | 1720 can_break_system_calls = 0; |
1515 if (retval == -1 && errno != EISCONN) | 1721 if (retval == -1 && errno != EISCONN) |
1516 { | 1722 { |
1517 int xerrno = errno; | 1723 int xerrno = errno; |
1518 if (errno == EINTR) | 1724 if (errno == EINTR) |
1519 goto loop; | |
1520 if (errno == EADDRINUSE && retry < 20) | |
1521 { | |
1522 /* A delay here is needed on some FreeBSD systems, | |
1523 and it is harmless, since this retrying takes time anyway | |
1524 and should be infrequent. | |
1525 `sleep-for' allowed for quitting this loop with interrupts | |
1526 slowed down so it can't be used here. Async timers should | |
1527 already be disabled at this point so we can use `sleep'. */ | |
1528 sleep (1); | |
1529 retry++; | |
1530 goto loop; | 1725 goto loop; |
1531 } | 1726 if (errno == EADDRINUSE && retry < 20) |
1532 | 1727 { |
1533 close (s); | 1728 /* A delay here is needed on some FreeBSD systems, |
1534 | 1729 and it is harmless, since this retrying takes time anyway |
1535 speed_up_interrupts (); | 1730 and should be infrequent. |
1536 | 1731 `sleep-for' allowed for quitting this loop with interrupts |
1537 errno = xerrno; | 1732 slowed down so it can't be used here. Async timers should |
1538 report_file_error ("connection failed", list2 (host, name)); | 1733 already be disabled at this point so we can use `sleep'. */ |
1539 } | 1734 sleep (1); |
1540 | 1735 retry++; |
1541 speed_up_interrupts (); | 1736 goto loop; |
1737 } | |
1738 | |
1739 close (s); | |
1740 | |
1741 speed_up_interrupts (); | |
1742 | |
1743 errno = xerrno; | |
1744 report_file_error ("connection failed", list2 (host, name)); | |
1745 } | |
1746 | |
1747 speed_up_interrupts (); | |
1748 #endif /* ! HAVE_GETADDRINFO */ | |
1749 } | |
1542 | 1750 |
1543 inch = s; | 1751 inch = s; |
1544 outch = dup (s); | 1752 outch = dup (s); |
1545 if (outch < 0) | 1753 if (outch < 0) |
1546 { | 1754 { |