summaryrefslogtreecommitdiff
path: root/libc/misc/internals
diff options
context:
space:
mode:
Diffstat (limited to 'libc/misc/internals')
-rw-r--r--libc/misc/internals/__uClibc_main.c107
-rw-r--r--libc/misc/internals/tempname.c14
-rw-r--r--libc/misc/internals/tempname.h3
3 files changed, 83 insertions, 41 deletions
diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c
index b166aaaa7..85dbe7123 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,7 +194,9 @@ 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
@@ -267,6 +280,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 +404,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);
+
+ /* 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
-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)
+ /* 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 */