mirror of
				https://sourceware.org/git/glibc.git
				synced 2025-10-28 23:34:53 +03:00 
			
		
		
		
	2003-07-31 Jakub Jelinek <jakub@redhat.com> * dlfcn/dlerror.c (once): New. (dlerror): Call __libc_once. (_dlerror_run): Remove once. 2003-07-31 Jakub Jelinek <jakub@redhat.com> * sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h (struct sigcontext): Sync with 2.5.7 and 2.5.73 kernel changes. 2003-07-31 Jakub Jelinek <jakub@redhat.com> * dlfcn/eval.c (funcall): Add noinline attribute to shut up warnings. * elf/rtld.c (dl_main): Cast ElfW(Addr) arguments with %Zx/%Zd formats to size_t. * elf/dl-lookup.c (_dl_debug_bindings): Likewise. * elf/tst-tls6.c (do_test): Use %zd format for l_tls_modid. * elf/tst-tls8.c (do_test): Use %zd format for modid1 and modid2. * gmon/tst-sprofil.c (main): Add parens to shut up warning. * iconv/tst-iconv3.c (main): Use %td instead of %zd for pointer difference argument. * stdio-common/tst-wc-printf.c (main): Cast arguments with %C format to wint_t. * stdlib/tst-limits.c (main): For WORD_BIT and LONG_BIT, use %d format and cast expected value to int. * sysdeps/generic/libc-start.c (STATIC): Add __attribute__((always_inline) if LIBC_START_MAIN is already defined. * sysdeps/powerpc/fpu/w_sqrt.c (a_nan, a_inf): Change from uint32_t to ieee_float_shape_type. (__sqrt): Avoid type punning. * sysdeps/powerpc/fpu/w_sqrtf.c (a_nan, a_inf): Change from uint32_t to ieee_float_shape_type. (__sqrtf): Avoid type punning. * sysdeps/s390/s390-32/dl-machine.h (elf_machine_rela): Don't define refsym if in dl-conflict.c. * sysdeps/s390/s390-64/dl-machine.h (elf_machine_rela): Likewise. * sysdeps/unix/sysv/linux/i386/semctl.c (union semun): Add __old_buf. (__new_semctl): Shut up warning. * sysdeps/unix/sysv/linux/semctl.c (union semun): Add __old_buf. (__new_semctl): Shut up warning. * sysdeps/unix/sysv/linux/shmctl.c (__new_shmctl): Wrap long lines. Change old into union of __old_shmid_ds and __old_shminfo structs. Adjust all users. * wcsmbs/wcsmbs-tst1.c (main): Cast arguments with %C format to wint_t. 2003-07-31 Jakub Jelinek <jakub@redhat.com> * sysdeps/unix/sysv/linux/utimes.c (__utimes): Fix actime and modtime computation. * sysdeps/unix/sysv/linux/futimes.c (__futimes): Likewise. * sysdeps/posix/utimes.c (__utimes): Likewise.
		
			
				
	
	
		
			229 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			229 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* Copyright (C) 2003 Free Software Foundation, Inc.
 | |
|    This file is part of the GNU C Library.
 | |
|    Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
 | |
| 
 | |
|    The GNU C Library is free software; you can redistribute it and/or
 | |
|    modify it under the terms of the GNU Lesser General Public License as
 | |
|    published by the Free Software Foundation; either version 2.1 of the
 | |
|    License, or (at your option) any later version.
 | |
| 
 | |
|    The GNU C Library is distributed in the hope that it will be useful,
 | |
|    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
|    Lesser General Public License for more details.
 | |
| 
 | |
|    You should have received a copy of the GNU Lesser General Public
 | |
|    License along with the GNU C Library; see the file COPYING.LIB.  If not,
 | |
|    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 | |
|    Boston, MA 02111-1307, USA.  */
 | |
| 
 | |
| #include <errno.h>
 | |
| #include <pthread.h>
 | |
| #include <signal.h>
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| #include <time.h>
 | |
| #include <sysdep.h>
 | |
| #include <kernel-features.h>
 | |
| #include <internaltypes.h>
 | |
| #include <nptl/pthreadP.h>
 | |
| #include "kernel-posix-timers.h"
 | |
| 
 | |
| 
 | |
| #ifdef __NR_timer_create
 | |
| # ifndef __ASSUME_POSIX_TIMERS
 | |
| static int compat_timer_create (clockid_t clock_id, struct sigevent *evp,
 | |
| 				timer_t *timerid);
 | |
| #  define timer_create static compat_timer_create
 | |
| #  include <nptl/sysdeps/pthread/timer_create.c>
 | |
| #  undef timer_create
 | |
| 
 | |
| /* Nonzero if the system calls are not available.  */
 | |
| int __no_posix_timers attribute_hidden;
 | |
| # endif
 | |
| 
 | |
| # ifdef timer_create_alias
 | |
| #  define timer_create timer_create_alias
 | |
| # endif
 | |
| 
 | |
| 
 | |
| int
 | |
| timer_create (clock_id, evp, timerid)
 | |
|      clockid_t clock_id;
 | |
|      struct sigevent *evp;
 | |
|      timer_t *timerid;
 | |
| {
 | |
| # undef timer_create
 | |
| # ifndef __ASSUME_POSIX_TIMERS
 | |
|   if  (__no_posix_timers >= 0)
 | |
| # endif
 | |
|     {
 | |
|       /* If the user wants notification via a thread we need to handle
 | |
| 	 this special.  */
 | |
|       if (evp == NULL
 | |
| 	  || __builtin_expect (evp->sigev_notify != SIGEV_THREAD, 1))
 | |
| 	{
 | |
| 	  struct sigevent local_evp;
 | |
| 
 | |
| 	  /* We avoid allocating too much memory by basically
 | |
| 	     using struct timer as a derived class with the
 | |
| 	     first two elements being in the superclass.  We only
 | |
| 	     need these two elements here.  */
 | |
| 	  struct timer *newp = (struct timer *) malloc (offsetof (struct timer,
 | |
| 								  thrfunc));
 | |
| 	  if (newp == NULL)
 | |
| 	    /* No more memory.  */
 | |
| 	    return -1;
 | |
| 
 | |
| 	  if (evp == NULL)
 | |
| 	    {
 | |
| 	      /* The kernel has to pass up the timer ID which is a
 | |
| 		 userlevel object.  Therefore we cannot leave it up to
 | |
| 		 the kernel to determine it.  */
 | |
| 	      local_evp.sigev_notify = SIGEV_SIGNAL;
 | |
| 	      local_evp.sigev_signo = SIGALRM;
 | |
| 	      local_evp.sigev_value.sival_ptr = newp;
 | |
| 
 | |
| 	      evp = &local_evp;
 | |
| 	    }
 | |
| 
 | |
| 	  kernel_timer_t ktimerid;
 | |
| 	  int retval = INLINE_SYSCALL (timer_create, 3, clock_id, evp,
 | |
| 				       &ktimerid);
 | |
| 
 | |
| # ifndef __ASSUME_POSIX_TIMERS
 | |
| 	  if (retval != -1 || errno != ENOSYS)
 | |
| # endif
 | |
| 	    {
 | |
| # ifndef __ASSUME_POSIX_TIMERS
 | |
| 	      __no_posix_timers = 1;
 | |
| # endif
 | |
| 
 | |
| 	      if (retval != -1)
 | |
| 		{
 | |
| 		  newp->sigev_notify = (evp != NULL
 | |
| 					? evp->sigev_notify : SIGEV_SIGNAL);
 | |
| 		  newp->ktimerid = ktimerid;
 | |
| 
 | |
| 		  *timerid = (timer_t) newp;
 | |
| 		}
 | |
| 	      else
 | |
| 		{
 | |
| 		  /* Cannot allocate the timer, fail.  */
 | |
| 		  free (newp);
 | |
| 		  retval = -1;
 | |
| 		}
 | |
| 
 | |
| 	      return retval;
 | |
| 	    }
 | |
| 
 | |
| 	  free (newp);
 | |
| 
 | |
| # ifndef __ASSUME_POSIX_TIMERS
 | |
| 	  /* When we come here the syscall does not exist.  Make sure we
 | |
| 	     do not try to use it again.  */
 | |
| 	  __no_posix_timers = -1;
 | |
| # endif
 | |
| 	}
 | |
|       else
 | |
| 	{
 | |
| # ifndef __ASSUME_POSIX_TIMERS
 | |
| 	  /* Make sure we have the necessary kernel support.  */
 | |
| 	  if (__no_posix_timers == 0)
 | |
| 	    {
 | |
| 	      INTERNAL_SYSCALL_DECL (err);
 | |
| 	      struct timespec ts;
 | |
| 	      int res;
 | |
| 	      res = INTERNAL_SYSCALL (clock_getres, err, 1, &ts);
 | |
| 	      __no_posix_timers = (INTERNAL_SYSCALL_ERROR_P (res, err)
 | |
| 				   ? -1 : 1);
 | |
| 	    }
 | |
| 
 | |
| 	  if (__no_posix_timers > 0)
 | |
| # endif
 | |
| 	    {
 | |
| 	      /* Create the helper thread.  */
 | |
| 	      pthread_once (&__helper_once, __start_helper_thread);
 | |
| 	      if (__helper_tid == 0)
 | |
| 		{
 | |
| 		  /* No resources to start the helper thread.  */
 | |
| 		  __set_errno (EAGAIN);
 | |
| 		  return -1;
 | |
| 		}
 | |
| 
 | |
| 	      struct timer *newp;
 | |
| 	      newp = (struct timer *) malloc (sizeof (struct timer));
 | |
| 	      if (newp == NULL)
 | |
| 		return -1;
 | |
| 
 | |
| 	      /* Copy the thread parameters the user provided.  */
 | |
| 	      newp->sival = evp->sigev_value;
 | |
| 	      newp->thrfunc = evp->sigev_notify_function;
 | |
| 
 | |
| 	      /* We cannot simply copy the thread attributes since the
 | |
| 		 implementation might keep internal information for
 | |
| 		 each instance.  */
 | |
| 	      (void) pthread_attr_init (&newp->attr);
 | |
| 	      if (evp->sigev_notify_attributes != NULL)
 | |
| 		{
 | |
| 		  struct pthread_attr *nattr;
 | |
| 		  struct pthread_attr *oattr;
 | |
| 
 | |
| 		  nattr = (struct pthread_attr *) &newp->attr;
 | |
| 		  oattr = (struct pthread_attr *) evp->sigev_notify_attributes;
 | |
| 
 | |
| 		  nattr->schedparam = oattr->schedparam;
 | |
| 		  nattr->schedpolicy = oattr->schedpolicy;
 | |
| 		  nattr->flags = oattr->flags;
 | |
| 		  nattr->guardsize = oattr->guardsize;
 | |
| 		  nattr->stackaddr = oattr->stackaddr;
 | |
| 		  nattr->stacksize = oattr->stacksize;
 | |
| 		}
 | |
| 
 | |
| 	      /* In any case set the detach flag.  */
 | |
| 	      (void) pthread_attr_setdetachstate (&newp->attr,
 | |
| 						  PTHREAD_CREATE_DETACHED);
 | |
| 
 | |
| 	      /* Create the event structure for the kernel timer.  */
 | |
| 	      struct sigevent sev;
 | |
| 	      sev.sigev_value.sival_ptr = newp;
 | |
| 	      sev.sigev_signo = SIGTIMER;
 | |
| 	      sev.sigev_notify = SIGEV_SIGNAL | SIGEV_THREAD_ID;
 | |
| 	      /* This is the thread ID of the helper thread.  */
 | |
| 	      sev._sigev_un._pad[0] = __helper_tid;
 | |
| 
 | |
| 	      /* Create the timer.  */
 | |
| 	      INTERNAL_SYSCALL_DECL (err);
 | |
| 	      int res;
 | |
| 	      res = INTERNAL_SYSCALL (timer_create, err, 3, clock_id, &sev,
 | |
| 				      &newp->ktimerid);
 | |
| 	      if (! INTERNAL_SYSCALL_ERROR_P (res, err))
 | |
| 		{
 | |
| 		  *timerid = (timer_t) newp;
 | |
| 		  return 0;
 | |
| 		}
 | |
| 
 | |
| 	      /* Free the resources.  */
 | |
| 	      free (newp);
 | |
| 
 | |
| 	      __set_errno (INTERNAL_SYSCALL_ERRNO (res, err));
 | |
| 
 | |
| 	      return -1;
 | |
| 	    }
 | |
| 	}
 | |
|     }
 | |
| 
 | |
| # ifndef __ASSUME_POSIX_TIMERS
 | |
|   /* Compatibility code.  */
 | |
|   return compat_timer_create (clock_id, evp, timerid);
 | |
| # endif
 | |
| }
 | |
| #else
 | |
| # ifdef timer_create_alias
 | |
| #  define timer_create timer_create_alias
 | |
| # endif
 | |
| /* The new system calls are not available.  Use the userlevel
 | |
|    implementation.  */
 | |
| # include <nptl/sysdeps/pthread/timer_create.c>
 | |
| #endif
 |