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 */