Your message dated Thu, 7 May 2009 19:39:35 +0100
with message-id <[email protected]>
and subject line subterfugue has been removed from Debian, closing #418894
has caused the Debian Bug report #418894,
regarding subterfugue FakePipeTrick
to be marked as done.
This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.
(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact [email protected]
immediately.)
--
418894: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=418894
Debian Bug Tracking System
Contact [email protected] with problems
--- Begin Message ---
Package: subterfugue
Version: 0.2.1a-9.5
Please find attached an sf trick I wrote for handling annoying
programs which insist on plain files. I originally wrote this before
discovering ffmpeg's image2pipe format :-) and amazingly it works.
Usage is eg:
sf -t FakePipe:debug=1 -t Scratch ffmpeg -y -f image2 ...
It is Copyright (C)2007 Ian Jackson. I hereby licence it under the
GNU GPL, version 2 or at your option any later version.
Ian.
# make program read from named pipes exactly once each while
# it thinks they're seekable files
from Trick import Trick
import Memory
import fnmatch
import stat
import os
import sys
import scratch
import shutil
class FakePipe(Trick):
def usage(self):
return """
Mediate attempts to open and read named pipes.
Restrictions on the sf client:
* The sf client opens a named pipe (only ever for reading).
* All of the reads, fstats and seeks of each named pipe must
occur on a single fd onto the pipe obtained from a single
call to open.
Consequences - if these restrictions are true, then:
* Other processes will see the sf client open the pipe once
and read all of the data from it in one go.
* The data from the pipe will be spooled to a file alongside
the pipe; the filename <name-of-pipe>.~fake-pipe-file~ is
reserved. These files may or may not be deleted but
disk space for their data will only be used at times when
this is necessary.
* The sf client will see not a pipe but a plain file
containing the relevant data.
Infelicities:
* The sf client may see a file with a zero link count in fstat.
* If the sf client calls [l]stat it will see the actual pipe
and not the file.
The `pattern' parameter is a glob pattern which specifies affected
`open's.
"""
def __init__(self,options):
self.pattern = '*'
self.suffix = '.~fake-pipe-file'
self.pids_fds = {}
self.debug = 0
if options.has_key('pattern'):
self.pattern = options['pattern']
if options.has_key('debug'):
self.debug = int(options['debug'])
def d(self, l, m):
if self.debug < l: return
print >>sys.stderr, "FakePipe:", m
class Entry: pass
def callbefore(self, pid, call, args):
getarg = Memory.getMemory(pid).get_string
if (call == 'open' and
args[1] & (os.O_RDONLY | os.O_RDWR | os.O_WRONLY) ==
os.O_RDONLY):
fn = getarg(args[0])
if not fnmatch.fnmatch(fn, self.pattern): return
try: statinfo = os.stat(fn)
except OSError, e:
self.d(3, 'opening "%s" - error %s' % (fn, e))
return
if not stat.S_ISFIFO(statinfo.st_mode):
self.d(3, 'opening "%s" - not a pipe' % fn);
return
state = self.Entry()
state.fn = fn
state.nf = fn+self.suffix
self.d(2, 'opening "%s" -> "%s" ...' % (fn, state.nf))
(state.tofree, nfc) = scratch.alloc_str(state.nf)
state.copied = False
args[0] = nfc
args[1] = os.O_RDWR | os.O_CREAT;
args[2] = 0600;
return (state, None,None, args)
if (call == 'read' or call == 'fstat' or
fnmatch.fnmatch(call, '*lseek*')):
fd = args[0]
try: state = self.pids_fds[pid][fd]
except KeyError:
self.d(3, 'examining %s %d - not ours' % (call,
fd))
return
if state.copied:
self.d(2, 'examining %s %d - already copied' %
(call, fd))
return
self.d(1, 'examining %s %d, copying ...' % (call, fd))
try:
real = open(state.fn, 'r')
fake = open(state.nf, 'w')
shutil.copyfileobj(real,fake)
real.close()
fake.close()
except IOError, e:
self.d(1, 'examining %s %d: copy-fail %s' %
(call, fd, e))
return (None, e.errno, None, None)
self.d(2, 'examining %s %d - copy ok' % (call, fd))
state.copied = True
if (call == 'close'):
return (args[0], None,None,None)
if (call == 'dup2'):
return (args[1], None,None,None)
def callafter(self, pid, call, result, state):
if (call == 'open' and state is not None):
self.d(1, 'opening "%s" ... result=%d' % (state.fn,
result))
scratch.free(state.tofree)
state.tofree = None
if (result >= 0):
try: pf = self.pids_fds[pid]
except KeyError: pf = {}; self.pids_fds[pid] =
pf
pf[result] = state
if (call == 'close' or call == 'dup2'):
self.do_close(call, pid, state)
def do_close(self, call, pid, fd):
try: ostate = self.pids_fds[pid][fd]
except KeyError:
self.d(3, 'closing %s %d - not ours' % (call,
fd))
return
if ostate.copied:
self.d(1, 'closing %s %d - copied, deleting' %
(call, fd))
os.remove(ostate.nf)
else:
self.d(2, 'closing %s %d - not copied' % (call,
fd))
del self.pids_fds[pid][fd]
--- End Message ---
--- Begin Message ---
Version: 0.2.1a-10+rm
The subterfugue package has been removed from Debian so we are closing
the bugs that were still opened against it.
For more information about this package's removal, read
http://bugs.debian.org/474132 . That bug might give the reasons why
this package was removed, and suggestions of possible replacements.
Don't hesitate to reply to this mail if you have any question.
Thank you for your contribution to Debian.
Kind regards,
--
Marco Rodrigues
--- End Message ---