Из вывода strace
(лучше всего, если используется версия C):
setresuid(-1, 123, -1) = 0
open("/dev/ptmx", O_RDWR) = 3
statfs("/dev/pts", {f_type=DEVPTS_SUPER_MAGIC, f_bsize=4096, f_blocks=0, f_bfree=0, f_bavail=0, f_files=0, f_ffree=0, f_fsid={val=[0, 0]}, f_namelen=255, f_frsize=4096, f_flags=ST_VALID|ST_NOSUID|ST_NOEXEC|ST_RELATIME}) = 0
ioctl(3, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(3, TIOCGPTN, [6]) = 0
stat("/dev/pts/6", {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 6), ...}) = 0
getuid() = 0
chown("/dev/pts/6", 0, 5) = -1 EPERM (Operation not permitted)
close(3) = 0
Поскольку geteuid()
больше не является пользователем root, невозможно изменить TTY, который будет принадлежать getuid()
.
Ваш выбор:
- изменить UID, а не только EUID
- сбросить EUID непосредственно перед вызовом
openpty
, chown
самостоятельно, затем снова изменить EUID
- реализовать
openpty
самим ... в Linux это довольно тривиально (вам не нужен ужасный запасной вариант BSD) ... насколько вам нужно быть переносимым?