Я пытаюсь реализовать программу getty (программа, которая получает определенный tty, устанавливает для него значения stdin, stdout и stderr и обычно выполняет процесс входа в систему; типичная реализация - agetty
).
Моя проблема в том, что она всегда выдает ошибку EPERM в строке с вызовом ioctl
, которая должна изменить управляющий терминал.
Справочная страница о ioctl_tty(2)
говорит:
TIOCSCTTY int arg
Make the given terminal the controlling terminal of the calling process. The calling process must be a session
leader and not have a controlling terminal already. For this case, arg should be specified as zero.
If this terminal is already the controlling terminal of a different session group, then the ioctl fails with EPERM,
unless the caller has the CAP_SYS_ADMIN capability and arg equals 1, in which case the terminal is stolen, and all
processes that had it as controlling terminal lose it.
Теперь, если я просто для теста запускаю его с привилегиями суперпользователя (это означает, что GID и UID = 0), теоретически ядро должно просто пропустить проверки возможностей, согласно man-странице capabilities(7)
.
Так что же не так со следующим кодом при запуске от имени root:
#include <termios.h>
#include <stropts.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
int main (int argc, char **argv) {
char path[50] = "/dev/";
if (argc > 1) strcat (path, argv[1]);
/* First argument is tty device name */
else return 1;
int fd = open (path, O_RDWR, 0);
if (fd == -1) return 1;
ioctl (fd, TIOCSCTTY, 1); /* Here is the error */
}