(fortran-imenu-generic-expression): Match
[emacs.git] / lib-src / emacsclient.c
blob97261b716aeff91689122e71e091e4bb6f41ea16
1 /* Client process that communicates with GNU Emacs acting as server.
2 Copyright (C) 1986, 1987, 1994 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
22 #define NO_SHORTNAMES
23 #include <../src/config.h>
24 #undef read
25 #undef write
26 #undef open
27 #undef close
28 #undef signal
30 #include <stdio.h>
31 #include <getopt.h>
33 char *getenv (), *getwd ();
34 char *getcwd ();
35 int geteuid ();
37 /* This is defined with -D from the compilation command,
38 which extracts it from ../lisp/version.el. */
40 #ifndef VERSION
41 #define VERSION "unspecified"
42 #endif
44 /* Name used to invoke this program. */
45 char *progname;
47 /* Nonzero means don't wait for a response from Emacs. --no-wait. */
48 int nowait = 0;
50 struct option longopts[] =
52 { "no-wait", no_argument, NULL, 'n' },
53 { "help", no_argument, NULL, 'H' },
54 { "version", no_argument, NULL, 'V' },
55 { 0 }
58 /* Decode the options from argv and argc.
59 The global variable `optind' will say how many arguments we used up. */
61 void
62 decode_options (argc, argv)
63 int argc;
64 char **argv;
66 while (1)
68 int opt = getopt_long (argc, argv,
69 "VHn", longopts, 0);
71 if (opt == EOF)
72 break;
74 switch (opt)
76 case 0:
77 /* If getopt returns 0, then it has already processed a
78 long-named option. We should do nothing. */
79 break;
81 case 'n':
82 nowait = 1;
83 break;
85 case 'V':
86 fprintf (stderr, "Version %s\n", VERSION);
87 exit (1);
88 break;
90 case 'H':
91 default:
92 print_help_and_exit ();
97 print_help_and_exit ()
99 fprintf (stderr,
100 "Usage: %s [-n] [--no-wait] [+LINENUMBER] FILENAME\n",
101 progname);
102 fprintf (stderr,
103 "Report bugs to bug-gnu-emacs@prep.ai.mit.edu.\n");
104 exit (1);
107 /* Return a copy of NAME, inserting a &
108 before each &, each space, and any initial -.
109 Change spaces to underscores, too, so that the
110 return value never contains a space. */
112 char *
113 quote_file_name (name)
114 char *name;
116 char *copy = (char *) malloc (strlen (name) * 2 + 1);
117 char *p, *q;
119 p = name;
120 q = copy;
121 while (*p)
123 if (*p == ' ')
125 *q++ = '&';
126 *q++ = '_';
127 p++;
129 else
131 if (*p == '&' || (*p == '-' && p == name))
132 *q++ = '&';
133 *q++ = *p++;
136 *q++ = 0;
138 return copy;
141 #ifdef C_ALLOCA
142 /* Like malloc but get fatal error if memory is exhausted. */
144 char *
145 xmalloc (size)
146 unsigned int size;
148 char *result = (char *) malloc (size);
149 if (result == NULL)
151 perror ("malloc");
152 exit (1);
154 return result;
156 #endif /* C_ALLOCA */
158 #if !defined (HAVE_SOCKETS) && !defined (HAVE_SYSVIPC)
160 main (argc, argv)
161 int argc;
162 char **argv;
164 fprintf (stderr, "%s: Sorry, the Emacs server is supported only\n",
165 argv[0]);
166 fprintf (stderr, "on systems with Berkeley sockets or System V IPC.\n");
167 exit (1);
170 #else /* HAVE_SOCKETS or HAVE_SYSVIPC */
172 #if defined (HAVE_SOCKETS) && ! defined (NO_SOCKETS_IN_FILE_SYSTEM)
173 /* BSD code is very different from SYSV IPC code */
175 #include <sys/types.h>
176 #include <sys/socket.h>
177 #include <sys/un.h>
178 #include <sys/stat.h>
179 #include <errno.h>
181 extern char *strerror ();
182 extern int errno;
185 main (argc, argv)
186 int argc;
187 char **argv;
189 char system_name[32];
190 int s, i;
191 FILE *out, *in;
192 struct sockaddr_un server;
193 char *homedir, *cwd, *str;
194 char string[BUFSIZ];
196 progname = argv[0];
198 /* Process options. */
199 decode_options (argc, argv);
201 if (argc - optind < 1)
202 print_help_and_exit ();
205 * Open up an AF_UNIX socket in this person's home directory
208 if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
210 fprintf (stderr, "%s: ", argv[0]);
211 perror ("socket");
212 exit (1);
214 server.sun_family = AF_UNIX;
215 #ifndef SERVER_HOME_DIR
217 struct stat statbfr;
219 gethostname (system_name, sizeof (system_name));
220 sprintf (server.sun_path, "/tmp/esrv%d-%s", geteuid (), system_name);
222 if (stat (server.sun_path, &statbfr) == -1)
224 if (errno == ENOENT)
225 fprintf (stderr,
226 "%s: can't find socket; have you started the server?\n",
227 argv[0]);
228 else
229 fprintf (stderr, "%s: can't stat %s: %s\n",
230 argv[0], server.sun_path, strerror (errno));
231 exit (1);
233 if (statbfr.st_uid != geteuid ())
235 fprintf (stderr, "%s: Invalid socket owner\n", argv[0]);
236 exit (1);
239 #else
240 if ((homedir = getenv ("HOME")) == NULL)
242 fprintf (stderr, "%s: No home directory\n", argv[0]);
243 exit (1);
245 strcpy (server.sun_path, homedir);
246 strcat (server.sun_path, "/.emacs-server-");
247 gethostname (system_name, sizeof (system_name));
248 strcat (server.sun_path, system_name);
249 #endif
251 if (connect (s, (struct sockaddr *) &server, strlen (server.sun_path) + 2)
252 < 0)
254 fprintf (stderr, "%s: ", argv[0]);
255 perror ("connect");
256 exit (1);
259 /* We use the stream OUT to send our command to the server. */
260 if ((out = fdopen (s, "r+")) == NULL)
262 fprintf (stderr, "%s: ", argv[0]);
263 perror ("fdopen");
264 exit (1);
267 /* We use the stream IN to read the response.
268 We used to use just one stream for both output and input
269 on the socket, but reversing direction works nonportably:
270 on some systems, the output appears as the first input;
271 on other systems it does not. */
272 if ((in = fdopen (s, "r+")) == NULL)
274 fprintf (stderr, "%s: ", argv[0]);
275 perror ("fdopen");
276 exit (1);
279 #ifdef BSD_SYSTEM
280 cwd = getwd (string);
281 #else
282 cwd = getcwd (string, sizeof string);
283 #endif
284 if (cwd == 0)
286 /* getwd puts message in STRING if it fails. */
287 fprintf (stderr, "%s: %s (%s)\n", argv[0],
288 #ifdef BSD_SYSTEM
289 string,
290 #else
291 "Cannot get current working directory",
292 #endif
293 strerror (errno));
294 exit (1);
297 if (nowait)
298 fprintf (out, "-nowait ");
300 for (i = optind; i < argc; i++)
302 if (*argv[i] == '+')
304 char *p = argv[i] + 1;
305 while (*p >= '0' && *p <= '9') p++;
306 if (*p != 0)
307 fprintf (out, "%s/", cwd);
309 else if (*argv[i] != '/')
310 fprintf (out, "%s/", cwd);
312 fprintf (out, "%s ", quote_file_name (argv[i]));
314 fprintf (out, "\n");
315 fflush (out);
317 /* Maybe wait for an answer. */
318 if (nowait)
319 return 0;
321 printf ("Waiting for Emacs...");
322 fflush (stdout);
324 /* Now, wait for an answer and print any messages. On some systems,
325 the first line we read will actually be the output we just sent.
326 We can't predict whether that will happen, so if it does, we
327 detect it by recognizing `Client: ' at the beginning. */
329 while (str = fgets (string, BUFSIZ, in))
330 printf ("%s", str);
332 return 0;
335 #else /* This is the SYSV IPC section */
337 #include <sys/types.h>
338 #include <sys/ipc.h>
339 #include <sys/msg.h>
340 #include <sys/utsname.h>
341 #include <stdio.h>
342 #include <errno.h>
343 extern int errno;
345 char *getwd (), *getcwd (), *getenv ();
346 struct utsname system_name;
348 main (argc, argv)
349 int argc;
350 char **argv;
352 int s;
353 key_t key;
354 /* Size of text allocated in MSGP. */
355 int size_allocated = BUFSIZ;
356 /* Amount of text used in MSGP. */
357 int used;
358 struct msgbuf *msgp
359 = (struct msgbuf *) malloc (sizeof (struct msgbuf) + size_allocated);
360 struct msqid_ds * msg_st;
361 char *homedir, buf[BUFSIZ];
362 char gwdirb[BUFSIZ];
363 char *cwd;
364 char *temp;
366 progname = argv[0];
368 /* Process options. */
369 decode_options (argc, argv);
371 if (argc - optind < 1)
372 print_help_and_exit ();
375 * Create a message queue using ~/.emacs-server as the path for ftok
377 if ((homedir = getenv ("HOME")) == NULL)
379 fprintf (stderr, "%s: No home directory\n", argv[0]);
380 exit (1);
382 strcpy (buf, homedir);
383 #ifndef HAVE_LONG_FILE_NAMES
384 /* If file names are short, we can't fit the host name. */
385 strcat (buf, "/.emacs-server");
386 #else
387 strcat (buf, "/.emacs-server-");
388 uname (&system_name);
389 strcat (buf, system_name.nodename);
390 #endif
391 creat (buf, 0600);
392 key = ftok (buf, 1); /* unlikely to be anyone else using it */
393 s = msgget (key, 0600 | IPC_CREAT);
394 if (s == -1)
396 fprintf (stderr, "%s: ", argv[0]);
397 perror ("msgget");
398 exit (1);
401 /* Determine working dir, so we can prefix it to all the arguments. */
402 #ifdef BSD_SYSTEM
403 temp = getwd (gwdirb);
404 #else
405 temp = getcwd (gwdirb, sizeof gwdirb);
406 #endif
408 cwd = gwdirb;
409 if (temp != 0)
411 /* On some systems, cwd can look like `@machine/...';
412 ignore everything before the first slash in such a case. */
413 while (*cwd && *cwd != '/')
414 cwd++;
415 strcat (cwd, "/");
417 else
419 #ifdef BSD_SYSTEM
420 fprintf (stderr, "%s: %s\n", argv[0], cwd);
421 #else
422 fprintf (stderr, "%s: Cannot get current working directory: %s\n",
423 argv[0], strerror (errno));
424 #endif
425 exit (1);
428 msgp->mtext[0] = 0;
429 used = 0;
431 if (nowait)
433 strcat (msgp->mtext, "-nowait ");
434 used += 8;
437 argc -= optind;
438 argv += optind;
440 while (argc)
442 int need_cwd = 0;
443 char *modified_arg = argv[0];
445 if (*modified_arg == '+')
447 char *p = modified_arg + 1;
448 while (*p >= '0' && *p <= '9') p++;
449 if (*p != 0)
450 need_cwd = 1;
452 else if (*modified_arg != '/')
453 need_cwd = 1;
455 modified_arg = quote_file_name (modified_arg);
457 if (need_cwd)
458 used += strlen (cwd);
459 used += strlen (modified_arg) + 1;
460 while (used + 2 > size_allocated)
462 size_allocated *= 2;
463 msgp = (struct msgbuf *) realloc (msgp,
464 (sizeof (struct msgbuf)
465 + size_allocated));
468 if (need_cwd)
469 strcat (msgp->mtext, cwd);
471 strcat (msgp->mtext, modified_arg);
472 strcat (msgp->mtext, " ");
473 argv++; argc--;
475 strcat (msgp->mtext, "\n");
476 #ifdef HPUX /* HPUX has a bug. */
477 if (strlen (msgp->mtext) >= 512)
479 fprintf (stderr, "%s: args too long for msgsnd\n", progname);
480 exit (1);
482 #endif
483 msgp->mtype = 1;
484 if (msgsnd (s, msgp, strlen (msgp->mtext)+1, 0) < 0)
486 fprintf (stderr, "%s: ", progname);
487 perror ("msgsnd");
488 exit (1);
491 /* Maybe wait for an answer. */
492 if (nowait)
493 return 0;
495 printf ("Waiting for Emacs...");
496 fflush (stdout);
498 msgrcv (s, msgp, BUFSIZ, getpid (), 0); /* wait for anything back */
499 strcpy (buf, msgp->mtext);
501 printf ("\n");
502 if (*buf)
503 printf ("%s\n", buf);
504 exit (0);
507 #endif /* HAVE_SYSVIPC */
509 #endif /* HAVE_SOCKETS or HAVE_SYSVIPC */
511 #ifndef HAVE_STRERROR
512 char *
513 strerror (errnum)
514 int errnum;
516 extern char *sys_errlist[];
517 extern int sys_nerr;
519 if (errnum >= 0 && errnum < sys_nerr)
520 return sys_errlist[errnum];
521 return (char *) "Unknown error";
524 #endif /* ! HAVE_STRERROR */