OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [uClibc/] [libc/] [unistd/] [sleep.c] - Blame information for rev 1771

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1325 phoenix
/* Implementation of the POSIX sleep function using nanosleep.
2
   Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
3
   This file is part of the GNU C Library.
4
   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
5
 
6
   The GNU C Library is free software; you can redistribute it and/or
7
   modify it under the terms of the GNU Library General Public License as
8
   published by the Free Software Foundation; either version 2 of the
9
   License, or (at your option) any later version.
10
 
11
   The GNU C Library is distributed in the hope that it will be useful,
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
   Library General Public License for more details.
15
 
16
   You should have received a copy of the GNU Library General Public
17
   License along with the GNU C Library; see the file COPYING.LIB.  If not,
18
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19
   Boston, MA 02111-1307, USA.  */
20
 
21
#include <errno.h>
22
#include <time.h>
23
#include <signal.h>
24
#include <unistd.h>
25
 
26
#if 0
27
/* This is a quick and dirty, but not 100% compliant with
28
 * the stupid SysV SIGCHLD vs. SIG_IGN behaviour.  It is
29
 * fine unless you are messing with SIGCHLD...  */
30
unsigned int sleep (unsigned int sec)
31
{
32
        unsigned int res;
33
        struct timespec ts = { .tv_sec = (long int) seconds, .tv_nsec = 0 };
34
        res = nanosleep(&ts, &ts);
35
        if (res) res = (unsigned int) ts.tv_sec + (ts.tv_nsec >= 500000000L);
36
        return res;
37
}
38
 
39
#else
40
 
41
/* We are going to use the `nanosleep' syscall of the kernel.  But the
42
   kernel does not implement the sstupid SysV SIGCHLD vs. SIG_IGN
43
   behaviour for this syscall.  Therefore we have to emulate it here.  */
44
unsigned int sleep (unsigned int seconds)
45
{
46
    struct timespec ts = { .tv_sec = (long int) seconds, .tv_nsec = 0 };
47
    sigset_t set, oset;
48
    unsigned int result;
49
 
50
    /* This is not necessary but some buggy programs depend on this.  */
51
    if (seconds == 0)
52
        return 0;
53
 
54
    /* Linux will wake up the system call, nanosleep, when SIGCHLD
55
       arrives even if SIGCHLD is ignored.  We have to deal with it
56
       in libc.  We block SIGCHLD first.  */
57
    if (__sigemptyset (&set) < 0
58
            || __sigaddset (&set, SIGCHLD) < 0
59
            || sigprocmask (SIG_BLOCK, &set, &oset))
60
        return -1;
61
 
62
    /* If SIGCHLD is already blocked, we don't have to do anything.  */
63
    if (!__sigismember (&oset, SIGCHLD))
64
    {
65
        int saved_errno;
66
        struct sigaction oact;
67
 
68
        if (__sigemptyset (&set) < 0 || __sigaddset (&set, SIGCHLD) < 0)
69
            return -1;
70
 
71
        /* We get the signal handler for SIGCHLD.  */
72
        if (sigaction (SIGCHLD, (struct sigaction *) NULL, &oact) < 0)
73
        {
74
            saved_errno = errno;
75
            /* Restore the original signal mask.  */
76
            (void) sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL);
77
            __set_errno (saved_errno);
78
            return -1;
79
        }
80
 
81
        if (oact.sa_handler == SIG_IGN)
82
        {
83
            /* We should leave SIGCHLD blocked.  */
84
            result = nanosleep (&ts, &ts);
85
 
86
            saved_errno = errno;
87
            /* Restore the original signal mask.  */
88
            (void) sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL);
89
            __set_errno (saved_errno);
90
        }
91
        else
92
        {
93
            /* We should unblock SIGCHLD.  Restore the original signal mask.  */
94
            (void) sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL);
95
            result = nanosleep (&ts, &ts);
96
        }
97
    }
98
    else
99
        result = nanosleep (&ts, &ts);
100
 
101
    if (result != 0)
102
        /* Round remaining time.  */
103
        result = (unsigned int) ts.tv_sec + (ts.tv_nsec >= 500000000L);
104
 
105
    return result;
106
}
107
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.