Mercurial > emacs
annotate lib-src/emacsclient.c @ 5526:5131e7d642b9
(version): Fix sed regexp to match two-elt version number.
author | Roland McGrath <roland@gnu.org> |
---|---|
date | Sat, 08 Jan 1994 22:06:34 +0000 |
parents | 64a936b21f74 |
children | 51451a050975 |
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 | |
58 main (argc, argv) | |
59 int argc; | |
60 char **argv; | |
61 { | |
62 char system_name[32]; | |
63 int s, i; | |
64 FILE *out; | |
65 struct sockaddr_un server; | |
66 char *homedir, *cwd, *str; | |
67 char string[BUFSIZ]; | |
68 | |
69 char *getenv (), *getwd (); | |
70 int geteuid (); | |
71 | |
72 if (argc < 2) | |
73 { | |
74 fprintf (stderr, "Usage: %s [+linenumber] filename\n", argv[0]); | |
75 exit (1); | |
76 } | |
77 | |
78 /* | |
79 * Open up an AF_UNIX socket in this person's home directory | |
80 */ | |
81 | |
82 if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) | |
83 { | |
84 fprintf (stderr, "%s: ", argv[0]); | |
85 perror ("socket"); | |
86 exit (1); | |
87 } | |
88 server.sun_family = AF_UNIX; | |
89 #ifndef SERVER_HOME_DIR | |
493 | 90 { |
91 struct stat statbfr; | |
92 | |
93 gethostname (system_name, sizeof (system_name)); | |
94 sprintf (server.sun_path, "/tmp/esrv%d-%s", geteuid (), system_name); | |
412 | 95 |
493 | 96 if (stat (server.sun_path, &statbfr) == -1) |
97 { | |
816 | 98 if (errno == ENOENT) |
99 fprintf (stderr, | |
100 "Can't find socket; have you started the server?\n"); | |
101 else | |
102 perror ("stat"); | |
493 | 103 exit (1); |
104 } | |
105 if (statbfr.st_uid != geteuid()) | |
106 { | |
107 fprintf (stderr, "Illegal socket owner\n"); | |
108 exit (1); | |
109 } | |
110 } | |
412 | 111 #else |
112 if ((homedir = getenv ("HOME")) == NULL) | |
113 { | |
114 fprintf (stderr, "%s: No home directory\n", argv[0]); | |
115 exit (1); | |
116 } | |
117 strcpy (server.sun_path, homedir); | |
118 strcat (server.sun_path, "/.emacs_server"); | |
119 #endif | |
120 | |
3595
e10f7473d2e3
* emacsserver.c (main): When we're passing a `struct sockaddr_un'
Jim Blandy <jimb@redhat.com>
parents:
1031
diff
changeset
|
121 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
|
122 < 0) |
412 | 123 { |
124 fprintf (stderr, "%s: ", argv[0]); | |
125 perror ("connect"); | |
126 exit (1); | |
127 } | |
128 if ((out = fdopen (s, "r+")) == NULL) | |
129 { | |
130 fprintf (stderr, "%s: ", argv[0]); | |
131 perror ("fdopen"); | |
132 exit (1); | |
133 } | |
134 | |
135 cwd = getwd (string); | |
136 if (cwd == 0) | |
137 { | |
138 /* 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
|
139 fprintf (stderr, "%s: %s (%s)\n", argv[0], string, strerror (errno)); |
412 | 140 exit (1); |
141 } | |
142 | |
143 for (i = 1; i < argc; i++) | |
144 { | |
145 if (*argv[i] == '+') | |
146 { | |
147 char *p = argv[i] + 1; | |
148 while (*p >= '0' && *p <= '9') p++; | |
149 if (*p != 0) | |
150 fprintf (out, "%s/", cwd); | |
151 } | |
152 else if (*argv[i] != '/') | |
153 fprintf (out, "%s/", cwd); | |
154 fprintf (out, "%s ", argv[i]); | |
155 } | |
156 fprintf (out, "\n"); | |
157 fflush (out); | |
158 | |
159 printf ("Waiting for Emacs..."); | |
160 fflush (stdout); | |
161 | |
162 rewind (out); /* re-read the output */ | |
163 str = fgets (string, BUFSIZ, out); | |
164 | |
165 /* Now, wait for an answer and print any messages. */ | |
166 | |
167 while (str = fgets (string, BUFSIZ, out)) | |
168 printf ("%s", str); | |
169 | |
170 exit (0); | |
171 } | |
172 | |
173 #else /* This is the SYSV IPC section */ | |
174 | |
175 #include <sys/types.h> | |
176 #include <sys/ipc.h> | |
177 #include <sys/msg.h> | |
178 #include <stdio.h> | |
179 | |
180 main (argc, argv) | |
181 int argc; | |
182 char **argv; | |
183 { | |
184 int s; | |
185 key_t key; | |
186 struct msgbuf * msgp = | |
187 (struct msgbuf *) malloc (sizeof *msgp + BUFSIZ); | |
188 struct msqid_ds * msg_st; | |
189 char *homedir, buf[BUFSIZ]; | |
190 char gwdirb[BUFSIZ]; | |
191 char *cwd; | |
192 char *temp; | |
193 char *getwd (), *getcwd (), *getenv (); | |
194 | |
195 if (argc < 2) | |
196 { | |
197 fprintf (stderr, "Usage: %s [+linenumber] filename\n", argv[0]); | |
198 exit (1); | |
199 } | |
200 | |
201 /* | |
202 * Create a message queue using ~/.emacs_server as the path for ftok | |
203 */ | |
204 if ((homedir = getenv ("HOME")) == NULL) | |
205 { | |
206 fprintf (stderr, "%s: No home directory\n", argv[0]); | |
207 exit (1); | |
208 } | |
209 strcpy (buf, homedir); | |
210 strcat (buf, "/.emacs_server"); | |
211 creat (buf, 0600); | |
212 key = ftok (buf, 1); /* unlikely to be anyone else using it */ | |
1031 | 213 s = msgget (key, 0600 | IPC_CREAT); |
412 | 214 if (s == -1) |
215 { | |
216 fprintf (stderr, "%s: ", argv[0]); | |
217 perror ("msgget"); | |
218 exit (1); | |
219 } | |
220 | |
221 /* Determine working dir, so we can prefix it to all the arguments. */ | |
222 #ifdef BSD | |
223 temp = getwd (gwdirb); | |
224 #else | |
225 temp = getcwd (gwdirb, sizeof gwdirb); | |
226 #endif | |
227 | |
228 cwd = gwdirb; | |
229 if (temp != 0) | |
230 { | |
231 /* On some systems, cwd can look like `@machine/...'; | |
232 ignore everything before the first slash in such a case. */ | |
233 while (*cwd && *cwd != '/') | |
234 cwd++; | |
235 strcat (cwd, "/"); | |
236 } | |
237 else | |
238 { | |
239 fprintf (stderr, cwd); | |
240 exit (1); | |
241 } | |
242 | |
243 msgp->mtext[0] = 0; | |
244 argc--; argv++; | |
245 while (argc) | |
246 { | |
247 if (*argv[0] == '+') | |
248 { | |
249 char *p = argv[0] + 1; | |
250 while (*p >= '0' && *p <= '9') p++; | |
251 if (*p != 0) | |
252 strcat (msgp->mtext, cwd); | |
253 } | |
254 else if (*argv[0] != '/') | |
255 strcat (msgp->mtext, cwd); | |
256 | |
257 strcat (msgp->mtext, argv[0]); | |
258 strcat (msgp->mtext, " "); | |
259 argv++; argc--; | |
260 } | |
261 strcat (msgp->mtext, "\n"); | |
262 msgp->mtype = 1; | |
263 if (msgsnd (s, msgp, strlen (msgp->mtext)+1, 0) < 0) | |
264 { | |
265 fprintf (stderr, "%s: ", argv[0]); | |
266 perror ("msgsnd"); | |
267 exit (1); | |
268 } | |
269 /* | |
270 * Now, wait for an answer | |
271 */ | |
272 printf ("Waiting for Emacs..."); | |
273 fflush (stdout); | |
274 | |
275 msgrcv (s, msgp, BUFSIZ, getpid (), 0); /* wait for anything back */ | |
276 strcpy (buf, msgp->mtext); | |
277 | |
278 printf ("\n%s\n", buf); | |
279 exit (0); | |
280 } | |
281 | |
282 #endif /* HAVE_SYSVIPC */ | |
283 | |
284 #endif /* HAVE_SOCKETS or HAVE_SYSVIPC */ |