diff options
Diffstat (limited to 'libc/misc/internals')
| -rw-r--r-- | libc/misc/internals/__uClibc_main.c | 110 | ||||
| -rw-r--r-- | libc/misc/internals/tempname.c | 14 | ||||
| -rw-r--r-- | libc/misc/internals/tempname.h | 3 | 
3 files changed, 85 insertions, 42 deletions
diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c index 6e520fabb..f7e45c60c 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(); @@ -181,17 +192,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 @@ -266,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 @@ -385,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); -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 */  | 
