~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/arch/um/kernel/process.c

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.