fchmod-tests, fchmodat tests, lchmod tests: Add more tests.
[gnulib.git] / lib / login_tty.c
blob8e018a4b5ed763311b99c57a8bb5c2dca2ec9ec3
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-2021 Free Software Foundation, Inc.
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.
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.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
18 #include <config.h>
20 /* Currently no specification header. */
22 #include <fcntl.h>
23 #include <unistd.h>
24 #include <sys/ioctl.h>
26 int
27 login_tty (int slave_fd)
29 int i;
31 /* Create a new session. */
32 setsid ();
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.
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
52 char *slave_name;
53 int dummy_fd;
55 slave_name = ttyname (slave_fd);
56 if (slave_name == NULL)
57 return -1;
58 dummy_fd = open (slave_name, O_RDWR | O_CLOEXEC);
59 if (dummy_fd < 0)
60 return -1;
61 close (dummy_fd);
63 #endif
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);
74 return 0;