Créer un FIFO temporaire (nommé pipe) en Python?

comment créer un FIFO temporaire (nommé pipe) en Python? Cela devrait fonctionner:

import tempfile

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

cependant, je suis hésitant en raison du grand Avertissement dans Python Docs 11.6 et le retrait potentiel parce qu'il est déprécié.

EDIT: Il est à noter que j'ai essayé tempfile.NamedTemporaryFile (et par extension tempfile.mkstemp), mais os.mkfifo lance:

OSError -17: le Fichier existe déjà

lorsque vous l'exécutez sur les fichiers que mkstemp / NamedTemporaryFile ont créé.

23
demandé sur Dougal 2009-09-16 05:16:58

5 réponses

os.mkfifo() échouera à l'exception OSError: [Errno 17] File exists si le fichier existe déjà, donc il n'y a pas de problème de sécurité ici. Le problème de sécurité avec l'aide de tempfile.mktemp() est la condition de la course où il est possible pour un attaquant de créer un fichier avec le même nom avant de l'ouvrir vous-même, mais depuis os.mkfifo() échoue si le fichier existe déjà, ce n'est pas un problème.

cependant, depuis mktemp() est obsolète, vous ne devriez pas l'utiliser. Vous pouvez utiliser tempfile.mkdtemp() au lieu de:

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)

MODIFIER: I devrait être clair que, juste parce que le mktemp() la vulnérabilité est évitée par ceci, il y a encore les autres problèmes de sécurité habituels qui doivent être pris en considération; par exemple, un attaquant pourrait créer le fifo (s'il avait les permissions appropriées) avant que votre programme ne le fasse, ce qui pourrait provoquer un plantage de votre programme si les erreurs/exceptions ne sont pas correctement gérées.

24
répondu mhawke 2015-08-20 21:42:53

Que Diriez-vous d'utiliser

d = mkdtemp()
t = os.path.join(d, 'fifo')
3
répondu brendan 2009-09-16 01:36:12

si c'est pour une utilisation dans votre programme, et pas avec des externes, regardez le module File d'attente. Comme avantage supplémentaire, les files d'attente python sont thread-safe.

3
répondu nilamo 2009-09-16 01:42:29

effectivement, tout cela mkstemp n'est run mktemp dans une boucle et continue de tenter de créer exclusivement jusqu'à ce qu'elle réussisse (voir code source stdlib ici). Vous pouvez faire de même avec 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")
1
répondu eestrada 2015-09-16 16:36:20

Pourquoi ne pas simplement utiliser mkstemp ()?

Par exemple:

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)
-1
répondu Daniel Pryden 2009-09-16 01:37:37