chiark / gitweb /
bus-policy: append items rather than prepending them
[elogind.git] / src / shared / pty.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2014 David Herrmann <dh.herrmann@gmail.com>
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 /*
23  * PTY
24  * A PTY object represents a single PTY connection between a master and a
25  * child. The child process is fork()ed so the caller controls what program
26  * will be run.
27  *
28  * Programs like /bin/login tend to perform a vhangup() on their TTY
29  * before running the login procedure. This also causes the pty master
30  * to get a EPOLLHUP event as long as no client has the TTY opened.
31  * This means, we cannot use the TTY connection as reliable way to track
32  * the client. Instead, we _must_ rely on the PID of the client to track
33  * them.
34  * However, this has the side effect that if the client forks and the
35  * parent exits, we loose them and restart the client. But this seems to
36  * be the expected behavior so we implement it here.
37  *
38  * Unfortunately, epoll always polls for EPOLLHUP so as long as the
39  * vhangup() is ongoing, we will _always_ get EPOLLHUP and cannot sleep.
40  * This gets worse if the client closes the TTY but doesn't exit.
41  * Therefore, the fd must be edge-triggered in the epoll-set so we
42  * only get the events once they change.
43  */
44
45 #include <errno.h>
46 #include <fcntl.h>
47 #include <limits.h>
48 #include <linux/ioctl.h>
49 #include <pty.h>
50 #include <signal.h>
51 #include <stdbool.h>
52 #include <stdint.h>
53 #include <stdio.h>
54 #include <stdlib.h>
55 #include <string.h>
56 #include <sys/epoll.h>
57 #include <sys/eventfd.h>
58 #include <sys/ioctl.h>
59 #include <sys/types.h>
60 #include <sys/uio.h>
61 #include <sys/wait.h>
62 #include <termios.h>
63 #include <unistd.h>
64
65 #include "barrier.h"
66 #include "macro.h"
67 #include "pty.h"
68 #include "ring.h"
69 #include "util.h"
70
71 #define PTY_BUFSIZE 16384
72
73 enum {
74         PTY_ROLE_UNKNOWN,
75         PTY_ROLE_PARENT,
76         PTY_ROLE_CHILD,
77 };
78
79 struct Pty {
80         unsigned long ref;
81         Barrier barrier;
82         int fd;
83         pid_t child;
84         sd_event_source *fd_source;
85         sd_event_source *child_source;
86
87         char in_buf[PTY_BUFSIZE];
88         Ring out_buf;
89
90         pty_event_t event_fn;
91         void *event_fn_userdata;
92
93         bool needs_requeue : 1;
94         unsigned int role : 2;
95 };
96
97 int pty_new(Pty **out) {
98         _pty_unref_ Pty *pty = NULL;
99         int r;
100
101         assert_return(out, -EINVAL);
102
103         pty = new0(Pty, 1);
104         if (!pty)
105                 return -ENOMEM;
106
107         pty->ref = 1;
108         pty->fd = -1;
109         pty->barrier = (Barrier) BARRIER_NULL;
110
111         pty->fd = posix_openpt(O_RDWR | O_NOCTTY | O_CLOEXEC | O_NONBLOCK);
112         if (pty->fd < 0)
113                 return -errno;
114
115         /*
116          * The slave-node is initialized to uid/gid of the caller of
117          * posix_openpt(). Only if devpts is mounted with fixed uid/gid this is
118          * skipped. In that case, grantpt() can overwrite these, but then you
119          * have to be root to use chown() (or a pt_chown helper has to be
120          * present). In those cases grantpt() really does something,
121          * otherwise it's a no-op. We call grantpt() here to try supporting
122          * those cases, even though no-one uses that, I guess. If you need other
123          * access-rights, set them yourself after this call returns (no, this is
124          * not racy, it looks racy, but races regarding your own UID are never
125          * important as an attacker could ptrace you; and the slave-pty is also
126          * still locked).
127          */
128         r = grantpt(pty->fd);
129         if (r < 0)
130                 return -errno;
131
132         r = barrier_create(&pty->barrier);
133         if (r < 0)
134                 return r;
135
136         *out = pty;
137         pty = NULL;
138         return 0;
139 }
140
141 Pty *pty_ref(Pty *pty) {
142         if (!pty || pty->ref < 1)
143                 return NULL;
144
145         ++pty->ref;
146         return pty;
147 }
148
149 Pty *pty_unref(Pty *pty) {
150         if (!pty || pty->ref < 1 || --pty->ref > 0)
151                 return NULL;
152
153         pty_close(pty);
154         pty->child_source = sd_event_source_unref(pty->child_source);
155         barrier_destroy(&pty->barrier);
156         ring_clear(&pty->out_buf);
157         free(pty);
158
159         return NULL;
160 }
161
162 Barrier *pty_get_barrier(Pty *pty) {
163         assert(pty);
164         return &pty->barrier;
165 }
166
167 bool pty_is_unknown(Pty *pty) {
168         return pty && pty->role == PTY_ROLE_UNKNOWN;
169 }
170
171 bool pty_is_parent(Pty *pty) {
172         return pty && pty->role == PTY_ROLE_PARENT;
173 }
174
175 bool pty_is_child(Pty *pty) {
176         return pty && pty->role == PTY_ROLE_CHILD;
177 }
178
179 bool pty_has_child(Pty *pty) {
180         return pty_is_parent(pty) && pty->child > 0;
181 }
182
183 pid_t pty_get_child(Pty *pty) {
184         return pty_has_child(pty) ? pty->child : -ECHILD;
185 }
186
187 bool pty_is_open(Pty *pty) {
188         return pty && pty->fd >= 0;
189 }
190
191 int pty_get_fd(Pty *pty) {
192         assert_return(pty, -EINVAL);
193
194         return pty_is_open(pty) ? pty->fd : -EPIPE;
195 }
196
197 int pty_make_child(Pty *pty) {
198         char slave_name[1024];
199         int r, fd;
200
201         assert_return(pty, -EINVAL);
202         assert_return(pty_is_unknown(pty), -EALREADY);
203
204         r = ptsname_r(pty->fd, slave_name, sizeof(slave_name));
205         if (r < 0)
206                 return -errno;
207
208         fd = open(slave_name, O_RDWR | O_CLOEXEC | O_NOCTTY);
209         if (fd < 0)
210                 return -errno;
211
212         safe_close(pty->fd);
213         pty->fd = fd;
214         pty->child = getpid();
215         pty->role = PTY_ROLE_CHILD;
216         barrier_set_role(&pty->barrier, BARRIER_CHILD);
217
218         return 0;
219 }
220
221 int pty_make_parent(Pty *pty, pid_t child) {
222         assert_return(pty, -EINVAL);
223         assert_return(pty_is_unknown(pty), -EALREADY);
224
225         pty->child = child;
226         pty->role = PTY_ROLE_PARENT;
227
228         return 0;
229 }
230
231 int pty_unlock(Pty *pty) {
232         assert_return(pty, -EINVAL);
233         assert_return(pty_is_unknown(pty) || pty_is_parent(pty), -EINVAL);
234         assert_return(pty_is_open(pty), -ENODEV);
235
236         return unlockpt(pty->fd) < 0 ? -errno : 0;
237 }
238
239 int pty_setup_child(Pty *pty) {
240         struct termios attr;
241         pid_t pid;
242         int r;
243
244         assert_return(pty, -EINVAL);
245         assert_return(pty_is_child(pty), -EINVAL);
246         assert_return(pty_is_open(pty), -EALREADY);
247
248         r = sigprocmask_many(SIG_SETMASK, -1);
249         if (r < 0)
250                 return r;
251
252         r = reset_all_signal_handlers();
253         if (r < 0)
254                 return r;
255
256         pid = setsid();
257         if (pid < 0 && errno != EPERM)
258                 return -errno;
259
260         r = ioctl(pty->fd, TIOCSCTTY, 0);
261         if (r < 0)
262                 return -errno;
263
264         r = tcgetattr(pty->fd, &attr);
265         if (r < 0)
266                 return -errno;
267
268         /* erase character should be normal backspace, PLEASEEE! */
269         attr.c_cc[VERASE] = 010;
270         /* always set UTF8 flag */
271         attr.c_iflag |= IUTF8;
272
273         r = tcsetattr(pty->fd, TCSANOW, &attr);
274         if (r < 0)
275                 return -errno;
276
277         if (dup2(pty->fd, STDIN_FILENO) != STDIN_FILENO ||
278             dup2(pty->fd, STDOUT_FILENO) != STDOUT_FILENO ||
279             dup2(pty->fd, STDERR_FILENO) != STDERR_FILENO)
280                 return -errno;
281
282         /* only close FD if it's not a std-fd */
283         pty->fd = (pty->fd > 2) ? safe_close(pty->fd) : -1;
284
285         return 0;
286 }
287
288 void pty_close(Pty *pty) {
289         if (!pty_is_open(pty))
290                 return;
291
292         pty->fd_source = sd_event_source_unref(pty->fd_source);
293         pty->fd = safe_close(pty->fd);
294 }
295
296 /*
297  * Drain input-queue and dispatch data via the event-handler. Returns <0 on
298  * error, 0 if queue is empty and 1 if we couldn't empty the input queue fast
299  * enough and there's still data left.
300  */
301 static int pty_dispatch_read(Pty *pty) {
302         unsigned int i;
303         ssize_t len;
304         int r;
305
306         /*
307          * We're edge-triggered, means we need to read the whole queue. This,
308          * however, might cause us to stall if the writer is faster than we
309          * are. Therefore, we read twice and if the second read still returned
310          * data, we reschedule.
311          */
312
313         for (i = 0; i < 2; ++i) {
314                 len = read(pty->fd, pty->in_buf, sizeof(pty->in_buf) - 1);
315                 if (len < 0) {
316                         if (errno == EINTR)
317                                 continue;
318
319                         return (errno == EAGAIN) ? 0 : -errno;
320                 } else if (len == 0) {
321                         continue;
322                 }
323
324                 /* set terminating zero for debugging safety */
325                 pty->in_buf[len] = 0;
326                 r = pty->event_fn(pty, pty->event_fn_userdata, PTY_DATA, pty->in_buf, len);
327                 if (r < 0)
328                         return r;
329         }
330
331         /* still data left, make sure we're queued again */
332         pty->needs_requeue = true;
333
334         return 1;
335 }
336
337 /*
338  * Drain output-queue by writing data to the pty. Returns <0 on error, 0 if the
339  * output queue is empty now and 1 if we couldn't empty the output queue fast
340  * enough and there's still data left.
341  */
342 static int pty_dispatch_write(Pty *pty) {
343         struct iovec vec[2];
344         unsigned int i;
345         ssize_t len;
346         size_t num;
347
348         /*
349          * Same as pty_dispatch_read(), we're edge-triggered so we need to call
350          * write() until either all data is written or it returns EAGAIN. We
351          * call it twice and if it still writes successfully, we reschedule.
352          */
353
354         for (i = 0; i < 2; ++i) {
355                 num = ring_peek(&pty->out_buf, vec);
356                 if (num < 1)
357                         return 0;
358
359                 len = writev(pty->fd, vec, (int)num);
360                 if (len < 0) {
361                         if (errno == EINTR)
362                                 continue;
363
364                         return (errno == EAGAIN) ? 1 : -errno;
365                 } else if (len == 0) {
366                         continue;
367                 }
368
369                 ring_pull(&pty->out_buf, (size_t)len);
370         }
371
372         /* still data left, make sure we're queued again */
373         if (ring_get_size(&pty->out_buf) > 0) {
374                 pty->needs_requeue = true;
375                 return 1;
376         }
377
378         return 0;
379 }
380
381 static int pty_fd_fn(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
382         Pty *pty = userdata;
383         int r_hup = 0, r_write = 0, r_read = 0, r;
384
385         /*
386          * Whenever we encounter I/O errors, we have to make sure to drain the
387          * input queue first, before we handle any HUP. A child might send us
388          * a message and immediately close the queue. We must not handle the
389          * HUP first or we loose data.
390          * Therefore, if we read a message successfully, we always return
391          * success and wait for the next event-loop iteration. Furthermore,
392          * whenever there is a write-error, we must try reading from the input
393          * queue even if EPOLLIN is not set. The input might have arrived in
394          * between epoll_wait() and write(). Therefore, write-errors are only
395          * ever handled if the input-queue is empty. In all other cases they
396          * are ignored until either reading fails or the input queue is empty.
397          */
398
399         if (revents & (EPOLLHUP | EPOLLERR))
400                 r_hup = -EPIPE;
401
402         if (revents & EPOLLOUT)
403                 r_write = pty_dispatch_write(pty);
404
405         /* Awesome! Kernel signals HUP without IN but queues are not empty.. */
406         if ((revents & EPOLLIN) || r_hup < 0 || r_write < 0) {
407                 r_read = pty_dispatch_read(pty);
408                 if (r_read > 0)
409                         return 0; /* still data left to fetch next round */
410         }
411
412         if (r_hup < 0 || r_write < 0 || r_read < 0) {
413                 /* PTY closed and input-queue drained */
414                 pty_close(pty);
415                 r = pty->event_fn(pty, pty->event_fn_userdata, PTY_HUP, NULL, 0);
416                 if (r < 0)
417                         return r;
418         }
419
420         return 0;
421 }
422
423 static int pty_fd_prepare_fn(sd_event_source *source, void *userdata) {
424         Pty *pty = userdata;
425         int r;
426
427         if (pty->needs_requeue) {
428                 /*
429                  * We're edge-triggered. In case we couldn't handle all events
430                  * or in case new write-data is queued, we set needs_requeue.
431                  * Before going asleep, we set the io-events *again*. sd-event
432                  * notices that we're edge-triggered and forwards the call to
433                  * the kernel even if the events didn't change. The kernel will
434                  * check the events and re-queue us on the ready queue in case
435                  * an event is pending.
436                  */
437                 r = sd_event_source_set_io_events(source, EPOLLHUP | EPOLLERR | EPOLLIN | EPOLLOUT | EPOLLET);
438                 if (r >= 0)
439                         pty->needs_requeue = false;
440         }
441
442         return 0;
443 }
444
445 static int pty_child_fn(sd_event_source *source, const siginfo_t *si, void *userdata) {
446         Pty *pty = userdata;
447         int r;
448
449         pty->child = 0;
450
451         r = pty->event_fn(pty, pty->event_fn_userdata, PTY_CHILD, si, sizeof(*si));
452         if (r < 0)
453                 return r;
454
455         return 0;
456 }
457
458 int pty_attach_event(Pty *pty, sd_event *event, pty_event_t event_fn, void *event_fn_userdata) {
459         int r;
460
461         assert_return(pty, -EINVAL);
462         assert_return(event, -EINVAL);
463         assert_return(event_fn, -EINVAL);
464         assert_return(pty_is_parent(pty), -EINVAL);
465
466         pty_detach_event(pty);
467
468         if (pty_is_open(pty)) {
469                 r = sd_event_add_io(event,
470                                     &pty->fd_source,
471                                     pty->fd,
472                                     EPOLLHUP | EPOLLERR | EPOLLIN | EPOLLOUT | EPOLLET,
473                                     pty_fd_fn,
474                                     pty);
475                 if (r < 0)
476                         goto error;
477
478                 r = sd_event_source_set_prepare(pty->fd_source, pty_fd_prepare_fn);
479                 if (r < 0)
480                         goto error;
481         }
482
483         if (pty_has_child(pty)) {
484                 r = sd_event_add_child(event,
485                                        &pty->child_source,
486                                        pty->child,
487                                        WEXITED,
488                                        pty_child_fn,
489                                        pty);
490                 if (r < 0)
491                         goto error;
492         }
493
494         pty->event_fn = event_fn;
495         pty->event_fn_userdata = event_fn_userdata;
496
497         return 0;
498
499 error:
500         pty_detach_event(pty);
501         return r;
502 }
503
504 void pty_detach_event(Pty *pty) {
505         if (!pty)
506                 return;
507
508         pty->child_source = sd_event_source_unref(pty->child_source);
509         pty->fd_source = sd_event_source_unref(pty->fd_source);
510         pty->event_fn = NULL;
511         pty->event_fn_userdata = NULL;
512 }
513
514 int pty_write(Pty *pty, const void *buf, size_t size) {
515         bool was_empty;
516         int r;
517
518         assert_return(pty, -EINVAL);
519         assert_return(pty_is_open(pty), -ENODEV);
520         assert_return(pty_is_parent(pty), -ENODEV);
521
522         if (size < 1)
523                 return 0;
524
525         /*
526          * Push @buf[0..@size] into the output ring-buffer. In case the
527          * ring-buffer wasn't empty beforehand, we're already waiting for
528          * EPOLLOUT and we're done. If it was empty, we have to re-queue the
529          * FD for EPOLLOUT as we're edge-triggered and wouldn't get any new
530          * EPOLLOUT event.
531          */
532
533         was_empty = ring_get_size(&pty->out_buf) < 1;
534
535         r = ring_push(&pty->out_buf, buf, size);
536         if (r < 0)
537                 return r;
538
539         if (was_empty)
540                 pty->needs_requeue = true;
541
542         return 0;
543 }
544
545 int pty_signal(Pty *pty, int sig) {
546         assert_return(pty, -EINVAL);
547         assert_return(pty_is_open(pty), -ENODEV);
548         assert_return(pty_is_parent(pty), -ENODEV);
549
550         return ioctl(pty->fd, TIOCSIG, sig) < 0 ? -errno : 0;
551 }
552
553 int pty_resize(Pty *pty, unsigned short term_width, unsigned short term_height) {
554         struct winsize ws;
555
556         assert_return(pty, -EINVAL);
557         assert_return(pty_is_open(pty), -ENODEV);
558         assert_return(pty_is_parent(pty), -ENODEV);
559
560         zero(ws);
561         ws.ws_col = term_width;
562         ws.ws_row = term_height;
563
564         /*
565          * This will send SIGWINCH to the pty slave foreground process group.
566          * We will also get one, but we don't need it.
567          */
568         return ioctl(pty->fd, TIOCSWINSZ, &ws) < 0 ? -errno : 0;
569 }
570
571 pid_t pty_fork(Pty **out, sd_event *event, pty_event_t event_fn, void *event_fn_userdata, unsigned short initial_term_width, unsigned short initial_term_height) {
572         _pty_unref_ Pty *pty = NULL;
573         int r;
574         pid_t pid;
575
576         assert_return(out, -EINVAL);
577         assert_return((event && event_fn) || (!event && !event_fn), -EINVAL);
578
579         r = pty_new(&pty);
580         if (r < 0)
581                 return r;
582
583         r = pty_unlock(pty);
584         if (r < 0)
585                 return r;
586
587         pid = fork();
588         if (pid < 0)
589                 return -errno;
590
591         if (pid == 0) {
592                 /* child */
593
594                 r = pty_make_child(pty);
595                 if (r < 0)
596                         _exit(-r);
597
598                 r = pty_setup_child(pty);
599                 if (r < 0)
600                         _exit(-r);
601
602                 /* sync with parent */
603                 if (!barrier_place_and_sync(&pty->barrier))
604                         _exit(1);
605
606                 /* fallthrough and return the child's PTY object */
607         } else {
608                 /* parent */
609
610                 r = pty_make_parent(pty, pid);
611                 if (r < 0)
612                         goto parent_error;
613
614                 r = pty_resize(pty, initial_term_width, initial_term_height);
615                 if (r < 0)
616                         goto parent_error;
617
618                 if (event) {
619                         r = pty_attach_event(pty, event, event_fn, event_fn_userdata);
620                         if (r < 0)
621                                 goto parent_error;
622                 }
623
624                 /* sync with child */
625                 if (!barrier_place_and_sync(&pty->barrier)) {
626                         r = -ECHILD;
627                         goto parent_error;
628                 }
629
630                 /* fallthrough and return the parent's PTY object */
631         }
632
633         *out = pty;
634         pty = NULL;
635         return pid;
636
637 parent_error:
638         barrier_abort(&pty->barrier);
639         waitpid(pty->child, NULL, 0);
640         pty->child = 0;
641         return r;
642 }