]> arthur.barton.de Git - bup.git/blob - lib/cmd/mux-cmd.py
damage-cmd: copy to bup.cmd.damage
[bup.git] / lib / cmd / mux-cmd.py
1 #!/bin/sh
2 """": # -*-python-*-
3 # https://sourceware.org/bugzilla/show_bug.cgi?id=26034
4 export "BUP_ARGV_0"="$0"
5 arg_i=1
6 for arg in "$@"; do
7     export "BUP_ARGV_${arg_i}"="$arg"
8     shift
9     arg_i=$((arg_i + 1))
10 done
11 # Here to end of preamble replaced during install
12 bup_python="$(dirname "$0")/../../config/bin/python" || exit $?
13 exec "$bup_python" "$0"
14 """
15 # end of bup preamble
16
17 from __future__ import absolute_import
18
19 # Intentionally replace the dirname "$0" that python prepends
20 import os, sys
21 sys.path[0] = os.path.dirname(os.path.realpath(__file__)) + '/..'
22
23 import struct, subprocess
24
25 from bup import compat, options
26 from bup.helpers import debug1, debug2, mux
27 from bup.io import byte_stream
28
29 # Give the subcommand exclusive access to stdin.
30 orig_stdin = os.dup(0)
31 devnull = os.open(os.devnull, os.O_RDONLY)
32 os.dup2(devnull, 0)
33 os.close(devnull)
34
35 optspec = """
36 bup mux command [arguments...]
37 --
38 """
39 o = options.Options(optspec)
40 opt, flags, extra = o.parse(compat.argv[1:])
41 if len(extra) < 1:
42     o.fatal('command is required')
43
44 subcmd = extra
45
46 debug2('bup mux: starting %r\n' % (extra,))
47
48 outr, outw = os.pipe()
49 errr, errw = os.pipe()
50 def close_fds():
51     os.close(outr)
52     os.close(errr)
53
54 p = subprocess.Popen(subcmd, stdin=orig_stdin, stdout=outw, stderr=errw,
55                      close_fds=False, preexec_fn=close_fds)
56 os.close(outw)
57 os.close(errw)
58 sys.stdout.flush()
59 out = byte_stream(sys.stdout)
60 out.write(b'BUPMUX')
61 out.flush()
62 mux(p, out.fileno(), outr, errr)
63 os.close(outr)
64 os.close(errr)
65 prv = p.wait()
66
67 if prv:
68     debug1('%s exited with code %d\n' % (extra[0], prv))
69
70 debug1('bup mux: done\n')
71
72 sys.exit(prv)