|
|
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.