summaryrefslogtreecommitdiff
path: root/libc/misc
diff options
context:
space:
mode:
Diffstat (limited to 'libc/misc')
-rw-r--r--libc/misc/Makefile.in1
-rw-r--r--libc/misc/dirent/closedir.c3
-rw-r--r--libc/misc/dirent/opendir.c10
-rw-r--r--libc/misc/internals/__uClibc_main.c110
-rw-r--r--libc/misc/internals/tempname.c14
-rw-r--r--libc/misc/internals/tempname.h3
-rw-r--r--libc/misc/pthread/Makefile.in1
-rw-r--r--libc/misc/pthread/tsd.c10
-rw-r--r--libc/misc/sysvipc/msgq.c53
-rw-r--r--libc/misc/utmp/utent.c13
-rw-r--r--libc/misc/utmp/wtent.c7
11 files changed, 162 insertions, 63 deletions
diff --git a/libc/misc/Makefile.in b/libc/misc/Makefile.in
index 838081d66..6c09d3142 100644
--- a/libc/misc/Makefile.in
+++ b/libc/misc/Makefile.in
@@ -21,6 +21,7 @@ include $(top_srcdir)libc/misc/gnu/Makefile.in
include $(top_srcdir)libc/misc/internals/Makefile.in
include $(top_srcdir)libc/misc/locale/Makefile.in
include $(top_srcdir)libc/misc/mntent/Makefile.in
+include $(top_srcdir)libc/misc/pthread/Makefile.in
include $(top_srcdir)libc/misc/regex/Makefile.in
include $(top_srcdir)libc/misc/search/Makefile.in
include $(top_srcdir)libc/misc/statfs/Makefile.in
diff --git a/libc/misc/dirent/closedir.c b/libc/misc/dirent/closedir.c
index cca03b8f7..dfb53f888 100644
--- a/libc/misc/dirent/closedir.c
+++ b/libc/misc/dirent/closedir.c
@@ -9,6 +9,7 @@
#include <stdlib.h>
#include <unistd.h>
#include "dirstream.h"
+#include <not-cancel.h>
int closedir(DIR * dir)
@@ -31,6 +32,6 @@ int closedir(DIR * dir)
__UCLIBC_MUTEX_UNLOCK(dir->dd_lock);
free(dir->dd_buf);
free(dir);
- return close(fd);
+ return close_not_cancel(fd);
}
libc_hidden_def(closedir)
diff --git a/libc/misc/dirent/opendir.c b/libc/misc/dirent/opendir.c
index b43f60814..4a23ab061 100644
--- a/libc/misc/dirent/opendir.c
+++ b/libc/misc/dirent/opendir.c
@@ -12,6 +12,7 @@
#include <unistd.h>
#include <sys/dir.h>
#include <sys/stat.h>
+#include <not-cancel.h>
#include <dirent.h>
#include "dirstream.h"
@@ -81,7 +82,7 @@ DIR *opendir(const char *name)
}
# define O_DIRECTORY 0
#endif
- fd = open(name, O_RDONLY|O_NDELAY|O_DIRECTORY|O_CLOEXEC);
+ fd = open_not_cancel_2(name, O_RDONLY|O_NDELAY|O_DIRECTORY|O_CLOEXEC);
if (fd < 0)
return NULL;
/* Note: we should check to make sure that between the stat() and open()
@@ -93,7 +94,7 @@ DIR *opendir(const char *name)
/* this close() never fails
*int saved_errno;
*saved_errno = errno; */
- close(fd);
+ close_not_cancel_no_status(fd);
/*__set_errno(saved_errno);*/
return NULL;
}
@@ -102,12 +103,13 @@ DIR *opendir(const char *name)
* exec. From "Anna Pluzhnikov" <besp@midway.uchicago.edu>.
*/
#ifndef __ASSUME_O_CLOEXEC
- fcntl(fd, F_SETFD, FD_CLOEXEC);
+ fcntl_not_cancel(fd, F_SETFD, FD_CLOEXEC);
#endif
ptr = fd_to_DIR(fd, statbuf.st_blksize);
+
if (!ptr) {
- close(fd);
+ close_not_cancel_no_status(fd);
__set_errno(ENOMEM);
}
return ptr;
diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c
index b166aaaa7..cb2c6ed14 100644
--- a/libc/misc/internals/__uClibc_main.c
+++ b/libc/misc/internals/__uClibc_main.c
@@ -1,5 +1,6 @@
/*
- * Copyright (C) Feb 2001 Manuel Novoa III
+ * Copyright (C) 2006 by Steven J. Hill <sjhill@realitydiluted.com>
+ * Copyright (C) 2001 by Manuel Novoa III <mjn3@uclibc.org>
* Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
*
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
@@ -13,8 +14,10 @@
* avoided in the static library case.
*/
-#define _ERRNO_H
#include <features.h>
+#ifndef __UCLIBC_HAS_THREADS_NATIVE__
+#define _ERRNO_H
+#endif
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
@@ -22,10 +25,17 @@
#include <link.h>
#include <bits/uClibc_page.h>
#include <paths.h>
+#include <unistd.h>
#include <asm/errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+#include <errno.h>
+#include <pthread-functions.h>
+#include <not-cancel.h>
+#include <atomic.h>
+#endif
#ifndef SHARED
@@ -64,16 +74,17 @@ void internal_function _dl_aux_init (ElfW(auxv_t) *av);
* Prototypes.
*/
extern int *weak_const_function __errno_location(void);
-libc_hidden_proto(__errno_location)
extern int *weak_const_function __h_errno_location(void);
-libc_hidden_proto(__h_errno_location)
-
extern void weak_function _stdio_init(void) attribute_hidden;
#ifdef __UCLIBC_HAS_LOCALE__
extern void weak_function _locale_init(void) attribute_hidden;
#endif
#ifdef __UCLIBC_HAS_THREADS__
+#if !defined (__UCLIBC_HAS_THREADS_NATIVE__) || defined (SHARED)
extern void weak_function __pthread_initialize_minimal(void);
+#else
+extern void __pthread_initialize_minimal(void);
+#endif
#endif
/* If __UCLIBC_FORMAT_SHARED_FLAT__, all array initialisation and finalisation
@@ -126,7 +137,7 @@ static void __check_one_fd(int fd, int mode)
int nullfd = open(_PATH_DEVNULL, mode);
/* /dev/null is major=1 minor=3. Make absolutely certain
* that is in fact the device that we have opened and not
- * some other weird file... [removed in uclibc] */
+ * some other wierd file... [removed in uclibc] */
if (nullfd!=fd)
{
abort();
@@ -183,17 +194,20 @@ void __uClibc_init(void)
* __pthread_initialize_minimal so we can use pthread_locks
* whenever they are needed.
*/
+#if !defined (__UCLIBC_HAS_THREADS_NATIVE__) || defined (SHARED)
if (likely(__pthread_initialize_minimal!=NULL))
+#endif
__pthread_initialize_minimal();
#endif
#ifndef SHARED
# ifdef __UCLIBC_HAS_SSP__
/* Set up the stack checker's canary. */
- stack_chk_guard = _dl_setup_stack_chk_guard();
# ifdef THREAD_SET_STACK_GUARD
+ uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard();
THREAD_SET_STACK_GUARD (stack_chk_guard);
# ifdef __UCLIBC_HAS_SSP_COMPAT__
+ stack_chk_guard = _dl_setup_stack_chk_guard();
__guard = stack_chk_guard;
# endif
# else
@@ -267,6 +281,11 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
ElfW(auxv_t) auxvt[AT_EGID + 1];
#endif
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+ /* Result of the 'main' function. */
+ int result;
+#endif
+
#ifndef SHARED
__libc_stack_end = stack_end;
#endif
@@ -386,34 +405,57 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
if (likely(__h_errno_location!=NULL))
*(__h_errno_location()) = 0;
- /*
- * Finally, invoke application's main and then exit.
- */
- exit(main(argc, argv, __environ));
-}
+#if defined HAVE_CLEANUP_JMP_BUF && defined __UCLIBC_HAS_THREADS_NATIVE__
+ /* Memory for the cancellation buffer. */
+ struct pthread_unwind_buf unwind_buf;
-#if defined(__UCLIBC_HAS_THREADS__) && !defined(SHARED)
-/* Weaks for internal library use only.
- *
- * We need to define weaks here to cover all the pthread functions that
- * libc itself will use so that we aren't forced to link libc against
- * libpthread. This file is only used in libc.a and since we have
- * weaks here, they will be automatically overridden by libpthread.a
- * if it gets linked in.
- */
+ int not_first_call;
+ not_first_call =
+ setjmp ((struct __jmp_buf_tag *) unwind_buf.cancel_jmp_buf);
+ if (__builtin_expect (! not_first_call, 1))
+ {
+ struct pthread *self = THREAD_SELF;
+
+ /* Store old info. */
+ unwind_buf.priv.data.prev = THREAD_GETMEM (self, cleanup_jmp_buf);
+ unwind_buf.priv.data.cleanup = THREAD_GETMEM (self, cleanup);
+
+ /* Store the new cleanup handler info. */
+ THREAD_SETMEM (self, cleanup_jmp_buf, &unwind_buf);
-static int __pthread_return_0 (void) { return 0; }
-static void __pthread_return_void (void) { return; }
-
-weak_alias (__pthread_return_0, __pthread_mutex_init)
-weak_alias (__pthread_return_0, __pthread_mutex_lock)
-weak_alias (__pthread_return_0, __pthread_mutex_trylock)
-weak_alias (__pthread_return_0, __pthread_mutex_unlock)
-weak_alias (__pthread_return_void, _pthread_cleanup_push_defer)
-weak_alias (__pthread_return_void, _pthread_cleanup_pop_restore)
-# ifdef __UCLIBC_HAS_THREADS_NATIVE__
-weak_alias (__pthread_return_0, __pthread_mutexattr_init)
-weak_alias (__pthread_return_0, __pthread_mutexattr_destroy)
-weak_alias (__pthread_return_0, __pthread_mutexattr_settype)
+ /* Run the program. */
+ result = main (argc, argv, __environ);
+ }
+ else
+ {
+ /* Remove the thread-local data. */
+# ifdef SHARED
+ __libc_pthread_functions.ptr__nptl_deallocate_tsd ();
+# else
+ extern void __nptl_deallocate_tsd (void) __attribute ((weak));
+ __nptl_deallocate_tsd ();
# endif
+
+ /* One less thread. Decrement the counter. If it is zero we
+ terminate the entire process. */
+ result = 0;
+# ifdef SHARED
+ unsigned int *const ptr = __libc_pthread_functions.ptr_nthreads;
+# else
+ extern unsigned int __nptl_nthreads __attribute ((weak));
+ unsigned int *const ptr = &__nptl_nthreads;
+# endif
+
+ if (! atomic_decrement_and_test (ptr))
+ /* Not much left to do but to exit the thread, not the process. */
+ __exit_thread_inline (0);
+ }
+
+ exit (result);
+#else
+ /*
+ * Finally, invoke application's main and then exit.
+ */
+ exit (main (argc, argv, __environ));
#endif
+}
diff --git a/libc/misc/internals/tempname.c b/libc/misc/internals/tempname.c
index cbd4ced7a..4145c9478 100644
--- a/libc/misc/internals/tempname.c
+++ b/libc/misc/internals/tempname.c
@@ -168,14 +168,14 @@ static void brain_damaged_fillrand(unsigned char *buf, unsigned int len)
KIND may be one of:
__GT_NOCREATE: simply verify that the name does not exist
- at the time of the call.
+ at the time of the call. mode argument is ignored.
__GT_FILE: create the file using open(O_CREAT|O_EXCL)
- and return a read-write fd. The file is mode 0600.
+ and return a read-write fd with given mode.
__GT_BIGFILE: same as __GT_FILE but use open64().
- __GT_DIR: create a directory, which will be mode 0700.
+ __GT_DIR: create a directory with given mode.
*/
-int attribute_hidden __gen_tempname (char *tmpl, int kind)
+int __gen_tempname (char *tmpl, int kind, mode_t mode)
{
char *XXXXXX;
unsigned int i;
@@ -217,15 +217,15 @@ int attribute_hidden __gen_tempname (char *tmpl, int kind)
fd = 0;
}
case __GT_FILE:
- fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
+ fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL, mode);
break;
#if defined __UCLIBC_HAS_LFS__
case __GT_BIGFILE:
- fd = open64 (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
+ fd = open64 (tmpl, O_RDWR | O_CREAT | O_EXCL, mode);
break;
#endif
case __GT_DIR:
- fd = mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR);
+ fd = mkdir (tmpl, mode);
break;
default:
fd = -1;
diff --git a/libc/misc/internals/tempname.h b/libc/misc/internals/tempname.h
index ac40bef6e..017dc5190 100644
--- a/libc/misc/internals/tempname.h
+++ b/libc/misc/internals/tempname.h
@@ -3,13 +3,14 @@
#define __need_size_t
#include <stddef.h>
+#include <sys/types.h>
/* Disable support for $TMPDIR */
extern int ___path_search (char *tmpl, size_t tmpl_len, const char *dir,
const char *pfx /*, int try_tmpdir */) attribute_hidden;
#define __path_search(tmpl, tmpl_len, dir, pfx, try_tmpdir) ___path_search(tmpl, tmpl_len, dir, pfx)
-extern int __gen_tempname (char *__tmpl, int __kind) attribute_hidden;
+extern int __gen_tempname (char *__tmpl, int __kind, mode_t mode);
/* The __kind argument to __gen_tempname may be one of: */
#define __GT_FILE 0 /* create a file */
diff --git a/libc/misc/pthread/Makefile.in b/libc/misc/pthread/Makefile.in
index ceea1c21b..48e816236 100644
--- a/libc/misc/pthread/Makefile.in
+++ b/libc/misc/pthread/Makefile.in
@@ -10,6 +10,7 @@ subdirs += libc/misc/pthread
MISC_PTHREAD_DIR := $(top_srcdir)libc/misc/pthread
MISC_PTHREAD_OUT := $(top_builddir)libc/misc/pthread
+libc-shared-$(UCLIBC_HAS_THREADS) += $(MISC_PTHREAD_OUT)/tsd.os
libc-$(UCLIBC_HAS_THREADS) += $(MISC_PTHREAD_OUT)/unlock.o
libc-$(UCLIBC_HAS_THREADS) += $(MISC_PTHREAD_OUT)/weaks.o
diff --git a/libc/misc/pthread/tsd.c b/libc/misc/pthread/tsd.c
new file mode 100644
index 000000000..835ee22ce
--- /dev/null
+++ b/libc/misc/pthread/tsd.c
@@ -0,0 +1,10 @@
+/* libpthread sets _dl_error_catch_tsd to point to this function.
+ We define it here instead of in libpthread so t here instead of in libpthread so that it doesn't
+ need to have a TLS segment of its own just for this one pointer. */
+
+void ** __attribute__ ((const))
+__libc_dl_error_tsd (void)
+{
+ static __thread void *data __attribute__ ((tls_model ("initial-exec")));
+ return &data;
+}
diff --git a/libc/misc/sysvipc/msgq.c b/libc/misc/sysvipc/msgq.c
index dac886f7f..e20e3ca64 100644
--- a/libc/misc/sysvipc/msgq.c
+++ b/libc/misc/sysvipc/msgq.c
@@ -1,6 +1,11 @@
#include <errno.h>
#include <sys/msg.h>
#include "ipc.h"
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+#include "sysdep-cancel.h"
+#else
+#define SINGLE_THREAD_P 1
+#endif
#ifdef L_msgctl
@@ -43,31 +48,65 @@ struct new_msg_buf{
#ifdef L_msgrcv
#ifdef __NR_msgrcv
-_syscall5(ssize_t, msgrcv, int, msqid, void *, msgp, size_t, msgsz, long int, msgtyp, int, msgflg)
-#else
-ssize_t msgrcv (int msqid, void *msgp, size_t msgsz,
- long int msgtyp, int msgflg)
+#define __NR___syscall_msgrcv __NR_msgrcv
+static inline _syscall5(ssize_t, __syscall_msgrcv, int, msqid, void *, msgp,
+ size_t, msgsz, long int, msgtyp, int, msgflg)
+#endif
+static inline ssize_t do_msgrcv (int msqid, void *msgp, size_t msgsz,
+ long int msgtyp, int msgflg)
{
+#ifdef __NR_msgrcv
+ return __syscall_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg);
+#else
struct new_msg_buf temp;
temp.r_msgtyp = msgtyp;
temp.oldmsg = msgp;
return __syscall_ipc(IPCOP_msgrcv ,msqid ,msgsz ,msgflg ,&temp, 0);
+#endif
}
+int msgrcv (int msqid, void *msgp, size_t msgsz,
+ long int msgtyp, int msgflg)
+{
+ if (SINGLE_THREAD_P)
+ return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg);
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+ int oldtype = LIBC_CANCEL_ASYNC ();
+ int result = do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg);
+ LIBC_CANCEL_RESET (oldtype);
+ return result;
#endif
+}
#endif
#ifdef L_msgsnd
#ifdef __NR_msgsnd
-_syscall4(int, msgsnd, int, msqid, const void *, msgp, size_t, msgsz, int, msgflg)
-#else
+#define __NR___syscall_msgsnd __NR_msgsnd
+static inline _syscall4(int, __syscall_msgsnd, int, msqid, const void *, msgp,
+ size_t, msgsz, int, msgflg)
+#endif
/* Send message to message queue. */
-int msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg)
+static inline int do_msgsnd (int msqid, const void *msgp, size_t msgsz,
+ int msgflg)
{
+#ifdef __NR_msgsnd
+ return __syscall_msgsnd(msqid, msgp, msgsz, msgflg);
+#else
return __syscall_ipc(IPCOP_msgsnd, msqid, msgsz, msgflg, (void *)msgp, 0);
+#endif
}
+int msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg)
+{
+ if (SINGLE_THREAD_P)
+ return do_msgsnd(msqid, msgp, msgsz, msgflg);
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+ int oldtype = LIBC_CANCEL_ASYNC ();
+ int result = do_msgsnd(msqid, msgp, msgsz, msgflg);
+ LIBC_CANCEL_RESET (oldtype);
+ return result;
#endif
+}
#endif
diff --git a/libc/misc/utmp/utent.c b/libc/misc/utmp/utent.c
index 336c0239b..a3f01b6e9 100644
--- a/libc/misc/utmp/utent.c
+++ b/libc/misc/utmp/utent.c
@@ -19,6 +19,7 @@
#include <errno.h>
#include <string.h>
#include <utmp.h>
+#include <not-cancel.h>
#include <bits/uClibc_mutex.h>
__UCLIBC_MUTEX_STATIC(utmplock, PTHREAD_MUTEX_INITIALIZER);
@@ -34,16 +35,16 @@ static const char *static_ut_name = default_file_name;
static void __setutent(void)
{
if (static_fd < 0) {
- static_fd = open(static_ut_name, O_RDWR | O_CLOEXEC);
+ static_fd = open_not_cancel_2(static_ut_name, O_RDWR | O_CLOEXEC);
if (static_fd < 0) {
- static_fd = open(static_ut_name, O_RDONLY | O_CLOEXEC);
+ static_fd = open_not_cancel_2(static_ut_name, O_RDONLY | O_CLOEXEC);
if (static_fd < 0) {
return; /* static_fd remains < 0 */
}
}
#ifndef __ASSUME_O_CLOEXEC
/* Make sure the file will be closed on exec() */
- fcntl(static_fd, F_SETFD, FD_CLOEXEC);
+ fcntl_not_cancel(static_fd, F_SETFD, FD_CLOEXEC);
#endif
return;
}
@@ -70,7 +71,7 @@ static struct utmp *__getutent(void)
}
}
- if (read(static_fd, &static_utmp, sizeof(static_utmp)) == sizeof(static_utmp)) {
+ if (read_not_cancel(static_fd, &static_utmp, sizeof(static_utmp)) == sizeof(static_utmp)) {
ret = &static_utmp;
}
@@ -81,7 +82,7 @@ void endutent(void)
{
__UCLIBC_MUTEX_LOCK(utmplock);
if (static_fd >= 0)
- close(static_fd);
+ close_not_cancel_no_status(static_fd);
static_fd = -1;
__UCLIBC_MUTEX_UNLOCK(utmplock);
}
@@ -182,7 +183,7 @@ int utmpname(const char *new_ut_name)
}
if (static_fd >= 0) {
- close(static_fd);
+ close_not_cancel_no_status(static_fd);
static_fd = -1;
}
__UCLIBC_MUTEX_UNLOCK(utmplock);
diff --git a/libc/misc/utmp/wtent.c b/libc/misc/utmp/wtent.c
index e73d99feb..5ab743d9b 100644
--- a/libc/misc/utmp/wtent.c
+++ b/libc/misc/utmp/wtent.c
@@ -13,6 +13,7 @@
#include <utmp.h>
#include <fcntl.h>
#include <sys/file.h>
+#include <not-cancel.h>
#if 0
/* This is enabled in uClibc/libutil/logwtmp.c */
@@ -36,12 +37,12 @@ void updwtmp(const char *wtmp_file, const struct utmp *lutmp)
{
int fd;
- fd = open(wtmp_file, O_APPEND | O_WRONLY);
+ fd = open_not_cancel(wtmp_file, O_APPEND | O_WRONLY, 0);
if (fd >= 0) {
if (lockf(fd, F_LOCK, 0) == 0) {
- write(fd, lutmp, sizeof(*lutmp));
+ write_not_cancel(fd, lutmp, sizeof(struct utmp));
lockf(fd, F_ULOCK, 0);
- close(fd);
+ close_not_cancel_no_status(fd);
}
}
}