diff options
Diffstat (limited to 'libc/unistd')
-rw-r--r-- | libc/unistd/daemon.c | 51 | ||||
-rw-r--r-- | libc/unistd/sysconf.c | 26 |
2 files changed, 69 insertions, 8 deletions
diff --git a/libc/unistd/daemon.c b/libc/unistd/daemon.c index 741672ec0..c3b563179 100644 --- a/libc/unistd/daemon.c +++ b/libc/unistd/daemon.c @@ -46,6 +46,20 @@ #include <paths.h> #include <signal.h> #include <unistd.h> +#include <not-cancel.h> +#include <errno.h> + +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ +#include <sys/stat.h> +#endif + +#ifdef __UCLIBC_HAS_LFS__ +#define STAT stat64 +#define FSTAT fstat64 +#else +#define STAT stat +#define FSTAT fstat +#endif #if defined __USE_BSD || (defined __USE_XOPEN && !defined __USE_UNIX98) @@ -97,15 +111,40 @@ int daemon(int nochdir, int noclose) if (setsid() == -1) return -1; +#ifndef __UCLIBC_HAS_THREADS_NATIVE__ + /* Make certain we are not a session leader, or else we + * might reacquire a controlling terminal */ + if (fork()) + _exit(0); +#endif + if (!nochdir) chdir("/"); - if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR)) != -1) { - dup2(fd, STDIN_FILENO); - dup2(fd, STDOUT_FILENO); - dup2(fd, STDERR_FILENO); - if (fd > 2) - close(fd); + if (!noclose) + { + struct STAT st; + + if ((fd = open_not_cancel(_PATH_DEVNULL, O_RDWR, 0)) != -1 + && (__builtin_expect (FSTAT (fd, &st), 0) == 0)) + { + if (__builtin_expect (S_ISCHR (st.st_mode), 1) != 0) { + dup2(fd, STDIN_FILENO); + dup2(fd, STDOUT_FILENO); + dup2(fd, STDERR_FILENO); + if (fd > 2) + close(fd); + } else { + /* We must set an errno value since no + function call actually failed. */ + close_not_cancel_no_status (fd); + __set_errno (ENODEV); + return -1; + } + } else { + close_not_cancel_no_status (fd); + return -1; + } } return 0; } diff --git a/libc/unistd/sysconf.c b/libc/unistd/sysconf.c index 87206648e..b3eb12021 100644 --- a/libc/unistd/sysconf.c +++ b/libc/unistd/sysconf.c @@ -33,6 +33,9 @@ #ifdef __UCLIBC_HAS_REGEX__ #include <regex.h> #endif +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ +#include <sysdep.h> +#endif #ifdef HAVE_LINUX_CPUMASK_H # include <linux/cpumask.h> @@ -881,13 +884,32 @@ long int sysconf(int name) #endif case _SC_MONOTONIC_CLOCK: -#if defined __UCLIBC_HAS_REALTIME__ && defined __NR_clock_getres - /* Check using the clock_getres system call. */ +#ifdef __NR_clock_getres + /* Check using the clock_getres system call. */ +# ifdef __UCLIBC_HAS_THREADS_NATIVE__ + { + struct timespec ts; + INTERNAL_SYSCALL_DECL (err); + int r; + r = INTERNAL_SYSCALL (clock_getres, err, 2, CLOCK_MONOTONIC, &ts); + return INTERNAL_SYSCALL_ERROR_P (r, err) ? -1 : _POSIX_VERSION; + } +# else if (clock_getres(CLOCK_MONOTONIC, NULL) >= 0) return _POSIX_VERSION; + + RETURN_NEG_1; +# endif #endif +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ + case _SC_THREAD_CPUTIME: +# if _POSIX_THREAD_CPUTIME > 0 + return _POSIX_THREAD_CPUTIME; +# else RETURN_NEG_1; +# endif +#endif } } libc_hidden_def(sysconf) |