Changeset d3ce33fa in mainline
- Timestamp:
- 2011-07-05T19:01:18Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- d9eaa43
- Parents:
- 4f86fa3
- Location:
- uspace/lib/posix
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/posix/signal.c
r4f86fa3 rd3ce33fa 37 37 #include "signal.h" 38 38 #include "internal/common.h" 39 #include "limits.h" 40 #include "stdlib.h" 41 #include "string.h" 42 #include "errno.h" 43 44 #include "libc/fibril_synch.h" 45 #include "libc/task.h" 46 47 /* Used to serialize signal handling. */ 48 static FIBRIL_MUTEX_INITIALIZE(_signal_mutex); 49 50 static posix_sigset_t _signal_mask = 0; 51 52 #define DEFAULT_HANDLER { .sa_handler = SIG_DFL, \ 53 .sa_mask = 0, .sa_flags = 0, .sa_sigaction = NULL } 54 55 static struct posix_sigaction _signal_actions[_TOP_SIGNAL + 1] = { 56 DEFAULT_HANDLER, DEFAULT_HANDLER, DEFAULT_HANDLER, DEFAULT_HANDLER, 57 DEFAULT_HANDLER, DEFAULT_HANDLER, DEFAULT_HANDLER, DEFAULT_HANDLER, 58 DEFAULT_HANDLER, DEFAULT_HANDLER, DEFAULT_HANDLER, DEFAULT_HANDLER, 59 DEFAULT_HANDLER, DEFAULT_HANDLER, DEFAULT_HANDLER, DEFAULT_HANDLER, 60 DEFAULT_HANDLER, DEFAULT_HANDLER, DEFAULT_HANDLER, DEFAULT_HANDLER, 61 DEFAULT_HANDLER, DEFAULT_HANDLER, DEFAULT_HANDLER, DEFAULT_HANDLER, 62 DEFAULT_HANDLER, DEFAULT_HANDLER, DEFAULT_HANDLER, DEFAULT_HANDLER 63 }; 64 65 void __posix_default_signal_handler(int signo) 66 { 67 switch (signo) { 68 case SIGABRT: 69 abort(); 70 case SIGQUIT: 71 fprintf(stderr, "Quit signal raised. Exiting."); 72 exit(EXIT_FAILURE); 73 case SIGINT: 74 fprintf(stderr, "Interrupt signal caught. Exiting."); 75 exit(EXIT_FAILURE); 76 case SIGTERM: 77 fprintf(stderr, "Termination signal caught. Exiting."); 78 exit(EXIT_FAILURE); 79 case SIGSTOP: 80 fprintf(stderr, "Stop signal caught, but unsupported. Ignoring."); 81 break; 82 case SIGKILL: 83 /* This will only occur when raise or similar is called. */ 84 /* Commit suicide. */ 85 task_kill(task_get_id()); 86 87 /* Should not be reached. */ 88 abort(); 89 case SIGFPE: 90 case SIGBUS: 91 case SIGILL: 92 case SIGSEGV: 93 posix_psignal(signo, "Hardware exception raised by user code"); 94 abort(); 95 case SIGSYS: 96 case SIGXCPU: 97 case SIGXFSZ: 98 case SIGTRAP: 99 case SIGHUP: 100 case SIGPIPE: 101 case SIGPOLL: 102 case SIGURG: 103 case SIGTSTP: 104 case SIGTTIN: 105 case SIGTTOU: 106 posix_psignal(signo, "Unsupported signal caught"); 107 abort(); 108 case SIGCHLD: 109 case SIGUSR1: 110 case SIGUSR2: 111 case SIGALRM: 112 case SIGVTALRM: 113 case SIGPROF: 114 case SIGCONT: 115 /* ignored */ 116 break; 117 } 118 } 119 120 void __posix_hold_signal_handler(int signo) 121 { 122 /* Nothing */ 123 } 124 125 void __posix_ignore_signal_handler(int signo) 126 { 127 /* Nothing */ 128 } 129 130 131 int posix_sigemptyset(posix_sigset_t *set) 132 { 133 assert(set != NULL); 134 135 *set = 0; 136 return 0; 137 } 138 139 int posix_sigfillset(posix_sigset_t *set) 140 { 141 assert(set != NULL); 142 143 *set = UINT32_MAX; 144 return 0; 145 } 146 147 int posix_sigaddset(posix_sigset_t *set, int signo) 148 { 149 assert(set != NULL); 150 151 *set |= (1 << signo); 152 return 0; 153 } 154 155 int posix_sigdelset(posix_sigset_t *set, int signo) 156 { 157 assert(set != NULL); 158 159 *set &= ~(1 << signo); 160 return 0; 161 } 162 163 int posix_sigismember(const posix_sigset_t *set, int signo) 164 { 165 assert(set != NULL); 166 167 return (*set & (1 << signo)) != 0; 168 } 169 170 static void _sigaction_unsafe(int sig, const struct posix_sigaction *restrict act, 171 struct posix_sigaction *restrict oact) 172 { 173 if (oact != NULL) { 174 memcpy(oact, &_signal_actions[sig], 175 sizeof(struct posix_sigaction)); 176 } 177 178 if (act != NULL) { 179 memcpy(&_signal_actions[sig], act, 180 sizeof(struct posix_sigaction)); 181 } 182 } 183 184 int posix_sigaction(int sig, const struct posix_sigaction *restrict act, 185 struct posix_sigaction *restrict oact) 186 { 187 if (sig > _TOP_SIGNAL || (act != NULL && 188 (sig == SIGKILL || sig == SIGSTOP))) { 189 errno = EINVAL; 190 return -1; 191 } 192 193 if (sig > _TOP_CATCHABLE_SIGNAL) { 194 posix_psignal(sig, 195 "WARNING: registering handler for a partially" 196 " or fully unsupported signal. This handler may only be" 197 " invoked by the raise() function, which may not be what" 198 " the application developer intended.\nSignal name"); 199 } 200 201 fibril_mutex_lock(&_signal_mutex); 202 _sigaction_unsafe(sig, act, oact); 203 fibril_mutex_unlock(&_signal_mutex); 204 205 return 0; 206 } 39 207 40 208 void (*posix_signal(int sig, void (*func)(int)))(int) 41 209 { 42 // TODO 43 not_implemented(); 210 struct posix_sigaction new = { 211 .sa_handler = func, 212 .sa_mask = 0, 213 .sa_flags = 0, 214 .sa_sigaction = NULL 215 }; 216 struct posix_sigaction old; 217 if (posix_sigaction(sig, func == NULL ? NULL : &new, &old) == 0) { 218 return old.sa_handler; 219 } else { 220 return SIG_ERR; 221 } 222 } 223 224 static int _raise_sigaction(int signo, posix_siginfo_t *siginfo) 225 { 226 assert(signo >= 0 && signo <= _TOP_SIGNAL); 227 assert(siginfo != NULL); 228 229 fibril_mutex_lock(&_signal_mutex); 230 231 struct posix_sigaction action = _signal_actions[signo]; 232 233 if (posix_sigismember(&_signal_mask, signo) || 234 action.sa_handler == SIG_HOLD) { 235 // TODO: queue signal 236 fibril_mutex_unlock(&_signal_mutex); 237 return -1; 238 } 239 240 /* Modifying signal mask is unnecessary, 241 * signal handling is serialized. 242 */ 243 244 if ((action.sa_flags & SA_RESETHAND) && signo != SIGILL && signo != SIGTRAP) { 245 _signal_actions[signo] = (struct posix_sigaction) DEFAULT_HANDLER; 246 }; 247 248 if (action.sa_flags & SA_SIGINFO) { 249 assert(action.sa_sigaction != NULL); 250 action.sa_sigaction(signo, siginfo, NULL); 251 } else { 252 assert(action.sa_handler != NULL); 253 action.sa_handler(signo); 254 } 255 256 fibril_mutex_unlock(&_signal_mutex); 257 258 return 0; 44 259 } 45 260 46 261 int posix_raise(int sig) 47 262 { 48 // TODO 49 not_implemented(); 50 } 51 52 int posix_kill(posix_pid_t pid, int sig) 53 { 54 // TODO 55 not_implemented(); 56 } 57 58 int posix_sigaddset(posix_sigset_t *set, int signo) 59 { 60 // TODO 61 not_implemented(); 62 } 63 64 int posix_sigemptyset(posix_sigset_t *set) 65 { 66 // TODO 67 not_implemented(); 263 if (sig >= 0 && sig <= _TOP_SIGNAL) { 264 posix_siginfo_t siginfo = { 265 .si_signo = sig, 266 .si_code = SI_USER 267 }; 268 return _raise_sigaction(sig, &siginfo); 269 } else { 270 errno = EINVAL; 271 return -1; 272 } 273 } 274 275 int posix_kill(posix_pid_t pid, int signo) 276 { 277 if (pid < 1) { 278 // TODO 279 errno = ENOTSUP; 280 return -1; 281 } 282 283 if (pid == task_get_id()) { 284 return posix_raise(signo); 285 } 286 287 if (pid > _TOP_SIGNAL) { 288 errno = EINVAL; 289 return -1; 290 } 291 292 switch (signo) { 293 case SIGKILL: 294 task_kill(pid); 295 break; 296 default: 297 /* Nothing else supported yet. */ 298 errno = ENOTSUP; 299 return -1; 300 } 301 302 return 0; 303 } 304 305 int posix_killpg(posix_pid_t pid, int sig) 306 { 307 assert(pid > 1); 308 return posix_kill(-pid, sig); 309 } 310 311 void posix_psiginfo(const posix_siginfo_t *pinfo, const char *message) 312 { 313 assert(pinfo != NULL); 314 posix_psignal(pinfo->si_signo, message); 315 // TODO: print si_code 316 } 317 318 void posix_psignal(int signum, const char *message) 319 { 320 char *sigmsg = posix_strsignal(signum); 321 if (message == NULL || *message == '\0') { 322 fprintf(stderr, "%s\n", sigmsg); 323 } else { 324 fprintf(stderr, "%s: %s\n", message, sigmsg); 325 } 326 } 327 328 int posix_thread_sigmask(int how, const posix_sigset_t *restrict set, 329 posix_sigset_t *restrict oset) 330 { 331 fibril_mutex_lock(&_signal_mutex); 332 333 if (oset != NULL) { 334 *oset = _signal_mask; 335 } 336 if (set != NULL) { 337 switch (how) { 338 case SIG_BLOCK: 339 _signal_mask |= *set; 340 break; 341 case SIG_UNBLOCK: 342 _signal_mask &= ~*set; 343 break; 344 case SIG_SETMASK: 345 _signal_mask = *set; 346 break; 347 default: 348 fibril_mutex_unlock(&_signal_mutex); 349 return EINVAL; 350 } 351 } 352 353 // TODO: queued signal handling 354 355 fibril_mutex_unlock(&_signal_mutex); 356 357 return 0; 68 358 } 69 359 … … 71 361 posix_sigset_t *restrict oset) 72 362 { 73 // TODO 74 not_implemented(); 363 int result = posix_thread_sigmask(how, set, oset); 364 if (result != 0) { 365 errno = result; 366 return -1; 367 } 368 return 0; 75 369 } 76 370 -
uspace/lib/posix/signal.h
r4f86fa3 rd3ce33fa 39 39 #include "sys/types.h" 40 40 41 /* HelenOS doesn't have signals, so calls to functions of this header 42 * are just replaced with their respective failure return value. 43 * 44 * Other macros and constants are here just to satisfy the symbol resolver 45 * and have no practical value whatsoever, until HelenOS implements some 46 * equivalent of signals. Maybe something neat based on IPC will be devised 47 * in the future? 48 */ 41 extern void __posix_default_signal_handler(int signo); 42 extern void __posix_hold_signal_handler(int signo); 43 extern void __posix_ignore_signal_handler(int signo); 49 44 50 45 #undef SIG_DFL 51 #define SIG_DFL ((void (*)(int)) 0)46 #define SIG_DFL ((void (*)(int)) __posix_default_signal_handler) 52 47 #undef SIG_ERR 53 #define SIG_ERR ((void (*)(int)) 0)48 #define SIG_ERR ((void (*)(int)) NULL) 54 49 #undef SIG_HOLD 55 #define SIG_HOLD ((void (*)(int)) 0)50 #define SIG_HOLD ((void (*)(int)) __posix_hold_signal_handler) 56 51 #undef SIG_IGN 57 #define SIG_IGN ((void (*)(int)) 0)52 #define SIG_IGN ((void (*)(int)) __posix_ignore_signal_handler) 58 53 59 54 typedef int posix_sig_atomic_t; 60 typedef int posix_sigset_t;55 typedef uint32_t posix_sigset_t; 61 56 typedef struct posix_mcontext { 62 57 // FIXME: should not be empty to avoid compiler warnings (-pedantic) … … 116 111 /* Values of posix_sigevent::sigev_notify */ 117 112 #undef SIGEV_NONE 113 #undef SIGEV_SIGNAL 114 #undef SIGEV_THREAD 118 115 #define SIGEV_NONE 0 119 #undef SIGEV_SIGNAL120 116 #define SIGEV_SIGNAL 0 121 #undef SIGEV_THREAD122 117 #define SIGEV_THREAD 0 123 118 124 119 #undef SIGRT_MIN 120 #undef SIGRT_MAX 125 121 #define SIGRT_MIN 0 126 #undef SIGRT_MAX127 122 #define SIGRT_MAX 0 128 123 129 124 #undef SIG_BLOCK 125 #undef SIG_UNBLOCK 126 #undef SIG_SETMASK 130 127 #define SIG_BLOCK 0 131 #undef SIG_UNBLOCK 132 #define SIG_UNBLOCK 0 133 #undef SIG_SETMASK 134 #define SIG_SETMASK 0 128 #define SIG_UNBLOCK 1 129 #define SIG_SETMASK 2 135 130 136 131 #undef SA_NOCLDSTOP 137 #define SA_NOCLDSTOP 0138 132 #undef SA_ONSTACK 139 #define SA_ONSTACK 0140 133 #undef SA_RESETHAND 141 #define SA_RESETHAND 0142 134 #undef SA_RESTART 143 #define SA_RESTART 0144 135 #undef SA_SIGINFO 145 #define SA_SIGINFO 0146 136 #undef SA_NOCLDWAIT 147 #define SA_NOCLDWAIT 0148 137 #undef SA_NODEFER 149 #define SA_NODEFER 0 138 #define SA_NOCLDSTOP (1 << 0) 139 #define SA_ONSTACK (1 << 1) 140 #define SA_RESETHAND (1 << 2) 141 #define SA_RESTART (1 << 3) 142 #define SA_SIGINFO (1 << 4) 143 #define SA_NOCLDWAIT (1 << 5) 144 #define SA_NODEFER (1 << 6) 150 145 151 146 #undef SS_ONSTACK 147 #undef SS_DISABLE 152 148 #define SS_ONSTACK 0 153 #undef SS_DISABLE154 149 #define SS_DISABLE 0 155 150 156 151 #undef MINSIGSTKSZ 152 #undef SIGSTKSZ 157 153 #define MINSIGSTKSZ 0 158 #undef SIGSTKSZ159 154 #define SIGSTKSZ 0 160 155 161 156 /* full POSIX set */ 162 157 enum { 158 /* Termination Signals */ 163 159 SIGABRT, 160 SIGQUIT, 161 SIGINT, 162 SIGTERM, 163 164 /* Child Signal */ 165 SIGCHLD, 166 167 /* User signals */ 168 SIGUSR1, 169 SIGUSR2, 170 171 /* Timer */ 164 172 SIGALRM, 173 SIGVTALRM, 174 SIGPROF, /* obsolete */ 175 176 _TOP_CATCHABLE_SIGNAL = SIGPROF, 177 178 /* Process Scheduler Interaction - not supported */ 179 SIGSTOP, 180 SIGCONT, 181 182 /* Process Termination - can't be caught */ 183 SIGKILL, 184 185 _TOP_SENDABLE_SIGNAL = SIGKILL, 186 187 /* Hardware Exceptions - can't be caught or sent */ 188 SIGFPE, 165 189 SIGBUS, 166 SIGCHLD, 167 SIGCONT, 168 SIGFPE, 190 SIGILL, 191 SIGSEGV, 192 193 /* Other Exceptions - not supported */ 194 SIGSYS, 195 SIGXCPU, 196 SIGXFSZ, 197 198 /* Debugging - not supported */ 199 SIGTRAP, 200 201 /* Communication Signals - not supported */ 169 202 SIGHUP, 170 SIGILL,171 SIGINT,172 SIGKILL,173 203 SIGPIPE, 174 SIG QUIT,175 SIG SEGV,176 SIGSTOP, 177 SIGTERM,204 SIGPOLL, /* obsolete */ 205 SIGURG, 206 207 /* Terminal Signals - not supported */ 178 208 SIGTSTP, 179 209 SIGTTIN, 180 210 SIGTTOU, 181 SIGUSR1, 182 SIGUSR2, 183 SIGPOLL, 184 SIGPROF, 185 SIGSYS, 186 SIGTRAP, 187 SIGURG, 188 SIGVTALRM, 189 SIGXCPU, 190 SIGXFSZ 191 }; 211 212 _TOP_SIGNAL = SIGTTOU 213 }; 214 215 /* Values for sigaction field si_code. */ 216 217 enum { 218 SI_USER, 219 SI_QUEUE, 220 SI_TIMER, 221 SI_ASYNCIO, 222 SI_MESGQ, 223 ILL_ILLOPC, 224 ILL_ILLOPN, 225 ILL_ILLADR, 226 ILL_ILLTRP, 227 ILL_PRVOPC, 228 ILL_PRVREG, 229 ILL_COPROC, 230 ILL_BADSTK, 231 FPE_INTDIV, 232 FPE_INTOVF, 233 FPE_FLTDIV, 234 FPE_FLTOVF, 235 FPE_FLTUND, 236 FPE_FLTRES, 237 FPE_FLTINV, 238 FPE_FLTSUB, 239 SEGV_MAPERR, 240 SEGV_ACCERR, 241 BUS_ADRALN, 242 BUS_ADRERR, 243 BUS_OBJERR, 244 TRAP_BRKPT, 245 TRAP_TRACE, 246 CLD_EXITED, 247 CLD_KILLED, 248 CLD_DUMPED, 249 CLD_TRAPPED, 250 CLD_STOPPED, 251 CLD_CONTINUED, 252 POLL_IN, 253 POLL_OUT, 254 POLL_MSG, 255 POLL_ERR, 256 POLL_PRI, 257 POLL_HUP 258 }; 259 260 extern int posix_sigaction(int sig, const struct posix_sigaction *restrict act, 261 struct posix_sigaction *restrict oact); 192 262 193 263 extern void (*posix_signal(int sig, void (*func)(int)))(int); 194 264 extern int posix_raise(int sig); 195 265 extern int posix_kill(posix_pid_t pid, int sig); 196 266 extern int posix_killpg(posix_pid_t pid, int sig); 267 268 extern void posix_psiginfo(const posix_siginfo_t *pinfo, const char *message); 269 extern void posix_psignal(int signum, const char *message); 270 271 extern int posix_sigemptyset(posix_sigset_t *set); 272 extern int posix_sigfillset(posix_sigset_t *set); 197 273 extern int posix_sigaddset(posix_sigset_t *set, int signo); 198 extern int posix_sigemptyset(posix_sigset_t *set); 274 extern int posix_sigdelset(posix_sigset_t *set, int signo); 275 extern int posix_sigismember(const posix_sigset_t *set, int signo); 276 277 extern int posix_thread_sigmask(int how, const posix_sigset_t *restrict set, 278 posix_sigset_t *restrict oset); 199 279 extern int posix_sigprocmask(int how, const posix_sigset_t *restrict set, 200 280 posix_sigset_t *restrict oset); … … 214 294 #define raise posix_raise 215 295 #define kill posix_kill 296 #define killpg posix_killpg 297 298 #define psiginfo posix_psiginfo 299 #define psignal posix_psignal 300 301 #define sigemptyset posix_sigemptyset 302 #define sigfillset posix_sigfillset 216 303 #define sigaddset posix_sigaddset 217 #define sigemptyset posix_sigemptyset 304 #define sigdelset posix_sigdelset 305 #define sigismember posix_sigismember 306 307 #define pthread_sigmask posix_thread_sigmask 218 308 #define sigprocmask posix_sigprocmask 219 309 #endif -
uspace/lib/posix/string.c
r4f86fa3 rd3ce33fa 43 43 #include "limits.h" 44 44 #include "stdlib.h" 45 #include "signal.h" 45 46 46 47 #include "libc/str_error.h" … … 570 571 } 571 572 573 /** 574 * 575 * @param signum 576 * @return 577 */ 578 char *posix_strsignal(int signum) 579 { 580 static const char *const sigstrings[] = { 581 [SIGABRT] = "SIGABRT (Process abort signal)", 582 [SIGALRM] = "SIGALRM (Alarm clock)", 583 [SIGBUS] = "SIGBUS (Access to an undefined portion of a memory object)", 584 [SIGCHLD] = "SIGCHLD (Child process terminated, stopped, or continued)", 585 [SIGCONT] = "SIGCONT (Continue executing, if stopped)", 586 [SIGFPE] = "SIGFPE (Erroneous arithmetic operation)", 587 [SIGHUP] = "SIGHUP (Hangup)", 588 [SIGILL] = "SIGILL (Illegal instruction)", 589 [SIGINT] = "SIGINT (Terminal interrupt signal)", 590 [SIGKILL] = "SIGKILL (Kill process)", 591 [SIGPIPE] = "SIGPIPE (Write on a pipe with no one to read it)", 592 [SIGQUIT] = "SIGQUIT (Terminal quit signal)", 593 [SIGSEGV] = "SIGSEGV (Invalid memory reference)", 594 [SIGSTOP] = "SIGSTOP (Stop executing)", 595 [SIGTERM] = "SIGTERM (Termination signal)", 596 [SIGTSTP] = "SIGTSTP (Terminal stop signal)", 597 [SIGTTIN] = "SIGTTIN (Background process attempting read)", 598 [SIGTTOU] = "SIGTTOU (Background process attempting write)", 599 [SIGUSR1] = "SIGUSR1 (User-defined signal 1)", 600 [SIGUSR2] = "SIGUSR2 (User-defined signal 2)", 601 [SIGPOLL] = "SIGPOLL (Pollable event)", 602 [SIGPROF] = "SIGPROF (Profiling timer expired)", 603 [SIGSYS] = "SIGSYS (Bad system call)", 604 [SIGTRAP] = "SIGTRAP (Trace/breakpoint trap)", 605 [SIGURG] = "SIGURG (High bandwidth data is available at a socket)", 606 [SIGVTALRM] = "SIGVTALRM (Virtual timer expired)", 607 [SIGXCPU] = "SIGXCPU (CPU time limit exceeded)", 608 [SIGXFSZ] = "SIGXFSZ (File size limit exceeded)" 609 }; 610 611 if (signum <= _TOP_SIGNAL) { 612 return (char *) sigstrings[signum]; 613 } 614 615 return (char *) "ERROR, Invalid signal number"; 616 } 617 572 618 /** @} 573 619 */ -
uspace/lib/posix/string.h
r4f86fa3 rd3ce33fa 103 103 extern size_t posix_strnlen(const char *s, size_t n); 104 104 105 /* Signal messages */ 106 extern char *posix_strsignal(int signum); 107 105 108 /* Legacy declarations */ 106 109 #ifndef POSIX_STRINGS_H_ … … 143 146 #define strnlen posix_strnlen 144 147 148 #define strsignal posix_strsignal 149 145 150 #define ffs posix_ffs 146 151 #define strcasecmp posix_strcasecmp
Note:
See TracChangeset
for help on using the changeset viewer.