maint: update copyright
[gnulib.git] / lib / login_tty.c
1 /* Assign a given terminal as controlling terminal and as standard input,
2    standard output, standard error of the current process.
3    Copyright (C) 2010-2014 Free Software Foundation, Inc.
4
5    This program is free software: you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17
18 #include <config.h>
19
20 /* Currently no specification header.  */
21
22 #include <fcntl.h>
23 #include <unistd.h>
24 #include <sys/ioctl.h>
25
26 int
27 login_tty (int slave_fd)
28 {
29   int i;
30
31   /* Create a new session.  */
32   setsid ();
33
34   /* Make fd the controlling terminal for the current process.
35      On BSD and OSF/1: There is ioctl TIOCSCTTY for this purpose.
36      On Solaris:
37        A terminal becomes the controlling terminal of a session
38        if it is being open()ed, at a moment when
39          1. it is not already the controlling terminal of some session, and
40          2. the process that open()s it is a session leader that does not have
41             a controlling terminal.
42        We assume condition 1, try to ensure condition 2, and then open() it.
43    */
44   for (i = 0; i < 3; i++)
45     if (i != slave_fd)
46       close (i);
47 #ifdef TIOCSCTTY
48   if (ioctl (slave_fd, TIOCSCTTY, NULL) < 0)
49     return -1;
50 #else
51   {
52     char *slave_name;
53     int dummy_fd;
54
55     slave_name = ttyname (slave_fd);
56     if (slave_name == NULL)
57       return -1;
58     dummy_fd = open (slave_name, O_RDWR);
59     if (dummy_fd < 0)
60       return -1;
61     close (dummy_fd);
62   }
63 #endif
64
65   /* Assign fd to the standard input, standard output, and standard error of
66      the current process.  */
67   for (i = 0; i < 3; i++)
68     if (slave_fd != i)
69       if (dup2 (slave_fd, i) < 0)
70         return -1;
71   if (slave_fd >= 3)
72     close (slave_fd);
73
74   return 0;
75 }