Почему Python не может открыть дескриптор файла, который я создал в Swift?
Краткий ответ (немного выдуманный): потому что дескриптор файла - это процесс локальный идентификатор, который используется ОС для связи с информацией об открытом файле, которую она хранит для процесса.Вы не можете копировать их между процессами.
Длинный ответ:
В macOS / Unix / Linux (* nix) дескриптор файла - это просто локальное значение процесса, котороеиспользуется ОС для ссылки на соответствующую информацию открытого файла в ОС.Разные процессы могут иметь одинаковые значения файловых дескрипторов, которые идентифицируют совершенно разные файлы.Поэтому нельзя просто скопировать значение дескриптора файла между процессами.
В * nix дочерний процесс наследует открытые файлы и связанные с ними дескрипторы от своего родителя.Это единственный способ передачи файловых дескрипторов между процессами.В общих чертах следующие шаги:
- Родительский процесс forks , создающий свой клон
- Затем клон закрывает все файлы, к которым дочерний элемент не должен обращаться (обычновсе они, за исключением стандартных файлов ввода, вывода и ошибок).
- Если родительский файл имеет предварительно открытые файлы, которые должны быть стандартными входными данными, выходными данными или ошибками, клон затем переназначает файловые дескрипторы для этих файловстандартные файловые дескрипторы для стандартного ввода, вывода и ошибки.
- После того, как вся эта работа с файловым дескриптором завершена, клон затем заменяет свой код кодом, который должен выполнить дочерний элемент - это сохраняет открытые файлы и файловые дескрипторы.
- Дочерний код теперь выполняется без информации обо всех этих настройках.
В Swift все вышеперечисленное обрабатывается Process
, в Terminal
оно обрабатывается оболочкой, которая используетчтобы настроить перенаправление файлов, каналы и т. д.
Чтобы получить канал для процесса Python, вы можете (а) использовать методы Process
, чтобы прикрепить его к spтент обрабатывает стандартный ввод или вывод;(б) создайте именованный канал , то есть канал с путем к файлу, и передайте путь к файлу в ваш python для открытия;или (c) перейти на низкоуровневый и написать некоторый интерфейсный C-код, который выполняет вызовы fork
/ dup(2)
/ exec
и запускает ваш код Python с конвейером по известному дескриптору, отличному от стандартного ввода или вывода.
(а) проще всего!(б) требует от вас некоторых исследований именованных каналов, это не сложно, но вам нужно будет работать с песочницей, если она включена, и создавать канал в каталоге, к которому могут обращаться оба процесса.(c) лучше избегать.
Веселитесь, и если вы застряли, задайте новый вопрос, показывающий, что вы пробовали, где он идет не так, и т. д., и кто-то, несомненно, поможет вам в этом.
НТН