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