Пример #1
0
void __stack_smash_handler(char func[], int damaged)
{
	extern char *__progname;
	const char message[] = ": stack smashing attack in function ";
	struct sigaction sa;
	sigset_t mask;

	sigfillset(&mask);

	sigdelset(&mask, SSP_SIGTYPE);	/* Block all signal handlers */
	sigprocmask(SIG_BLOCK, &mask, NULL);	/* except SSP_SIGTYPE */

	/* Print error message to stderr and syslog */
#if 1 /* syslog() causes issues with glibc #94325 */
	__libc_write(STDERR_FILENO, __progname, strlen(__progname));
	__libc_write(STDERR_FILENO, message, strlen(message));
	__libc_write(STDERR_FILENO, func, strlen(func));
	__libc_write(STDERR_FILENO, "()\n", 3);
	//_syscall3(int, _ssp_syslog, int, type, char *, bufp, int, len)
	//_ssp_syslog(LOG_INFO,
#else
	fprintf(stderr, "%s%s%s()\n", __progname, message, func);
	syslog(LOG_INFO, "%s%s%s()", __progname, message, func);
#endif

	/* Make the default handler associated with the signal handler */
	memset(&sa, 0, sizeof(struct sigaction));
	sigfillset(&sa.sa_mask);	/* Block all signals */
	sa.sa_flags = 0;
	sa.sa_handler = SIG_DFL;
	sigaction(SSP_SIGTYPE, &sa, NULL);
	(void) kill(getpid(), SSP_SIGTYPE);
	_exit(127);
}
Пример #2
0
int pthread_join(pthread_t th, void **thread_return)
{
	volatile pthread_t self = thread_self();
	struct pthread_request request;

	if (th == self) 
		return EDEADLK;
	
	/* If detached or already joined, error */
	if (th->p_detached || th->p_joining != NULL) {
		return EINVAL;
	}
	
	/* If not terminated yet, suspend ourselves. */
	if (! th->p_terminated) {
		th->p_joining = self;
		suspend(self);
	}

	/* Get return value */
	if (thread_return != NULL) 
		*thread_return = th->p_retval;
	
	/* Send notification to thread manager */
	if (__pthread_manager_request >= 0) {
		request.req_thread = self;
		request.req_kind = REQ_FREE;
		request.req_args.free.thread = th;
		__libc_write(__pthread_manager_request,
			(char *) &request, sizeof(request));
	}
	
	return 0;
}
Пример #3
0
int pthread_detach(pthread_t th)
{
  int terminated;
  struct pthread_request request;

  acquire(&th->p_spinlock);
  /* If already detached, error */
  if (th->p_detached) {
    release(&th->p_spinlock);
    return EINVAL;
  }
  /* If already joining, don't do anything. */
  if (th->p_joining != NULL) {
    release(&th->p_spinlock);
    return 0;
  }
  /* Mark as detached */
  th->p_detached = 1;
  terminated = th->p_terminated;
  release(&th->p_spinlock);
  /* If already terminated, notify thread manager to reclaim resources */
  if (terminated && __pthread_manager_request >= 0) {
    request.req_thread = thread_self();
    request.req_kind = REQ_FREE;
    request.req_args.free.thread = th;
    __libc_write(__pthread_manager_request,
		 (char *) &request, sizeof(request));
  }
  return 0;
}
Пример #4
0
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                   void * (*start_routine)(void *), void *arg)
{
    pthread_descr self = thread_self();
    struct pthread_request request;
    if (__pthread_manager_request < 0) {
        if (__pthread_initialize_manager() < 0) return EAGAIN;
    }
    request.req_thread = self;
    request.req_kind = REQ_CREATE;
    request.req_args.create.attr = attr;
    request.req_args.create.fn = start_routine;
    request.req_args.create.arg = arg;
    sigprocmask(SIG_SETMASK, (const sigset_t *) NULL,
                &request.req_args.create.mask);
    PDEBUG("write REQ_CREATE to manager thread\n");
    TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request,
                                    (char *) &request, sizeof(request)));
    PDEBUG("before suspend(self)\n");
    suspend(self);
    PDEBUG("after suspend(self)\n");
    if (THREAD_GETMEM(self, p_retcode) == 0)
        *thread = (pthread_t) THREAD_GETMEM(self, p_retval);
    return THREAD_GETMEM(self, p_retcode);
}
void
__assert_fail (const char *assertion, const char *file, unsigned int line,
	       const char *function)
{
  char *buf;

#ifdef FATAL_PREPARE
  FATAL_PREPARE;
#endif

  if (__asprintf (&buf, _("%s%s%s:%u: %s%sAssertion `%s' failed.\n"),
		  __progname, __progname[0] ? ": " : "",
		  file, line,
		  function ? function : "", function ? ": " : "",
		  assertion) >= 0)
    {
      /* Print the message.  */
      (void) __fxprintf (NULL, "%s", buf);
      (void) fflush (stderr);

      /* We have to free the old buffer since the application might
	 catch the SIGABRT signal.  */
      char *old = atomic_exchange_acq (&__abort_msg, buf);
      free (old);
    }
  else
    {
      /* At least print a minimal message.  */
      static const char errstr[] = "Unexpected error.\n";
      __libc_write (STDERR_FILENO, errstr, sizeof (errstr) - 1);
    }

  abort ();
}
Пример #6
0
ssize_t
pwrite (int fd, const 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_write (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;
}
Пример #7
0
void pthread_exit(void * retval)
{
  pthread_t self = thread_self();
  pthread_t joining;
  struct pthread_request request;

  /* Reset the cancellation flag to avoid looping if the cleanup handlers
     contain cancellation points */
  self->p_canceled = 0;
  /* Call cleanup functions and destroy the thread-specific data */
  __pthread_perform_cleanup();
  __pthread_destroy_specifics();
  /* Store return value */
  acquire(&self->p_spinlock);
  self->p_retval = retval;
  /* Say that we've terminated */
  self->p_terminated = 1;
  /* See if someone is joining on us */
  joining = self->p_joining;
  release(&self->p_spinlock);
  /* Restart joining thread if any */
  if (joining != NULL) restart(joining);
  /* If this is the initial thread, block until all threads have terminated.
     If another thread calls exit, we'll be terminated from our signal
     handler. */
  if (self == __pthread_main_thread && __pthread_manager_request >= 0) {
    request.req_thread = self;
    request.req_kind = REQ_MAIN_THREAD_EXIT;
    __libc_write(__pthread_manager_request, (char *)&request, sizeof(request));
    suspend(self);
  }
  /* Exit the process (but don't flush stdio streams, and don't run
     atexit functions). */
  _exit(0);
}
void
__assert_perror_fail (int errnum,
		      const char *file, unsigned int line,
		      const char *function)
{
  char errbuf[1024];
  char *buf;

#ifdef FATAL_PREPARE
  FATAL_PREPARE;
#endif

  if (__asprintf (&buf, _("%s%s%s:%u: %s%sUnexpected error: %s.\n"),
		  __progname, __progname[0] ? ": " : "",
		  file, line,
		  function ? function : "", function ? ": " : "",
		  __strerror_r (errnum, errbuf, sizeof errbuf)) >= 0)
    {
      /* Print the message.  */
      (void) __fxprintf (NULL, "%s", buf);
      (void) fflush (stderr);

      /* We have to free the buffer since the appplication might catch the
	 SIGABRT.  */
      free (buf);
    }
  else
    {
      /* At least print a minimal message.  */
      static const char errstr[] = "Unexpected error.\n";
      __libc_write (STDERR_FILENO, errstr, sizeof (errstr) - 1);
    }

  abort ();
}
void __pthread_message(char * fmt, ...)
{
  char buffer[1024];
  va_list args;
  sprintf(buffer, "%05d : ", __getpid());
  va_start(args, fmt);
  vsnprintf(buffer + 8, sizeof(buffer) - 8, fmt, args);
  va_end(args);
  TEMP_FAILURE_RETRY(__libc_write(2, buffer, strlen(buffer)));
}
Пример #10
0
int fputc_unlocked(int c, FILE *stream) {
  if (!__likely(stream->flags&CANWRITE) || __fflush4(stream,0)) {
kaputt:
    stream->flags|=ERRORINDICATOR;
    return EOF;
  }
  if (__unlikely(stream->bm>=stream->buflen-1))
    if (fflush_unlocked(stream)) goto kaputt;
  if (stream->flags&NOBUF) {
#if __BYTE_ORDER == __LITTLE_ENDIAN
    if (__libc_write(stream->fd,&c,1) != 1)
#else
    if (__libc_write(stream->fd,(char*)&c+sizeof(c)-1,1) != 1)
#endif
      goto kaputt;
    return 0;
  }
  stream->buf[stream->bm]=c;
  ++stream->bm;
  if (((stream->flags&BUFLINEWISE) && c=='\n') ||
      ((stream->flags&NOBUF))) /* puke */
    if (fflush_unlocked(stream)) goto kaputt;
  return 0;
}
Пример #11
0
void
__assert_fail_base (const char *fmt, const char *assertion, const char *file,
		    unsigned int line, const char *function)
{
  char *str;

#ifdef FATAL_PREPARE
  FATAL_PREPARE;
#endif

  int total;
  if (__asprintf (&str, fmt,
		  __progname, __progname[0] ? ": " : "",
		  file, line,
		  function ? function : "", function ? ": " : "",
		  assertion, &total) >= 0)
    {
      /* Print the message.  */
      (void) __fxprintf (NULL, "%s", str);
      (void) fflush (stderr);

      total = (total + 1 + GLRO(dl_pagesize) - 1) & ~(GLRO(dl_pagesize) - 1);
      struct abort_msg_s *buf = __mmap (NULL, total, PROT_READ | PROT_WRITE,
					MAP_ANON | MAP_PRIVATE, -1, 0);
      if (__builtin_expect (buf != MAP_FAILED, 1))
	{
	  buf->size = total;
	  strcpy (buf->msg, str);

	  /* We have to free the old buffer since the application might
	     catch the SIGABRT signal.  */
	  struct abort_msg_s *old = atomic_exchange_acq (&__abort_msg, buf);

	  if (old != NULL)
	    __munmap (old, old->size);
	}

      free (str);
    }
  else
    {
      /* At least print a minimal message.  */
      static const char errstr[] = "Unexpected error.\n";
      __libc_write (STDERR_FILENO, errstr, sizeof (errstr) - 1);
    }

  abort ();
}
Пример #12
0
/* Process creation */
static int
attribute_noreturn
pthread_start_thread(void *arg)
{
  pthread_descr self = (pthread_descr) arg;
  struct pthread_request request;
  void * outcome;
  /* Initialize special thread_self processing, if any.  */
#ifdef INIT_THREAD_SELF
  INIT_THREAD_SELF(self, self->p_nr);
#endif
  PDEBUG("\n");
  /* Make sure our pid field is initialized, just in case we get there
     before our father has initialized it. */
  THREAD_SETMEM(self, p_pid, getpid());
  /* Initial signal mask is that of the creating thread. (Otherwise,
     we'd just inherit the mask of the thread manager.) */
  sigprocmask(SIG_SETMASK, &self->p_start_args.mask, NULL);
  /* Set the scheduling policy and priority for the new thread, if needed */
  if (THREAD_GETMEM(self, p_start_args.schedpolicy) >= 0)
    /* Explicit scheduling attributes were provided: apply them */
    sched_setscheduler(THREAD_GETMEM(self, p_pid),
			 THREAD_GETMEM(self, p_start_args.schedpolicy),
                         &self->p_start_args.schedparam);
  else if (__pthread_manager_thread.p_priority > 0)
    /* Default scheduling required, but thread manager runs in realtime
       scheduling: switch new thread to SCHED_OTHER policy */
    {
      struct sched_param default_params;
      default_params.sched_priority = 0;
      sched_setscheduler(THREAD_GETMEM(self, p_pid),
                           SCHED_OTHER, &default_params);
    }
  /* Make gdb aware of new thread */
  if (__pthread_threads_debug && __pthread_sig_debug > 0) {
    request.req_thread = self;
    request.req_kind = REQ_DEBUG;
    TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request,
		(char *) &request, sizeof(request)));
    suspend(self);
  }
  /* Run the thread code */
  outcome = self->p_start_args.start_routine(THREAD_GETMEM(self,
							   p_start_args.arg));
  /* Exit with the given return value */
  __pthread_do_exit(outcome, CURRENT_STACK_FRAME);
}
Пример #13
0
void __pthread_manager_sighandler(int sig attribute_unused)
{
    int kick_manager = terminated_children == 0 && main_thread_exiting;
    terminated_children = 1;

    /* If the main thread is terminating, kick the thread manager loop
       each time some threads terminate. This eliminates a two second
       shutdown delay caused by the thread manager sleeping in the
       call to __poll(). Instead, the thread manager is kicked into
       action, reaps the outstanding threads and resumes the main thread
       so that it can complete the shutdown. */

    if (kick_manager) {
	struct pthread_request request;
	request.req_thread = 0;
	request.req_kind = REQ_KICK;
	TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request,
		    (char *) &request, sizeof(request)));
    }
}
Пример #14
0
/* Delete a key */
int pthread_key_delete(pthread_key_t key)
{
  pthread_descr self = thread_self();

  pthread_mutex_lock(&pthread_keys_mutex);
  if (key >= PTHREAD_KEYS_MAX || !pthread_keys[key].in_use) {
    pthread_mutex_unlock(&pthread_keys_mutex);
    return EINVAL;
  }
  pthread_keys[key].in_use = 0;
  pthread_keys[key].destr = NULL;

  /* Set the value of the key to NULL in all running threads, so
     that if the key is reallocated later by pthread_key_create, its
     associated values will be NULL in all threads.

     Do nothing if no threads have been created yet.  */

  if (__pthread_manager_request != -1)
    {
      struct pthread_key_delete_helper_args args;
      struct pthread_request request;

      args.idx1st = key / PTHREAD_KEY_2NDLEVEL_SIZE;
      args.idx2nd = key % PTHREAD_KEY_2NDLEVEL_SIZE;
      args.self = 0;

      request.req_thread = self;
      request.req_kind = REQ_FOR_EACH_THREAD;
      request.req_args.for_each.arg = &args;
      request.req_args.for_each.fn = pthread_key_delete_helper;

      TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request,
				      (char *) &request, sizeof(request)));
      suspend(self);
    }

  pthread_mutex_unlock(&pthread_keys_mutex);
  return 0;
}
Пример #15
0
int __new_sem_post(sem_t * sem)
{
  pthread_descr self = thread_self();
  pthread_descr th;
  struct pthread_request request;

  if (THREAD_GETMEM(self, p_in_sighandler) == NULL) {
    __pthread_lock(&sem->__sem_lock, self);
    if (sem->__sem_waiting == NULL) {
      if (sem->__sem_value >= SEM_VALUE_MAX) {
        /* Overflow */
        errno = ERANGE;
        __pthread_unlock(&sem->__sem_lock);
        return -1;
      }
      sem->__sem_value++;
      __pthread_unlock(&sem->__sem_lock);
    } else {
      th = dequeue(&sem->__sem_waiting);
      __pthread_unlock(&sem->__sem_lock);
      th->p_sem_avail = 1;
      WRITE_MEMORY_BARRIER();
      restart(th);
    }
  } else {
    /* If we're in signal handler, delegate post operation to
       the thread manager. */
    if (__pthread_manager_request < 0) {
      if (__pthread_initialize_manager() < 0) {
        errno = EAGAIN;
        return -1;
      }
    }
    request.req_kind = REQ_POST;
    request.req_args.post = sem;
    TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request,
				    (char *) &request, sizeof(request)));
  }
  return 0;
}
Пример #16
0
void
__assert_fail (const char *assertion, const char *file, unsigned int line,
	       const char *function)
{
  char *buf;

#ifdef FATAL_PREPARE
  FATAL_PREPARE;
#endif

  if (__asprintf (&buf, _("%s%s%s:%u: %s%sAssertion `%s' failed.\n"),
		  __progname, __progname[0] ? ": " : "",
		  file, line,
		  function ? function : "", function ? ": " : "",
		  assertion) >= 0)
    {
      /* Print the message.  */
#ifdef USE_IN_LIBIO
      if (_IO_fwide (stderr, 0) > 0)
	(void) __fwprintf (stderr, L"%s", buf);
      else
#endif
	(void) fputs (buf, stderr);

      (void) fflush (stderr);

      /* We have to free the buffer since the application might catch the
	 SIGABRT.  */
      free (buf);
    }
  else
    {
      /* At least print a minimal message.  */
      static const char errstr[] = "Unexpected error.\n";
      __libc_write (STDERR_FILENO, errstr, sizeof (errstr) - 1);
    }

  abort ();
}
static void pthread_onexit_process(int retcode, void *arg)
{
    struct pthread_request request;
    pthread_descr self = thread_self();

    if (__pthread_manager_request >= 0) {
	request.req_thread = self;
	request.req_kind = REQ_PROCESS_EXIT;
	request.req_args.exit.code = retcode;
	TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request,
		    (char *) &request, sizeof(request)));
	suspend(self);
	/* Main thread should accumulate times for thread manager and its
	   children, so that timings for main thread account for all threads. */
	if (self == __pthread_main_thread) {
	    waitpid(__pthread_manager_thread.p_pid, NULL, __WCLONE);
	    /* Since all threads have been asynchronously terminated
	     * (possibly holding locks), free cannot be used any more.  */
	    __pthread_manager_thread_bos = __pthread_manager_thread_tos = NULL;
	}
    }
}
Пример #18
0
int pthread_join(pthread_t th, void ** thread_return)
{
  volatile pthread_t self = thread_self();
  struct pthread_request request;

  if (th == self) return EDEADLK;
  acquire(&th->p_spinlock);
  /* If detached or already joined, error */
  if (th->p_detached || th->p_joining != NULL) {
    release(&th->p_spinlock);
    return EINVAL;
  }
  /* If not terminated yet, suspend ourselves. */
  if (! th->p_terminated) {
    th->p_joining = self;
    release(&th->p_spinlock);
    suspend_with_cancellation(self);
    acquire(&th->p_spinlock);
    /* This is a cancellation point */
    if (self->p_canceled && self->p_cancelstate == PTHREAD_CANCEL_ENABLE) {
      th->p_joining = NULL;
      release(&th->p_spinlock);
      pthread_exit(PTHREAD_CANCELED);
    }
  }
  /* Get return value */
  if (thread_return != NULL) *thread_return = th->p_retval;
  release(&th->p_spinlock);
  /* Send notification to thread manager */
  if (__pthread_manager_request >= 0) {
    request.req_thread = self;
    request.req_kind = REQ_FREE;
    request.req_args.free.thread = th;
    __libc_write(__pthread_manager_request,
		 (char *) &request, sizeof(request));
  }
  return 0;
}
Пример #19
0
int pthread_detach(pthread_t thread_id)
{
  int terminated;
  struct pthread_request request;
  pthread_handle handle = thread_handle(thread_id);
  pthread_descr th;

  __pthread_lock(&handle->h_lock, NULL);
  if (invalid_handle(handle, thread_id)) {
    __pthread_unlock(&handle->h_lock);
    return ESRCH;
  }
  th = handle->h_descr;
  /* If already detached, error */
  if (th->p_detached) {
    __pthread_unlock(&handle->h_lock);
    return EINVAL;
  }
  /* If already joining, don't do anything. */
  if (th->p_joining != NULL) {
    __pthread_unlock(&handle->h_lock);
    return 0;
  }
  /* Mark as detached */
  th->p_detached = 1;
  terminated = th->p_terminated;
  __pthread_unlock(&handle->h_lock);
  /* If already terminated, notify thread manager to reclaim resources */
  if (terminated && __pthread_manager_request >= 0) {
    request.req_thread = thread_self();
    request.req_kind = REQ_FREE;
    request.req_args.free.thread_id = thread_id;
    TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request,
		(char *) &request, sizeof(request)));
  }
  return 0;
}
Пример #20
0
int __pthread_create_2_1(pthread_t *thread, const pthread_attr_t *attr,
			 void * (*start_routine)(void *), void *arg)
{
  pthread_descr self = thread_self();
  struct pthread_request request;
  int retval;
  if (__builtin_expect (__pthread_manager_request, 0) < 0) {
    if (__pthread_initialize_manager() < 0) return EAGAIN;
  }
  request.req_thread = self;
  request.req_kind = REQ_CREATE;
  request.req_args.create.attr = attr;
  request.req_args.create.fn = start_routine;
  request.req_args.create.arg = arg;
  sigprocmask(SIG_SETMASK, (const sigset_t *) NULL,
              &request.req_args.create.mask);
  TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request,
				  (char *) &request, sizeof(request)));
  suspend(self);
  retval = THREAD_GETMEM(self, p_retcode);
  if (__builtin_expect (retval, 0) == 0)
    *thread = (pthread_t) THREAD_GETMEM(self, p_retval);
  return retval;
}
ssize_t write(int fd, const void *buf, size_t count) {
  __TEST_CANCEL();
  return __libc_write(fd,buf,count);
}
Пример #22
0
void __libc_vsyslog(int priority, const char *format, va_list arg_ptr)
{
  char buffer[BUF_SIZE];
  char time_buf[20];
  int buflen, headerlen;
  time_t now;
  struct tm now_tm;
  pid_t pid;
  int fd;
  int sigpipe;
  struct sigaction action, oldaction;
  int saved_errno = errno;

  /* check for invalid priority/facility bits */
  if (priority & ~(LOG_PRIMASK|LOG_FACMASK)) {
    syslog(LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID, "syslog: unknown facility/priorityority: %x", priority);
    priority &= LOG_PRIMASK|LOG_FACMASK;
  }

  /* check priority against setlogmask */
  if ((LOG_MASK(LOG_PRI(priority)) && LogMask) == 0) return;

  /* Set default facility if none specified. */
  if ((priority & LOG_FACMASK) == 0) priority |= LogFacility;

  pid = getpid();
  time(&now);
  strftime(time_buf, 20, "%h %e %T", localtime_r (&now, &now_tm));

  if (LogStat & LOG_PID)
    headerlen = snprintf(buffer, 130, "<%d>%s %s[%ld]: ", priority, time_buf, LogTag, (long) pid);
  else
    headerlen = snprintf(buffer, 130, "<%d>%s %s: ", priority, time_buf, LogTag);

  if (!LogTag[0]) {
    if ((LogStat & LOG_PID) != LOG_PID)
      headerlen = snprintf(buffer, 130, "<%d>%s (unknown)[%ld]: ", priority, time_buf, (long) pid);
    strcat(buffer+headerlen, "syslog without openlog w/ ident, please check code!");
    buflen = 41;
  }
  else {
    errno=saved_errno;
    buflen = vsnprintf(buffer+headerlen, BUF_SIZE - headerlen, format, arg_ptr);
  }
  if (LogStat & LOG_PERROR) {
    __libc_write(1, buffer+headerlen, buflen);
    if (buffer[headerlen+buflen] != '\n') __libc_write(1,"\n", 1);
  }

  /* prepare for broken connection */
  memset(&action, 0, sizeof(action));
  action.sa_handler = SIG_IGN;
  sigemptyset(&action.sa_mask);

  sigpipe = sigaction (SIGPIPE, &action, &oldaction);

  if (!connected) openlog_intern(LogStat | LOG_NDELAY, 0);

  /* If we have a SOCK_STREAM connection, also send ASCII NUL as a
   * record terminator. */
  if (LogType == SOCK_STREAM) buflen++;

  if (!connected || (send(LogFile, buffer, buflen+headerlen, 0) != buflen+headerlen)) {
    if (LogType == SOCK_STREAM) buflen--;
    closelog_intern();
    /*
     * Output the message to the console; don't worry about blocking,
     * if console blocks everything will.  Make sure the error reported
     * is the one from the syslogd failure.
     */
    if ((LogStat & LOG_CONS) &&
       ((fd = __libc_open(_PATH_CONSOLE, O_WRONLY|O_NOCTTY, 0)) >= 0))
    {
      __libc_write(fd, buffer, buflen+headerlen);
      __libc_write(fd, "\r\n", 2);
      __libc_close(fd);
    }
  }

  if (sigpipe == 0)
    sigaction(SIGPIPE, &oldaction, (struct sigaction *) NULL);
}
Пример #23
0
int __pthread_initialize_manager(void)
{
    int manager_pipe[2];
    int pid;
    int report_events;
    struct pthread_request request;

    *__libc_multiple_threads_ptr = 1;

    /* If basic initialization not done yet (e.g. we're called from a
       constructor run before our constructor), do it now */
    if (__pthread_initial_thread_bos == NULL) pthread_initialize();
    /* Setup stack for thread manager */
    __pthread_manager_thread_bos = malloc(THREAD_MANAGER_STACK_SIZE);
    if (__pthread_manager_thread_bos == NULL) return -1;
    __pthread_manager_thread_tos =
        __pthread_manager_thread_bos + THREAD_MANAGER_STACK_SIZE;

    /* On non-MMU systems we make sure that the initial thread bounds don't overlap
     * with the manager stack frame */
    NOMMU_INITIAL_THREAD_BOUNDS(__pthread_manager_thread_tos,__pthread_manager_thread_bos);
    PDEBUG("manager stack: size=%d, bos=%p, tos=%p\n", THREAD_MANAGER_STACK_SIZE,
           __pthread_manager_thread_bos, __pthread_manager_thread_tos);
#if 0
    PDEBUG("initial stack: estimate bos=%p, tos=%p\n",
           __pthread_initial_thread_bos, __pthread_initial_thread_tos);
#endif

    /* Setup pipe to communicate with thread manager */
    if (pipe(manager_pipe) == -1) {
        free(__pthread_manager_thread_bos);
        return -1;
    }
    /* Start the thread manager */
    pid = 0;
#ifdef USE_TLS
    if (__linuxthreads_initial_report_events != 0)
        THREAD_SETMEM (((pthread_descr) NULL), p_report_events,
                       __linuxthreads_initial_report_events);
    report_events = THREAD_GETMEM (((pthread_descr) NULL), p_report_events);
#else
    if (__linuxthreads_initial_report_events != 0)
        __pthread_initial_thread.p_report_events
            = __linuxthreads_initial_report_events;
    report_events = __pthread_initial_thread.p_report_events;
#endif
    if (__builtin_expect (report_events, 0))
    {
        /* It's a bit more complicated.  We have to report the creation of
        the manager thread.  */
        int idx = __td_eventword (TD_CREATE);
        uint32_t mask = __td_eventmask (TD_CREATE);

        if ((mask & (__pthread_threads_events.event_bits[idx]
                     | __pthread_initial_thread.p_eventbuf.eventmask.event_bits[idx]))
                != 0)
        {

            __pthread_lock(__pthread_manager_thread.p_lock, NULL);

#ifdef __ia64__
            pid = __clone2(__pthread_manager_event,
                           (void **) __pthread_manager_thread_tos,
                           THREAD_MANAGER_STACK_SIZE,
                           CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
                           (void *)(long)manager_pipe[0]);
#else
            pid = clone(__pthread_manager_event,
                        (void **) __pthread_manager_thread_tos,
                        CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
                        (void *)(long)manager_pipe[0]);
#endif

            if (pid != -1)
            {
                /* Now fill in the information about the new thread in
                   the newly created thread's data structure.  We cannot let
                   the new thread do this since we don't know whether it was
                   already scheduled when we send the event.  */
                __pthread_manager_thread.p_eventbuf.eventdata =
                    &__pthread_manager_thread;
                __pthread_manager_thread.p_eventbuf.eventnum = TD_CREATE;
                __pthread_last_event = &__pthread_manager_thread;
                __pthread_manager_thread.p_tid = 2* PTHREAD_THREADS_MAX + 1;
                __pthread_manager_thread.p_pid = pid;

                /* Now call the function which signals the event.  */
                __linuxthreads_create_event ();
            }
            /* Now restart the thread.  */
            __pthread_unlock(__pthread_manager_thread.p_lock);
        }
    }

    if (pid == 0) {
#ifdef __ia64__
        pid = __clone2(__pthread_manager, (void **) __pthread_manager_thread_tos,
                       THREAD_MANAGER_STACK_SIZE,
                       CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
                       (void *)(long)manager_pipe[0]);
#else
        pid = clone(__pthread_manager, (void **) __pthread_manager_thread_tos,
                    CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
                    (void *)(long)manager_pipe[0]);
#endif
    }
    if (pid == -1) {
        free(__pthread_manager_thread_bos);
        __libc_close(manager_pipe[0]);
        __libc_close(manager_pipe[1]);
        return -1;
    }
    __pthread_manager_request = manager_pipe[1]; /* writing end */
    __pthread_manager_reader = manager_pipe[0]; /* reading end */
    __pthread_manager_thread.p_tid = 2* PTHREAD_THREADS_MAX + 1;
    __pthread_manager_thread.p_pid = pid;

    /* Make gdb aware of new thread manager */
    if (__pthread_threads_debug && __pthread_sig_debug > 0)
    {
        raise(__pthread_sig_debug);
        /* We suspend ourself and gdb will wake us up when it is
        ready to handle us. */
        __pthread_wait_for_restart_signal(thread_self());
    }
    /* Synchronize debugging of the thread manager */
    PDEBUG("send REQ_DEBUG to manager thread\n");
    request.req_kind = REQ_DEBUG;
    TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request,
                                    (char *) &request, sizeof(request)));
    return 0;
}
Пример #24
0
size_t fwrite_unlocked(const void *ptr, size_t size, size_t nmemb, FILE *stream) {
  ssize_t res;
  size_t len=size*nmemb;
  size_t i,done;
  if (!__likely(stream->flags&CANWRITE) || __fflush4(stream,0)) {
kaputt:
    stream->flags|=ERRORINDICATOR;
    return 0;
  }
  if (!nmemb || len/nmemb!=size) return 0; /* check for integer overflow */
  if (__unlikely(len>stream->buflen || (stream->flags&NOBUF))) {
    if (fflush_unlocked(stream)) return 0;
    do {
      res=__libc_write(stream->fd,ptr,len);
    } while (res==-1 && errno==EINTR);
  } else
again:
         {
    /* try to make the common case fast */
    size_t todo=stream->buflen-stream->bm;
    if (todo>len) todo=len;

    if (todo) {
      if (stream->flags&BUFLINEWISE) {
	if (__unlikely((stream->flags&CHECKLINEWISE)!=0)) {
	  stream->flags&=~CHECKLINEWISE;
	  /* stdout is set to BUFLINEWISE|CHECKLINEWISE by default. */
	  /* that means we should check whether it is connected to a
	   * tty on first flush, and if not so, reset BUFLINEWISE */
	  if (!isatty(stream->fd)) {
	    stream->flags&=~BUFLINEWISE;
	    goto notlinewise;
	  }
	}
	for (i=0; i<todo; ++i) {
	  if ((stream->buf[stream->bm++]=((char*)ptr)[i])=='\n') {
	    if (fflush_unlocked(stream)) goto kaputt;
	  }
	}
      } else {
notlinewise:
	memcpy(stream->buf+stream->bm,ptr,todo);
	stream->bm+=todo;
	if (stream->bm==stream->buflen) {
	  if (fflush_unlocked(stream)) return 0;
	  /* if we are here, we should not have an empty buffer */
	  len-=todo;
	  if (!len) return nmemb;
	  ptr+=todo;
	  goto again;
	} else
	  return nmemb;
      }
      done=todo;
    } else
      done=0;
    for (i=done; i<len; ++i)
      if (fputc_unlocked(((char*)ptr)[i],stream) == EOF) {
	res=len-i;
	goto abort;
      }
    res=len;
  }
  if (res<0) {
    stream->flags|=ERRORINDICATOR;
    return 0;
  }
abort:
  return size?res/size:0;
}
Пример #25
0
int pthread_join(pthread_t thread_id, void ** thread_return)
{
  volatile pthread_descr self = thread_self();
  struct pthread_request request;
  pthread_handle handle = thread_handle(thread_id);
  pthread_descr th;
  pthread_extricate_if extr;
  int already_canceled = 0;
  PDEBUG("\n");

  /* Set up extrication interface */
  extr.pu_object = handle;
  extr.pu_extricate_func = join_extricate_func;

  __pthread_lock(&handle->h_lock, self);
  if (invalid_handle(handle, thread_id)) {
    __pthread_unlock(&handle->h_lock);
    return ESRCH;
  }
  th = handle->h_descr;
  if (th == self) {
    __pthread_unlock(&handle->h_lock);
    return EDEADLK;
  }
  /* If detached or already joined, error */
  if (th->p_detached || th->p_joining != NULL) {
    __pthread_unlock(&handle->h_lock);
    return EINVAL;
  }
  /* If not terminated yet, suspend ourselves. */
  if (! th->p_terminated) {
    /* Register extrication interface */
    __pthread_set_own_extricate_if(self, &extr);
    if (!(THREAD_GETMEM(self, p_canceled)
	&& THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE))
      th->p_joining = self;
    else
      already_canceled = 1;
    __pthread_unlock(&handle->h_lock);

    if (already_canceled) {
      __pthread_set_own_extricate_if(self, 0);
      __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME);
    }

  PDEBUG("before suspend\n");
    suspend(self);
  PDEBUG("after suspend\n");
    /* Deregister extrication interface */
    __pthread_set_own_extricate_if(self, 0);

    /* This is a cancellation point */
    if (THREAD_GETMEM(self, p_woken_by_cancel)
	&& THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) {
      THREAD_SETMEM(self, p_woken_by_cancel, 0);
      __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME);
    }
    __pthread_lock(&handle->h_lock, self);
  }
  /* Get return value */
  if (thread_return != NULL) *thread_return = th->p_retval;
  __pthread_unlock(&handle->h_lock);
  /* Send notification to thread manager */
  if (__pthread_manager_request >= 0) {
    request.req_thread = self;
    request.req_kind = REQ_FREE;
    request.req_args.free.thread_id = thread_id;
    TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request,
		(char *) &request, sizeof(request)));
  }
  return 0;
}
Пример #26
0
void __pthread_do_exit(void *retval, char *currentframe)
{
  pthread_descr self = thread_self();
  pthread_descr joining;
  struct pthread_request request;
  PDEBUG("self=%p, pid=%d\n", self, self->p_pid);

  /* obey POSIX behavior and prevent cancellation functions from
   * being called more than once.
   * http://sourceware.org/ml/libc-ports/2006-10/msg00043.html
   */
  THREAD_SETMEM(self, p_cancelstate, PTHREAD_CANCEL_DISABLE);
  THREAD_SETMEM(self, p_canceltype, PTHREAD_CANCEL_DEFERRED);

  /* Call cleanup functions and destroy the thread-specific data */
  __pthread_perform_cleanup(currentframe);
  __pthread_destroy_specifics();
  /* Store return value */
  __pthread_lock(THREAD_GETMEM(self, p_lock), self);
  THREAD_SETMEM(self, p_retval, retval);
  /* See whether we have to signal the death.  */
  if (THREAD_GETMEM(self, p_report_events))
    {
      /* See whether TD_DEATH is in any of the mask.  */
      int idx = __td_eventword (TD_DEATH);
      uint32_t mask = __td_eventmask (TD_DEATH);

      if ((mask & (__pthread_threads_events.event_bits[idx]
		   | THREAD_GETMEM_NC(self,
				   p_eventbuf.eventmask).event_bits[idx]))
	  != 0)
	{
	  /* Yep, we have to signal the death.  */
	  THREAD_SETMEM(self, p_eventbuf.eventnum, TD_DEATH);
	  THREAD_SETMEM(self, p_eventbuf.eventdata, self);
	  __pthread_last_event = self;

	  /* Now call the function to signal the event.  */
	  __linuxthreads_death_event();
	}
    }
  /* Say that we've terminated */
  THREAD_SETMEM(self, p_terminated, 1);
  /* See if someone is joining on us */
  joining = THREAD_GETMEM(self, p_joining);
  PDEBUG("joining = %p, pid=%d\n", joining, joining->p_pid);
  __pthread_unlock(THREAD_GETMEM(self, p_lock));
  /* Restart joining thread if any */
  if (joining != NULL) restart(joining);
  /* If this is the initial thread, block until all threads have terminated.
     If another thread calls exit, we'll be terminated from our signal
     handler. */
  if (self == __pthread_main_thread && __pthread_manager_request >= 0) {
    request.req_thread = self;
    request.req_kind = REQ_MAIN_THREAD_EXIT;
    TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request,
		(char *)&request, sizeof(request)));
    suspend(self);
    /* Main thread flushes stdio streams and runs atexit functions.
     * It also calls a handler within LinuxThreads which sends a process exit
     * request to the thread manager. */
    exit(0);
  }
  /* Exit the process (but don't flush stdio streams, and don't run
     atexit functions). */
  _exit(0);
}
Пример #27
0
int __pthread_initialize_manager(void)
{
  int manager_pipe[2];
  int pid;
  struct pthread_request request;

#ifndef HAVE_Z_NODELETE
  if (__builtin_expect (&__dso_handle != NULL, 1))
    __cxa_atexit ((void (*) (void *)) pthread_atexit_retcode, NULL,
		  __dso_handle);
#endif

  if (__pthread_max_stacksize == 0)
    __pthread_init_max_stacksize ();
  /* If basic initialization not done yet (e.g. we're called from a
     constructor run before our constructor), do it now */
  if (__pthread_initial_thread_bos == NULL) pthread_initialize();
  /* Setup stack for thread manager */
  __pthread_manager_thread_bos = malloc(THREAD_MANAGER_STACK_SIZE);
  if (__pthread_manager_thread_bos == NULL) return -1;
  __pthread_manager_thread_tos =
    __pthread_manager_thread_bos + THREAD_MANAGER_STACK_SIZE;
  /* Setup pipe to communicate with thread manager */
  if (__libc_pipe(manager_pipe) == -1) {
    free(__pthread_manager_thread_bos);
    return -1;
  }
  /* Start the thread manager */
  pid = 0;
  if (__builtin_expect (__pthread_initial_thread.p_report_events, 0))
    {
      /* It's a bit more complicated.  We have to report the creation of
	 the manager thread.  */
      int idx = __td_eventword (TD_CREATE);
      uint32_t mask = __td_eventmask (TD_CREATE);

      if ((mask & (__pthread_threads_events.event_bits[idx]
		   | __pthread_initial_thread.p_eventbuf.eventmask.event_bits[idx]))
	  != 0)
	{
	  __pthread_lock(__pthread_manager_thread.p_lock, NULL);

#ifdef NEED_SEPARATE_REGISTER_STACK
	  pid = __clone2(__pthread_manager_event,
			 (void **) __pthread_manager_thread_bos,
			 THREAD_MANAGER_STACK_SIZE,
			 CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
			 (void *)(long)manager_pipe[0]);
#elif _STACK_GROWS_UP
	  pid = __clone(__pthread_manager_event,
			(void **) __pthread_manager_thread_bos,
			CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
			(void *)(long)manager_pipe[0]);
#else
	  pid = __clone(__pthread_manager_event,
			(void **) __pthread_manager_thread_tos,
			CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
			(void *)(long)manager_pipe[0]);
#endif

	  if (pid != -1)
	    {
	      /* Now fill in the information about the new thread in
	         the newly created thread's data structure.  We cannot let
	         the new thread do this since we don't know whether it was
	         already scheduled when we send the event.  */
	      __pthread_manager_thread.p_eventbuf.eventdata =
		&__pthread_manager_thread;
	      __pthread_manager_thread.p_eventbuf.eventnum = TD_CREATE;
	      __pthread_last_event = &__pthread_manager_thread;
	      __pthread_manager_thread.p_tid = 2* PTHREAD_THREADS_MAX + 1;
	      __pthread_manager_thread.p_pid = pid;

	      /* Now call the function which signals the event.  */
	      __linuxthreads_create_event ();
	    }

	  /* Now restart the thread.  */
	  __pthread_unlock(__pthread_manager_thread.p_lock);
	}
    }

  if (__builtin_expect (pid, 0) == 0)
    {
#ifdef NEED_SEPARATE_REGISTER_STACK
      pid = __clone2(__pthread_manager, (void **) __pthread_manager_thread_bos,
		     THREAD_MANAGER_STACK_SIZE,
		     CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
		     (void *)(long)manager_pipe[0]);
#elif _STACK_GROWS_UP
      pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_bos,
		    CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
		    (void *)(long)manager_pipe[0]);
#else
      pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_tos,
		    CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
		    (void *)(long)manager_pipe[0]);
#endif
    }
  if (__builtin_expect (pid, 0) == -1) {
    free(__pthread_manager_thread_bos);
    __libc_close(manager_pipe[0]);
    __libc_close(manager_pipe[1]);
    return -1;
  }
  __pthread_manager_request = manager_pipe[1]; /* writing end */
  __pthread_manager_reader = manager_pipe[0]; /* reading end */
  __pthread_manager_thread.p_tid = 2* PTHREAD_THREADS_MAX + 1;
  __pthread_manager_thread.p_pid = pid;
  /* Make gdb aware of new thread manager */
  if (__builtin_expect (__pthread_threads_debug, 0) && __pthread_sig_debug > 0)
    {
      raise(__pthread_sig_debug);
      /* We suspend ourself and gdb will wake us up when it is
	 ready to handle us. */
      __pthread_wait_for_restart_signal(thread_self());
    }
  /* Synchronize debugging of the thread manager */
  request.req_kind = REQ_DEBUG;
  TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request,
				  (char *) &request, sizeof(request)));
  return 0;
}
Пример #28
0
void
__nptl_main (void)
{
  __libc_write (STDOUT_FILENO, banner, sizeof banner - 1);
  _exit (0);
}