Создать временный FIFO (именованный канал) в Python?



Как можно создать временный FIFO (именованный канал) в Python? Это должно сработать:



import tempfile

temp_file_name = mktemp()
os.mkfifo(temp_file_name)
open(temp_file_name, os.O_WRONLY)
# ... some process, somewhere, will read it ...


Однако я сомневаюсь из-за большого предупреждения в Python Docs 11.6 и потенциального удаления, потому что он устарел.



EDIT : примечательно, что я пытался tempfile.NamedTemporaryFile (и по расширению tempfile.mkstemp), но os.mkfifo бросает:




OSError -17: файл уже существует




При запуске его в файлах, созданных mkstemp/NamedTemporaryFile.

767   5  

5 ответов:

os.mkfifo() произойдет сбой с исключением OSError: [Errno 17] File exists, Если файл уже существует, поэтому здесь нет проблемы безопасности. Проблема безопасности с использованием tempfile.mktemp() - это состояние гонки, при котором злоумышленник может создать файл с тем же именем, прежде чем открыть его самостоятельно, но поскольку os.mkfifo() не удается, если файл уже существует, это не проблема.

Однако, поскольку mktemp() является устаревшим, вы не должны использовать его. Вместо этого можно использовать tempfile.mkdtemp():

import os, tempfile

tmpdir = tempfile.mkdtemp()
filename = os.path.join(tmpdir, 'myfifo')
print filename
try:
    os.mkfifo(filename)
except OSError, e:
    print "Failed to create FIFO: %s" % e
else:
    fifo = open(filename, 'w')
    # write stuff to fifo
    print >> fifo, "hello"
    fifo.close()
    os.remove(filename)
    os.rmdir(tmpdir)

EDIT: я должен пояснить, что, просто поскольку уязвимость mktemp() предотвращается этим, все еще существуют другие обычные проблемы безопасности, которые необходимо учитывать; например, злоумышленник может создать fifo (если у него есть соответствующие разрешения) до того, как это сделает ваша программа, что может привести к сбою вашей программы, если ошибки/исключения не будут должным образом обработаны.

Как насчет использования

d = mkdtemp()
t = os.path.join(d, 'fifo')

Если он предназначен для использования в вашей программе, а не с какими-либо внешними устройствами, посмотрите на модуль очереди . В качестве дополнительного преимущества очереди python являются потокобезопасными.

Фактически, все, что делает mkstemp, выполняется mktemp в цикле и продолжает попытки исключительно создавать, пока это не удастся (см. исходный код stdlibздесь ). То же самое можно сделать с os.mkfifo:

import os, errno, tempfile

def mkftemp(*args, **kwargs):
    for attempt in xrange(1024):
        tpath = tempfile.mktemp(*args, **kwargs)

        try:
            os.mkfifo(tpath, 0600)
        except OSError as e:
            if e.errno == errno.EEXIST:
                # lets try again
                continue
            else:
                raise
        else:
           # NOTE: we only return the path because opening with
           # os.open here would block indefinitely since there 
           # isn't anyone on the other end of the fifo.
           return tpath
    else:
        raise IOError(errno.EEXIST, "No usable temporary file name found")

Почему бы просто не использовать mkstemp () ?

Например:

import tempfile
import os

handle, filename = tempfile.mkstemp()
os.mkfifo(filename)
writer = open(filename, os.O_WRONLY)
reader = open(filename, os.O_RDONLY)
os.close(handle)

Comments

    Ничего не найдено.