]>
code.delx.au - gnu-emacs/blob - lib-src/emacsclient.c
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)
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. */
23 #include <../src/config.h>
39 char *getenv (), *getwd ();
42 /* This is defined with -D from the compilation command,
43 which extracts it from ../lisp/version.el. */
46 #define VERSION "unspecified"
49 /* Name used to invoke this program. */
52 /* Nonzero means don't wait for a response from Emacs. --no-wait. */
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' },
65 /* Decode the options from argv and argc.
66 The global variable `optind' will say how many arguments we used up. */
69 decode_options (argc
, argv
)
75 int opt
= getopt_long (argc
, argv
,
84 /* If getopt returns 0, then it has already processed a
85 long-named option. We should do nothing. */
93 fprintf (stderr
, "emacsclient %s\n", VERSION
);
99 print_help_and_exit ();
105 print_help_and_exit ()
108 "Usage: %s [-n] [--no-wait] [+LINENUMBER] FILENAME\n",
111 "Report bugs to bug-gnu-emacs@gnu.org.\n");
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. */
121 quote_file_name (name
)
124 char *copy
= (char *) malloc (strlen (name
) * 2 + 1);
139 if (*p
== '&' || (*p
== '-' && p
== name
))
149 /* Like malloc but get fatal error if memory is exhausted. */
155 long *result
= (long *) malloc (size
);
164 #if !defined (HAVE_SOCKETS) && !defined (HAVE_SYSVIPC)
170 fprintf (stderr
, "%s: Sorry, the Emacs server is supported only\n",
172 fprintf (stderr
, "on systems with Berkeley sockets or System V IPC.\n");
176 #else /* HAVE_SOCKETS or HAVE_SYSVIPC */
178 #if defined (HAVE_SOCKETS) && ! defined (NO_SOCKETS_IN_FILE_SYSTEM)
179 /* BSD code is very different from SYSV IPC code */
181 #include <sys/types.h>
182 #include <sys/socket.h>
184 #include <sys/stat.h>
187 extern char *strerror ();
196 int system_name_length
;
199 struct sockaddr_un server
;
200 char *homedir
, *cwd
, *str
;
205 /* Process options. */
206 decode_options (argc
, argv
);
208 if (argc
- optind
< 1)
209 print_help_and_exit ();
212 * Open up an AF_UNIX socket in this person's home directory
215 if ((s
= socket (AF_UNIX
, SOCK_STREAM
, 0)) < 0)
217 fprintf (stderr
, "%s: ", argv
[0]);
221 server
.sun_family
= AF_UNIX
;
224 system_name_length
= 32;
228 system_name
= (char *) xmalloc (system_name_length
+ 1);
230 /* system_name must be null-terminated string. */
231 system_name
[system_name_length
] = '\0';
233 if (gethostname (system_name
, system_name_length
) == 0)
237 system_name_length
*= 2;
241 #ifndef SERVER_HOME_DIR
245 sprintf (server
.sun_path
, "/tmp/esrv%d-%s", geteuid (), system_name
);
247 if (stat (server
.sun_path
, &statbfr
) == -1)
251 "%s: can't find socket; have you started the server?\n",
254 fprintf (stderr
, "%s: can't stat %s: %s\n",
255 argv
[0], server
.sun_path
, strerror (errno
));
258 if (statbfr
.st_uid
!= geteuid ())
260 fprintf (stderr
, "%s: Invalid socket owner\n", argv
[0]);
265 if ((homedir
= getenv ("HOME")) == NULL
)
267 fprintf (stderr
, "%s: No home directory\n", argv
[0]);
270 strcpy (server
.sun_path
, homedir
);
271 strcat (server
.sun_path
, "/.emacs-server-");
272 strcat (server
.sun_path
, system_name
);
275 if (connect (s
, (struct sockaddr
*) &server
, strlen (server
.sun_path
) + 2)
278 fprintf (stderr
, "%s: ", argv
[0]);
283 /* We use the stream OUT to send our command to the server. */
284 if ((out
= fdopen (s
, "r+")) == NULL
)
286 fprintf (stderr
, "%s: ", argv
[0]);
291 /* We use the stream IN to read the response.
292 We used to use just one stream for both output and input
293 on the socket, but reversing direction works nonportably:
294 on some systems, the output appears as the first input;
295 on other systems it does not. */
296 if ((in
= fdopen (s
, "r+")) == NULL
)
298 fprintf (stderr
, "%s: ", argv
[0]);
304 cwd
= getwd (string
);
306 cwd
= getcwd (string
, sizeof string
);
310 /* getwd puts message in STRING if it fails. */
311 fprintf (stderr
, "%s: %s (%s)\n", argv
[0],
315 "Cannot get current working directory",
322 fprintf (out
, "-nowait ");
324 for (i
= optind
; i
< argc
; i
++)
328 char *p
= argv
[i
] + 1;
329 while (*p
>= '0' && *p
<= '9') p
++;
331 fprintf (out
, "%s/", quote_file_name (cwd
));
333 else if (*argv
[i
] != '/')
334 fprintf (out
, "%s/", quote_file_name (cwd
));
336 fprintf (out
, "%s ", quote_file_name (argv
[i
]));
341 /* Maybe wait for an answer. */
345 printf ("Waiting for Emacs...");
348 /* Now, wait for an answer and print any messages. On some systems,
349 the first line we read will actually be the output we just sent.
350 We can't predict whether that will happen, so if it does, we
351 detect it by recognizing `Client: ' at the beginning. */
353 while (str
= fgets (string
, BUFSIZ
, in
))
359 #else /* This is the SYSV IPC section */
361 #include <sys/types.h>
364 #include <sys/utsname.h>
369 char *getwd (), *getcwd (), *getenv ();
370 struct utsname system_name
;
378 /* Size of text allocated in MSGP. */
379 int size_allocated
= BUFSIZ
;
380 /* Amount of text used in MSGP. */
383 = (struct msgbuf
*) malloc (sizeof (struct msgbuf
) + size_allocated
);
384 struct msqid_ds
* msg_st
;
385 char *homedir
, buf
[BUFSIZ
];
392 /* Process options. */
393 decode_options (argc
, argv
);
395 if (argc
- optind
< 1)
396 print_help_and_exit ();
399 * Create a message queue using ~/.emacs-server as the path for ftok
401 if ((homedir
= getenv ("HOME")) == NULL
)
403 fprintf (stderr
, "%s: No home directory\n", argv
[0]);
406 strcpy (buf
, homedir
);
407 #ifndef HAVE_LONG_FILE_NAMES
408 /* If file names are short, we can't fit the host name. */
409 strcat (buf
, "/.emacs-server");
411 strcat (buf
, "/.emacs-server-");
412 uname (&system_name
);
413 strcat (buf
, system_name
.nodename
);
416 key
= ftok (buf
, 1); /* unlikely to be anyone else using it */
417 s
= msgget (key
, 0600 | IPC_CREAT
);
420 fprintf (stderr
, "%s: ", argv
[0]);
425 /* Determine working dir, so we can prefix it to all the arguments. */
427 temp
= getwd (gwdirb
);
429 temp
= getcwd (gwdirb
, sizeof gwdirb
);
435 /* On some systems, cwd can look like `@machine/...';
436 ignore everything before the first slash in such a case. */
437 while (*cwd
&& *cwd
!= '/')
444 fprintf (stderr
, "%s: %s\n", argv
[0], cwd
);
446 fprintf (stderr
, "%s: Cannot get current working directory: %s\n",
447 argv
[0], strerror (errno
));
457 strcat (msgp
->mtext
, "-nowait ");
467 char *modified_arg
= argv
[0];
469 if (*modified_arg
== '+')
471 char *p
= modified_arg
+ 1;
472 while (*p
>= '0' && *p
<= '9') p
++;
476 else if (*modified_arg
!= '/')
479 modified_arg
= quote_file_name (modified_arg
);
482 /* Overestimate in case we have to quote something in CWD. */
483 used
+= 2 * strlen (cwd
);
484 used
+= strlen (modified_arg
) + 1;
485 while (used
+ 2 > size_allocated
)
488 msgp
= (struct msgbuf
*) realloc (msgp
,
489 (sizeof (struct msgbuf
)
494 strcat (msgp
->mtext
, quote_file_name (cwd
));
496 strcat (msgp
->mtext
, modified_arg
);
497 strcat (msgp
->mtext
, " ");
500 strcat (msgp
->mtext
, "\n");
501 #ifdef HPUX /* HPUX has a bug. */
502 if (strlen (msgp
->mtext
) >= 512)
504 fprintf (stderr
, "%s: args too long for msgsnd\n", progname
);
509 if (msgsnd (s
, msgp
, strlen (msgp
->mtext
)+1, 0) < 0)
511 fprintf (stderr
, "%s: ", progname
);
516 /* Maybe wait for an answer. */
520 printf ("Waiting for Emacs...");
523 msgrcv (s
, msgp
, BUFSIZ
, getpid (), 0); /* wait for anything back */
524 strcpy (buf
, msgp
->mtext
);
528 printf ("%s\n", buf
);
532 #endif /* HAVE_SYSVIPC */
534 #endif /* HAVE_SOCKETS or HAVE_SYSVIPC */
536 #ifndef HAVE_STRERROR
541 extern char *sys_errlist
[];
544 if (errnum
>= 0 && errnum
< sys_nerr
)
545 return sys_errlist
[errnum
];
546 return (char *) "Unknown error";
549 #endif /* ! HAVE_STRERROR */