Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 4419c34 in mainline


Ignore:
Timestamp:
2011-08-17T17:44:07Z (10 years ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
lfn, master
Children:
0d33863
Parents:
4c8f5e7
Message:

Documentation and addition of signal queue to <signal.h>

Location:
uspace/lib/posix
Files:
2 edited

Legend:

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

    r4c8f5e7 r4419c34  
    4545#include "libc/task.h"
    4646
    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 */
    4855
    4956/* Used to serialize signal handling. */
    5057static FIBRIL_MUTEX_INITIALIZE(_signal_mutex);
    5158
     59static LIST_INITIALIZE(_signal_queue);
     60
    5261static posix_sigset_t _signal_mask = 0;
    5362
     
    5564    .sa_mask = 0, .sa_flags = 0, .sa_sigaction = NULL }
    5665
     66/* Actions associated with each signal number. */
    5767static struct posix_sigaction _signal_actions[_TOP_SIGNAL + 1] = {
    5868        DEFAULT_HANDLER, DEFAULT_HANDLER, DEFAULT_HANDLER, DEFAULT_HANDLER,
     
    126136}
    127137
    128 /**
     138/** Just an empty function to get an unique pointer value for comparison.
    129139 *
    130140 * @param signo
     
    135145}
    136146
    137 /**
     147/** Empty function to be used as ignoring handler.
    138148 *
    139149 * @param signo
     
    144154}
    145155
    146 /**
    147  *
    148  * @param set
    149  * @return
     156/** Clear the signal set.
     157 *
     158 * @param set Pointer to the signal set.
     159 * @return Always returns zero.
    150160 */
    151161int posix_sigemptyset(posix_sigset_t *set)
     
    157167}
    158168
    159 /**
    160  *
    161  * @param set
    162  * @return
     169/** Fill the signal set (i.e. add all signals).
     170 *
     171 * @param set Pointer to the signal set.
     172 * @return Always returns zero.
    163173 */
    164174int posix_sigfillset(posix_sigset_t *set)
     
    170180}
    171181
    172 /**
    173  *
    174  * @param set
    175  * @param signo
    176  * @return
     182/** Add a signal to the set.
     183 *
     184 * @param set Pointer to the signal set.
     185 * @param signo Signal number to add.
     186 * @return Always returns zero.
    177187 */
    178188int posix_sigaddset(posix_sigset_t *set, int signo)
     
    184194}
    185195
    186 /**
    187  *
    188  * @param set
    189  * @param signo
    190  * @return
     196/** Delete a signal from the set.
     197 *
     198 * @param set Pointer to the signal set.
     199 * @param signo Signal number to remove.
     200 * @return Always returns zero.
    191201 */
    192202int posix_sigdelset(posix_sigset_t *set, int signo)
     
    198208}
    199209
    200 /**
    201  *
    202  * @param set
    203  * @param signo
    204  * @return
     210/** Inclusion test for a signal set.
     211 *
     212 * @param set Pointer to the signal set.
     213 * @param signo Signal number to query.
     214 * @return 1 if the signal is in the set, 0 otherwise.
    205215 */
    206216int posix_sigismember(const posix_sigset_t *set, int signo)
     
    211221}
    212222
    213 /**
     223/** Unsafe variant of the sigaction() function.
     224 *  Doesn't do any checking of its arguments and
     225 *  does not deal with thread-safety.
    214226 *
    215227 * @param sig
     
    231243}
    232244
    233 /**
    234  *
    235  * @param sig
    236  * @param act
    237  * @param oact
    238  * @return
     245/** Sets a new action for the given signal number.
     246 *
     247 * @param sig Signal number to set action for.
     248 * @param act If not NULL, contents of this structure are
     249 *     used as the new action for the signal.
     250 * @param oact If not NULL, the original action associated with the signal
     251 *     is stored in the structure pointer to.
     252 * @return -1 with errno set on failure, 0 on success.
    239253 */
    240254int posix_sigaction(int sig, const struct posix_sigaction *restrict act,
     
    262276}
    263277
    264 /**
    265  *
    266  * @param sig
    267  * @param func
    268  * @return
     278/** Sets a new handler for the given signal number.
     279 *
     280 * @param sig Signal number to set handler for.
     281 * @param func Handler function.
     282 * @return SIG_ERR on failure, original handler on success.
    269283 */
    270284void (*posix_signal(int sig, void (*func)(int)))(int)
     
    284298}
    285299
    286 /**
    287  *
    288  * @param signo
    289  * @param siginfo
    290  * @return
    291  */
    292 static int _raise_sigaction(int signo, posix_siginfo_t *siginfo)
     300typedef struct {
     301        link_t link;
     302        int signo;
     303        posix_siginfo_t siginfo;
     304} signal_queue_item;
     305
     306/** Queue blocked signal.
     307 *
     308 * @param signo Signal number.
     309 * @param siginfo Additional information about the signal.
     310 */
     311static void _queue_signal(int signo, posix_siginfo_t *siginfo)
    293312{
    294313        assert(signo >= 0 && signo <= _TOP_SIGNAL);
    295314        assert(siginfo != NULL);
     315       
     316        signal_queue_item *item = malloc(sizeof(signal_queue_item));
     317        link_initialize(&(item->link));
     318        item->signo = signo;
     319        memcpy(&item->siginfo, siginfo, sizeof(posix_siginfo_t));
     320        list_append(&(item->link), &_signal_queue);
     321}
     322
     323
     324/** Executes an action associated with the given signal.
     325 *
     326 * @param signo Signal number.
     327 * @param siginfo Additional information about the circumstances of this raise.
     328 * @return 0 if the action has been successfully executed. -1 if the signal is
     329 *     blocked.
     330 */
     331static int _raise_sigaction(int signo, posix_siginfo_t *siginfo)
     332{
     333        assert(signo >= 0 && signo <= _TOP_SIGNAL);
     334        assert(siginfo != NULL);
    296335
    297336        fibril_mutex_lock(&_signal_mutex);
     
    301340        if (posix_sigismember(&_signal_mask, signo) ||
    302341            action.sa_handler == SIG_HOLD) {
    303                 // TODO: queue signal
     342                _queue_signal(signo, siginfo);
    304343                fibril_mutex_unlock(&_signal_mutex);
    305344                return -1;
     
    327366}
    328367
    329 /**
    330  *
    331  * @param sig
    332  * @return
     368/** Raise all unblocked previously queued signals.
     369 */
     370static void _dequeue_unblocked_signals()
     371{
     372        link_t *iterator = _signal_queue.head.next;
     373        link_t *next;
     374       
     375        while (iterator != &(_signal_queue).head) {
     376                next = iterator->next;
     377               
     378                signal_queue_item *item =
     379                    list_get_instance(iterator, signal_queue_item, link);
     380               
     381                if (!posix_sigismember(&_signal_mask, item->signo) &&
     382                    _signal_actions[item->signo].sa_handler != SIG_HOLD) {
     383                        list_remove(&(item->link));
     384                        _raise_sigaction(item->signo, &(item->siginfo));
     385                        free(item);
     386                }
     387               
     388                iterator = next;
     389        }
     390}
     391
     392/** Raise a signal for the calling process.
     393 *
     394 * @param sig Signal number.
     395 * @return -1 with errno set on failure, 0 on success.
    333396 */
    334397int posix_raise(int sig)
     
    346409}
    347410
    348 /**
    349  *
    350  * @param pid
    351  * @param signo
    352  * @return
     411/** Raises a signal for a selected process.
     412 *
     413 * @param pid PID of the process for which the signal shall be raised.
     414 * @param signo Signal to raise.
     415 * @return -1 with errno set on failure (possible errors include unsupported
     416 *     action, invalid signal number, lack of permissions, etc.), 0 on success.
    353417 */
    354418int posix_kill(posix_pid_t pid, int signo)
     
    382446}
    383447
    384 /**
    385  *
    386  * @param pid
    387  * @param sig
    388  * @return
     448/** Send a signal to a process group. Always fails at the moment because of
     449 *  lack of this functionality in HelenOS.
     450 *
     451 * @param pid PID of the process group.
     452 * @param sig Signal number.
     453 * @return -1 on failure, 0 on success (see kill()).
    389454 */
    390455int posix_killpg(posix_pid_t pid, int sig)
     
    394459}
    395460
    396 /**
    397  *
    398  * @param pinfo
    399  * @param message
     461/** Outputs information about the signal to the standard error stream.
     462 *
     463 * @param pinfo SigInfo struct to write.
     464 * @param message String to output alongside human-readable signal description.
    400465 */
    401466void posix_psiginfo(const posix_siginfo_t *pinfo, const char *message)
     
    406471}
    407472
    408 /**
    409  *
    410  * @param signum
    411  * @param message
     473/** Outputs information about the signal to the standard error stream.
     474 *
     475 * @param signum Signal number.
     476 * @param message String to output alongside human-readable signal description.
    412477 */
    413478void posix_psignal(int signum, const char *message)
     
    421486}
    422487
    423 /**
    424  *
    425  * @param how
    426  * @param set
    427  * @param oset
    428  * @return
     488/** Manipulate the signal mask of the calling thread.
     489 *
     490 * @param how What to do with the mask.
     491 * @param set Signal set to work with.
     492 * @param oset If not NULL, the original signal mask is coppied here.
     493 * @return 0 success, errorcode on failure.
    429494 */
    430495int posix_thread_sigmask(int how, const posix_sigset_t *restrict set,
     
    452517                }
    453518        }
    454 
    455         // TODO: queued signal handling
     519       
     520        _dequeue_unblocked_signals();
    456521
    457522        fibril_mutex_unlock(&_signal_mutex);
     
    460525}
    461526
    462 /**
    463  *
    464  * @param how
    465  * @param set
    466  * @param oset
    467  * @return
     527/** Manipulate the signal mask of the process.
     528 *
     529 * @param how What to do with the mask.
     530 * @param set Signal set to work with.
     531 * @param oset If not NULL, the original signal mask is coppied here.
     532 * @return 0 on success, -1 with errno set on failure.
    468533 */
    469534int posix_sigprocmask(int how, const posix_sigset_t *restrict set,
  • uspace/lib/posix/signal.h

    r4c8f5e7 r4419c34  
    3636#define POSIX_SIGNAL_H_
    3737
    38 // TODO: documentation
    39 
    4038#include "libc/errno.h"
    4139#include "sys/types.h"
     
    5755typedef uint32_t posix_sigset_t;
    5856typedef struct posix_mcontext {
    59         // FIXME: should not be empty to avoid compiler warnings (-pedantic)
     57        /* must not be empty to avoid compiler warnings (-pedantic) */
    6058        int dummy;
    6159} posix_mcontext_t;
Note: See TracChangeset for help on using the changeset viewer.