]>
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, 1999 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>
32 char *getenv (), *getwd ();
35 /* This is defined with -D from the compilation command,
36 which extracts it from ../lisp/version.el. */
39 #define VERSION "unspecified"
42 /* Name used to invoke this program. */
45 /* Nonzero means don't wait for a response from Emacs. --no-wait. */
48 void print_help_and_exit ();
50 struct option longopts
[] =
52 { "no-wait", no_argument
, NULL
, 'n' },
53 { "help", no_argument
, NULL
, 'H' },
54 { "version", no_argument
, NULL
, 'V' },
55 { "alternate-editor",required_argument
, NULL
, 'a' },
60 const char * alternate_editor
= NULL
;
62 /* Decode the options from argv and argc.
63 The global variable `optind' will say how many arguments we used up. */
66 decode_options (argc
, argv
)
72 int opt
= getopt_long (argc
, argv
,
73 "VHna:", longopts
, 0);
78 alternate_editor
= getenv ("ALTERNATE_EDITOR");
83 /* If getopt returns 0, then it has already processed a
84 long-named option. We should do nothing. */
88 alternate_editor
= optarg
;
96 fprintf (stderr
, "emacsclient %s\n", VERSION
);
102 print_help_and_exit ();
108 print_help_and_exit ()
111 "Usage: %s [-a ALTERNATE-EDITOR] [-n] [--no-wait] [+LINENUMBER] FILENAME\n",
117 "Report bugs to bug-gnu-emacs@gnu.org.\n");
121 /* Return a copy of NAME, inserting a &
122 before each &, each space, and any initial -.
123 Change spaces to underscores, too, so that the
124 return value never contains a space. */
127 quote_file_name (name
)
130 char *copy
= (char *) malloc (strlen (name
) * 2 + 1);
145 if (*p
== '&' || (*p
== '-' && p
== name
))
156 /* Like malloc but get fatal error if memory is exhausted. */
162 long *result
= (long *) malloc (size
);
172 Try to run a different command, or --if no alternate editor is
173 defined-- exit with an errorcode.
179 if (alternate_editor
)
182 execvp (alternate_editor
, argv
+ i
);
193 #if !defined (HAVE_SOCKETS) && !defined (HAVE_SYSVIPC)
199 fprintf (stderr
, "%s: Sorry, the Emacs server is supported only\n",
201 fprintf (stderr
, "on systems with Berkeley sockets or System V IPC.\n");
206 #else /* HAVE_SOCKETS or HAVE_SYSVIPC */
208 #if defined (HAVE_SOCKETS) && ! defined (NO_SOCKETS_IN_FILE_SYSTEM)
209 /* BSD code is very different from SYSV IPC code */
211 #include <sys/types.h>
212 #include <sys/socket.h>
214 #include <sys/stat.h>
217 extern char *strerror ();
226 int system_name_length
;
229 struct sockaddr_un server
;
230 char *homedir
, *cwd
, *str
;
235 /* Process options. */
236 decode_options (argc
, argv
);
238 if (argc
- optind
< 1)
239 print_help_and_exit ();
242 * Open up an AF_UNIX socket in this person's home directory
245 if ((s
= socket (AF_UNIX
, SOCK_STREAM
, 0)) < 0)
247 fprintf (stderr
, "%s: ", argv
[0]);
252 server
.sun_family
= AF_UNIX
;
255 system_name_length
= 32;
259 system_name
= (char *) xmalloc (system_name_length
+ 1);
261 /* system_name must be null-terminated string. */
262 system_name
[system_name_length
] = '\0';
264 if (gethostname (system_name
, system_name_length
) == 0)
268 system_name_length
*= 2;
272 #ifndef SERVER_HOME_DIR
276 sprintf (server
.sun_path
, "/tmp/esrv%d-%s", geteuid (), system_name
);
278 if (stat (server
.sun_path
, &statbfr
) == -1)
282 "%s: can't find socket; have you started the server?\n",
285 fprintf (stderr
, "%s: can't stat %s: %s\n",
286 argv
[0], server
.sun_path
, strerror (errno
));
289 if (statbfr
.st_uid
!= geteuid ())
291 fprintf (stderr
, "%s: Invalid socket owner\n", argv
[0]);
296 if ((homedir
= getenv ("HOME")) == NULL
)
298 fprintf (stderr
, "%s: No home directory\n", argv
[0]);
301 strcpy (server
.sun_path
, homedir
);
302 strcat (server
.sun_path
, "/.emacs-server-");
303 strcat (server
.sun_path
, system_name
);
306 if (connect (s
, (struct sockaddr
*) &server
, strlen (server
.sun_path
) + 2)
309 fprintf (stderr
, "%s: ", argv
[0]);
314 /* We use the stream OUT to send our command to the server. */
315 if ((out
= fdopen (s
, "r+")) == NULL
)
317 fprintf (stderr
, "%s: ", argv
[0]);
322 /* We use the stream IN to read the response.
323 We used to use just one stream for both output and input
324 on the socket, but reversing direction works nonportably:
325 on some systems, the output appears as the first input;
326 on other systems it does not. */
327 if ((in
= fdopen (s
, "r+")) == NULL
)
329 fprintf (stderr
, "%s: ", argv
[0]);
335 cwd
= getwd (string
);
337 cwd
= getcwd (string
, sizeof string
);
341 /* getwd puts message in STRING if it fails. */
342 fprintf (stderr
, "%s: %s (%s)\n", argv
[0],
346 "Cannot get current working directory",
353 fprintf (out
, "-nowait ");
355 for (i
= optind
; i
< argc
; i
++)
359 char *p
= argv
[i
] + 1;
360 while (*p
>= '0' && *p
<= '9') p
++;
362 fprintf (out
, "%s/", quote_file_name (cwd
));
364 else if (*argv
[i
] != '/')
365 fprintf (out
, "%s/", quote_file_name (cwd
));
367 fprintf (out
, "%s ", quote_file_name (argv
[i
]));
372 /* Maybe wait for an answer. */
376 printf ("Waiting for Emacs...");
379 /* Now, wait for an answer and print any messages. On some systems,
380 the first line we read will actually be the output we just sent.
381 We can't predict whether that will happen, so if it does, we
382 detect it by recognizing `Client: ' at the beginning. */
384 while (str
= fgets (string
, BUFSIZ
, in
))
390 #else /* This is the SYSV IPC section */
392 #include <sys/types.h>
395 #include <sys/utsname.h>
400 char *getwd (), *getcwd (), *getenv ();
401 struct utsname system_name
;
409 /* Size of text allocated in MSGP. */
410 int size_allocated
= BUFSIZ
;
411 /* Amount of text used in MSGP. */
414 = (struct msgbuf
*) malloc (sizeof (struct msgbuf
) + size_allocated
);
415 struct msqid_ds
* msg_st
;
416 char *homedir
, buf
[BUFSIZ
];
423 /* Process options. */
424 decode_options (argc
, argv
);
426 if (argc
- optind
< 1)
427 print_help_and_exit ();
430 * Create a message queue using ~/.emacs-server as the path for ftok
432 if ((homedir
= getenv ("HOME")) == NULL
)
434 fprintf (stderr
, "%s: No home directory\n", argv
[0]);
437 strcpy (buf
, homedir
);
438 #ifndef HAVE_LONG_FILE_NAMES
439 /* If file names are short, we can't fit the host name. */
440 strcat (buf
, "/.emacs-server");
442 strcat (buf
, "/.emacs-server-");
443 uname (&system_name
);
444 strcat (buf
, system_name
.nodename
);
447 key
= ftok (buf
, 1); /* unlikely to be anyone else using it */
448 s
= msgget (key
, 0600 | IPC_CREAT
);
451 fprintf (stderr
, "%s: ", argv
[0]);
456 /* Determine working dir, so we can prefix it to all the arguments. */
458 temp
= getwd (gwdirb
);
460 temp
= getcwd (gwdirb
, sizeof gwdirb
);
466 /* On some systems, cwd can look like `@machine/...';
467 ignore everything before the first slash in such a case. */
468 while (*cwd
&& *cwd
!= '/')
475 fprintf (stderr
, "%s: %s\n", argv
[0], cwd
);
477 fprintf (stderr
, "%s: Cannot get current working directory: %s\n",
478 argv
[0], strerror (errno
));
488 strcat (msgp
->mtext
, "-nowait ");
498 char *modified_arg
= argv
[0];
500 if (*modified_arg
== '+')
502 char *p
= modified_arg
+ 1;
503 while (*p
>= '0' && *p
<= '9') p
++;
507 else if (*modified_arg
!= '/')
510 modified_arg
= quote_file_name (modified_arg
);
513 /* Overestimate in case we have to quote something in CWD. */
514 used
+= 2 * strlen (cwd
);
515 used
+= strlen (modified_arg
) + 1;
516 while (used
+ 2 > size_allocated
)
519 msgp
= (struct msgbuf
*) realloc (msgp
,
520 (sizeof (struct msgbuf
)
525 strcat (msgp
->mtext
, quote_file_name (cwd
));
527 strcat (msgp
->mtext
, modified_arg
);
528 strcat (msgp
->mtext
, " ");
531 strcat (msgp
->mtext
, "\n");
532 #ifdef HPUX /* HPUX has a bug. */
533 if (strlen (msgp
->mtext
) >= 512)
535 fprintf (stderr
, "%s: args too long for msgsnd\n", progname
);
540 if (msgsnd (s
, msgp
, strlen (msgp
->mtext
)+1, 0) < 0)
542 fprintf (stderr
, "%s: ", progname
);
547 /* Maybe wait for an answer. */
551 printf ("Waiting for Emacs...");
554 msgrcv (s
, msgp
, BUFSIZ
, getpid (), 0); /* wait for anything back */
555 strcpy (buf
, msgp
->mtext
);
559 printf ("%s\n", buf
);
563 #endif /* HAVE_SYSVIPC */
565 #endif /* HAVE_SOCKETS or HAVE_SYSVIPC */
567 #ifndef HAVE_STRERROR
572 extern char *sys_errlist
[];
575 if (errnum
>= 0 && errnum
< sys_nerr
)
576 return sys_errlist
[errnum
];
577 return (char *) "Unknown error";
580 #endif /* ! HAVE_STRERROR */