(type-break-mode): remove :version field from defcustom declaration.
[emacs.git] / lib-src / emacsclient.c
blob07d446b7aa41a608cb4f0db51b18682339734cc3
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>
32 #ifdef STDC_HEADERS
33 #include <stdlib.h>
34 #endif
35 #ifdef HAVE_UNISTD_H
36 #include <unistd.h>
37 #endif
39 char *getenv (), *getwd ();
40 char *getcwd ();
42 /* This is defined with -D from the compilation command,
43 which extracts it from ../lisp/version.el. */
45 #ifndef VERSION
46 #define VERSION "unspecified"
47 #endif
49 /* Name used to invoke this program. */
50 char *progname;
52 /* Nonzero means don't wait for a response from Emacs. --no-wait. */
53 int nowait = 0;
55 void print_help_and_exit ();
57 struct option longopts[] =
59 { "no-wait", no_argument, NULL, 'n' },
60 { "help", no_argument, NULL, 'H' },
61 { "version", no_argument, NULL, 'V' },
62 { 0 }
65 /* Decode the options from argv and argc.
66 The global variable `optind' will say how many arguments we used up. */
68 void
69 decode_options (argc, argv)
70 int argc;
71 char **argv;
73 while (1)
75 int opt = getopt_long (argc, argv,
76 "VHn", longopts, 0);
78 if (opt == EOF)
79 break;
81 switch (opt)
83 case 0:
84 /* If getopt returns 0, then it has already processed a
85 long-named option. We should do nothing. */
86 break;
88 case 'n':
89 nowait = 1;
90 break;
92 case 'V':
93 fprintf (stderr, "Version %s\n", VERSION);
94 exit (1);
95 break;
97 case 'H':
98 default:
99 print_help_and_exit ();
104 void
105 print_help_and_exit ()
107 fprintf (stderr,
108 "Usage: %s [-n] [--no-wait] [+LINENUMBER] FILENAME\n",
109 progname);
110 fprintf (stderr,
111 "Report bugs to bug-gnu-emacs@prep.ai.mit.edu.\n");
112 exit (1);
115 /* Return a copy of NAME, inserting a &
116 before each &, each space, and any initial -.
117 Change spaces to underscores, too, so that the
118 return value never contains a space. */
120 char *
121 quote_file_name (name)
122 char *name;
124 char *copy = (char *) malloc (strlen (name) * 2 + 1);
125 char *p, *q;
127 p = name;
128 q = copy;
129 while (*p)
131 if (*p == ' ')
133 *q++ = '&';
134 *q++ = '_';
135 p++;
137 else
139 if (*p == '&' || (*p == '-' && p == name))
140 *q++ = '&';
141 *q++ = *p++;
144 *q++ = 0;
146 return copy;
149 #ifdef C_ALLOCA
150 /* Like malloc but get fatal error if memory is exhausted. */
152 char *
153 xmalloc (size)
154 unsigned int size;
156 char *result = (char *) malloc (size);
157 if (result == NULL)
159 perror ("malloc");
160 exit (1);
162 return result;
164 #endif /* C_ALLOCA */
166 #if !defined (HAVE_SOCKETS) && !defined (HAVE_SYSVIPC)
168 main (argc, argv)
169 int argc;
170 char **argv;
172 fprintf (stderr, "%s: Sorry, the Emacs server is supported only\n",
173 argv[0]);
174 fprintf (stderr, "on systems with Berkeley sockets or System V IPC.\n");
175 exit (1);
178 #else /* HAVE_SOCKETS or HAVE_SYSVIPC */
180 #if defined (HAVE_SOCKETS) && ! defined (NO_SOCKETS_IN_FILE_SYSTEM)
181 /* BSD code is very different from SYSV IPC code */
183 #include <sys/types.h>
184 #include <sys/socket.h>
185 #include <sys/un.h>
186 #include <sys/stat.h>
187 #include <errno.h>
189 extern char *strerror ();
190 extern int errno;
193 main (argc, argv)
194 int argc;
195 char **argv;
197 char system_name[32];
198 int s, i;
199 FILE *out, *in;
200 struct sockaddr_un server;
201 char *homedir, *cwd, *str;
202 char string[BUFSIZ];
204 progname = argv[0];
206 /* Process options. */
207 decode_options (argc, argv);
209 if (argc - optind < 1)
210 print_help_and_exit ();
213 * Open up an AF_UNIX socket in this person's home directory
216 if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
218 fprintf (stderr, "%s: ", argv[0]);
219 perror ("socket");
220 exit (1);
222 server.sun_family = AF_UNIX;
223 #ifndef SERVER_HOME_DIR
225 struct stat statbfr;
227 gethostname (system_name, sizeof (system_name));
228 sprintf (server.sun_path, "/tmp/esrv%d-%s", geteuid (), system_name);
230 if (stat (server.sun_path, &statbfr) == -1)
232 if (errno == ENOENT)
233 fprintf (stderr,
234 "%s: can't find socket; have you started the server?\n",
235 argv[0]);
236 else
237 fprintf (stderr, "%s: can't stat %s: %s\n",
238 argv[0], server.sun_path, strerror (errno));
239 exit (1);
241 if (statbfr.st_uid != geteuid ())
243 fprintf (stderr, "%s: Invalid socket owner\n", argv[0]);
244 exit (1);
247 #else
248 if ((homedir = getenv ("HOME")) == NULL)
250 fprintf (stderr, "%s: No home directory\n", argv[0]);
251 exit (1);
253 strcpy (server.sun_path, homedir);
254 strcat (server.sun_path, "/.emacs-server-");
255 gethostname (system_name, sizeof (system_name));
256 strcat (server.sun_path, system_name);
257 #endif
259 if (connect (s, (struct sockaddr *) &server, strlen (server.sun_path) + 2)
260 < 0)
262 fprintf (stderr, "%s: ", argv[0]);
263 perror ("connect");
264 exit (1);
267 /* We use the stream OUT to send our command to the server. */
268 if ((out = fdopen (s, "r+")) == NULL)
270 fprintf (stderr, "%s: ", argv[0]);
271 perror ("fdopen");
272 exit (1);
275 /* We use the stream IN to read the response.
276 We used to use just one stream for both output and input
277 on the socket, but reversing direction works nonportably:
278 on some systems, the output appears as the first input;
279 on other systems it does not. */
280 if ((in = fdopen (s, "r+")) == NULL)
282 fprintf (stderr, "%s: ", argv[0]);
283 perror ("fdopen");
284 exit (1);
287 #ifdef BSD_SYSTEM
288 cwd = getwd (string);
289 #else
290 cwd = getcwd (string, sizeof string);
291 #endif
292 if (cwd == 0)
294 /* getwd puts message in STRING if it fails. */
295 fprintf (stderr, "%s: %s (%s)\n", argv[0],
296 #ifdef BSD_SYSTEM
297 string,
298 #else
299 "Cannot get current working directory",
300 #endif
301 strerror (errno));
302 exit (1);
305 if (nowait)
306 fprintf (out, "-nowait ");
308 for (i = optind; i < argc; i++)
310 if (*argv[i] == '+')
312 char *p = argv[i] + 1;
313 while (*p >= '0' && *p <= '9') p++;
314 if (*p != 0)
315 fprintf (out, "%s/", cwd);
317 else if (*argv[i] != '/')
318 fprintf (out, "%s/", cwd);
320 fprintf (out, "%s ", quote_file_name (argv[i]));
322 fprintf (out, "\n");
323 fflush (out);
325 /* Maybe wait for an answer. */
326 if (nowait)
327 return 0;
329 printf ("Waiting for Emacs...");
330 fflush (stdout);
332 /* Now, wait for an answer and print any messages. On some systems,
333 the first line we read will actually be the output we just sent.
334 We can't predict whether that will happen, so if it does, we
335 detect it by recognizing `Client: ' at the beginning. */
337 while (str = fgets (string, BUFSIZ, in))
338 printf ("%s", str);
340 return 0;
343 #else /* This is the SYSV IPC section */
345 #include <sys/types.h>
346 #include <sys/ipc.h>
347 #include <sys/msg.h>
348 #include <sys/utsname.h>
349 #include <stdio.h>
350 #include <errno.h>
351 extern int errno;
353 char *getwd (), *getcwd (), *getenv ();
354 struct utsname system_name;
356 main (argc, argv)
357 int argc;
358 char **argv;
360 int s;
361 key_t key;
362 /* Size of text allocated in MSGP. */
363 int size_allocated = BUFSIZ;
364 /* Amount of text used in MSGP. */
365 int used;
366 struct msgbuf *msgp
367 = (struct msgbuf *) malloc (sizeof (struct msgbuf) + size_allocated);
368 struct msqid_ds * msg_st;
369 char *homedir, buf[BUFSIZ];
370 char gwdirb[BUFSIZ];
371 char *cwd;
372 char *temp;
374 progname = argv[0];
376 /* Process options. */
377 decode_options (argc, argv);
379 if (argc - optind < 1)
380 print_help_and_exit ();
383 * Create a message queue using ~/.emacs-server as the path for ftok
385 if ((homedir = getenv ("HOME")) == NULL)
387 fprintf (stderr, "%s: No home directory\n", argv[0]);
388 exit (1);
390 strcpy (buf, homedir);
391 #ifndef HAVE_LONG_FILE_NAMES
392 /* If file names are short, we can't fit the host name. */
393 strcat (buf, "/.emacs-server");
394 #else
395 strcat (buf, "/.emacs-server-");
396 uname (&system_name);
397 strcat (buf, system_name.nodename);
398 #endif
399 creat (buf, 0600);
400 key = ftok (buf, 1); /* unlikely to be anyone else using it */
401 s = msgget (key, 0600 | IPC_CREAT);
402 if (s == -1)
404 fprintf (stderr, "%s: ", argv[0]);
405 perror ("msgget");
406 exit (1);
409 /* Determine working dir, so we can prefix it to all the arguments. */
410 #ifdef BSD_SYSTEM
411 temp = getwd (gwdirb);
412 #else
413 temp = getcwd (gwdirb, sizeof gwdirb);
414 #endif
416 cwd = gwdirb;
417 if (temp != 0)
419 /* On some systems, cwd can look like `@machine/...';
420 ignore everything before the first slash in such a case. */
421 while (*cwd && *cwd != '/')
422 cwd++;
423 strcat (cwd, "/");
425 else
427 #ifdef BSD_SYSTEM
428 fprintf (stderr, "%s: %s\n", argv[0], cwd);
429 #else
430 fprintf (stderr, "%s: Cannot get current working directory: %s\n",
431 argv[0], strerror (errno));
432 #endif
433 exit (1);
436 msgp->mtext[0] = 0;
437 used = 0;
439 if (nowait)
441 strcat (msgp->mtext, "-nowait ");
442 used += 8;
445 argc -= optind;
446 argv += optind;
448 while (argc)
450 int need_cwd = 0;
451 char *modified_arg = argv[0];
453 if (*modified_arg == '+')
455 char *p = modified_arg + 1;
456 while (*p >= '0' && *p <= '9') p++;
457 if (*p != 0)
458 need_cwd = 1;
460 else if (*modified_arg != '/')
461 need_cwd = 1;
463 modified_arg = quote_file_name (modified_arg);
465 if (need_cwd)
466 used += strlen (cwd);
467 used += strlen (modified_arg) + 1;
468 while (used + 2 > size_allocated)
470 size_allocated *= 2;
471 msgp = (struct msgbuf *) realloc (msgp,
472 (sizeof (struct msgbuf)
473 + size_allocated));
476 if (need_cwd)
477 strcat (msgp->mtext, cwd);
479 strcat (msgp->mtext, modified_arg);
480 strcat (msgp->mtext, " ");
481 argv++; argc--;
483 strcat (msgp->mtext, "\n");
484 #ifdef HPUX /* HPUX has a bug. */
485 if (strlen (msgp->mtext) >= 512)
487 fprintf (stderr, "%s: args too long for msgsnd\n", progname);
488 exit (1);
490 #endif
491 msgp->mtype = 1;
492 if (msgsnd (s, msgp, strlen (msgp->mtext)+1, 0) < 0)
494 fprintf (stderr, "%s: ", progname);
495 perror ("msgsnd");
496 exit (1);
499 /* Maybe wait for an answer. */
500 if (nowait)
501 return 0;
503 printf ("Waiting for Emacs...");
504 fflush (stdout);
506 msgrcv (s, msgp, BUFSIZ, getpid (), 0); /* wait for anything back */
507 strcpy (buf, msgp->mtext);
509 printf ("\n");
510 if (*buf)
511 printf ("%s\n", buf);
512 exit (0);
515 #endif /* HAVE_SYSVIPC */
517 #endif /* HAVE_SOCKETS or HAVE_SYSVIPC */
519 #ifndef HAVE_STRERROR
520 char *
521 strerror (errnum)
522 int errnum;
524 extern char *sys_errlist[];
525 extern int sys_nerr;
527 if (errnum >= 0 && errnum < sys_nerr)
528 return sys_errlist[errnum];
529 return (char *) "Unknown error";
532 #endif /* ! HAVE_STRERROR */