Changes in uspace/lib/posix/signal.c [55b1efd:ffff746] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/posix/signal.c
r55b1efd rffff746 45 45 #include "libc/task.h" 46 46 47 /* This file implements a fairly dumb and incomplete "simulation" of 48 * POSIX signals. Since HelenOS doesn't support signals and mostly doesn't 49 * have any equivalent functionality, most of the signals are useless. The 50 * main purpose of this implementation is thus to help port applications using 51 * signals with minimal modification, but if the application uses signals for 52 * anything non-trivial, it's quite probable it won't work properly even if 53 * it builds without problems. 54 */ 47 // TODO: documentation 55 48 56 49 /* Used to serialize signal handling. */ 57 50 static FIBRIL_MUTEX_INITIALIZE(_signal_mutex); 58 51 59 static LIST_INITIALIZE(_signal_queue);60 61 52 static posix_sigset_t _signal_mask = 0; 62 53 … … 64 55 .sa_mask = 0, .sa_flags = 0, .sa_sigaction = NULL } 65 56 66 /* Actions associated with each signal number. */67 57 static struct posix_sigaction _signal_actions[_TOP_SIGNAL + 1] = { 68 58 DEFAULT_HANDLER, DEFAULT_HANDLER, DEFAULT_HANDLER, DEFAULT_HANDLER, … … 137 127 138 128 /** 139 * Just an empty function to get an unique pointer value for comparison.140 129 * 141 * @param signo Signal number.130 * @param signo 142 131 */ 143 132 void __posix_hold_signal_handler(int signo) … … 147 136 148 137 /** 149 * Empty function to be used as ignoring handler. 150 * 151 * @param signo Signal number. 138 * 139 * @param signo 152 140 */ 153 141 void __posix_ignore_signal_handler(int signo) … … 157 145 158 146 /** 159 * Clear the signal set. 160 * 161 * @param set Pointer to the signal set. 162 * @return Always returns zero. 147 * 148 * @param set 149 * @return 163 150 */ 164 151 int posix_sigemptyset(posix_sigset_t *set) … … 171 158 172 159 /** 173 * Fill the signal set (i.e. add all signals). 174 * 175 * @param set Pointer to the signal set. 176 * @return Always returns zero. 160 * 161 * @param set 162 * @return 177 163 */ 178 164 int posix_sigfillset(posix_sigset_t *set) … … 185 171 186 172 /** 187 * Add a signal to the set. 188 * 189 * @param set Pointer to the signal set. 190 * @param signo Signal number to add. 191 * @return Always returns zero. 173 * 174 * @param set 175 * @param signo 176 * @return 192 177 */ 193 178 int posix_sigaddset(posix_sigset_t *set, int signo) … … 200 185 201 186 /** 202 * Delete a signal from the set. 203 * 204 * @param set Pointer to the signal set. 205 * @param signo Signal number to remove. 206 * @return Always returns zero. 187 * 188 * @param set 189 * @param signo 190 * @return 207 191 */ 208 192 int posix_sigdelset(posix_sigset_t *set, int signo) … … 215 199 216 200 /** 217 * Inclusion test for a signal set. 218 * 219 * @param set Pointer to the signal set. 220 * @param signo Signal number to query. 221 * @return 1 if the signal is in the set, 0 otherwise. 201 * 202 * @param set 203 * @param signo 204 * @return 222 205 */ 223 206 int posix_sigismember(const posix_sigset_t *set, int signo) … … 229 212 230 213 /** 231 * Unsafe variant of the sigaction() function.232 * Doesn't do any checking of its arguments and233 * does not deal with thread-safety.234 214 * 235 215 * @param sig … … 252 232 253 233 /** 254 * Sets a new action for the given signal number. 255 * 256 * @param sig Signal number to set action for. 257 * @param act If not NULL, contents of this structure are 258 * used as the new action for the signal. 259 * @param oact If not NULL, the original action associated with the signal 260 * is stored in the structure pointer to. 261 * @return -1 with errno set on failure, 0 on success. 234 * 235 * @param sig 236 * @param act 237 * @param oact 238 * @return 262 239 */ 263 240 int posix_sigaction(int sig, const struct posix_sigaction *restrict act, … … 286 263 287 264 /** 288 * Sets a new handler for the given signal number. 289 * 290 * @param sig Signal number to set handler for. 291 * @param func Handler function. 292 * @return SIG_ERR on failure, original handler on success. 265 * 266 * @param sig 267 * @param func 268 * @return 293 269 */ 294 270 void (*posix_signal(int sig, void (*func)(int)))(int) … … 308 284 } 309 285 310 typedef struct { 311 link_t link; 312 int signo; 313 posix_siginfo_t siginfo; 314 } signal_queue_item; 315 316 /** 317 * Queue blocked signal. 318 * 319 * @param signo Signal number. 320 * @param siginfo Additional information about the signal. 321 */ 322 static void _queue_signal(int signo, posix_siginfo_t *siginfo) 286 /** 287 * 288 * @param signo 289 * @param siginfo 290 * @return 291 */ 292 static int _raise_sigaction(int signo, posix_siginfo_t *siginfo) 323 293 { 324 294 assert(signo >= 0 && signo <= _TOP_SIGNAL); 325 295 assert(siginfo != NULL); 326 327 signal_queue_item *item = malloc(sizeof(signal_queue_item));328 link_initialize(&(item->link));329 item->signo = signo;330 memcpy(&item->siginfo, siginfo, sizeof(posix_siginfo_t));331 list_append(&(item->link), &_signal_queue);332 }333 334 335 /**336 * Executes an action associated with the given signal.337 *338 * @param signo Signal number.339 * @param siginfo Additional information about the circumstances of this raise.340 * @return 0 if the action has been successfully executed. -1 if the signal is341 * blocked.342 */343 static int _raise_sigaction(int signo, posix_siginfo_t *siginfo)344 {345 assert(signo >= 0 && signo <= _TOP_SIGNAL);346 assert(siginfo != NULL);347 296 348 297 fibril_mutex_lock(&_signal_mutex); … … 352 301 if (posix_sigismember(&_signal_mask, signo) || 353 302 action.sa_handler == SIG_HOLD) { 354 _queue_signal(signo, siginfo);303 // TODO: queue signal 355 304 fibril_mutex_unlock(&_signal_mutex); 356 305 return -1; … … 363 312 if ((action.sa_flags & SA_RESETHAND) && signo != SIGILL && signo != SIGTRAP) { 364 313 _signal_actions[signo] = (struct posix_sigaction) DEFAULT_HANDLER; 365 } 314 }; 366 315 367 316 if (action.sa_flags & SA_SIGINFO) { … … 379 328 380 329 /** 381 * Raise all unblocked previously queued signals. 382 */ 383 static void _dequeue_unblocked_signals() 384 { 385 link_t *iterator = _signal_queue.head.next; 386 link_t *next; 387 388 while (iterator != &(_signal_queue).head) { 389 next = iterator->next; 390 391 signal_queue_item *item = 392 list_get_instance(iterator, signal_queue_item, link); 393 394 if (!posix_sigismember(&_signal_mask, item->signo) && 395 _signal_actions[item->signo].sa_handler != SIG_HOLD) { 396 list_remove(&(item->link)); 397 _raise_sigaction(item->signo, &(item->siginfo)); 398 free(item); 399 } 400 401 iterator = next; 402 } 403 } 404 405 /** 406 * Raise a signal for the calling process. 407 * 408 * @param sig Signal number. 409 * @return -1 with errno set on failure, 0 on success. 330 * 331 * @param sig 332 * @return 410 333 */ 411 334 int posix_raise(int sig) … … 424 347 425 348 /** 426 * Raises a signal for a selected process. 427 * 428 * @param pid PID of the process for which the signal shall be raised. 429 * @param signo Signal to raise. 430 * @return -1 with errno set on failure (possible errors include unsupported 431 * action, invalid signal number, lack of permissions, etc.), 0 on success. 349 * 350 * @param pid 351 * @param signo 352 * @return 432 353 */ 433 354 int posix_kill(posix_pid_t pid, int signo) … … 462 383 463 384 /** 464 * Send a signal to a process group. Always fails at the moment because of 465 * lack of this functionality in HelenOS. 466 * 467 * @param pid PID of the process group. 468 * @param sig Signal number. 469 * @return -1 on failure, 0 on success (see kill()). 385 * 386 * @param pid 387 * @param sig 388 * @return 470 389 */ 471 390 int posix_killpg(posix_pid_t pid, int sig) … … 476 395 477 396 /** 478 * Outputs information about the signal to the standard error stream. 479 * 480 * @param pinfo SigInfo struct to write. 481 * @param message String to output alongside human-readable signal description. 397 * 398 * @param pinfo 399 * @param message 482 400 */ 483 401 void posix_psiginfo(const posix_siginfo_t *pinfo, const char *message) … … 489 407 490 408 /** 491 * Outputs information about the signal to the standard error stream. 492 * 493 * @param signum Signal number. 494 * @param message String to output alongside human-readable signal description. 409 * 410 * @param signum 411 * @param message 495 412 */ 496 413 void posix_psignal(int signum, const char *message) … … 505 422 506 423 /** 507 * Manipulate the signal mask of the calling thread. 508 * 509 * @param how What to do with the mask. 510 * @param set Signal set to work with. 511 * @param oset If not NULL, the original signal mask is coppied here. 512 * @return 0 success, errorcode on failure. 424 * 425 * @param how 426 * @param set 427 * @param oset 428 * @return 513 429 */ 514 430 int posix_thread_sigmask(int how, const posix_sigset_t *restrict set, … … 536 452 } 537 453 } 538 539 _dequeue_unblocked_signals();454 455 // TODO: queued signal handling 540 456 541 457 fibril_mutex_unlock(&_signal_mutex); … … 545 461 546 462 /** 547 * Manipulate the signal mask of the process. 548 * 549 * @param how What to do with the mask. 550 * @param set Signal set to work with. 551 * @param oset If not NULL, the original signal mask is coppied here. 552 * @return 0 on success, -1 with errno set on failure. 463 * 464 * @param how 465 * @param set 466 * @param oset 467 * @return 553 468 */ 554 469 int posix_sigprocmask(int how, const posix_sigset_t *restrict set,
Note:
See TracChangeset
for help on using the changeset viewer.