diff options
Diffstat (limited to 'libc/misc')
| -rw-r--r-- | libc/misc/Makefile.in | 1 | ||||
| -rw-r--r-- | libc/misc/dirent/closedir.c | 3 | ||||
| -rw-r--r-- | libc/misc/dirent/opendir.c | 10 | ||||
| -rw-r--r-- | libc/misc/internals/__uClibc_main.c | 107 | ||||
| -rw-r--r-- | libc/misc/internals/tempname.c | 14 | ||||
| -rw-r--r-- | libc/misc/internals/tempname.h | 3 | ||||
| -rw-r--r-- | libc/misc/pthread/Makefile.in | 1 | ||||
| -rw-r--r-- | libc/misc/pthread/tsd.c | 10 | ||||
| -rw-r--r-- | libc/misc/sysvipc/msgq.c | 53 | ||||
| -rw-r--r-- | libc/misc/utmp/utent.c | 13 | ||||
| -rw-r--r-- | libc/misc/utmp/wtent.c | 7 | 
11 files changed, 160 insertions, 62 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..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 */ 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);  	}      }  }  | 
