Create a temporary FIFO (named pipe) in Python?

后端 未结 6 1290
被撕碎了的回忆
被撕碎了的回忆 2020-11-29 05:49

How can you create a temporary FIFO (named pipe) in Python? This should work:

import tempfile

temp_file_name = mktemp()
os.mkfifo(temp_file_name)
open(temp_         


        
相关标签:
6条回答
  • 2020-11-29 06:14

    How about using

    d = mkdtemp()
    t = os.path.join(d, 'fifo')
    
    0 讨论(0)
  • 2020-11-29 06:21

    If it's for use within your program, and not with any externals, have a look at the Queue module. As an added benefit, python queues are thread-safe.

    0 讨论(0)
  • 2020-11-29 06:24

    You may find it handy to use the following context manager, which creates and removes the temporary file for you:

    import os
    import tempfile
    from contextlib import contextmanager
    
    
    @contextmanager
    def temp_fifo():
        """Context Manager for creating named pipes with temporary names."""
        tmpdir = tempfile.mkdtemp()
        filename = os.path.join(tmpdir, 'fifo')  # Temporary filename
        os.mkfifo(filename)  # Create FIFO
        try:
            yield filename
        finally:
            os.unlink(filename)  # Remove file
            os.rmdir(tmpdir)  # Remove directory
    

    You can use it, for example, like this:

    with temp_fifo() as fifo_file:
        # Pass the fifo_file filename e.g. to some other process to read from.
        # Write something to the pipe 
        with open(fifo_file, 'w') as f:
            f.write("Hello\n")
    
    0 讨论(0)
  • 2020-11-29 06:36

    os.mkfifo() will fail with exception OSError: [Errno 17] File exists if the file already exists, so there is no security issue here. The security issue with using tempfile.mktemp() is the race condition where it is possible for an attacker to create a file with the same name before you open it yourself, but since os.mkfifo() fails if the file already exists this is not a problem.

    However, since mktemp() is deprecated you shouldn't use it. You can use tempfile.mkdtemp() instead:

    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: I should make it clear that, just because the mktemp() vulnerability is averted by this, there are still the other usual security issues that need to be considered; e.g. an attacker could create the fifo (if they had suitable permissions) before your program did which could cause your program to crash if errors/exceptions are not properly handled.

    0 讨论(0)
  • 2020-11-29 06:37

    Why not just use mkstemp()?

    For example:

    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)
    
    0 讨论(0)
  • 2020-11-29 06:38

    Effectively, all that mkstemp does is run mktemp in a loop and keeps attempting to exclusively create until it succeeds (see stdlib source code here). You can do the same with 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")
    
    0 讨论(0)
提交回复
热议问题