Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/posix/signal.c

    r55b1efd rffff746  
    4545#include "libc/task.h"
    4646
    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
    5548
    5649/* Used to serialize signal handling. */
    5750static FIBRIL_MUTEX_INITIALIZE(_signal_mutex);
    5851
    59 static LIST_INITIALIZE(_signal_queue);
    60 
    6152static posix_sigset_t _signal_mask = 0;
    6253
     
    6455    .sa_mask = 0, .sa_flags = 0, .sa_sigaction = NULL }
    6556
    66 /* Actions associated with each signal number. */
    6757static struct posix_sigaction _signal_actions[_TOP_SIGNAL + 1] = {
    6858        DEFAULT_HANDLER, DEFAULT_HANDLER, DEFAULT_HANDLER, DEFAULT_HANDLER,
     
    137127
    138128/**
    139  * Just an empty function to get an unique pointer value for comparison.
    140129 *
    141  * @param signo Signal number.
     130 * @param signo
    142131 */
    143132void __posix_hold_signal_handler(int signo)
     
    147136
    148137/**
    149  * Empty function to be used as ignoring handler.
    150  *
    151  * @param signo Signal number.
     138 *
     139 * @param signo
    152140 */
    153141void __posix_ignore_signal_handler(int signo)
     
    157145
    158146/**
    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
    163150 */
    164151int posix_sigemptyset(posix_sigset_t *set)
     
    171158
    172159/**
    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
    177163 */
    178164int posix_sigfillset(posix_sigset_t *set)
     
    185171
    186172/**
    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
    192177 */
    193178int posix_sigaddset(posix_sigset_t *set, int signo)
     
    200185
    201186/**
    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
    207191 */
    208192int posix_sigdelset(posix_sigset_t *set, int signo)
     
    215199
    216200/**
    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
    222205 */
    223206int posix_sigismember(const posix_sigset_t *set, int signo)
     
    229212
    230213/**
    231  * Unsafe variant of the sigaction() function.
    232  * Doesn't do any checking of its arguments and
    233  * does not deal with thread-safety.
    234214 *
    235215 * @param sig
     
    252232
    253233/**
    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
    262239 */
    263240int posix_sigaction(int sig, const struct posix_sigaction *restrict act,
     
    286263
    287264/**
    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
    293269 */
    294270void (*posix_signal(int sig, void (*func)(int)))(int)
     
    308284}
    309285
    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 */
     292static int _raise_sigaction(int signo, posix_siginfo_t *siginfo)
    323293{
    324294        assert(signo >= 0 && signo <= _TOP_SIGNAL);
    325295        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);
    347296
    348297        fibril_mutex_lock(&_signal_mutex);
     
    352301        if (posix_sigismember(&_signal_mask, signo) ||
    353302            action.sa_handler == SIG_HOLD) {
    354                 _queue_signal(signo, siginfo);
     303                // TODO: queue signal
    355304                fibril_mutex_unlock(&_signal_mutex);
    356305                return -1;
     
    363312        if ((action.sa_flags & SA_RESETHAND) && signo != SIGILL && signo != SIGTRAP) {
    364313                _signal_actions[signo] = (struct posix_sigaction) DEFAULT_HANDLER;
    365         }
     314        };
    366315
    367316        if (action.sa_flags & SA_SIGINFO) {
     
    379328
    380329/**
    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
    410333 */
    411334int posix_raise(int sig)
     
    424347
    425348/**
    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
    432353 */
    433354int posix_kill(posix_pid_t pid, int signo)
     
    462383
    463384/**
    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
    470389 */
    471390int posix_killpg(posix_pid_t pid, int sig)
     
    476395
    477396/**
    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
    482400 */
    483401void posix_psiginfo(const posix_siginfo_t *pinfo, const char *message)
     
    489407
    490408/**
    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
    495412 */
    496413void posix_psignal(int signum, const char *message)
     
    505422
    506423/**
    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
    513429 */
    514430int posix_thread_sigmask(int how, const posix_sigset_t *restrict set,
     
    536452                }
    537453        }
    538        
    539         _dequeue_unblocked_signals();
     454
     455        // TODO: queued signal handling
    540456
    541457        fibril_mutex_unlock(&_signal_mutex);
     
    545461
    546462/**
    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
    553468 */
    554469int posix_sigprocmask(int how, const posix_sigset_t *restrict set,
Note: See TracChangeset for help on using the changeset viewer.