|
|
1.1 ! root 1: ! 2: /* open a TCP network connection to a given HOST/SERVICE. Treated ! 3: exactly like a normal process when reading and writing. Only ! 4: differences are in status display and process deletion. A network ! 5: connection has no PID; you cannot signal it. All you can do is ! 6: deactivate and close it via delete-process */ ! 7: ! 8: #ifdef HAVE_UNIX_DOMAIN ! 9: #include <sys/un.h> ! 10: #endif HAVE_UNIX_DOMAIN ! 11: ! 12: DEFUN ("open-network-stream", Fopen_network_stream, Sopen_network_stream, ! 13: 4, 4, 0, ! 14: #ifdef HAVE_UNIX_DOMAIN ! 15: "Open a TCP connection for a service to a host.\n\ ! 16: Returns a subprocess-object to represent the connection.\n\ ! 17: Input and output work as for subprocesses; `delete-process' closes it.\n\ ! 18: Args are NAME BUFFER HOST SERVICE.\n\ ! 19: If SERVICE is 0, then HOST is taken to be the name of a socket file, and a\n\ ! 20: Unix domain socket is opened.\n\ ! 21: NAME is name for process. It is modified if necessary to make it unique.\n\ ! 22: BUFFER is the buffer (or buffer-name) to associate with the process.\n\ ! 23: Process output goes at end of that buffer, unless you specify\n\ ! 24: an output stream or filter function to handle the output.\n\ ! 25: BUFFER may be also nil, meaning that this process is not associated\n\ ! 26: with any buffer\n\ ! 27: Third arg is name of the host to connect to.\n\ ! 28: Fourth arg SERVICE is name of the service desired, or an integer\n\ ! 29: specifying a port number to connect to." ! 30: #else ! 31: "Open a TCP connection for a service to a host.\n\ ! 32: Returns a subprocess-object to represent the connection.\n\ ! 33: Input and output work as for subprocesses; `delete-process' closes it.\n\ ! 34: Args are NAME BUFFER HOST SERVICE.\n\ ! 35: NAME is name for process. It is modified if necessary to make it unique.\n\ ! 36: BUFFER is the buffer (or buffer-name) to associate with the process.\n\ ! 37: Process output goes at end of that buffer, unless you specify\n\ ! 38: an output stream or filter function to handle the output.\n\ ! 39: BUFFER may be also nil, meaning that this process is not associated\n\ ! 40: with any buffer\n\ ! 41: Third arg is name of the host to connect to.\n\ ! 42: Fourth arg SERVICE is name of the service desired, or an integer\n\ ! 43: specifying a port number to connect to." ! 44: #endif HAVE_UNIX_DOMAIN ! 45: ) ! 46: (name, buffer, host, service) ! 47: Lisp_Object name, buffer, host, service; ! 48: { ! 49: Lisp_Object proc; ! 50: register int i; ! 51: struct sockaddr_in address; ! 52: #ifdef HAVE_UNIX_DOMAIN ! 53: struct sockaddr_un server; ! 54: int unix_domain = 0; ! 55: #endif HAVE_UNIX_DOMAIN ! 56: struct servent *svc_info; ! 57: struct hostent *host_info; ! 58: int s, outch, inch; ! 59: char errstring[80]; ! 60: int port; ! 61: ! 62: CHECK_STRING (name, 0); ! 63: CHECK_STRING (host, 0); ! 64: if (XTYPE(service) == Lisp_Int) ! 65: { ! 66: #ifdef HAVE_UNIX_DOMAIN ! 67: if (XINT (service) == 0) ! 68: unix_domain = 1; ! 69: else ! 70: #endif HAVE_UNIX_DOMAIN ! 71: port = htons ((unsigned short) XINT (service)); ! 72: } ! 73: else ! 74: { ! 75: CHECK_STRING (service, 0); ! 76: svc_info = getservbyname (XSTRING (service)->data, "tcp"); ! 77: if (svc_info == 0) ! 78: error ("Unknown service \"%s\"", XSTRING (service)->data); ! 79: port = svc_info->s_port; ! 80: } ! 81: ! 82: #ifdef HAVE_UNIX_DOMAIN ! 83: if (unix_domain) ! 84: { ! 85: server.sun_family = AF_UNIX; ! 86: strcpy (server.sun_path, XSTRING (host)->data); ! 87: } ! 88: else ! 89: #endif HAVE_UNIX_DOMAIN ! 90: { ! 91: host_info = gethostbyname (XSTRING (host)->data); ! 92: if (host_info == 0) ! 93: error ("Unknown host \"%s\"", XSTRING(host)->data); ! 94: ! 95: bzero (&address, sizeof address); ! 96: bcopy (host_info->h_addr, (char *) &address.sin_addr, host_info->h_length); ! 97: address.sin_family = host_info->h_addrtype; ! 98: address.sin_port = port; ! 99: } ! 100: ! 101: #ifdef HAVE_UNIX_DOMAIN ! 102: if (unix_domain) ! 103: s = socket (AF_UNIX, SOCK_STREAM, 0); ! 104: else ! 105: #endif HAVE_UNIX_DOMAIN ! 106: s = socket (host_info->h_addrtype, SOCK_STREAM, 0); ! 107: ! 108: if (s < 0) ! 109: report_file_error ("error creating socket", Fcons (name, Qnil)); ! 110: ! 111: #ifdef HAVE_UNIX_DOMAIN ! 112: if (unix_domain) ! 113: { ! 114: if (connect (s, &server, strlen (server.sun_path) + 2) < 0) ! 115: error ("connect failed for socket: \"%s\"", XSTRING (host)->data); ! 116: } ! 117: else ! 118: #endif HAVE_UNIX_DOMAIN ! 119: { ! 120: if (connect (s, &address, sizeof address) == -1) ! 121: error ("Host \"%s\" not responding", XSTRING (host)->data); ! 122: } ! 123: ! 124: inch = s; ! 125: outch = dup (s); ! 126: if (outch < 0) ! 127: report_file_error ("error duplicating socket", Fcons (name, Qnil)); ! 128: ! 129: if (!NULL (buffer)) ! 130: buffer = Fget_buffer_create (buffer); ! 131: proc = make_process (name); ! 132: ! 133: chan_process[inch] = proc; ! 134: ! 135: #ifdef O_NDELAY ! 136: fcntl (inch, F_SETFL, O_NDELAY); ! 137: #endif ! 138: ! 139: XPROCESS (proc)->childp = host; ! 140: XPROCESS (proc)->command_channel_p = Qnil; ! 141: XPROCESS (proc)->buffer = buffer; ! 142: XPROCESS (proc)->sentinel = Qnil; ! 143: XPROCESS (proc)->filter = Qnil; ! 144: XPROCESS (proc)->command = Qnil; ! 145: XPROCESS (proc)->pid = Qnil; ! 146: XPROCESS (proc)->kill_without_query = Qt; ! 147: XFASTINT (XPROCESS (proc)->infd) = s; ! 148: XFASTINT (XPROCESS (proc)->outfd) = outch; ! 149: XFASTINT (XPROCESS (proc)->flags) = RUNNING; ! 150: input_wait_mask |= ChannelMask (inch); ! 151: return proc; ! 152: } ! 153: ! 154: ! 155: DEFUN ("accept-process-output", Faccept_process_output, Saccept_process_output, ! 156: 0, 2, 0, ! 157: "Allow any pending output from subprocesses to be read by Emacs.\n\ ! 158: It is read into the process' buffers or given to their filter functions.\n\ ! 159: Non-nil arg PROCESS means do not return until some output has been received\n\ ! 160: from PROCESS. Non-nil arg TIMEOUT means wait for that many seconds, -1\n\ ! 161: return immediately.") ! 162: (proc, timeout) ! 163: register Lisp_Object proc, timeout; ! 164: { ! 165: if (NULL (proc)) { ! 166: if (XTYPE(timeout) == Lisp_Int) ! 167: timeout = XINT(timeout); ! 168: else ! 169: timeout = -1; ! 170: wait_reading_process_input (timeout, 0, 0); ! 171: } ! 172: else ! 173: { ! 174: if (XTYPE(timeout) == Lisp_Int) ! 175: timeout = XINT(timeout); ! 176: else ! 177: timeout = 0; ! 178: proc = get_process (proc); ! 179: wait_reading_process_input (timeout, XPROCESS (proc), 0); ! 180: } ! 181: return Qnil; ! 182: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.