Version:
~ [ 0.6-2.3.46 ] ~
Architecture:
~ [ um ] ~
** Warning: Cannot open xref database.
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <signal.h>
4 #include <sched.h>
5 #include <errno.h>
6 #include <string.h>
7 #include <sys/time.h>
8 #include <sys/ptrace.h>
9 #include <asm/ptrace.h>
10 #include "user_util.h"
11 #include "kern_util.h"
12 #include "user.h"
13
14 void stop_pid(int pid)
15 {
16 kill(pid, SIGSTOP);
17 }
18
19 void kill_pid(int pid)
20 {
21 kill(pid, SIGKILL);
22 }
23
24 void trap_pid(int pid)
25 {
26 kill(pid, SIGTRAP);
27 }
28
29 void usr1_pid(int pid)
30 {
31 kill(pid, SIGUSR1);
32 }
33
34 void cont_pid(int pid)
35 {
36 kill(pid, SIGCONT);
37 }
38
39 void exit_thread(void)
40 {
41 }
42
43 void signal_handler(void *task, unsigned long h, int sig)
44 {
45 __sighandler_t handler, segv_handler;
46
47 handler = (__sighandler_t) h;
48 segv_handler = set_signal_handler(SIGSEGV, user_segv_handler);
49 set_user_thread(task, 1);
50 (*handler)(sig);
51 set_user_thread(task, 0);
52 set_signal_handler(SIGSEGV, segv_handler);
53 }
54
55 void set_sigstack(void *sig_stack, int sig, void (*handler)(int),
56 int alt_stack, int nodefer, int mask_sig)
57 {
58 struct sigaction action;
59 stack_t stack;
60
61 action.sa_handler = handler;
62 sigemptyset(&action.sa_mask);
63 if(mask_sig != -1) sigaddset(&action.sa_mask, mask_sig);
64 if(nodefer) action.sa_flags = SA_NODEFER;
65 else action.sa_flags = 0;
66 action.sa_restorer = NULL;
67 if(alt_stack){
68 stack.ss_sp = (__ptr_t) sig_stack;
69 stack.ss_flags = 0;
70 stack.ss_size = 2 * page_size() - sizeof(void *);
71 if(sigaltstack(&stack, NULL) != 0)
72 panic("sigaltstack failed");
73 action.sa_flags |= SA_ONSTACK;
74 }
75 if(sigaction(sig, &action, NULL) < 0)
76 panic("sigaction failed");
77 }
78
79 void fork_handler(int sig)
80 {
81 finish_fork();
82 }
83
84 static void io_handler(int sig)
85 {
86 printf("thread got SIGIO\n");
87 stop();
88 }
89
90 int trampoline(void *sig_stack)
91 {
92 set_sigstack(sig_stack, SIGSEGV, user_segv_handler, 1, 0, SIGVTALRM);
93 set_sigstack(sig_stack, SIGUSR1, fork_handler, 1, 0, SIGVTALRM);
94 set_sigstack(NULL, SIGUSR2, syscall_handler, 0, 1, -1);
95 set_sigstack(sig_stack, SIGVTALRM, timer_handler, 1, 0, -1);
96 set_timers();
97 if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0)
98 panic("ptrace PTRACE_TRACEME failed");
99 set_cmdline(current_cmd());
100 kill(getpid(), SIGSTOP);
101 kill(getpid(), SIGSTOP);
102 return(0);
103 }
104
105 int start_fork_tramp(unsigned long *saved_regs, unsigned long sig_stack,
106 unsigned long temp_stack)
107 {
108 unsigned long sp;
109 int new_pid;
110
111 /* The trampoline will run on the temporary stack */
112 sp = stack_sp(temp_stack);
113
114 /* Start the process and wait for it to stop itself */
115 new_pid = clone(trampoline, (void *) sp, CLONE_FILES | SIGCHLD,
116 (void *) sig_stack);
117 wait_for_stop(new_pid, SIGSTOP);
118
119 /* Set the child return value to 0 */
120 saved_regs[EAX] = 0;
121
122 return(new_pid);
123 }
124
125 void trace_myself(void)
126 {
127 if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0)
128 panic("ptrace failed in trace_myself");
129 }
130
131 struct reg_fd reg_fd[32];
132 static int next_reg = 0;
133 static fd_set input_fds;
134 static int max_fd;
135 static int shutting_down = 0;
136 static int do_reboot = 0;
137
138 extern void *input_task;
139
140 static void handler(int sig)
141 {
142 void (*proc)(int);
143 int op, new_fd, response_pid;
144
145 op = get_input_request(input_task, &new_fd, &proc, &response_pid);
146 switch(op){
147 case INPUT_REBOOT:
148 shutting_down = 1;
149 do_reboot = 1;
150 break;
151 case INPUT_HALT:
152 shutting_down = 1;
153 do_reboot = 0;
154 break;
155 case INPUT_NEW_FD:
156 if(next_reg == sizeof(reg_fd)/sizeof(reg_fd[0])){
157 printk("fd registration overflow\n");
158 return;
159 }
160 reg_fd[next_reg].fd = new_fd;
161 reg_fd[next_reg++].proc = proc;
162 FD_SET(new_fd, &input_fds);
163 if(new_fd >= max_fd) max_fd = new_fd + 1;
164 break;
165 default:
166 printk("Bogus input loop request : %d\n", op);
167 break;
168 }
169 if(response_pid != -1) kill(response_pid, SIGUSR1);
170 }
171
172 int input_loop(void)
173 {
174 fd_set fds;
175 int i, j, n;
176
177 signal(SIGUSR1, handler);
178 signal(SIGIO, io_handler);
179 while(1){
180 do {
181 fds = input_fds;
182 n = select(max_fd + 1, &fds, NULL, NULL, NULL);
183 } while((n < 0) && (errno == EINTR) && (shutting_down == 0));
184 if(n < 0){
185 if(shutting_down) return(do_reboot);
186 else continue;
187 }
188 for(i=0;i<max_fd;i++){
189 if(FD_ISSET(i, &fds)){
190 for(j=0;j<next_reg;j++){
191 if(reg_fd[j].fd == i){
192 input_notify(j);
193 break;
194 }
195 }
196 }
197 }
198 }
199 }
200
201 void usr1_and_wait(int pid)
202 {
203 sigset_t new_mask, old_mask;
204
205 sigemptyset(&new_mask);
206 sigaddset(&new_mask, SIGUSR1);
207 sigprocmask(SIG_BLOCK, &new_mask, &old_mask);
208 usr1_pid(pid);
209 sigsuspend(&old_mask);
210 sigprocmask(SIG_SETMASK, &old_mask, NULL);
211 }
212
213 void (*set_signal_handler(int sig, void (*new_handler)(int)))(int)
214 {
215 struct sigaction action;
216 void (*old_handler)(int);
217
218 sigaction(sig, NULL, &action);
219 old_handler = action.sa_handler;
220 action.sa_handler = new_handler;
221 sigaction(sig, &action, NULL);
222 return(old_handler);
223 }
224
225 void continue_fork(int pid, unsigned long *regs)
226 {
227 if(ptrace(PTRACE_CONT, pid, 0, SIGUSR1) < 0)
228 panic("Couldn't continue forked process");
229 wait_for_stop(pid, SIGSTOP);
230 if(ptrace(PTRACE_SETREGS, pid, 0, regs) < 0)
231 panic("Couldn't save registers");
232 }
233
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.