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