Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 509 lines (441 sloc) 12.243 kb
7216c39 Karl Ferdinand Ebert Imported Upstream version 1.5
kfebert authored
1 /* $Id: client.c 2553 2011-07-09 09:42:33Z tcunha $ */
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
2
3 /*
4 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include <sys/types.h>
20 #include <sys/socket.h>
21 #include <sys/stat.h>
22 #include <sys/un.h>
23 #include <sys/wait.h>
24
25 #include <errno.h>
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
26 #include <event.h>
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
27 #include <fcntl.h>
28 #include <pwd.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <unistd.h>
32
33 #include "tmux.h"
34
35 struct imsgbuf client_ibuf;
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
36 struct event client_event;
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
37 const char *client_exitmsg;
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
38 int client_exitval;
7216c39 Karl Ferdinand Ebert Imported Upstream version 1.5
kfebert authored
39 enum msgtype client_exittype;
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
40 int client_attached;
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
41
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
42 int client_connect(char *, int);
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
43 void client_send_identify(int);
44 void client_send_environ(void);
45 void client_write_server(enum msgtype, void *, size_t);
46 void client_update_event(void);
47 void client_signal(int, short, void *);
48 void client_callback(int, short, void *);
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
49 int client_dispatch_attached(void);
50 int client_dispatch_wait(void *);
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
51
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
52 /* Connect client to server. */
53 int
54 client_connect(char *path, int start_server)
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
55 {
56 struct sockaddr_un sa;
57 size_t size;
7216c39 Karl Ferdinand Ebert Imported Upstream version 1.5
kfebert authored
58 int fd;
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
59
60 memset(&sa, 0, sizeof sa);
61 sa.sun_family = AF_UNIX;
62 size = strlcpy(sa.sun_path, path, sizeof sa.sun_path);
63 if (size >= sizeof sa.sun_path) {
64 errno = ENAMETOOLONG;
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
65 return (-1);
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
66 }
67
68 if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
69 fatal("socket failed");
70
71 if (connect(fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) == -1) {
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
72 if (!start_server)
73 goto failed;
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
74 switch (errno) {
75 case ECONNREFUSED:
76 if (unlink(path) != 0)
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
77 goto failed;
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
78 /* FALLTHROUGH */
79 case ENOENT:
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
80 if ((fd = server_start()) == -1)
81 goto failed;
82 break;
83 default:
84 goto failed;
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
85 }
86 }
87
7216c39 Karl Ferdinand Ebert Imported Upstream version 1.5
kfebert authored
88 setblocking(fd, 0);
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
89 return (fd);
90
91 failed:
92 close(fd);
93 return (-1);
94 }
95
96 /* Client main loop. */
97 int
98 client_main(int argc, char **argv, int flags)
99 {
100 struct cmd *cmd;
101 struct cmd_list *cmdlist;
102 struct msg_command_data cmddata;
103 int cmdflags, fd;
7216c39 Karl Ferdinand Ebert Imported Upstream version 1.5
kfebert authored
104 pid_t ppid;
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
105 enum msgtype msg;
106 char *cause;
107
108 /* Set up the initial command. */
109 cmdflags = 0;
110 if (shell_cmd != NULL) {
111 msg = MSG_SHELL;
112 cmdflags = CMD_STARTSERVER;
113 } else if (argc == 0) {
114 msg = MSG_COMMAND;
115 cmdflags = CMD_STARTSERVER|CMD_SENDENVIRON|CMD_CANTNEST;
116 } else {
117 msg = MSG_COMMAND;
118
119 /*
120 * It sucks parsing the command string twice (in client and
121 * later in server) but it is necessary to get the start server
122 * flag.
123 */
124 if ((cmdlist = cmd_list_parse(argc, argv, &cause)) == NULL) {
125 log_warnx("%s", cause);
126 return (1);
127 }
128 cmdflags &= ~CMD_STARTSERVER;
129 TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
130 if (cmd->entry->flags & CMD_STARTSERVER)
131 cmdflags |= CMD_STARTSERVER;
132 if (cmd->entry->flags & CMD_SENDENVIRON)
133 cmdflags |= CMD_SENDENVIRON;
134 if (cmd->entry->flags & CMD_CANTNEST)
135 cmdflags |= CMD_CANTNEST;
136 }
137 cmd_list_free(cmdlist);
138 }
139
140 /*
141 * Check if this could be a nested session, if the command can't nest:
142 * if the socket path matches $TMUX, this is probably the same server.
143 */
144 if (shell_cmd == NULL && environ_path != NULL &&
145 cmdflags & CMD_CANTNEST && strcmp(socket_path, environ_path) == 0) {
146 log_warnx("sessions should be nested with care. "
147 "unset $TMUX to force.");
148 return (1);
149 }
150
151 /* Initialise the client socket and start the server. */
152 fd = client_connect(socket_path, cmdflags & CMD_STARTSERVER);
153 if (fd == -1) {
154 log_warn("failed to connect to server");
155 return (1);
156 }
157
158 /* Set process title, log and signals now this is the client. */
159 #ifdef HAVE_SETPROCTITLE
160 setproctitle("client (%s)", socket_path);
161 #endif
162 logfile("client");
163
164 /* Create imsg. */
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
165 imsg_init(&client_ibuf, fd);
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
166 event_set(&client_event, fd, EV_READ, client_callback, shell_cmd);
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
167
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
168 /* Establish signal handlers. */
169 set_signals(client_signal);
170
171 /* Send initial environment. */
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
172 if (cmdflags & CMD_SENDENVIRON)
173 client_send_environ();
fb53a63 Karl Ferdinand Ebert Imported Upstream version 1.3
kfebert authored
174 client_send_identify(flags);
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
175
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
176 /* Send first command. */
177 if (msg == MSG_COMMAND) {
178 /* Fill in command line arguments. */
179 cmddata.pid = environ_pid;
180 cmddata.idx = environ_idx;
181
182 /* Prepare command for server. */
183 cmddata.argc = argc;
184 if (cmd_pack_argv(
185 argc, argv, cmddata.argv, sizeof cmddata.argv) != 0) {
186 log_warnx("command too long");
187 return (1);
188 }
189
190 client_write_server(msg, &cmddata, sizeof cmddata);
191 } else if (msg == MSG_SHELL)
192 client_write_server(msg, NULL, 0);
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
193
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
194 /* Set the event and dispatch. */
195 client_update_event();
196 event_dispatch();
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
197
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
198 /* Print the exit message, if any, and exit. */
7216c39 Karl Ferdinand Ebert Imported Upstream version 1.5
kfebert authored
199 if (client_attached) {
200 if (client_exitmsg != NULL && !login_shell)
201 printf("[%s]\n", client_exitmsg);
202
203 ppid = getppid();
204 if (client_exittype == MSG_DETACHKILL && ppid > 1)
205 kill(ppid, SIGHUP);
206 }
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
207 return (client_exitval);
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
208 }
209
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
210 /* Send identify message to server with the file descriptors. */
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
211 void
212 client_send_identify(int flags)
213 {
214 struct msg_identify_data data;
215 char *term;
216 int fd;
217
218 data.flags = flags;
219
220 if (getcwd(data.cwd, sizeof data.cwd) == NULL)
221 *data.cwd = '\0';
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
222
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
223 term = getenv("TERM");
224 if (term == NULL ||
225 strlcpy(data.term, term, sizeof data.term) >= sizeof data.term)
226 *data.term = '\0';
227
228 if ((fd = dup(STDIN_FILENO)) == -1)
229 fatal("dup failed");
230 imsg_compose(&client_ibuf,
231 MSG_IDENTIFY, PROTOCOL_VERSION, -1, fd, &data, sizeof data);
fb53a63 Karl Ferdinand Ebert Imported Upstream version 1.3
kfebert authored
232
233 if ((fd = dup(STDOUT_FILENO)) == -1)
234 fatal("dup failed");
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
235 imsg_compose(&client_ibuf,
236 MSG_STDOUT, PROTOCOL_VERSION, -1, fd, NULL, 0);
fb53a63 Karl Ferdinand Ebert Imported Upstream version 1.3
kfebert authored
237
238 if ((fd = dup(STDERR_FILENO)) == -1)
239 fatal("dup failed");
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
240 imsg_compose(&client_ibuf,
241 MSG_STDERR, PROTOCOL_VERSION, -1, fd, NULL, 0);
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
242 }
243
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
244 /* Forward entire environment to server. */
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
245 void
246 client_send_environ(void)
247 {
248 struct msg_environ_data data;
249 char **var;
250
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
251 for (var = environ; *var != NULL; var++) {
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
252 if (strlcpy(data.var, *var, sizeof data.var) >= sizeof data.var)
253 continue;
254 client_write_server(MSG_ENVIRON, &data, sizeof data);
255 }
256 }
257
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
258 /* Write a message to the server without a file descriptor. */
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
259 void
260 client_write_server(enum msgtype type, void *buf, size_t len)
261 {
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
262 imsg_compose(&client_ibuf, type, PROTOCOL_VERSION, -1, -1, buf, len);
263 }
264
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
265 /* Update client event based on whether it needs to read or read and write. */
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
266 void
267 client_update_event(void)
268 {
269 short events;
270
271 event_del(&client_event);
272 events = EV_READ;
273 if (client_ibuf.w.queued > 0)
274 events |= EV_WRITE;
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
275 event_set(
276 &client_event, client_ibuf.fd, events, client_callback, shell_cmd);
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
277 event_add(&client_event, NULL);
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
278 }
279
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
280 /* Callback to handle signals in the client. */
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
281 /* ARGSUSED */
282 void
283 client_signal(int sig, unused short events, unused void *data)
284 {
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
285 struct sigaction sigact;
286 int status;
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
287
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
288 if (!client_attached) {
289 switch (sig) {
290 case SIGCHLD:
291 waitpid(WAIT_ANY, &status, WNOHANG);
292 break;
293 case SIGTERM:
294 event_loopexit(NULL);
295 break;
296 }
297 } else {
298 switch (sig) {
299 case SIGHUP:
300 client_exitmsg = "lost tty";
301 client_exitval = 1;
302 client_write_server(MSG_EXITING, NULL, 0);
303 break;
304 case SIGTERM:
305 client_exitmsg = "terminated";
306 client_exitval = 1;
307 client_write_server(MSG_EXITING, NULL, 0);
308 break;
309 case SIGWINCH:
310 client_write_server(MSG_RESIZE, NULL, 0);
311 break;
312 case SIGCONT:
313 memset(&sigact, 0, sizeof sigact);
314 sigemptyset(&sigact.sa_mask);
315 sigact.sa_flags = SA_RESTART;
316 sigact.sa_handler = SIG_IGN;
317 if (sigaction(SIGTSTP, &sigact, NULL) != 0)
318 fatal("sigaction failed");
319 client_write_server(MSG_WAKEUP, NULL, 0);
320 break;
321 }
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
322 }
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
323
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
324 client_update_event();
325 }
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
326
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
327 /* Callback for client imsg read events. */
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
328 /* ARGSUSED */
329 void
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
330 client_callback(unused int fd, short events, void *data)
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
331 {
332 ssize_t n;
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
333 int retval;
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
334
335 if (events & EV_READ) {
336 if ((n = imsg_read(&client_ibuf)) == -1 || n == 0)
337 goto lost_server;
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
338 if (client_attached)
339 retval = client_dispatch_attached();
340 else
341 retval = client_dispatch_wait(data);
342 if (retval != 0) {
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
343 event_loopexit(NULL);
344 return;
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
345 }
346 }
347
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
348 if (events & EV_WRITE) {
349 if (msgbuf_write(&client_ibuf.w) < 0)
350 goto lost_server;
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
351 }
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
352
353 client_update_event();
354 return;
355
356 lost_server:
357 client_exitmsg = "lost server";
358 client_exitval = 1;
359 event_loopexit(NULL);
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
360 }
361
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
362 /* Dispatch imsgs when in wait state (before MSG_READY). */
363 int
364 client_dispatch_wait(void *data)
365 {
366 struct imsg imsg;
367 ssize_t n, datalen;
368 struct msg_shell_data shelldata;
369 struct msg_exit_data exitdata;
370 const char *shellcmd = data;
371
372 if ((n = imsg_read(&client_ibuf)) == -1 || n == 0)
373 fatalx("imsg_read failed");
374
375 for (;;) {
376 if ((n = imsg_get(&client_ibuf, &imsg)) == -1)
377 fatalx("imsg_get failed");
378 if (n == 0)
379 return (0);
380 datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
381
382 switch (imsg.hdr.type) {
383 case MSG_EXIT:
384 case MSG_SHUTDOWN:
385 if (datalen != sizeof exitdata) {
386 if (datalen != 0)
387 fatalx("bad MSG_EXIT size");
388 } else {
389 memcpy(&exitdata, imsg.data, sizeof exitdata);
390 client_exitval = exitdata.retcode;
391 }
392 imsg_free(&imsg);
393 return (-1);
394 case MSG_READY:
395 if (datalen != 0)
396 fatalx("bad MSG_READY size");
397
398 client_attached = 1;
399 break;
400 case MSG_VERSION:
401 if (datalen != 0)
402 fatalx("bad MSG_VERSION size");
403
404 log_warnx("protocol version mismatch (client %u, "
405 "server %u)", PROTOCOL_VERSION, imsg.hdr.peerid);
406 client_exitval = 1;
407
408 imsg_free(&imsg);
409 return (-1);
410 case MSG_SHELL:
411 if (datalen != sizeof shelldata)
412 fatalx("bad MSG_SHELL size");
413 memcpy(&shelldata, imsg.data, sizeof shelldata);
414 shelldata.shell[(sizeof shelldata.shell) - 1] = '\0';
415
416 clear_signals(0);
417
418 shell_exec(shelldata.shell, shellcmd);
419 /* NOTREACHED */
420 default:
421 fatalx("unexpected message");
422 }
423
424 imsg_free(&imsg);
425 }
426 }
427
428 /* Dispatch imsgs in attached state (after MSG_READY). */
429 /* ARGSUSED */
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
430 int
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
431 client_dispatch_attached(void)
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
432 {
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
433 struct imsg imsg;
434 struct msg_lock_data lockdata;
435 struct sigaction sigact;
436 ssize_t n, datalen;
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
437
438 for (;;) {
439 if ((n = imsg_get(&client_ibuf, &imsg)) == -1)
440 fatalx("imsg_get failed");
441 if (n == 0)
442 return (0);
443 datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
444
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
445 log_debug("client got %d", imsg.hdr.type);
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
446 switch (imsg.hdr.type) {
7216c39 Karl Ferdinand Ebert Imported Upstream version 1.5
kfebert authored
447 case MSG_DETACHKILL:
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
448 case MSG_DETACH:
449 if (datalen != 0)
450 fatalx("bad MSG_DETACH size");
451
7216c39 Karl Ferdinand Ebert Imported Upstream version 1.5
kfebert authored
452 client_exittype = imsg.hdr.type;
453 if (imsg.hdr.type == MSG_DETACHKILL)
454 client_exitmsg = "detached and SIGHUP";
455 else
456 client_exitmsg = "detached";
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
457 client_write_server(MSG_EXITING, NULL, 0);
458 break;
459 case MSG_EXIT:
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
460 if (datalen != 0 &&
461 datalen != sizeof (struct msg_exit_data))
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
462 fatalx("bad MSG_EXIT size");
463
464 client_write_server(MSG_EXITING, NULL, 0);
465 client_exitmsg = "exited";
466 break;
467 case MSG_EXITED:
468 if (datalen != 0)
469 fatalx("bad MSG_EXITED size");
470
471 imsg_free(&imsg);
472 return (-1);
473 case MSG_SHUTDOWN:
474 if (datalen != 0)
475 fatalx("bad MSG_SHUTDOWN size");
476
477 client_write_server(MSG_EXITING, NULL, 0);
478 client_exitmsg = "server exited";
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
479 client_exitval = 1;
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
480 break;
481 case MSG_SUSPEND:
482 if (datalen != 0)
483 fatalx("bad MSG_SUSPEND size");
484
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
485 memset(&sigact, 0, sizeof sigact);
486 sigemptyset(&sigact.sa_mask);
487 sigact.sa_flags = SA_RESTART;
488 sigact.sa_handler = SIG_DFL;
489 if (sigaction(SIGTSTP, &sigact, NULL) != 0)
490 fatal("sigaction failed");
491 kill(getpid(), SIGTSTP);
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
492 break;
493 case MSG_LOCK:
494 if (datalen != sizeof lockdata)
495 fatalx("bad MSG_LOCK size");
496 memcpy(&lockdata, imsg.data, sizeof lockdata);
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
497
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
498 lockdata.cmd[(sizeof lockdata.cmd) - 1] = '\0';
499 system(lockdata.cmd);
500 client_write_server(MSG_UNLOCK, NULL, 0);
501 break;
502 default:
503 fatalx("unexpected message");
504 }
505
506 imsg_free(&imsg);
507 }
508 }
Something went wrong with that request. Please try again.