Mercurial > hg > xemacs-beta
comparison src/process.c @ 259:11cf20601dec r20-5b28
Import from CVS: tag r20-5b28
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:23:02 +0200 |
parents | 65c19d2020f7 |
children | 727739f917cb |
comparison
equal
deleted
inserted
replaced
258:58424f6abf56 | 259:11cf20601dec |
---|---|
21 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 21 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
22 Boston, MA 02111-1307, USA. */ | 22 Boston, MA 02111-1307, USA. */ |
23 | 23 |
24 /* Synched up with: Mule 2.0, FSF 19.30. */ | 24 /* Synched up with: Mule 2.0, FSF 19.30. */ |
25 | 25 |
26 /* This file has been Mule-ized except for `start-process-internal' | 26 /* This file has been Mule-ized except for `start-process-internal', |
27 and `open-network-stream-internal'. */ | 27 `open-network-stream-internal' and `open-multicast-group-internal'. */ |
28 | 28 |
29 #include <config.h> | 29 #include <config.h> |
30 | 30 |
31 #if !defined (NO_SUBPROCESSES) | 31 #if !defined (NO_SUBPROCESSES) |
32 | 32 |
42 #include "lstream.h" | 42 #include "lstream.h" |
43 #include "opaque.h" | 43 #include "opaque.h" |
44 #include "process.h" | 44 #include "process.h" |
45 #include "sysdep.h" | 45 #include "sysdep.h" |
46 #include "window.h" | 46 #include "window.h" |
47 #ifdef MULE | 47 #ifdef FILE_CODING |
48 #include "mule-coding.h" | 48 #include "file-coding.h" |
49 #endif | 49 #endif |
50 | 50 |
51 #include <setjmp.h> | 51 #include <setjmp.h> |
52 #include "sysfile.h" | 52 #include "sysfile.h" |
53 #include "sysproc.h" | 53 #include "sysproc.h" |
62 | 62 |
63 /* Valid values of process->status_symbol */ | 63 /* Valid values of process->status_symbol */ |
64 Lisp_Object Qrun, Qstop; /* Qexit from eval.c, Qsignal from data.c. */ | 64 Lisp_Object Qrun, Qstop; /* Qexit from eval.c, Qsignal from data.c. */ |
65 /* Qrun => Qopen, Qexit => Qclosed for "network connection" processes */ | 65 /* Qrun => Qopen, Qexit => Qclosed for "network connection" processes */ |
66 Lisp_Object Qopen, Qclosed; | 66 Lisp_Object Qopen, Qclosed; |
67 | |
68 #ifdef HAVE_MULTICAST | |
69 Lisp_Object Qmulticast; /* Will be used for occasional warnings */ | |
70 #endif | |
67 | 71 |
68 /* t means use pty, nil means use a pipe, | 72 /* t means use pty, nil means use a pipe, |
69 maybe other values to come. */ | 73 maybe other values to come. */ |
70 static Lisp_Object Vprocess_connection_type; | 74 static Lisp_Object Vprocess_connection_type; |
71 | 75 |
785 Bufbyte eof_char = get_eof_char (p); | 789 Bufbyte eof_char = get_eof_char (p); |
786 int pty_max_bytes = get_pty_max_bytes (p); | 790 int pty_max_bytes = get_pty_max_bytes (p); |
787 filedesc_stream_set_pty_flushing (XLSTREAM (p->outstream), | 791 filedesc_stream_set_pty_flushing (XLSTREAM (p->outstream), |
788 pty_max_bytes, eof_char); | 792 pty_max_bytes, eof_char); |
789 } | 793 } |
790 #ifdef MULE | 794 |
795 #ifdef FILE_CODING | |
796 | |
791 p->instream = make_decoding_input_stream | 797 p->instream = make_decoding_input_stream |
792 (XLSTREAM (p->instream), | 798 (XLSTREAM (p->instream), |
793 Fget_coding_system (Vcoding_system_for_read)); | 799 Fget_coding_system (Vcoding_system_for_read)); |
794 Lstream_set_character_mode (XLSTREAM (p->instream)); | 800 Lstream_set_character_mode (XLSTREAM (p->instream)); |
795 p->outstream = make_encoding_output_stream | 801 p->outstream = make_encoding_output_stream |
796 (XLSTREAM (p->outstream), | 802 (XLSTREAM (p->outstream), |
797 Fget_coding_system (Vcoding_system_for_write)); | 803 Fget_coding_system (Vcoding_system_for_write)); |
798 /* CODE_CNTL (&out_state[outchannel]) |= CC_END; !!#### | 804 /* CODE_CNTL (&out_state[outchannel]) |= CC_END; !!#### |
799 What's going on here? */ | 805 What's going on here? */ |
800 #endif /* MULE */ | 806 #endif |
801 } | 807 } |
802 | 808 |
803 static void | 809 static void |
804 create_process (Lisp_Object process, | 810 create_process (Lisp_Object process, |
805 char **new_argv, CONST char *current_dir) | 811 char **new_argv, CONST char *current_dir) |
1502 event_stream_select_process (XPROCESS (proc)); | 1508 event_stream_select_process (XPROCESS (proc)); |
1503 | 1509 |
1504 UNGCPRO; | 1510 UNGCPRO; |
1505 return proc; | 1511 return proc; |
1506 } | 1512 } |
1513 | |
1514 #ifdef HAVE_MULTICAST | |
1515 /* Didier Verna <verna@inf.enst.fr> Nov. 28 1997. | |
1516 | |
1517 This function is similar to open-network-stream-internal, but provides a | |
1518 mean to open an UDP multicast connection instead of a TCP one. Like in the | |
1519 TCP case, the multicast connection will be seen as a sub-process, | |
1520 | |
1521 Some notes: | |
1522 - Normaly, we should use sendto and recvfrom with non connected | |
1523 sockets. The current code doesn't allow us to do this. In the future, it | |
1524 would be a good idea to extend the process data structure in order to deal | |
1525 properly with the different types network connections. | |
1526 - For the same reason, when leaving a multicast group, it is better to make | |
1527 a setsockopt - IP_DROP_MEMBERSHIP before closing the descriptors. | |
1528 Unfortunately, this can't be done here because delete_process doesn't know | |
1529 about the kind of connection we have. However, this is not such an | |
1530 important issue. | |
1531 */ | |
1532 DEFUN ("open-multicast-group-internal", Fopen_multicast_group_internal, 5, 5, 0, /* | |
1533 Open a multicast connection on the specified dest/port/ttl. | |
1534 Returns a subprocess-object to represent the connection. | |
1535 Input and output work as for subprocesses; `delete-process' closes it. | |
1536 | |
1537 NAME is name for process. It is modified if necessary to make it unique. | |
1538 BUFFER is the buffer (or buffer-name) to associate with the process. | |
1539 Process output goes at end of that buffer, unless you specify | |
1540 an output stream or filter function to handle the output. | |
1541 BUFFER may also be nil, meaning that this process is not associated | |
1542 with any buffer. | |
1543 Third, fourth and fifth args are the multicast destination group, port and ttl. | |
1544 dest must be an internet address between 224.0.0.0 and 239.255.255.255 | |
1545 port is a communication port like in traditional unicast | |
1546 ttl is the time-to-live (15 for site, 63 for region and 127 for world) | |
1547 */ | |
1548 (name, buffer, dest, port, ttl)) | |
1549 { | |
1550 /* !!#### This function has not been Mule-ized */ | |
1551 /* This function can GC */ | |
1552 Lisp_Object proc; | |
1553 struct ip_mreq imr; | |
1554 struct sockaddr_in sa; | |
1555 struct protoent *udp; | |
1556 int ws, rs; | |
1557 int theport; | |
1558 unsigned char thettl; | |
1559 int one = 1; /* For REUSEADDR */ | |
1560 int ret; | |
1561 volatile int retry = 0; | |
1562 struct gcpro gcpro1; | |
1563 | |
1564 CHECK_STRING (name); | |
1565 CHECK_STRING (dest); | |
1566 | |
1567 CHECK_NATNUM (port); | |
1568 theport = htons ((unsigned short) XINT (port)); | |
1569 | |
1570 CHECK_NATNUM (ttl); | |
1571 thettl = (unsigned char) XINT (ttl); | |
1572 | |
1573 if ((udp = getprotobyname ("udp")) == NULL) | |
1574 error ("No info available for UDP protocol"); | |
1575 | |
1576 /* Init the sockets. Yes, I need 2 sockets. I couldn't duplicate one. */ | |
1577 if ((rs = socket (PF_INET, SOCK_DGRAM, udp->p_proto)) < 0) | |
1578 report_file_error ("error creating socket", list1(name)); | |
1579 if ((ws = socket (PF_INET, SOCK_DGRAM, udp->p_proto)) < 0) | |
1580 { | |
1581 close (rs); | |
1582 report_file_error ("error creating socket", list1(name)); | |
1583 } | |
1584 | |
1585 /* This will be used for both sockets */ | |
1586 bzero(&sa, sizeof(sa)); | |
1587 sa.sin_family = AF_INET; | |
1588 sa.sin_port = theport; | |
1589 sa.sin_addr.s_addr = htonl (inet_addr ((char *) XSTRING_DATA (dest))); | |
1590 | |
1591 /* Socket configuration for reading ------------------------ */ | |
1592 | |
1593 /* Multiple connections from the same machine. This must be done before | |
1594 bind. If it fails, it shouldn't be fatal. The only consequence is that | |
1595 people won't be able to connect twice from the same machine. */ | |
1596 if (setsockopt (rs, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof (one)) | |
1597 < 0) | |
1598 warn_when_safe (Qmulticast, Qwarning, "Cannot reuse socket address"); | |
1599 | |
1600 /* bind socket name */ | |
1601 if (bind (rs, (struct sockaddr *)&sa, sizeof(sa))) | |
1602 { | |
1603 close (rs); | |
1604 close (ws); | |
1605 report_file_error ("error binding socket", list2(name, port)); | |
1606 } | |
1607 | |
1608 /* join multicast group */ | |
1609 imr.imr_multiaddr.s_addr = htonl (inet_addr ((char *) XSTRING_DATA (dest))); | |
1610 imr.imr_interface.s_addr = htonl (INADDR_ANY); | |
1611 if (setsockopt (rs, IPPROTO_IP, IP_ADD_MEMBERSHIP, | |
1612 (char *) &imr, sizeof (struct ip_mreq)) < 0) | |
1613 { | |
1614 close (ws); | |
1615 close (rs); | |
1616 report_file_error ("error adding membership", list2(name, dest)); | |
1617 } | |
1618 | |
1619 /* Socket configuration for writing ----------------------- */ | |
1620 | |
1621 /* Normaly, there's no 'connect' in multicast, since we use preferentialy | |
1622 'sendto' and 'recvfrom'. However, in order to handle this connection in | |
1623 the process-like way it is done for TCP, we must be able to use 'write' | |
1624 instead of 'sendto'. Consequently, we 'connect' this socket. */ | |
1625 | |
1626 /* See open-network-stream-internal for comments on this part of the code */ | |
1627 slow_down_interrupts (); | |
1628 | |
1629 loop: | |
1630 | |
1631 /* A system call interrupted with a SIGALRM or SIGIO comes back | |
1632 here, with can_break_system_calls reset to 0. */ | |
1633 SETJMP (break_system_call_jump); | |
1634 if (QUITP) | |
1635 { | |
1636 speed_up_interrupts (); | |
1637 REALLY_QUIT; | |
1638 /* In case something really weird happens ... */ | |
1639 slow_down_interrupts (); | |
1640 } | |
1641 | |
1642 /* Break out of connect with a signal (it isn't otherwise possible). | |
1643 Thus you don't get screwed with a hung network. */ | |
1644 can_break_system_calls = 1; | |
1645 ret = connect (ws, (struct sockaddr *) &sa, sizeof (sa)); | |
1646 can_break_system_calls = 0; | |
1647 if (ret == -1 && errno != EISCONN) | |
1648 { | |
1649 int xerrno = errno; | |
1650 | |
1651 if (errno == EINTR) | |
1652 goto loop; | |
1653 if (errno == EADDRINUSE && retry < 20) | |
1654 { | |
1655 /* A delay here is needed on some FreeBSD systems, | |
1656 and it is harmless, since this retrying takes time anyway | |
1657 and should be infrequent. | |
1658 `sleep-for' allowed for quitting this loop with interrupts | |
1659 slowed down so it can't be used here. Async timers should | |
1660 already be disabled at this point so we can use `sleep'. */ | |
1661 sleep (1); | |
1662 retry++; | |
1663 goto loop; | |
1664 } | |
1665 | |
1666 close (rs); | |
1667 close (ws); | |
1668 speed_up_interrupts (); | |
1669 | |
1670 errno = xerrno; | |
1671 report_file_error ("error connecting socket", list2(name, port)); | |
1672 } | |
1673 | |
1674 speed_up_interrupts (); | |
1675 | |
1676 /* scope */ | |
1677 if (setsockopt (ws, IPPROTO_IP, IP_MULTICAST_TTL, | |
1678 (char *) &thettl, sizeof (thettl)) < 0) | |
1679 { | |
1680 close (rs); | |
1681 close (ws); | |
1682 report_file_error ("error setting ttl", list2(name, ttl)); | |
1683 } | |
1684 | |
1685 if (!NILP (buffer)) | |
1686 buffer = Fget_buffer_create (buffer); | |
1687 | |
1688 proc = make_process_internal (name); | |
1689 GCPRO1 (proc); | |
1690 | |
1691 descriptor_to_process[rs] = proc; | |
1692 | |
1693 #ifdef PROCESS_IO_BLOCKING | |
1694 { | |
1695 Lisp_Object tail; | |
1696 | |
1697 for (tail = network_stream_blocking_port_list; | |
1698 CONSP (tail); tail = XCDR (tail)) | |
1699 { | |
1700 Lisp_Object tail_port = XCAR (tail); | |
1701 | |
1702 if (STRINGP (tail_port)) | |
1703 { | |
1704 struct servent *svc_info; | |
1705 | |
1706 svc_info = | |
1707 getservbyname ((char *) XSTRING_DATA (tail_port), "udp"); | |
1708 if ((svc_info != 0) && (svc_info->s_port == theport)) | |
1709 break; | |
1710 else | |
1711 continue; | |
1712 } | |
1713 else if ((INTP (tail_port)) && | |
1714 (htons ((unsigned short) XINT (tail_port)) == theport)) | |
1715 break; | |
1716 } | |
1717 | |
1718 if (!CONSP (tail)) | |
1719 { | |
1720 #endif /* PROCESS_IO_BLOCKING */ | |
1721 set_descriptor_non_blocking (rs); | |
1722 #ifdef PROCESS_IO_BLOCKING | |
1723 } | |
1724 } | |
1725 #endif /* PROCESS_IO_BLOCKING */ | |
1726 | |
1727 XPROCESS (proc)->pid = Fcons (port, dest); | |
1728 XPROCESS (proc)->buffer = buffer; | |
1729 init_process_fds (XPROCESS (proc), rs, ws); | |
1730 XPROCESS (proc)->connected_via_filedesc_p = 0; | |
1731 | |
1732 event_stream_select_process (XPROCESS (proc)); | |
1733 | |
1734 UNGCPRO; | |
1735 return proc; | |
1736 } | |
1737 #endif /* HAVE_MULTICAST */ | |
1507 | 1738 |
1508 #endif /* HAVE_SOCKETS */ | 1739 #endif /* HAVE_SOCKETS */ |
1509 | 1740 |
1510 Lisp_Object | 1741 Lisp_Object |
1511 canonicalize_host_name (Lisp_Object host) | 1742 canonicalize_host_name (Lisp_Object host) |
1965 | 2196 |
1966 send_process (proc, string, 0, bfr, len); | 2197 send_process (proc, string, 0, bfr, len); |
1967 return Qnil; | 2198 return Qnil; |
1968 } | 2199 } |
1969 | 2200 |
1970 #ifdef MULE | 2201 #ifdef FILE_CODING |
1971 | 2202 |
1972 DEFUN ("process-input-coding-system", Fprocess_input_coding_system, 1, 1, 0, /* | 2203 DEFUN ("process-input-coding-system", Fprocess_input_coding_system, 1, 1, 0, /* |
1973 Return PROCESS's input coding system. | 2204 Return PROCESS's input coding system. |
1974 */ | 2205 */ |
1975 (process)) | 2206 (process)) |
2037 Fset_process_output_coding_system(process, encoding); | 2268 Fset_process_output_coding_system(process, encoding); |
2038 } | 2269 } |
2039 return Qnil; | 2270 return Qnil; |
2040 } | 2271 } |
2041 | 2272 |
2042 #endif /* MULE */ | 2273 #endif |
2043 | 2274 |
2044 | 2275 |
2045 /************************************************************************/ | 2276 /************************************************************************/ |
2046 /* process status */ | 2277 /* process status */ |
2047 /************************************************************************/ | 2278 /************************************************************************/ |
3254 /* Qexit is already defined by syms_of_eval | 3485 /* Qexit is already defined by syms_of_eval |
3255 * defsymbol (&Qexit, "exit"); | 3486 * defsymbol (&Qexit, "exit"); |
3256 */ | 3487 */ |
3257 defsymbol (&Qopen, "open"); | 3488 defsymbol (&Qopen, "open"); |
3258 defsymbol (&Qclosed, "closed"); | 3489 defsymbol (&Qclosed, "closed"); |
3490 | |
3491 #ifdef HAVE_MULTICAST | |
3492 defsymbol(&Qmulticast, "multicast"); /* Used for occasional warnings */ | |
3493 #endif | |
3259 | 3494 |
3260 DEFSUBR (Fprocessp); | 3495 DEFSUBR (Fprocessp); |
3261 DEFSUBR (Fget_process); | 3496 DEFSUBR (Fget_process); |
3262 DEFSUBR (Fget_buffer_process); | 3497 DEFSUBR (Fget_buffer_process); |
3263 DEFSUBR (Fdelete_process); | 3498 DEFSUBR (Fdelete_process); |
3279 DEFSUBR (Fprocess_kill_without_query_p); | 3514 DEFSUBR (Fprocess_kill_without_query_p); |
3280 DEFSUBR (Fprocess_list); | 3515 DEFSUBR (Fprocess_list); |
3281 DEFSUBR (Fstart_process_internal); | 3516 DEFSUBR (Fstart_process_internal); |
3282 #ifdef HAVE_SOCKETS | 3517 #ifdef HAVE_SOCKETS |
3283 DEFSUBR (Fopen_network_stream_internal); | 3518 DEFSUBR (Fopen_network_stream_internal); |
3519 #ifdef HAVE_MULTICAST | |
3520 DEFSUBR (Fopen_multicast_group_internal); | |
3521 #endif /* HAVE_MULTICAST */ | |
3284 #endif /* HAVE_SOCKETS */ | 3522 #endif /* HAVE_SOCKETS */ |
3285 DEFSUBR (Fprocess_send_region); | 3523 DEFSUBR (Fprocess_send_region); |
3286 DEFSUBR (Fprocess_send_string); | 3524 DEFSUBR (Fprocess_send_string); |
3287 DEFSUBR (Finterrupt_process); | 3525 DEFSUBR (Finterrupt_process); |
3288 DEFSUBR (Fkill_process); | 3526 DEFSUBR (Fkill_process); |
3290 DEFSUBR (Fstop_process); | 3528 DEFSUBR (Fstop_process); |
3291 DEFSUBR (Fcontinue_process); | 3529 DEFSUBR (Fcontinue_process); |
3292 DEFSUBR (Fprocess_send_eof); | 3530 DEFSUBR (Fprocess_send_eof); |
3293 DEFSUBR (Fsignal_process); | 3531 DEFSUBR (Fsignal_process); |
3294 /* DEFSUBR (Fprocess_connection); */ | 3532 /* DEFSUBR (Fprocess_connection); */ |
3295 #ifdef MULE | 3533 #ifdef FILE_CODING |
3296 DEFSUBR (Fprocess_input_coding_system); | 3534 DEFSUBR (Fprocess_input_coding_system); |
3297 DEFSUBR (Fprocess_output_coding_system); | 3535 DEFSUBR (Fprocess_output_coding_system); |
3298 DEFSUBR (Fset_process_input_coding_system); | 3536 DEFSUBR (Fset_process_input_coding_system); |
3299 DEFSUBR (Fset_process_output_coding_system); | 3537 DEFSUBR (Fset_process_output_coding_system); |
3300 DEFSUBR (Fprocess_coding_system); | 3538 DEFSUBR (Fprocess_coding_system); |
3301 DEFSUBR (Fset_process_coding_system); | 3539 DEFSUBR (Fset_process_coding_system); |
3302 #endif /* MULE */ | 3540 #endif |
3303 } | 3541 } |
3304 | 3542 |
3305 void | 3543 void |
3306 vars_of_process (void) | 3544 vars_of_process (void) |
3307 { | 3545 { |
3308 Fprovide (intern ("subprocesses")); | 3546 Fprovide (intern ("subprocesses")); |
3309 #ifdef HAVE_SOCKETS | 3547 #ifdef HAVE_SOCKETS |
3310 Fprovide (intern ("network-streams")); | 3548 Fprovide (intern ("network-streams")); |
3311 #endif | 3549 #ifdef HAVE_MULTICAST |
3550 Fprovide (intern ("multicast")); | |
3551 #endif /* HAVE_MULTICAST */ | |
3552 #endif /* HAVE_SOCKETS */ | |
3312 staticpro (&Vprocess_list); | 3553 staticpro (&Vprocess_list); |
3313 | 3554 |
3314 DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes /* | 3555 DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes /* |
3315 *Non-nil means delete processes immediately when they exit. | 3556 *Non-nil means delete processes immediately when they exit. |
3316 nil means don't delete them until `list-processes' is run. | 3557 nil means don't delete them until `list-processes' is run. |