From 7ae6605846ecc70c937fca31b2133082aae055df Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 19 Aug 2014 14:22:22 +0200 Subject: Use Gnulib forkpty() --- lib/login_tty.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 lib/login_tty.c (limited to 'lib/login_tty.c') diff --git a/lib/login_tty.c b/lib/login_tty.c new file mode 100644 index 00000000..e07f1607 --- /dev/null +++ b/lib/login_tty.c @@ -0,0 +1,75 @@ +/* Assign a given terminal as controlling terminal and as standard input, + standard output, standard error of the current process. + Copyright (C) 2010-2014 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +/* Currently no specification header. */ + +#include +#include +#include + +int +login_tty (int slave_fd) +{ + int i; + + /* Create a new session. */ + setsid (); + + /* Make fd the controlling terminal for the current process. + On BSD and OSF/1: There is ioctl TIOCSCTTY for this purpose. + On Solaris: + A terminal becomes the controlling terminal of a session + if it is being open()ed, at a moment when + 1. it is not already the controlling terminal of some session, and + 2. the process that open()s it is a session leader that does not have + a controlling terminal. + We assume condition 1, try to ensure condition 2, and then open() it. + */ + for (i = 0; i < 3; i++) + if (i != slave_fd) + close (i); +#ifdef TIOCSCTTY + if (ioctl (slave_fd, TIOCSCTTY, NULL) < 0) + return -1; +#else + { + char *slave_name; + int dummy_fd; + + slave_name = ttyname (slave_fd); + if (slave_name == NULL) + return -1; + dummy_fd = open (slave_name, O_RDWR); + if (dummy_fd < 0) + return -1; + close (dummy_fd); + } +#endif + + /* Assign fd to the standard input, standard output, and standard error of + the current process. */ + for (i = 0; i < 3; i++) + if (slave_fd != i) + if (dup2 (slave_fd, i) < 0) + return -1; + if (slave_fd >= 3) + close (slave_fd); + + return 0; +} -- cgit v1.2.3