summaryrefslogtreecommitdiff
path: root/syscall.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2012-03-18 22:10:48 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2012-03-18 22:10:48 +0100
commit146b944d4a968c2922f4220d33219ed3534f50d0 (patch)
tree971355dd08821a9c3d70a22a90513e2c051b89cf /syscall.c
parentf50e7141d5b5aedafa220d851a8b6afe753d679a (diff)
downloadstrace-146b944d4a968c2922f4220d33219ed3534f50d0.tar.gz
strace-146b944d4a968c2922f4220d33219ed3534f50d0.tar.bz2
strace-146b944d4a968c2922f4220d33219ed3534f50d0.tar.xz
Make internal_fork and internal_exec static
text data bss dec hex filename 237917 672 18980 257569 3ee21 strace 237845 672 18980 257497 3edd9 strace_new * defs.h: Remove declarations of internal_fork and internal_exec. * process.c: Remove definitions of internal_fork and internal_exec. * syscall.c: Move them here. (internal_syscall): Return void instead of int. We were always returning zero, and callers weren't checking it anyway. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'syscall.c')
-rw-r--r--syscall.c69
1 files changed, 61 insertions, 8 deletions
diff --git a/syscall.c b/syscall.c
index 272e3a0..3f157b2 100644
--- a/syscall.c
+++ b/syscall.c
@@ -1169,7 +1169,58 @@ syscall_fixup_on_sysenter(struct tcb *tcp)
return 1;
}
-static int
+static void
+internal_fork(struct tcb *tcp)
+{
+#if defined S390 || defined S390X || defined CRISV10 || defined CRISV32
+# define ARG_FLAGS 1
+#else
+# define ARG_FLAGS 0
+#endif
+#ifndef CLONE_UNTRACED
+# define CLONE_UNTRACED 0x00800000
+#endif
+ if ((ptrace_setoptions
+ & (PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK))
+ == (PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK))
+ return;
+
+ if (!followfork)
+ return;
+
+ if (entering(tcp)) {
+ /*
+ * We won't see the new child if clone is called with
+ * CLONE_UNTRACED, so we keep the same logic with that option
+ * and don't trace it.
+ */
+ if ((sysent[tcp->scno].sys_func == sys_clone) &&
+ (tcp->u_arg[ARG_FLAGS] & CLONE_UNTRACED))
+ return;
+ setbpt(tcp);
+ } else {
+ if (tcp->flags & TCB_BPTSET)
+ clearbpt(tcp);
+ }
+}
+
+#if defined(TCB_WAITEXECVE)
+static void
+internal_exec(struct tcb *tcp)
+{
+ /* Maybe we have post-execve SIGTRAP suppressed? */
+ if (ptrace_setoptions & PTRACE_O_TRACEEXEC)
+ return; /* yes, no need to do anything */
+
+ if (exiting(tcp) && syserror(tcp))
+ /* Error in execve, no post-execve SIGTRAP expected */
+ tcp->flags &= ~TCB_WAITEXECVE;
+ else
+ tcp->flags |= TCB_WAITEXECVE;
+}
+#endif
+
+static void
internal_syscall(struct tcb *tcp)
{
/*
@@ -1180,26 +1231,28 @@ internal_syscall(struct tcb *tcp)
int (*func)();
if (!SCNO_IN_RANGE(tcp->scno))
- return 0;
+ return;
func = sysent[tcp->scno].sys_func;
if ( sys_fork == func
|| sys_vfork == func
|| sys_clone == func
- )
- return internal_fork(tcp);
+ ) {
+ internal_fork(tcp);
+ return;
+ }
#if defined(TCB_WAITEXECVE)
if ( sys_execve == func
# if defined(SPARC) || defined(SPARC64)
|| sys_execv == func
# endif
- )
- return internal_exec(tcp);
+ ) {
+ internal_exec(tcp);
+ return;
+ }
#endif
-
- return 0;
}
static int