-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
grabfd
executable file
·151 lines (129 loc) · 2.77 KB
/
grabfd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#!/bin/sh
##
## Grab stdin/stdout/stderr from another process
## Copyright (c) 2014 SATOH Fumiyasu @ OSS Technology Corp., Japan
##
## License: GNU General Public License version 3
##
## Inspired by:
## http://yudoufu.hatenablog.jp/entry/2014/02/06/001440
## http://qiita.com/kawaz/items/96af6fa59fdf999b94bd
set -u
pdie() {
echo "$0: ERROR: $1"
exit ${2-1}
}
cmd_usage="Usage: $0 [OPTIONS] PID
Options:
-w, --wait
Wait for process termination (default: Wait if stdout and/or stderr is tty)
-W, --no-wait
Do not wait for process termination
-i, --stdin
Grab process's stdin too (default: stdout and stderr only)
"
o_rdonly=0x0000
o_wronly=0x0001
if [ x"`uname`" = x"Linux" ]; then
o_append=02000
else
o_append=0x0008
fi
unset wait_f
stdin_f=''
while [ $# -gt 0 ]; do
case "$1" in
--wait|-w)
wait_f='set'
;;
--no-wait|-W)
wait_f=''
;;
--stdin|-i)
stdin_f='set'
;;
--)
break
;;
-*)
pdie "Unknown option: $1"
;;
*)
break
;;
esac
shift
done
if [ -n "$stdin_f" ] && [ -t 0 ] || [ -t 1 ] || [ -t 2 ]; then
wait_f='set'
else
wait_f=''
fi
if [ $# -lt 1 ] || [ $# -gt 2 ]; then
echo "$cmd_usage"
exit 1
fi
pid="$1"; shift
kill -0 "$pid" || pdie "No such process ID: $pid"
if [ -n "${1:+set}" ]; then
pid2="$1"; shift
kill -0 "$pid" || pdie "No such process ID: $pid2"
else
pid2="$$"
fi
if [ -d "/proc/$pid2/fd" ]; then
stdin="/proc/$pid2/fd/0"
stdout="/proc/$pid2/fd/1"
stderr="/proc/$pid2/fd/2"
else
if [ "$pid2" -ne "$$" ]; then
pdie "Cannot attach to another process's stdio on this platform"
fi
tty=`tty` || pdie "Tty not detected"
stdin="$tty"
stdout="$tty"
stderr="$tty"
fi
shift $#
## FIXME: Only gdb 7.0+ support --eval-command option
if [ -n "$stdin_f" ]; then
set -- "$@" --eval-command="print close(0)"
set -- "$@" --eval-command="print open(\"$stdin\", $o_rdonly)"
fi
set -- "$@" --eval-command="print close(1)"
set -- "$@" --eval-command="print open(\"$stdout\", $o_wronly|$o_append)"
set -- "$@" --eval-command="print close(2)"
set -- "$@" --eval-command="print open(\"$stderr\", $o_wronly|$o_append)"
set -- "$@" --eval-command="quit"
gdb_out=`gdb --batch --quiet -p "$pid" "$@" 2>&1`
if [ $? -ne 0 ]; then
echo "$gdb_out" 1>&2
pdie "gdb failed"
fi
if [ -z "$wait_f" ]; then
exit 0
fi
if type pwait >/dev/null 2>&1; then
pwait "$pid"
elif type procwait >/dev/null 2>&1; then
procwait "$pid"
else
## pwait(1) emulation
cd "/proc/$pid" 2>/dev/null || exit 0
if type inotifywait >/dev/null 2>&1; then
inotifywait='set'
else
inotifywait=
fi
while :; do
if [ -n "$inotifywait" ]; then
inotifywait --quiet --event close_nowrite exe >/dev/null || sleep 1
else
sleep 1
fi
if ! cd . 2>/dev/null; then
break
fi
done
fi
exit 0