Changeset ee24574 in mainline for uspace/lib/posix/signal.c
- Timestamp:
- 2011-08-18T08:00:42Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a92cf94f
- Parents:
- 0f963cb (diff), c53a705 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/posix/signal.c
r0f963cb ree24574 45 45 #include "libc/task.h" 46 46 47 // TODO: documentation 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 */ 48 55 49 56 /* Used to serialize signal handling. */ 50 57 static FIBRIL_MUTEX_INITIALIZE(_signal_mutex); 51 58 59 static LIST_INITIALIZE(_signal_queue); 60 52 61 static posix_sigset_t _signal_mask = 0; 53 62 … … 55 64 .sa_mask = 0, .sa_flags = 0, .sa_sigaction = NULL } 56 65 66 /* Actions associated with each signal number. */ 57 67 static struct posix_sigaction _signal_actions[_TOP_SIGNAL + 1] = { 58 68 DEFAULT_HANDLER, DEFAULT_HANDLER, DEFAULT_HANDLER, DEFAULT_HANDLER, … … 127 137 128 138 /** 129 * 130 * @param signo 139 * Just an empty function to get an unique pointer value for comparison. 140 * 141 * @param signo Signal number. 131 142 */ 132 143 void __posix_hold_signal_handler(int signo) … … 136 147 137 148 /** 138 * 139 * @param signo 149 * Empty function to be used as ignoring handler. 150 * 151 * @param signo Signal number. 140 152 */ 141 153 void __posix_ignore_signal_handler(int signo) … … 145 157 146 158 /** 147 * 148 * @param set 149 * @return 159 * Clear the signal set. 160 * 161 * @param set Pointer to the signal set. 162 * @return Always returns zero. 150 163 */ 151 164 int posix_sigemptyset(posix_sigset_t *set) … … 158 171 159 172 /** 160 * 161 * @param set 162 * @return 173 * Fill the signal set (i.e. add all signals). 174 * 175 * @param set Pointer to the signal set. 176 * @return Always returns zero. 163 177 */ 164 178 int posix_sigfillset(posix_sigset_t *set) … … 171 185 172 186 /** 173 * 174 * @param set 175 * @param signo 176 * @return 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. 177 192 */ 178 193 int posix_sigaddset(posix_sigset_t *set, int signo) … … 185 200 186 201 /** 187 * 188 * @param set 189 * @param signo 190 * @return 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. 191 207 */ 192 208 int posix_sigdelset(posix_sigset_t *set, int signo) … … 199 215 200 216 /** 201 * 202 * @param set 203 * @param signo 204 * @return 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. 205 222 */ 206 223 int posix_sigismember(const posix_sigset_t *set, int signo) … … 212 229 213 230 /** 231 * Unsafe variant of the sigaction() function. 232 * Doesn't do any checking of its arguments and 233 * does not deal with thread-safety. 214 234 * 215 235 * @param sig … … 232 252 233 253 /** 234 * 235 * @param sig 236 * @param act 237 * @param oact 238 * @return 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. 239 262 */ 240 263 int posix_sigaction(int sig, const struct posix_sigaction *restrict act, … … 263 286 264 287 /** 265 * 266 * @param sig 267 * @param func 268 * @return 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. 269 293 */ 270 294 void (*posix_signal(int sig, void (*func)(int)))(int) … … 284 308 } 285 309 286 /** 287 * 288 * @param signo 289 * @param siginfo 290 * @return 291 */ 292 static int _raise_sigaction(int signo, posix_siginfo_t *siginfo) 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) 293 323 { 294 324 assert(signo >= 0 && signo <= _TOP_SIGNAL); 295 325 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 is 341 * 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); 296 347 297 348 fibril_mutex_lock(&_signal_mutex); … … 301 352 if (posix_sigismember(&_signal_mask, signo) || 302 353 action.sa_handler == SIG_HOLD) { 303 // TODO: queue signal354 _queue_signal(signo, siginfo); 304 355 fibril_mutex_unlock(&_signal_mutex); 305 356 return -1; … … 312 363 if ((action.sa_flags & SA_RESETHAND) && signo != SIGILL && signo != SIGTRAP) { 313 364 _signal_actions[signo] = (struct posix_sigaction) DEFAULT_HANDLER; 314 } ;365 } 315 366 316 367 if (action.sa_flags & SA_SIGINFO) { … … 328 379 329 380 /** 330 * 331 * @param sig 332 * @return 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. 333 410 */ 334 411 int posix_raise(int sig) … … 347 424 348 425 /** 349 * 350 * @param pid 351 * @param signo 352 * @return 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. 353 432 */ 354 433 int posix_kill(posix_pid_t pid, int signo) … … 383 462 384 463 /** 385 * 386 * @param pid 387 * @param sig 388 * @return 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()). 389 470 */ 390 471 int posix_killpg(posix_pid_t pid, int sig) … … 395 476 396 477 /** 397 * 398 * @param pinfo 399 * @param message 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. 400 482 */ 401 483 void posix_psiginfo(const posix_siginfo_t *pinfo, const char *message) … … 407 489 408 490 /** 409 * 410 * @param signum 411 * @param message 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. 412 495 */ 413 496 void posix_psignal(int signum, const char *message) … … 422 505 423 506 /** 424 * 425 * @param how 426 * @param set 427 * @param oset 428 * @return 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. 429 513 */ 430 514 int posix_thread_sigmask(int how, const posix_sigset_t *restrict set, … … 452 536 } 453 537 } 454 455 // TODO: queued signal handling538 539 _dequeue_unblocked_signals(); 456 540 457 541 fibril_mutex_unlock(&_signal_mutex); … … 461 545 462 546 /** 463 * 464 * @param how 465 * @param set 466 * @param oset 467 * @return 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. 468 553 */ 469 554 int posix_sigprocmask(int how, const posix_sigset_t *restrict set,
Note:
See TracChangeset
for help on using the changeset viewer.