Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
syscall.c
Go to the documentation of this file.
1 #include <linux/ptrace.h>
2 #include <linux/sched.h>
3 #include <linux/export.h>
4 #include <asm/syscall.h>
5 
6 static int collect_syscall(struct task_struct *target, long *callno,
7  unsigned long args[6], unsigned int maxargs,
8  unsigned long *sp, unsigned long *pc)
9 {
10  struct pt_regs *regs = task_pt_regs(target);
11  if (unlikely(!regs))
12  return -EAGAIN;
13 
14  *sp = user_stack_pointer(regs);
15  *pc = instruction_pointer(regs);
16 
17  *callno = syscall_get_nr(target, regs);
18  if (*callno != -1L && maxargs > 0)
19  syscall_get_arguments(target, regs, 0, maxargs, args);
20 
21  return 0;
22 }
23 
50 int task_current_syscall(struct task_struct *target, long *callno,
51  unsigned long args[6], unsigned int maxargs,
52  unsigned long *sp, unsigned long *pc)
53 {
54  long state;
55  unsigned long ncsw;
56 
57  if (unlikely(maxargs > 6))
58  return -EINVAL;
59 
60  if (target == current)
61  return collect_syscall(target, callno, args, maxargs, sp, pc);
62 
63  state = target->state;
64  if (unlikely(!state))
65  return -EAGAIN;
66 
67  ncsw = wait_task_inactive(target, state);
68  if (unlikely(!ncsw) ||
69  unlikely(collect_syscall(target, callno, args, maxargs, sp, pc)) ||
70  unlikely(wait_task_inactive(target, state) != ncsw))
71  return -EAGAIN;
72 
73  return 0;
74 }