Page MenuHomeFreeBSD

D11035.id29175.diff
No OneTemporary

D11035.id29175.diff

Index: usr.bin/truss/extern.h
===================================================================
--- usr.bin/truss/extern.h
+++ usr.bin/truss/extern.h
@@ -34,6 +34,5 @@
extern int print_line_prefix(struct trussinfo *);
extern void setup_and_wait(struct trussinfo *, char **);
extern void start_tracing(struct trussinfo *, pid_t);
-extern void restore_proc(int);
extern void eventloop(struct trussinfo *);
extern const char *ioctlname(unsigned long val);
Index: usr.bin/truss/main.c
===================================================================
--- usr.bin/truss/main.c
+++ usr.bin/truss/main.c
@@ -65,7 +65,6 @@
int
main(int ac, char **av)
{
- struct sigaction sa;
struct trussinfo *trussinfo;
char *fname;
char **command;
@@ -143,26 +142,11 @@
err(1, "cannot open %s", fname);
}
- /*
- * If truss starts the process itself, it will ignore some signals --
- * they should be passed off to the process, which may or may not
- * exit. If, however, we are examining an already-running process,
- * then we restore the event mask on these same signals.
- */
if (pid == 0) {
/* Start a command ourselves */
command = av;
setup_and_wait(trussinfo, command);
- signal(SIGINT, SIG_IGN);
- signal(SIGTERM, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
} else {
- sa.sa_handler = restore_proc;
- sa.sa_flags = 0;
- sigemptyset(&sa.sa_mask);
- sigaction(SIGINT, &sa, NULL);
- sigaction(SIGQUIT, &sa, NULL);
- sigaction(SIGTERM, &sa, NULL);
start_tracing(trussinfo, pid);
}
Index: usr.bin/truss/setup.c
===================================================================
--- usr.bin/truss/setup.c
+++ usr.bin/truss/setup.c
@@ -61,16 +61,29 @@
SET_DECLARE(procabi, struct procabi);
static sig_atomic_t detaching;
+static pid_t new_child;
static void enter_syscall(struct trussinfo *, struct threadinfo *,
struct ptrace_lwpinfo *);
static void new_proc(struct trussinfo *, pid_t, lwpid_t);
+static void restore_proc(int);
+static void
+forward_signal(int signo)
+{
+
+ kill(new_child, signo);
+}
+
/*
- * setup_and_wait() is called to start a process. All it really does
- * is fork(), enable tracing in the child, and then exec the given
+ * setup_and_wait() is called to start a process. First, it fork()s a new
+ * child, enables tracing in the child, and then execs the given
* command. At that point, the child process stops, and the parent
* can wake up and deal with it.
+ *
+ * A signal handler is installed for SIGINT, SIGTERM, and SIGQUIT
+ * which forwards signals received by truss to the new child process
+ * so that truss is transparent from the shell's perspective.
*/
void
setup_and_wait(struct trussinfo *info, char *command[])
@@ -81,6 +94,7 @@
if (pid == -1)
err(1, "fork failed");
if (pid == 0) { /* Child */
+ setpgid(0, 0);
ptrace(PT_TRACE_ME, 0, 0, 0);
execvp(command[0], command);
err(1, "execvp %s", command[0]);
@@ -90,6 +104,10 @@
if (waitpid(pid, NULL, 0) < 0)
err(1, "unexpect stop in waitpid");
+ new_child = pid;
+ signal(SIGINT, forward_signal);
+ signal(SIGTERM, forward_signal);
+ signal(SIGQUIT, forward_signal);
new_proc(info, pid, 0);
}
@@ -99,8 +117,15 @@
void
start_tracing(struct trussinfo *info, pid_t pid)
{
+ struct sigaction sa;
int ret, retry;
+ sa.sa_handler = restore_proc;
+ sa.sa_flags = 0;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGINT, &sa, NULL);
+ sigaction(SIGQUIT, &sa, NULL);
+ sigaction(SIGTERM, &sa, NULL);
retry = 10;
do {
ret = ptrace(PT_ATTACH, pid, NULL, 0);
@@ -121,7 +146,7 @@
* applies if truss was told to monitor an already-existing
* process.
*/
-void
+static void
restore_proc(int signo __unused)
{

File Metadata

Mime Type
text/plain
Expires
Wed, Feb 4, 2:58 PM (15 h, 5 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28435628
Default Alt Text
D11035.id29175.diff (3 KB)

Event Timeline