Linux ioctl для tty дает EPERM - PullRequest
0 голосов
/ 08 мая 2019

Я пытаюсь реализовать программу 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 */
}
...