execve не наследует ни один файловый дескриптор - PullRequest
0 голосов
/ 20 июня 2019

Я пишу оболочку и пытаюсь реализовать процесс подстановки . форк-наследование всех файловых дескрипторов, выделенной памяти и т. д. Я понял, что execve должен также хранить такую ​​информацию и сохранять каждый открытый файловый дескриптор всякий раз, когда флаг O_CLOEXEC не установлен.

Я попробовал простой скрипт на python:
fd.py:

#!/usr/bin/env python3
import sys, os

if __name__ == "__main__":
    if len(sys.argv) == 1:
        new_fd = open("the_content_file", "w+")
        print("father table : ", os.listdir("/dev/fd"))
        if os.fork() == 0:
            os.execve("/PATH/OF/SCRIPT/fd.py", ["fd", "content"], os.environ)
    else:
        print("child table : ", os.listdir("/dev/fd"))
    pass

и в качестве вывода я получаю:

father table :  ['0', '1', '2', '3', '4']
child table :  ['0', '1', '2', '3']

После разветвления я сохраняю ту же таблицу fd, но всякий раз, когда я использую execve для исполняемого файла, я теряю все и открываю fd по умолчанию. Почему открытый фд исчезает? Спасибо

1 Ответ

2 голосов
/ 20 июня 2019

python3 (начиная с версии 3.4 и в отличие от python2) открывает файлы с флагом O_CLOEXEC по умолчанию.

Я не программист на python, но простой способ включить O_CLOEXEC обратнофайл может быть добавлен сразу после строки new_fd = ..:

        os.set_inheritable(new_fd.fileno(), True)

(протестировано на python 3.6.6, см. документы здесь )

или,в более старых версиях, таких как 3.5.3:

        tmp_fd = os.dup(new_fd.fileno())
        os.dup2(tmp_fd, new_fd.fileno())
        os.close(tmp_fd)

(os.dup2 используется для назначения fd по умолчанию наследуемой )

Обратите внимание, что, несмотря на ваше имяучитывая это, ваш new_fd не дескриптор файла, а поток Python.Дополнительный файл, который вы видите в родительском и дочернем элементах, является открытым дескриптором каталога /dev/fd.

...