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.