ssize_t
pread (int fd, void *buf, size_t nbyte, off_t offset)
{
  /* Since we must not change the file pointer preserve the value so that
     we can restore it later.  */
  int save_errno;
  ssize_t result;
  off_t old_offset = __libc_lseek (fd, 0, SEEK_CUR);
  if (old_offset == (off_t) -1)
    return -1;

  /* Set to wanted position.  */
  if (__libc_lseek (fd, offset, SEEK_SET) == (off_t) -1)
    return -1;

  /* Write out the data.  */
  result = __libc_read (fd, buf, nbyte);

  /* Now we have to restore the position.  If this fails we have to
     return this as an error.  But if the writing also failed we
     return this error.  */
  save_errno = errno;
  if (__libc_lseek (fd, old_offset, SEEK_SET) == (off_t) -1)
    {
      if (result == -1)
        __set_errno (save_errno);
      return -1;
    }
  __set_errno (save_errno);

  return result;
}
示例#2
0
void __guard_setup(void)
{
	size_t size;

	if (__guard != 0UL)
		return;

	/* Start with the "terminator canary". */
	__guard = 0xFF0A0D00UL;

#ifndef __SSP_QUICK_CANARY__
# ifdef __SSP_USE_ERANDOM__
	{
		int mib[3];
		/* Random is another depth in Linux, hence an array of 3. */
		mib[0] = CTL_KERN;
		mib[1] = KERN_RANDOM;
		mib[2] = RANDOM_ERANDOM;

		size = sizeof(unsigned long);
		if (__sysctl(mib, 3, &__guard, &size, NULL, 0) != (-1))
			if (__guard != 0UL)
				return;
	}
# endif /* ifdef __SSP_USE_ERANDOM__ */
	/* 
	 * Attempt to open kernel pseudo random device if one exists before 
	 * opening urandom to avoid system entropy depletion.
	 */
	{
		int fd;

# ifdef __SSP_USE_ERANDOM__
		if ((fd = __libc_open("/dev/erandom", O_RDONLY)) == (-1))
# endif
			fd = __libc_open("/dev/urandom", O_RDONLY);
		if (fd != (-1)) {
			size = __libc_read(fd, (char *) &__guard, sizeof(__guard));
			__libc_close(fd);
			if (size == sizeof(__guard))
				return;
		}
	}
#endif /* ifndef __SSP_QUICK_CANARY__ */

	/* Everything failed? Or we are using a weakened model of the 
	 * terminator canary */
	{
		struct timeval tv;
		__gettimeofday(&tv, NULL);
		__guard ^= tv.tv_usec ^ tv.tv_sec;
	}
}
示例#3
0
size_t fread_unlocked(void *ptr, size_t size, size_t nmemb, FILE *stream) {
  unsigned long i,j;
  j=size*nmemb;
  i=0;

  if (!(stream->flags&CANREAD)) {
    stream->flags|=ERRORINDICATOR;
    return 0;
  }
  if (!j || j/nmemb!=size) return 0;
  if (stream->ungotten) {
    stream->ungotten=0;
    *(char*)ptr=stream->ungetbuf;
    ++i;
    if (j==1) return 1;
  }

#ifdef WANT_FREAD_OPTIMIZATION
  if ( !(stream->flags&FDPIPE) && (j>stream->buflen)) {
    size_t tmp=j-i;
    ssize_t res;
    size_t inbuf=stream->bs-stream->bm;
    memcpy(ptr+i,stream->buf+stream->bm,inbuf);
    stream->bm=stream->bs=0;
    tmp-=inbuf;
    i+=inbuf;
    if (fflush_unlocked(stream)) return 0;
    while ((res=__libc_read(stream->fd,ptr+i,tmp))<(ssize_t)tmp) {
      if (res==-1) {
	stream->flags|=ERRORINDICATOR;
	goto exit;
      } else if (!res) {
	stream->flags|=EOFINDICATOR;
	goto exit;
      }
      i+=res; tmp-=res;
    }
    return nmemb;
  }
#endif
  for (; i<j; ++i) {
    int res;
    res=fgetc_unlocked(stream);
    if (res==EOF)
exit:
      return i/size;
    else
      ((unsigned char*)ptr)[i]=(unsigned char)res;
  }
  return nmemb;
}
示例#4
0
文件: manager.c 项目: OPSF/uClinux
int attribute_noreturn __pthread_manager(void *arg)
{
  int reqfd = (int) (long int) arg;
#ifdef USE_SELECT
  struct timeval tv;
  fd_set fd;
#else
  struct pollfd ufd;
#endif
  sigset_t manager_mask;
  int n;
  struct pthread_request request;

  /* If we have special thread_self processing, initialize it.  */
#ifdef INIT_THREAD_SELF
  INIT_THREAD_SELF(&__pthread_manager_thread, 1);
#endif
  /* Set the error variable.  */
  __pthread_manager_thread.p_errnop = &__pthread_manager_thread.p_errno;
  __pthread_manager_thread.p_h_errnop = &__pthread_manager_thread.p_h_errno;

#ifdef __UCLIBC_HAS_XLOCALE__
  /* Initialize thread's locale to the global locale. */
  __pthread_manager_thread.locale = __global_locale;
#endif /* __UCLIBC_HAS_XLOCALE__ */

  /* Block all signals except __pthread_sig_cancel and SIGTRAP */
  sigfillset(&manager_mask);
  sigdelset(&manager_mask, __pthread_sig_cancel); /* for thread termination */
  sigdelset(&manager_mask, SIGTRAP);            /* for debugging purposes */
  if (__pthread_threads_debug && __pthread_sig_debug > 0)
      sigdelset(&manager_mask, __pthread_sig_debug);
  sigprocmask(SIG_SETMASK, &manager_mask, NULL);
  /* Raise our priority to match that of main thread */
  __pthread_manager_adjust_prio(__pthread_main_thread->p_priority);
  /* Synchronize debugging of the thread manager */
  n = TEMP_FAILURE_RETRY(__libc_read(reqfd, (char *)&request,
				     sizeof(request)));
#ifndef USE_SELECT
  ufd.fd = reqfd;
  ufd.events = POLLIN;
#endif
  /* Enter server loop */
  while(1) {
#ifdef USE_SELECT
    tv.tv_sec = 2;
    tv.tv_usec = 0;
    FD_ZERO (&fd);
    FD_SET (reqfd, &fd);
    n = select (reqfd + 1, &fd, NULL, NULL, &tv);
#else
    PDEBUG("before poll\n");
    n = poll(&ufd, 1, 2000);
    PDEBUG("after poll\n");
#endif
    /* Check for termination of the main thread */
    if (getppid() == 1) {
      pthread_kill_all_threads(SIGKILL, 0);
      _exit(0);
    }
    /* Check for dead children */
    if (terminated_children) {
      terminated_children = 0;
      pthread_reap_children();
    }
    /* Read and execute request */
#ifdef USE_SELECT
    if (n == 1)
#else
    if (n == 1 && (ufd.revents & POLLIN))
#endif
    {

      PDEBUG("before __libc_read\n");
      n = __libc_read(reqfd, (char *)&request, sizeof(request));
      PDEBUG("after __libc_read, n=%d\n", n);
      switch(request.req_kind) {
      case REQ_CREATE:
        PDEBUG("got REQ_CREATE\n");
        request.req_thread->p_retcode =
          pthread_handle_create((pthread_t *) &request.req_thread->p_retval,
                                request.req_args.create.attr,
                                request.req_args.create.fn,
                                request.req_args.create.arg,
                                &request.req_args.create.mask,
                                request.req_thread->p_pid,
                                request.req_thread->p_report_events,
                                &request.req_thread->p_eventbuf.eventmask);
        PDEBUG("restarting %d\n", request.req_thread);
        restart(request.req_thread);
        break;
      case REQ_FREE:
        PDEBUG("got REQ_FREE\n");
        pthread_handle_free(request.req_args.free.thread_id);
        break;
      case REQ_PROCESS_EXIT:
        PDEBUG("got REQ_PROCESS_EXIT from %d, exit code = %d\n", 
        request.req_thread, request.req_args.exit.code);
        pthread_handle_exit(request.req_thread,
                            request.req_args.exit.code);
        break;
      case REQ_MAIN_THREAD_EXIT:
        PDEBUG("got REQ_MAIN_THREAD_EXIT\n");
        main_thread_exiting = 1;
	/* Reap children in case all other threads died and the signal handler
	   went off before we set main_thread_exiting to 1, and therefore did
	   not do REQ_KICK. */
	pthread_reap_children();

        if (__pthread_main_thread->p_nextlive == __pthread_main_thread) {
          restart(__pthread_main_thread);
	  /* The main thread will now call exit() which will trigger an
	     __on_exit handler, which in turn will send REQ_PROCESS_EXIT
	     to the thread manager. In case you are wondering how the
	     manager terminates from its loop here. */
	}
        break;
      case REQ_POST:
        PDEBUG("got REQ_POST\n");
        __new_sem_post(request.req_args.post);
        break;
      case REQ_DEBUG:
        PDEBUG("got REQ_DEBUG\n");
	/* Make gdb aware of new thread and gdb will restart the
	   new thread when it is ready to handle the new thread. */
	if (__pthread_threads_debug && __pthread_sig_debug > 0) {
      PDEBUG("about to call raise(__pthread_sig_debug)\n");
	  raise(__pthread_sig_debug);
	}
      case REQ_KICK:
	/* This is just a prod to get the manager to reap some
	   threads right away, avoiding a potential delay at shutdown. */
	break;
      }
    }
  }
}