static int pthread_initialize_manager(void) { int manager_pipe[2]; /* 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 (pipe(manager_pipe) == -1) { free(__pthread_manager_thread_bos); return -1; } __pthread_manager_request = manager_pipe[1]; /* writing end */ __pthread_manager_reader = manager_pipe[0]; /* reading end */ /* Start the thread manager */ if (__clone(__pthread_manager, __pthread_manager_thread_tos, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)(long)manager_pipe[0]) == -1) { free(__pthread_manager_thread_bos); __libc_close(manager_pipe[0]); __libc_close(manager_pipe[1]); __pthread_manager_request = -1; return -1; } return 0; }
FILE*__stdio_init_file(int fd,int closeonerror,int mode) { FILE *tmp=(FILE*)malloc(sizeof(FILE)); if (!tmp) goto err_out; tmp->buf=(char*)malloc(BUFSIZE); if (!tmp->buf) { free(tmp); err_out: if (closeonerror) __libc_close(fd); errno=ENOMEM; return 0; } tmp->fd=fd; tmp->bm=0; tmp->bs=0; tmp->buflen=BUFSIZE; { struct stat st; fstat(fd,&st); tmp->flags=(S_ISFIFO(st.st_mode))?FDPIPE:0; } switch (mode&3) { case O_RDWR: tmp->flags|=CANWRITE; /* fall through */ case O_RDONLY: tmp->flags|=CANREAD|BUFINPUT; break; case O_WRONLY: tmp->flags|=CANWRITE; } tmp->popen_kludge=0; if (__stdio_atexit==0) { __stdio_atexit=1; atexit(__stdio_flushall); } tmp->next=__stdio_root; __stdio_root=tmp; tmp->ungotten=0; return tmp; }
static void openlog_intern(int option, int facility) { LogStat = option; if (facility && ((facility & ~LOG_FACMASK) == 0)) LogFacility = facility; /* yep, there is a continue inside ;) */ while(1) { if (LogFile == -1) { SyslogAddr.sa_family = AF_UNIX; strncpy(SyslogAddr.sa_data, _PATH_LOG, sizeof(SyslogAddr.sa_data)); if (LogStat & LOG_NDELAY) { if ((LogFile = socket(AF_UNIX, LogType, 0)) == -1) return; __libc_fcntl(LogFile, F_SETFD, 1); } } if ((LogFile != -1) && !connected) { int old_errno=errno; if(connect(LogFile, &SyslogAddr, sizeof(SyslogAddr)) == -1) { int saved_errno=errno; __libc_close(LogFile); LogFile = -1; if((LogType == SOCK_DGRAM) && (saved_errno == EPROTOTYPE)) { /* retry with SOCK_STREAM instead of SOCK_DGRAM */ LogType = SOCK_STREAM; errno=old_errno; continue; } } else connected = 1; } break; } }
static void closelog_intern(void) { if (!connected) return; __libc_close(LogFile); LogFile = -1; connected = 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; } }
void __pthread_reset_main_thread() { pthread_descr self = thread_self(); if (__pthread_manager_request != -1) { /* Free the thread manager stack */ free(__pthread_manager_thread_bos); __pthread_manager_thread_bos = __pthread_manager_thread_tos = NULL; /* Close the two ends of the pipe */ __libc_close(__pthread_manager_request); __libc_close(__pthread_manager_reader); __pthread_manager_request = __pthread_manager_reader = -1; } /* Update the pid of the main thread */ THREAD_SETMEM(self, p_pid, __getpid()); /* Make the forked thread the main thread */ __pthread_main_thread = self; THREAD_SETMEM(self, p_nextlive, self); THREAD_SETMEM(self, p_prevlive, self); /* Now this thread modifies the global variables. */ THREAD_SETMEM(self, p_errnop, &_errno); THREAD_SETMEM(self, p_h_errnop, &_h_errno); }
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; }
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; }
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); }