Mercurial > hg > xemacs-beta
comparison lib-src/gnuclient.c @ 149:538048ae2ab8 r20-3b1
Import from CVS: tag r20-3b1
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:36:16 +0200 |
parents | 360340f9fd5f |
children | 59463afc5666 |
comparison
equal
deleted
inserted
replaced
148:f659db2a1f73 | 149:538048ae2ab8 |
---|---|
1 /* -*-C-*- | 1 /* -*-C-*- |
2 Client code to allow local and remote editing of files by XEmacs. | 2 Client code to allow local and remote editing of files by XEmacs. |
3 Copyright (C) 1989 Free Software Foundation, Inc. | 3 Copyright (C) 1989 Free Software Foundation, Inc. |
4 Copyright (C) 1995 Sun Microsystems, Inc. | 4 Copyright (C) 1995 Sun Microsystems, Inc. |
5 Copyright (C) 1997 Free Software Foundation, Inc. | |
5 | 6 |
6 This file is part of XEmacs. | 7 This file is part of XEmacs. |
7 | 8 |
8 XEmacs is free software; you can redistribute it and/or modify it | 9 XEmacs is free software; you can redistribute it and/or modify it |
9 under the terms of the GNU General Public License as published by the | 10 under the terms of the GNU General Public License as published by the |
44 #include "gnuserv.h" | 45 #include "gnuserv.h" |
45 #include "getopt.h" | 46 #include "getopt.h" |
46 | 47 |
47 #include <stdio.h> | 48 #include <stdio.h> |
48 #include <stdlib.h> | 49 #include <stdlib.h> |
50 #ifdef HAVE_STRING_H | |
49 #include <string.h> | 51 #include <string.h> |
52 #endif /* HAVE_STRING_H */ | |
50 #include <sys/types.h> | 53 #include <sys/types.h> |
54 #ifdef HAVE_UNISTD_H | |
51 #include <unistd.h> | 55 #include <unistd.h> |
56 #endif /* HAVE_UNISTD_H */ | |
57 #include <signal.h> | |
58 | |
52 | 59 |
53 #if !defined(SYSV_IPC) && !defined(UNIX_DOMAIN_SOCKETS) && \ | 60 #if !defined(SYSV_IPC) && !defined(UNIX_DOMAIN_SOCKETS) && \ |
54 !defined(INTERNET_DOMAIN_SOCKETS) | 61 !defined(INTERNET_DOMAIN_SOCKETS) |
55 int | 62 int |
56 main (int argc, char *argv[]) | 63 main (int argc, char *argv[]) |
64 #else /* SYSV_IPC || UNIX_DOMAIN_SOCKETS || INTERNET_DOMAIN_SOCKETS */ | 71 #else /* SYSV_IPC || UNIX_DOMAIN_SOCKETS || INTERNET_DOMAIN_SOCKETS */ |
65 | 72 |
66 static char cwd[MAXPATHLEN+2]; /* current working directory when calculated */ | 73 static char cwd[MAXPATHLEN+2]; /* current working directory when calculated */ |
67 static char *cp = NULL; /* ptr into valid bit of cwd above */ | 74 static char *cp = NULL; /* ptr into valid bit of cwd above */ |
68 | 75 |
69 #ifdef GNUATTACH | |
70 #include <signal.h> | |
71 | |
72 static pid_t emacs_pid; /* Process id for emacs process */ | 76 static pid_t emacs_pid; /* Process id for emacs process */ |
73 | 77 |
74 void tell_emacs_to_resume(int sig) | 78 void initialize_signals (void); |
75 { | 79 |
76 char buffer[GSERV_BUFSZ+1]; | 80 void |
77 int s; /* socket / msqid to server */ | 81 tell_emacs_to_resume (int sig) |
78 int connect_type; /* CONN_UNIX, CONN_INTERNET, or | 82 { |
79 * CONN_IPC */ | 83 char buffer[GSERV_BUFSZ+1]; |
84 int s; /* socket / msqid to server */ | |
85 int connect_type; /* CONN_UNIX, CONN_INTERNET, or | |
86 ONN_IPC */ | |
80 | 87 |
81 /* Why is SYSV so retarded? */ | 88 /* Why is SYSV so retarded? */ |
82 /* We want emacs to realize that we are resuming */ | 89 /* We want emacs to realize that we are resuming */ |
83 signal(SIGCONT, tell_emacs_to_resume); | 90 signal(SIGCONT, tell_emacs_to_resume); |
84 | 91 |
85 connect_type = make_connection (NULL, (u_short) 0, &s); | 92 connect_type = make_connection (NULL, (u_short) 0, &s); |
86 | 93 |
87 sprintf(buffer,"(server-eval '(resume-pid-console %d))", getpid()); | 94 sprintf(buffer,"(gnuserv-eval '(resume-pid-console %d))", getpid()); |
88 send_string(s, buffer); | 95 send_string(s, buffer); |
89 | 96 |
90 #ifdef SYSV_IPC | 97 #ifdef SYSV_IPC |
91 if (connect_type == (int) CONN_IPC) | 98 if (connect_type == (int) CONN_IPC) |
92 disconnect_from_ipc_server (s, msgp, FALSE); | 99 disconnect_from_ipc_server (s, msgp, FALSE); |
93 #else /* !SYSV_IPC */ | 100 #else /* !SYSV_IPC */ |
94 if (connect_type != (int) CONN_IPC) | 101 if (connect_type != (int) CONN_IPC) |
95 disconnect_from_server (s, FALSE); | 102 disconnect_from_server (s, FALSE); |
96 #endif /* !SYSV_IPC */ | 103 #endif /* !SYSV_IPC */ |
97 } | 104 } |
98 | 105 |
99 void pass_signal_to_emacs(int sig) | 106 void |
100 { | 107 pass_signal_to_emacs (int sig) |
101 if (kill(emacs_pid, sig) == -1) { | 108 { |
102 fprintf(stderr, "gnuattach: Could not pass signal to emacs process\n"); | 109 if (kill (emacs_pid, sig) == -1) |
103 exit(1); | 110 { |
104 } | 111 fprintf (stderr, "gnuattach: Could not pass signal to emacs process\n"); |
112 exit (1); | |
113 } | |
114 initialize_signals (); | |
105 } | 115 } |
106 | 116 |
107 void initialize_signals() | 117 void |
108 { | 118 initialize_signals () |
109 /* Set up signal handler to pass relevant signals to emacs process */ | 119 { |
110 signal(SIGHUP, pass_signal_to_emacs); | 120 /* Set up signal handler to pass relevant signals to emacs process. |
111 signal(SIGQUIT, pass_signal_to_emacs); | 121 We used to send SIGSEGV, SIGBUS, SIGPIPE, SIGILL and others to |
112 signal(SIGILL, pass_signal_to_emacs); | 122 Emacs, but I think it's better not to. I can see no reason why |
113 signal(SIGTRAP, pass_signal_to_emacs); | 123 Emacs should SIGSEGV whenever gnuclient SIGSEGV-s, etc. */ |
114 signal(SIGSEGV, pass_signal_to_emacs); | 124 signal (SIGHUP, pass_signal_to_emacs); |
115 signal(SIGPIPE, pass_signal_to_emacs); | 125 signal (SIGQUIT, pass_signal_to_emacs); |
116 signal(SIGTERM, pass_signal_to_emacs); | 126 signal (SIGINT, pass_signal_to_emacs); |
117 #ifdef SIGBUS | |
118 signal(SIGBUS, pass_signal_to_emacs); | |
119 #endif | |
120 #ifdef SIGIOT | |
121 signal(SIGIOT, pass_signal_to_emacs); | |
122 #endif | |
123 | 127 |
124 /* We want emacs to realize that we are resuming */ | 128 /* We want emacs to realize that we are resuming */ |
125 signal(SIGCONT, tell_emacs_to_resume); | 129 signal (SIGCONT, tell_emacs_to_resume); |
126 } | 130 } |
127 | |
128 #endif /* GNUATTACH */ | |
129 | 131 |
130 | 132 |
131 /* | 133 /* |
132 get_current_working_directory -- return the cwd. | 134 get_current_working_directory -- return the cwd. |
133 */ | 135 */ |
190 | 192 |
191 int | 193 int |
192 main (int argc, char *argv[]) | 194 main (int argc, char *argv[]) |
193 { | 195 { |
194 int starting_line = 1; /* line to start editing at */ | 196 int starting_line = 1; /* line to start editing at */ |
195 char command[MAXPATHLEN+50]; /* emacs command buffer */ | 197 char command[MAXPATHLEN+50]; /* emacs command buffer */ |
196 char fullpath[MAXPATHLEN+1]; /* full pathname to file */ | 198 char fullpath[MAXPATHLEN+1]; /* full pathname to file */ |
197 #ifndef GNUATTACH | |
198 int qflg = 0; /* quick edit, don't wait for | 199 int qflg = 0; /* quick edit, don't wait for |
199 * user to finish */ | 200 * user to finish */ |
200 #endif | 201 int view = 0; /* view only. */ |
201 int errflg = 0; /* option error */ | 202 int errflg = 0; /* option error */ |
202 int c; /* char from getopt */ | 203 int c; /* char from getopt */ |
203 int s; /* socket / msqid to server */ | 204 int s; /* socket / msqid to server */ |
204 int connect_type; /* CONN_UNIX, CONN_INTERNET, or | 205 int connect_type; /* CONN_UNIX, CONN_INTERNET, or |
205 * CONN_IPC */ | 206 * CONN_IPC */ |
207 int suppress_windows_system = 0; | |
208 char *display; | |
206 #ifdef INTERNET_DOMAIN_SOCKETS | 209 #ifdef INTERNET_DOMAIN_SOCKETS |
207 char *hostarg = NULL; /* remote hostname */ | 210 char *hostarg = NULL; /* remote hostname */ |
208 char thishost[HOSTNAMSZ]; /* this hostname */ | 211 char thishost[HOSTNAMSZ]; /* this hostname */ |
209 char remotepath[MAXPATHLEN+1]; /* remote pathname */ | 212 char remotepath[MAXPATHLEN+1]; /* remote pathname */ |
210 int rflg = 0; /* pathname given on cmdline */ | 213 int rflg = 0; /* pathname given on cmdline */ |
212 char *ptr; /* return from getenv */ | 215 char *ptr; /* return from getenv */ |
213 #endif /* INTERNET_DOMAIN_SOCKETS */ | 216 #endif /* INTERNET_DOMAIN_SOCKETS */ |
214 #ifdef SYSV_IPC | 217 #ifdef SYSV_IPC |
215 struct msgbuf *msgp; /* message */ | 218 struct msgbuf *msgp; /* message */ |
216 #endif /* SYSV_IPC */ | 219 #endif /* SYSV_IPC */ |
217 #ifdef GNUATTACH | |
218 char *tty; | 220 char *tty; |
219 char buffer[GSERV_BUFSZ+1]; /* buffer to read pid */ | 221 char buffer[GSERV_BUFSZ+1]; /* buffer to read pid */ |
220 #endif | |
221 | 222 |
222 #ifdef INTERNET_DOMAIN_SOCKETS | 223 #ifdef INTERNET_DOMAIN_SOCKETS |
223 memset (remotepath, 0, sizeof (remotepath)); | 224 memset (remotepath, 0, sizeof (remotepath)); |
224 #endif /* INTERNET_DOMAIN_SOCKETS */ | 225 #endif /* INTERNET_DOMAIN_SOCKETS */ |
225 | 226 |
226 progname = argv[0]; | 227 progname = argv[0]; |
227 | 228 |
229 display = getenv ("DISPLAY"); | |
230 if (!display) | |
231 suppress_windows_system = 1; | |
232 | |
228 while ((c = getopt (argc, argv, | 233 while ((c = getopt (argc, argv, |
229 | 234 |
230 #ifdef INTERNET_DOMAIN_SOCKETS | 235 #ifdef INTERNET_DOMAIN_SOCKETS |
231 "h:p:r:q" | 236 "n:h:p:r:qv" |
232 #else /* !INTERNET_DOMAIN_SOCKETS */ | 237 #else /* !INTERNET_DOMAIN_SOCKETS */ |
233 # ifdef GNUATTACH | 238 "n:qv" |
234 "" | |
235 # else | |
236 "q" | |
237 # endif | |
238 #endif /* !INTERNET_DOMAIN_SOCKETS */ | 239 #endif /* !INTERNET_DOMAIN_SOCKETS */ |
239 | 240 |
240 )) != EOF) | 241 )) != EOF) |
241 switch (c) | 242 switch (c) |
242 { | 243 { |
243 #ifndef GNUATTACH | 244 case 'n': |
245 if (*optarg == 'w') | |
246 suppress_windows_system++; | |
247 else | |
248 errflg++; | |
249 break; | |
244 case 'q': /* quick mode specified */ | 250 case 'q': /* quick mode specified */ |
245 qflg++; | 251 qflg++; |
246 break; | 252 break; |
247 #endif | 253 case 'v': |
254 view++; | |
255 break; | |
248 | 256 |
249 #ifdef INTERNET_DOMAIN_SOCKETS | 257 #ifdef INTERNET_DOMAIN_SOCKETS |
250 case 'h': /* server host name specified */ | 258 case 'h': /* server host name specified */ |
251 hostarg = optarg; | 259 hostarg = optarg; |
252 break; | 260 break; |
268 fprintf (stderr, | 276 fprintf (stderr, |
269 #ifdef INTERNET_DOMAIN_SOCKETS | 277 #ifdef INTERNET_DOMAIN_SOCKETS |
270 "usage: %s [-q] [-h hostname] [-p port] [-r pathname] " | 278 "usage: %s [-q] [-h hostname] [-p port] [-r pathname] " |
271 "[[+line] path] ...\n", | 279 "[[+line] path] ...\n", |
272 #else /* !INTERNET_DOMAIN_SOCKETS */ | 280 #else /* !INTERNET_DOMAIN_SOCKETS */ |
273 # ifdef GNUATTACH | 281 "usage: %s [-nw] [-q] [[+line] path] ...\n", |
274 "usage: %s [[+line] path] ...\n", | |
275 # else | |
276 "usage: %s [-q] [[+line] path] ...\n", | |
277 # endif | |
278 #endif /* !INTERNET_DOMAIN_SOCKETS */ | 282 #endif /* !INTERNET_DOMAIN_SOCKETS */ |
279 progname); | 283 progname); |
280 exit (1); | 284 exit (1); |
281 } /* if */ | 285 } /* if */ |
282 | 286 |
283 #ifdef GNUATTACH | 287 if (suppress_windows_system) |
284 tty = ttyname (0); | 288 { |
285 if (!tty) | 289 tty = ttyname (0); |
286 { | 290 if (!tty) |
287 fprintf (stderr, "%s: Not connected to a tty", progname); | 291 { |
292 fprintf (stderr, "%s: Not connected to a tty", progname); | |
293 exit (1); | |
294 } | |
295 } | |
296 /* This next stuff added in an attempt to make handling of the tty | |
297 do the right thing when dealing with signals. The idea is to | |
298 pass all the appropriate signals to the emacs process. */ | |
299 | |
300 connect_type = make_connection (NULL, (u_short) 0, &s); | |
301 | |
302 send_string (s, "(gnuserv-eval '(emacs-pid))"); | |
303 send_string (s, EOT_STR); | |
304 | |
305 if (read_line (s, buffer) == 0) | |
306 { | |
307 fprintf (stderr, "%s: Could not establish emacs procces id\n", | |
308 progname); | |
288 exit (1); | 309 exit (1); |
289 } | 310 } |
290 | 311 /* Don't do disconnect_from_server becasue we have already read |
291 /* This next stuff added in an attempt to make handling of | 312 data, and disconnect doesn't do anything else. */ |
292 the tty do the right thing when dealing with signals. | |
293 Idea is to pass all the appropriate signals to the emacs process | |
294 */ | |
295 | |
296 connect_type = make_connection (NULL, (u_short) 0, &s); | |
297 | |
298 send_string(s,"(server-eval '(emacs-pid))"); | |
299 send_string(s,EOT_STR); | |
300 | |
301 if (read_line(s,buffer) == 0) { | |
302 fprintf(stderr, "%s: Could not establish emacs procces id\n",progname); | |
303 exit(1); | |
304 } | |
305 /* don't do disconnect_from_server becasue we have already read data, | |
306 and disconnect doesn't do anything else | |
307 */ | |
308 #ifdef SYSV_IPC | 313 #ifdef SYSV_IPC |
309 if (connect_type == (int) CONN_IPC) | 314 if (connect_type == (int) CONN_IPC) |
310 disconnect_from_ipc_server (s, msgp, FALSE); | 315 disconnect_from_ipc_server (s, msgp, FALSE); |
311 #endif /* !SYSV_IPC */ | 316 #endif /* !SYSV_IPC */ |
312 | 317 |
313 emacs_pid = (pid_t)atol(buffer); | 318 emacs_pid = (pid_t)atol(buffer); |
314 initialize_signals(); | 319 initialize_signals(); |
315 | |
316 #endif /*GNUATTACH */ | |
317 | 320 |
318 #if defined(INTERNET_DOMAIN_SOCKETS) && !defined(GNUATTACH) | 321 #if defined(INTERNET_DOMAIN_SOCKETS) && !defined(GNUATTACH) |
319 connect_type = make_connection (hostarg, portarg, &s); | 322 connect_type = make_connection (hostarg, portarg, &s); |
320 #else | 323 #else |
321 connect_type = make_connection (NULL, (u_short) 0, &s); | 324 connect_type = make_connection (NULL, (u_short) 0, &s); |
358 } /* if */ | 361 } /* if */ |
359 | 362 |
360 msgp->mtext[0] = '\0'; /* ready for later strcats */ | 363 msgp->mtext[0] = '\0'; /* ready for later strcats */ |
361 #endif /* SYSV_IPC */ | 364 #endif /* SYSV_IPC */ |
362 | 365 |
363 #ifdef GNUATTACH | 366 if (suppress_windows_system) |
364 ptr = getenv ("TERM"); | 367 { |
365 if (!ptr) | 368 ptr = getenv ("TERM"); |
366 { | 369 if (!ptr) |
367 fprintf (stderr, "%s: unknown terminal type\n", progname); | 370 { |
368 exit (1); | 371 fprintf (stderr, "%s: unknown terminal type\n", progname); |
369 } | 372 exit (1); |
370 sprintf (command, "(server-tty-edit-files \"%s\" \"%s\" %d '(", | 373 } |
371 tty, ptr, getpid()); | 374 sprintf (command, |
375 "(gnuserv-edit-files '(tty \"%s\" \"%s\" %d) '(", | |
376 tty, ptr, getpid ()); | |
377 } | |
378 else /* !suppress_windows_system */ | |
379 { | |
380 sprintf (command, "(gnuserv-edit-files '(x \"%s\") '(", | |
381 display); | |
382 } /* !suppress_windows_system */ | |
372 send_string (s, command); | 383 send_string (s, command); |
373 #else | 384 |
374 if (qflg) | 385 if (!suppress_windows_system && (optind == argc)) |
375 { | 386 qflg = 1; |
376 send_string (s, "(server-edit-files-quickly '("); | 387 |
377 } | 388 for (; optind < argc; optind++) |
378 else | 389 { |
379 { | 390 if (optind < argc - 1 && *argv[optind] == '+') |
380 send_string (s, "(server-edit-files '("); | 391 starting_line = atoi (argv[optind++]); |
381 } | 392 else |
393 starting_line = 1; | |
394 /* If the last argument is +something, treat it as a file. */ | |
395 if (optind == argc) | |
396 { | |
397 starting_line = 1; | |
398 --optind; | |
399 } | |
400 filename_expand (fullpath, argv[optind]); | |
401 sprintf (command, "(%d . \"%s%s\")", starting_line, | |
402 #ifdef INTERNET_DOMAIN_SOCKETS | |
403 remotepath, | |
404 #else /* !INTERNET_DOMAIN_SOCKETS */ | |
405 "", | |
382 #endif | 406 #endif |
383 | 407 fullpath); |
384 for (; optind < argc; optind++) | 408 send_string (s, command); |
385 { | |
386 if (*argv[optind] == '+') | |
387 starting_line = atoi (argv[optind]); | |
388 else | |
389 { | |
390 filename_expand (fullpath, argv[optind]); | |
391 sprintf (command, "(%d . \"%s%s\")", starting_line, | |
392 | |
393 #ifdef INTERNET_DOMAIN_SOCKETS | |
394 remotepath, | |
395 #else /* !INTERNET_DOMAIN_SOCKETS */ | |
396 "", | |
397 #endif | |
398 fullpath); | |
399 send_string (s,command); | |
400 starting_line = 1; | |
401 } /* else */ | |
402 } /* for */ | 409 } /* for */ |
403 | 410 |
404 send_string (s,"))"); | 411 sprintf (command, ") %s)", qflg ? "'quick" : (view ? "'view" : "")); |
412 send_string (s, command); | |
405 | 413 |
406 #ifdef SYSV_IPC | 414 #ifdef SYSV_IPC |
407 if (connect_type == (int) CONN_IPC) | 415 if (connect_type == (int) CONN_IPC) |
408 disconnect_from_ipc_server (s, msgp, FALSE); | 416 disconnect_from_ipc_server (s, msgp, FALSE); |
409 #else /* !SYSV_IPC */ | 417 #else /* !SYSV_IPC */ |