Mercurial > emacs
annotate lib-src/emacsclient.c @ 10058:5803ff60cf47
(map-y-or-n-p): Handle exit-prefix as definition of char.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Wed, 23 Nov 1994 09:11:05 +0000 |
parents | dd3b83e4ceb0 |
children | baab57e76991 |
rev | line source |
---|---|
493 | 1 /* Client process that communicates with GNU Emacs acting as server. |
5522
64a936b21f74
Don't declare sys_errlist; declare strerror instead.
Roland McGrath <roland@gnu.org>
parents:
4696
diff
changeset
|
2 Copyright (C) 1986, 1987, 1994 Free Software Foundation, Inc. |
412 | 3 |
4 This file is part of GNU Emacs. | |
5 | |
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 | |
5522
64a936b21f74
Don't declare sys_errlist; declare strerror instead.
Roland McGrath <roland@gnu.org>
parents:
4696
diff
changeset
|
8 the Free Software Foundation; either version 2, or (at your option) |
412 | 9 any later version. |
10 | |
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. | |
15 | |
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, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
19 | |
20 | |
21 #define NO_SHORTNAMES | |
4696
1fc792473491
Include <config.h> instead of "config.h".
Roland McGrath <roland@gnu.org>
parents:
3595
diff
changeset
|
22 #include <../src/config.h> |
412 | 23 #undef read |
24 #undef write | |
25 #undef open | |
26 #undef close | |
3595
e10f7473d2e3
* emacsserver.c (main): When we're passing a `struct sockaddr_un'
Jim Blandy <jimb@redhat.com>
parents:
1031
diff
changeset
|
27 #undef signal |
412 | 28 |
29 | |
30 #if !defined(HAVE_SOCKETS) && !defined(HAVE_SYSVIPC) | |
31 #include <stdio.h> | |
32 | |
33 main (argc, argv) | |
34 int argc; | |
35 char **argv; | |
36 { | |
37 fprintf (stderr, "%s: Sorry, the Emacs server is supported only\n", | |
38 argv[0]); | |
39 fprintf (stderr, "on systems with Berkeley sockets or System V IPC.\n"); | |
40 exit (1); | |
41 } | |
42 | |
43 #else /* HAVE_SOCKETS or HAVE_SYSVIPC */ | |
44 | |
45 #if ! defined (HAVE_SYSVIPC) | |
46 /* BSD code is very different from SYSV IPC code */ | |
47 | |
48 #include <sys/types.h> | |
49 #include <sys/socket.h> | |
50 #include <sys/un.h> | |
493 | 51 #include <sys/stat.h> |
412 | 52 #include <stdio.h> |
53 #include <errno.h> | |
54 | |
5522
64a936b21f74
Don't declare sys_errlist; declare strerror instead.
Roland McGrath <roland@gnu.org>
parents:
4696
diff
changeset
|
55 extern char *strerror (); |
412 | 56 extern int errno; |
57 | |
9491
dd3b83e4ceb0
Eliminate some -Wall warnings.
David J. MacKenzie <djm@gnu.org>
parents:
8360
diff
changeset
|
58 int |
412 | 59 main (argc, argv) |
60 int argc; | |
61 char **argv; | |
62 { | |
63 char system_name[32]; | |
64 int s, i; | |
65 FILE *out; | |
66 struct sockaddr_un server; | |
67 char *homedir, *cwd, *str; | |
68 char string[BUFSIZ]; | |
69 | |
70 char *getenv (), *getwd (); | |
71 int geteuid (); | |
72 | |
73 if (argc < 2) | |
74 { | |
75 fprintf (stderr, "Usage: %s [+linenumber] filename\n", argv[0]); | |
76 exit (1); | |
77 } | |
78 | |
79 /* | |
80 * Open up an AF_UNIX socket in this person's home directory | |
81 */ | |
82 | |
83 if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) | |
84 { | |
85 fprintf (stderr, "%s: ", argv[0]); | |
86 perror ("socket"); | |
87 exit (1); | |
88 } | |
89 server.sun_family = AF_UNIX; | |
90 #ifndef SERVER_HOME_DIR | |
493 | 91 { |
92 struct stat statbfr; | |
93 | |
94 gethostname (system_name, sizeof (system_name)); | |
95 sprintf (server.sun_path, "/tmp/esrv%d-%s", geteuid (), system_name); | |
412 | 96 |
493 | 97 if (stat (server.sun_path, &statbfr) == -1) |
98 { | |
816 | 99 if (errno == ENOENT) |
100 fprintf (stderr, | |
101 "Can't find socket; have you started the server?\n"); | |
102 else | |
103 perror ("stat"); | |
493 | 104 exit (1); |
105 } | |
106 if (statbfr.st_uid != geteuid()) | |
107 { | |
108 fprintf (stderr, "Illegal socket owner\n"); | |
109 exit (1); | |
110 } | |
111 } | |
412 | 112 #else |
113 if ((homedir = getenv ("HOME")) == NULL) | |
114 { | |
115 fprintf (stderr, "%s: No home directory\n", argv[0]); | |
116 exit (1); | |
117 } | |
118 strcpy (server.sun_path, homedir); | |
119 strcat (server.sun_path, "/.emacs_server"); | |
120 #endif | |
121 | |
3595
e10f7473d2e3
* emacsserver.c (main): When we're passing a `struct sockaddr_un'
Jim Blandy <jimb@redhat.com>
parents:
1031
diff
changeset
|
122 if (connect (s, (struct sockaddr *) &server, strlen (server.sun_path) + 2) |
e10f7473d2e3
* emacsserver.c (main): When we're passing a `struct sockaddr_un'
Jim Blandy <jimb@redhat.com>
parents:
1031
diff
changeset
|
123 < 0) |
412 | 124 { |
125 fprintf (stderr, "%s: ", argv[0]); | |
126 perror ("connect"); | |
127 exit (1); | |
128 } | |
129 if ((out = fdopen (s, "r+")) == NULL) | |
130 { | |
131 fprintf (stderr, "%s: ", argv[0]); | |
132 perror ("fdopen"); | |
133 exit (1); | |
134 } | |
135 | |
136 cwd = getwd (string); | |
137 if (cwd == 0) | |
138 { | |
139 /* getwd puts message in STRING if it fails. */ | |
5522
64a936b21f74
Don't declare sys_errlist; declare strerror instead.
Roland McGrath <roland@gnu.org>
parents:
4696
diff
changeset
|
140 fprintf (stderr, "%s: %s (%s)\n", argv[0], string, strerror (errno)); |
412 | 141 exit (1); |
142 } | |
143 | |
144 for (i = 1; i < argc; i++) | |
145 { | |
146 if (*argv[i] == '+') | |
147 { | |
148 char *p = argv[i] + 1; | |
149 while (*p >= '0' && *p <= '9') p++; | |
150 if (*p != 0) | |
151 fprintf (out, "%s/", cwd); | |
152 } | |
153 else if (*argv[i] != '/') | |
154 fprintf (out, "%s/", cwd); | |
155 fprintf (out, "%s ", argv[i]); | |
156 } | |
157 fprintf (out, "\n"); | |
158 fflush (out); | |
159 | |
160 printf ("Waiting for Emacs..."); | |
161 fflush (stdout); | |
162 | |
163 rewind (out); /* re-read the output */ | |
164 str = fgets (string, BUFSIZ, out); | |
165 | |
166 /* Now, wait for an answer and print any messages. */ | |
167 | |
168 while (str = fgets (string, BUFSIZ, out)) | |
169 printf ("%s", str); | |
170 | |
9491
dd3b83e4ceb0
Eliminate some -Wall warnings.
David J. MacKenzie <djm@gnu.org>
parents:
8360
diff
changeset
|
171 return 0; |
412 | 172 } |
173 | |
174 #else /* This is the SYSV IPC section */ | |
175 | |
176 #include <sys/types.h> | |
177 #include <sys/ipc.h> | |
178 #include <sys/msg.h> | |
179 #include <stdio.h> | |
180 | |
6213
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
181 char *getwd (), *getcwd (), *getenv (); |
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
182 |
412 | 183 main (argc, argv) |
184 int argc; | |
185 char **argv; | |
186 { | |
187 int s; | |
188 key_t key; | |
6213
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
189 /* Size of text allocated in MSGP. */ |
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
190 int size_allocated = BUFSIZ; |
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
191 /* Amount of text used in MSGP. */ |
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
192 int used; |
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
193 struct msgbuf *msgp |
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
194 = (struct msgbuf *) malloc (sizeof (struct msgbuf) + size_allocated); |
412 | 195 struct msqid_ds * msg_st; |
196 char *homedir, buf[BUFSIZ]; | |
197 char gwdirb[BUFSIZ]; | |
198 char *cwd; | |
199 char *temp; | |
8360
e1518247fd63
(main): New local var progname saves argv[0].
Richard M. Stallman <rms@gnu.org>
parents:
8346
diff
changeset
|
200 char *progname = argv[0]; |
412 | 201 |
202 if (argc < 2) | |
203 { | |
204 fprintf (stderr, "Usage: %s [+linenumber] filename\n", argv[0]); | |
205 exit (1); | |
206 } | |
207 | |
208 /* | |
209 * Create a message queue using ~/.emacs_server as the path for ftok | |
210 */ | |
211 if ((homedir = getenv ("HOME")) == NULL) | |
212 { | |
213 fprintf (stderr, "%s: No home directory\n", argv[0]); | |
214 exit (1); | |
215 } | |
216 strcpy (buf, homedir); | |
217 strcat (buf, "/.emacs_server"); | |
218 creat (buf, 0600); | |
219 key = ftok (buf, 1); /* unlikely to be anyone else using it */ | |
1031 | 220 s = msgget (key, 0600 | IPC_CREAT); |
412 | 221 if (s == -1) |
222 { | |
223 fprintf (stderr, "%s: ", argv[0]); | |
224 perror ("msgget"); | |
225 exit (1); | |
226 } | |
227 | |
228 /* Determine working dir, so we can prefix it to all the arguments. */ | |
229 #ifdef BSD | |
230 temp = getwd (gwdirb); | |
231 #else | |
232 temp = getcwd (gwdirb, sizeof gwdirb); | |
233 #endif | |
234 | |
235 cwd = gwdirb; | |
236 if (temp != 0) | |
237 { | |
238 /* On some systems, cwd can look like `@machine/...'; | |
239 ignore everything before the first slash in such a case. */ | |
240 while (*cwd && *cwd != '/') | |
241 cwd++; | |
242 strcat (cwd, "/"); | |
243 } | |
244 else | |
245 { | |
246 fprintf (stderr, cwd); | |
247 exit (1); | |
248 } | |
249 | |
250 msgp->mtext[0] = 0; | |
6213
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
251 used = 0; |
412 | 252 argc--; argv++; |
253 while (argc) | |
254 { | |
6213
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
255 int need_cwd = 0; |
8346
3f82ba603fa3
(main): Don't actually modify argv[0]. Modify a copy instead.
Richard M. Stallman <rms@gnu.org>
parents:
6213
diff
changeset
|
256 char *modified_arg = argv[0]; |
3f82ba603fa3
(main): Don't actually modify argv[0]. Modify a copy instead.
Richard M. Stallman <rms@gnu.org>
parents:
6213
diff
changeset
|
257 if (*modified_arg == '+') |
412 | 258 { |
8346
3f82ba603fa3
(main): Don't actually modify argv[0]. Modify a copy instead.
Richard M. Stallman <rms@gnu.org>
parents:
6213
diff
changeset
|
259 char *p = modified_arg + 1; |
412 | 260 while (*p >= '0' && *p <= '9') p++; |
261 if (*p != 0) | |
6213
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
262 need_cwd = 1; |
412 | 263 } |
8346
3f82ba603fa3
(main): Don't actually modify argv[0]. Modify a copy instead.
Richard M. Stallman <rms@gnu.org>
parents:
6213
diff
changeset
|
264 else if (*modified_arg != '/') |
6213
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
265 need_cwd = 1; |
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
266 |
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
267 if (need_cwd) |
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
268 used += strlen (cwd); |
8346
3f82ba603fa3
(main): Don't actually modify argv[0]. Modify a copy instead.
Richard M. Stallman <rms@gnu.org>
parents:
6213
diff
changeset
|
269 used += strlen (modified_arg) + 1; |
6213
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
270 while (used + 2 > size_allocated) |
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
271 { |
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
272 size_allocated *= 2; |
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
273 msgp = (struct msgbuf *) realloc (msgp, |
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
274 (sizeof (struct msgbuf) |
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
275 + size_allocated)); |
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
276 } |
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
277 |
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
278 if (need_cwd) |
412 | 279 strcat (msgp->mtext, cwd); |
280 | |
8346
3f82ba603fa3
(main): Don't actually modify argv[0]. Modify a copy instead.
Richard M. Stallman <rms@gnu.org>
parents:
6213
diff
changeset
|
281 strcat (msgp->mtext, modified_arg); |
412 | 282 strcat (msgp->mtext, " "); |
283 argv++; argc--; | |
284 } | |
285 strcat (msgp->mtext, "\n"); | |
6213
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
286 #ifdef HPUX /* HPUX has a bug. */ |
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
287 if (strlen (msgp->mtext) >= 512) |
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
288 { |
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
289 fprintf (stderr, "emacsclient: args too long for msgsnd\n"); |
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
290 exit (1); |
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
291 } |
7eefa1bd1478
(main) [HAVE_SYSVIPC]: Make msgp->mtext longer if necessary.
Richard M. Stallman <rms@gnu.org>
parents:
5527
diff
changeset
|
292 #endif |
412 | 293 msgp->mtype = 1; |
294 if (msgsnd (s, msgp, strlen (msgp->mtext)+1, 0) < 0) | |
295 { | |
8360
e1518247fd63
(main): New local var progname saves argv[0].
Richard M. Stallman <rms@gnu.org>
parents:
8346
diff
changeset
|
296 fprintf (stderr, "%s: ", progname); |
412 | 297 perror ("msgsnd"); |
298 exit (1); | |
299 } | |
300 /* | |
301 * Now, wait for an answer | |
302 */ | |
303 printf ("Waiting for Emacs..."); | |
304 fflush (stdout); | |
305 | |
306 msgrcv (s, msgp, BUFSIZ, getpid (), 0); /* wait for anything back */ | |
307 strcpy (buf, msgp->mtext); | |
308 | |
309 printf ("\n%s\n", buf); | |
310 exit (0); | |
311 } | |
312 | |
313 #endif /* HAVE_SYSVIPC */ | |
314 | |
315 #endif /* HAVE_SOCKETS or HAVE_SYSVIPC */ | |
5527
51451a050975
[! HAVE_STRERROR] (strerror): Define the function.
Roland McGrath <roland@gnu.org>
parents:
5522
diff
changeset
|
316 |
51451a050975
[! HAVE_STRERROR] (strerror): Define the function.
Roland McGrath <roland@gnu.org>
parents:
5522
diff
changeset
|
317 #ifndef HAVE_STRERROR |
51451a050975
[! HAVE_STRERROR] (strerror): Define the function.
Roland McGrath <roland@gnu.org>
parents:
5522
diff
changeset
|
318 char * |
51451a050975
[! HAVE_STRERROR] (strerror): Define the function.
Roland McGrath <roland@gnu.org>
parents:
5522
diff
changeset
|
319 strerror (errnum) |
51451a050975
[! HAVE_STRERROR] (strerror): Define the function.
Roland McGrath <roland@gnu.org>
parents:
5522
diff
changeset
|
320 int errnum; |
51451a050975
[! HAVE_STRERROR] (strerror): Define the function.
Roland McGrath <roland@gnu.org>
parents:
5522
diff
changeset
|
321 { |
51451a050975
[! HAVE_STRERROR] (strerror): Define the function.
Roland McGrath <roland@gnu.org>
parents:
5522
diff
changeset
|
322 extern char *sys_errlist[]; |
51451a050975
[! HAVE_STRERROR] (strerror): Define the function.
Roland McGrath <roland@gnu.org>
parents:
5522
diff
changeset
|
323 extern int sys_nerr; |
51451a050975
[! HAVE_STRERROR] (strerror): Define the function.
Roland McGrath <roland@gnu.org>
parents:
5522
diff
changeset
|
324 |
51451a050975
[! HAVE_STRERROR] (strerror): Define the function.
Roland McGrath <roland@gnu.org>
parents:
5522
diff
changeset
|
325 if (errnum >= 0 && errnum < sys_nerr) |
51451a050975
[! HAVE_STRERROR] (strerror): Define the function.
Roland McGrath <roland@gnu.org>
parents:
5522
diff
changeset
|
326 return sys_errlist[errnum]; |
51451a050975
[! HAVE_STRERROR] (strerror): Define the function.
Roland McGrath <roland@gnu.org>
parents:
5522
diff
changeset
|
327 return (char *) "Unknown error"; |
51451a050975
[! HAVE_STRERROR] (strerror): Define the function.
Roland McGrath <roland@gnu.org>
parents:
5522
diff
changeset
|
328 } |
51451a050975
[! HAVE_STRERROR] (strerror): Define the function.
Roland McGrath <roland@gnu.org>
parents:
5522
diff
changeset
|
329 |
51451a050975
[! HAVE_STRERROR] (strerror): Define the function.
Roland McGrath <roland@gnu.org>
parents:
5522
diff
changeset
|
330 #endif /* ! HAVE_STRERROR */ |