Index: head/contrib/jemalloc/include/jemalloc/internal/mutex.h =================================================================== --- head/contrib/jemalloc/include/jemalloc/internal/mutex.h (revision 276629) +++ head/contrib/jemalloc/include/jemalloc/internal/mutex.h (revision 276630) @@ -1,96 +1,97 @@ /******************************************************************************/ #ifdef JEMALLOC_H_TYPES typedef struct malloc_mutex_s malloc_mutex_t; #ifdef _WIN32 # define MALLOC_MUTEX_INITIALIZER #elif (defined(JEMALLOC_OSSPIN)) # define MALLOC_MUTEX_INITIALIZER {0} #elif (defined(JEMALLOC_MUTEX_INIT_CB)) # define MALLOC_MUTEX_INITIALIZER {PTHREAD_MUTEX_INITIALIZER, NULL} #else # if (defined(PTHREAD_MUTEX_ADAPTIVE_NP) && \ defined(PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP)) # define MALLOC_MUTEX_TYPE PTHREAD_MUTEX_ADAPTIVE_NP # define MALLOC_MUTEX_INITIALIZER {PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP} # else # define MALLOC_MUTEX_TYPE PTHREAD_MUTEX_DEFAULT # define MALLOC_MUTEX_INITIALIZER {PTHREAD_MUTEX_INITIALIZER} # endif #endif #endif /* JEMALLOC_H_TYPES */ /******************************************************************************/ #ifdef JEMALLOC_H_STRUCTS struct malloc_mutex_s { #ifdef _WIN32 CRITICAL_SECTION lock; #elif (defined(JEMALLOC_OSSPIN)) OSSpinLock lock; #elif (defined(JEMALLOC_MUTEX_INIT_CB)) pthread_mutex_t lock; malloc_mutex_t *postponed_next; #else pthread_mutex_t lock; #endif }; #endif /* JEMALLOC_H_STRUCTS */ /******************************************************************************/ #ifdef JEMALLOC_H_EXTERNS #ifdef JEMALLOC_LAZY_LOCK extern bool isthreaded; #endif bool malloc_mutex_init(malloc_mutex_t *mutex); void malloc_mutex_prefork(malloc_mutex_t *mutex); void malloc_mutex_postfork_parent(malloc_mutex_t *mutex); void malloc_mutex_postfork_child(malloc_mutex_t *mutex); +bool malloc_mutex_first_thread(void); bool mutex_boot(void); #endif /* JEMALLOC_H_EXTERNS */ /******************************************************************************/ #ifdef JEMALLOC_H_INLINES #ifndef JEMALLOC_ENABLE_INLINE void malloc_mutex_lock(malloc_mutex_t *mutex); void malloc_mutex_unlock(malloc_mutex_t *mutex); #endif #if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_MUTEX_C_)) JEMALLOC_INLINE void malloc_mutex_lock(malloc_mutex_t *mutex) { if (isthreaded) { #ifdef _WIN32 EnterCriticalSection(&mutex->lock); #elif (defined(JEMALLOC_OSSPIN)) OSSpinLockLock(&mutex->lock); #else pthread_mutex_lock(&mutex->lock); #endif } } JEMALLOC_INLINE void malloc_mutex_unlock(malloc_mutex_t *mutex) { if (isthreaded) { #ifdef _WIN32 LeaveCriticalSection(&mutex->lock); #elif (defined(JEMALLOC_OSSPIN)) OSSpinLockUnlock(&mutex->lock); #else pthread_mutex_unlock(&mutex->lock); #endif } } #endif #endif /* JEMALLOC_H_INLINES */ /******************************************************************************/ Index: head/contrib/jemalloc/src/jemalloc.c =================================================================== --- head/contrib/jemalloc/src/jemalloc.c (revision 276629) +++ head/contrib/jemalloc/src/jemalloc.c (revision 276630) @@ -1,2116 +1,2123 @@ #define JEMALLOC_C_ #include "jemalloc/internal/jemalloc_internal.h" /******************************************************************************/ /* Data. */ malloc_tsd_data(, arenas, arena_t *, NULL) malloc_tsd_data(, thread_allocated, thread_allocated_t, THREAD_ALLOCATED_INITIALIZER) /* Work around : */ const char *__malloc_options_1_0 = NULL; __sym_compat(_malloc_options, __malloc_options_1_0, FBSD_1.0); /* Runtime configuration options. */ const char *je_malloc_conf; bool opt_abort = #ifdef JEMALLOC_DEBUG true #else false #endif ; bool opt_junk = #if (defined(JEMALLOC_DEBUG) && defined(JEMALLOC_FILL)) true #else false #endif ; size_t opt_quarantine = ZU(0); bool opt_redzone = false; bool opt_utrace = false; bool opt_valgrind = false; bool opt_xmalloc = false; bool opt_zero = false; size_t opt_narenas = 0; unsigned ncpus; malloc_mutex_t arenas_lock; arena_t **arenas; unsigned narenas_total; unsigned narenas_auto; /* Set to true once the allocator has been initialized. */ static bool malloc_initialized = false; #ifdef JEMALLOC_THREADED_INIT /* Used to let the initializing thread recursively allocate. */ # define NO_INITIALIZER ((unsigned long)0) # define INITIALIZER pthread_self() # define IS_INITIALIZER (malloc_initializer == pthread_self()) static pthread_t malloc_initializer = NO_INITIALIZER; #else # define NO_INITIALIZER false # define INITIALIZER true # define IS_INITIALIZER malloc_initializer static bool malloc_initializer = NO_INITIALIZER; #endif /* Used to avoid initialization races. */ #ifdef _WIN32 static malloc_mutex_t init_lock; JEMALLOC_ATTR(constructor) static void WINAPI _init_init_lock(void) { malloc_mutex_init(&init_lock); } #ifdef _MSC_VER # pragma section(".CRT$XCU", read) JEMALLOC_SECTION(".CRT$XCU") JEMALLOC_ATTR(used) static const void (WINAPI *init_init_lock)(void) = _init_init_lock; #endif #else static malloc_mutex_t init_lock = MALLOC_MUTEX_INITIALIZER; #endif typedef struct { void *p; /* Input pointer (as in realloc(p, s)). */ size_t s; /* Request size. */ void *r; /* Result pointer. */ } malloc_utrace_t; #ifdef JEMALLOC_UTRACE # define UTRACE(a, b, c) do { \ if (opt_utrace) { \ int utrace_serrno = errno; \ malloc_utrace_t ut; \ ut.p = (a); \ ut.s = (b); \ ut.r = (c); \ utrace(&ut, sizeof(ut)); \ errno = utrace_serrno; \ } \ } while (0) #else # define UTRACE(a, b, c) #endif /******************************************************************************/ /* * Function prototypes for static functions that are referenced prior to * definition. */ static bool malloc_init_hard(void); /******************************************************************************/ /* * Begin miscellaneous support functions. */ /* Create a new arena and insert it into the arenas array at index ind. */ arena_t * arenas_extend(unsigned ind) { arena_t *ret; ret = (arena_t *)base_alloc(sizeof(arena_t)); if (ret != NULL && arena_new(ret, ind) == false) { arenas[ind] = ret; return (ret); } /* Only reached if there is an OOM error. */ /* * OOM here is quite inconvenient to propagate, since dealing with it * would require a check for failure in the fast path. Instead, punt * by using arenas[0]. In practice, this is an extremely unlikely * failure. */ malloc_write(": Error initializing arena\n"); if (opt_abort) abort(); return (arenas[0]); } /* Slow path, called only by choose_arena(). */ arena_t * choose_arena_hard(void) { arena_t *ret; if (narenas_auto > 1) { unsigned i, choose, first_null; choose = 0; first_null = narenas_auto; malloc_mutex_lock(&arenas_lock); assert(arenas[0] != NULL); for (i = 1; i < narenas_auto; i++) { if (arenas[i] != NULL) { /* * Choose the first arena that has the lowest * number of threads assigned to it. */ if (arenas[i]->nthreads < arenas[choose]->nthreads) choose = i; } else if (first_null == narenas_auto) { /* * Record the index of the first uninitialized * arena, in case all extant arenas are in use. * * NB: It is possible for there to be * discontinuities in terms of initialized * versus uninitialized arenas, due to the * "thread.arena" mallctl. */ first_null = i; } } if (arenas[choose]->nthreads == 0 || first_null == narenas_auto) { /* * Use an unloaded arena, or the least loaded arena if * all arenas are already initialized. */ ret = arenas[choose]; } else { /* Initialize a new arena. */ ret = arenas_extend(first_null); } ret->nthreads++; malloc_mutex_unlock(&arenas_lock); } else { ret = arenas[0]; malloc_mutex_lock(&arenas_lock); ret->nthreads++; malloc_mutex_unlock(&arenas_lock); } arenas_tsd_set(&ret); return (ret); } static void stats_print_atexit(void) { if (config_tcache && config_stats) { unsigned narenas, i; /* * Merge stats from extant threads. This is racy, since * individual threads do not lock when recording tcache stats * events. As a consequence, the final stats may be slightly * out of date by the time they are reported, if other threads * continue to allocate. */ for (i = 0, narenas = narenas_total_get(); i < narenas; i++) { arena_t *arena = arenas[i]; if (arena != NULL) { tcache_t *tcache; /* * tcache_stats_merge() locks bins, so if any * code is introduced that acquires both arena * and bin locks in the opposite order, * deadlocks may result. */ malloc_mutex_lock(&arena->lock); ql_foreach(tcache, &arena->tcache_ql, link) { tcache_stats_merge(tcache, arena); } malloc_mutex_unlock(&arena->lock); } } } je_malloc_stats_print(NULL, NULL, NULL); } /* * End miscellaneous support functions. */ /******************************************************************************/ /* * Begin initialization functions. */ static unsigned malloc_ncpus(void) { long result; #ifdef _WIN32 SYSTEM_INFO si; GetSystemInfo(&si); result = si.dwNumberOfProcessors; #else result = sysconf(_SC_NPROCESSORS_ONLN); #endif return ((result == -1) ? 1 : (unsigned)result); } void arenas_cleanup(void *arg) { arena_t *arena = *(arena_t **)arg; malloc_mutex_lock(&arenas_lock); arena->nthreads--; malloc_mutex_unlock(&arenas_lock); } JEMALLOC_ALWAYS_INLINE_C void malloc_thread_init(void) { /* * TSD initialization can't be safely done as a side effect of * deallocation, because it is possible for a thread to do nothing but * deallocate its TLS data via free(), in which case writing to TLS * would cause write-after-free memory corruption. The quarantine * facility *only* gets used as a side effect of deallocation, so make * a best effort attempt at initializing its TSD by hooking all * allocation events. */ if (config_fill && opt_quarantine) quarantine_alloc_hook(); } JEMALLOC_ALWAYS_INLINE_C bool malloc_init(void) { if (malloc_initialized == false && malloc_init_hard()) return (true); malloc_thread_init(); return (false); } static bool malloc_conf_next(char const **opts_p, char const **k_p, size_t *klen_p, char const **v_p, size_t *vlen_p) { bool accept; const char *opts = *opts_p; *k_p = opts; for (accept = false; accept == false;) { switch (*opts) { case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '_': opts++; break; case ':': opts++; *klen_p = (uintptr_t)opts - 1 - (uintptr_t)*k_p; *v_p = opts; accept = true; break; case '\0': if (opts != *opts_p) { malloc_write(": Conf string ends " "with key\n"); } return (true); default: malloc_write(": Malformed conf string\n"); return (true); } } for (accept = false; accept == false;) { switch (*opts) { case ',': opts++; /* * Look ahead one character here, because the next time * this function is called, it will assume that end of * input has been cleanly reached if no input remains, * but we have optimistically already consumed the * comma if one exists. */ if (*opts == '\0') { malloc_write(": Conf string ends " "with comma\n"); } *vlen_p = (uintptr_t)opts - 1 - (uintptr_t)*v_p; accept = true; break; case '\0': *vlen_p = (uintptr_t)opts - (uintptr_t)*v_p; accept = true; break; default: opts++; break; } } *opts_p = opts; return (false); } static void malloc_conf_error(const char *msg, const char *k, size_t klen, const char *v, size_t vlen) { malloc_printf(": %s: %.*s:%.*s\n", msg, (int)klen, k, (int)vlen, v); } static void malloc_conf_init(void) { unsigned i; char buf[PATH_MAX + 1]; const char *opts, *k, *v; size_t klen, vlen; /* * Automatically configure valgrind before processing options. The * valgrind option remains in jemalloc 3.x for compatibility reasons. */ if (config_valgrind) { opt_valgrind = (RUNNING_ON_VALGRIND != 0) ? true : false; if (config_fill && opt_valgrind) { opt_junk = false; assert(opt_zero == false); opt_quarantine = JEMALLOC_VALGRIND_QUARANTINE_DEFAULT; opt_redzone = true; } if (config_tcache && opt_valgrind) opt_tcache = false; } for (i = 0; i < 3; i++) { /* Get runtime configuration. */ switch (i) { case 0: if (je_malloc_conf != NULL) { /* * Use options that were compiled into the * program. */ opts = je_malloc_conf; } else { /* No configuration specified. */ buf[0] = '\0'; opts = buf; } break; case 1: { int linklen = 0; #ifndef _WIN32 int saved_errno = errno; const char *linkname = # ifdef JEMALLOC_PREFIX "/etc/"JEMALLOC_PREFIX"malloc.conf" # else "/etc/malloc.conf" # endif ; /* * Try to use the contents of the "/etc/malloc.conf" * symbolic link's name. */ linklen = readlink(linkname, buf, sizeof(buf) - 1); if (linklen == -1) { /* No configuration specified. */ linklen = 0; /* restore errno */ set_errno(saved_errno); } #endif buf[linklen] = '\0'; opts = buf; break; } case 2: { const char *envname = #ifdef JEMALLOC_PREFIX JEMALLOC_CPREFIX"MALLOC_CONF" #else "MALLOC_CONF" #endif ; if (issetugid() == 0 && (opts = getenv(envname)) != NULL) { /* * Do nothing; opts is already initialized to * the value of the MALLOC_CONF environment * variable. */ } else { /* No configuration specified. */ buf[0] = '\0'; opts = buf; } break; } default: not_reached(); buf[0] = '\0'; opts = buf; } while (*opts != '\0' && malloc_conf_next(&opts, &k, &klen, &v, &vlen) == false) { #define CONF_HANDLE_BOOL(o, n) \ if (sizeof(n)-1 == klen && strncmp(n, k, \ klen) == 0) { \ if (strncmp("true", v, vlen) == 0 && \ vlen == sizeof("true")-1) \ o = true; \ else if (strncmp("false", v, vlen) == \ 0 && vlen == sizeof("false")-1) \ o = false; \ else { \ malloc_conf_error( \ "Invalid conf value", \ k, klen, v, vlen); \ } \ continue; \ } #define CONF_HANDLE_SIZE_T(o, n, min, max, clip) \ if (sizeof(n)-1 == klen && strncmp(n, k, \ klen) == 0) { \ uintmax_t um; \ char *end; \ \ set_errno(0); \ um = malloc_strtoumax(v, &end, 0); \ if (get_errno() != 0 || (uintptr_t)end -\ (uintptr_t)v != vlen) { \ malloc_conf_error( \ "Invalid conf value", \ k, klen, v, vlen); \ } else if (clip) { \ if (min != 0 && um < min) \ o = min; \ else if (um > max) \ o = max; \ else \ o = um; \ } else { \ if ((min != 0 && um < min) || \ um > max) { \ malloc_conf_error( \ "Out-of-range " \ "conf value", \ k, klen, v, vlen); \ } else \ o = um; \ } \ continue; \ } #define CONF_HANDLE_SSIZE_T(o, n, min, max) \ if (sizeof(n)-1 == klen && strncmp(n, k, \ klen) == 0) { \ long l; \ char *end; \ \ set_errno(0); \ l = strtol(v, &end, 0); \ if (get_errno() != 0 || (uintptr_t)end -\ (uintptr_t)v != vlen) { \ malloc_conf_error( \ "Invalid conf value", \ k, klen, v, vlen); \ } else if (l < (ssize_t)min || l > \ (ssize_t)max) { \ malloc_conf_error( \ "Out-of-range conf value", \ k, klen, v, vlen); \ } else \ o = l; \ continue; \ } #define CONF_HANDLE_CHAR_P(o, n, d) \ if (sizeof(n)-1 == klen && strncmp(n, k, \ klen) == 0) { \ size_t cpylen = (vlen <= \ sizeof(o)-1) ? vlen : \ sizeof(o)-1; \ strncpy(o, v, cpylen); \ o[cpylen] = '\0'; \ continue; \ } CONF_HANDLE_BOOL(opt_abort, "abort") /* * Chunks always require at least one header page, plus * one data page in the absence of redzones, or three * pages in the presence of redzones. In order to * simplify options processing, fix the limit based on * config_fill. */ CONF_HANDLE_SIZE_T(opt_lg_chunk, "lg_chunk", LG_PAGE + (config_fill ? 2 : 1), (sizeof(size_t) << 3) - 1, true) if (strncmp("dss", k, klen) == 0) { int i; bool match = false; for (i = 0; i < dss_prec_limit; i++) { if (strncmp(dss_prec_names[i], v, vlen) == 0) { if (chunk_dss_prec_set(i)) { malloc_conf_error( "Error setting dss", k, klen, v, vlen); } else { opt_dss = dss_prec_names[i]; match = true; break; } } } if (match == false) { malloc_conf_error("Invalid conf value", k, klen, v, vlen); } continue; } CONF_HANDLE_SIZE_T(opt_narenas, "narenas", 1, SIZE_T_MAX, false) CONF_HANDLE_SSIZE_T(opt_lg_dirty_mult, "lg_dirty_mult", -1, (sizeof(size_t) << 3) - 1) CONF_HANDLE_BOOL(opt_stats_print, "stats_print") if (config_fill) { CONF_HANDLE_BOOL(opt_junk, "junk") CONF_HANDLE_SIZE_T(opt_quarantine, "quarantine", 0, SIZE_T_MAX, false) CONF_HANDLE_BOOL(opt_redzone, "redzone") CONF_HANDLE_BOOL(opt_zero, "zero") } if (config_utrace) { CONF_HANDLE_BOOL(opt_utrace, "utrace") } if (config_valgrind) { CONF_HANDLE_BOOL(opt_valgrind, "valgrind") } if (config_xmalloc) { CONF_HANDLE_BOOL(opt_xmalloc, "xmalloc") } if (config_tcache) { CONF_HANDLE_BOOL(opt_tcache, "tcache") CONF_HANDLE_SSIZE_T(opt_lg_tcache_max, "lg_tcache_max", -1, (sizeof(size_t) << 3) - 1) } if (config_prof) { CONF_HANDLE_BOOL(opt_prof, "prof") CONF_HANDLE_CHAR_P(opt_prof_prefix, "prof_prefix", "jeprof") CONF_HANDLE_BOOL(opt_prof_active, "prof_active") CONF_HANDLE_SSIZE_T(opt_lg_prof_sample, "lg_prof_sample", 0, (sizeof(uint64_t) << 3) - 1) CONF_HANDLE_BOOL(opt_prof_accum, "prof_accum") CONF_HANDLE_SSIZE_T(opt_lg_prof_interval, "lg_prof_interval", -1, (sizeof(uint64_t) << 3) - 1) CONF_HANDLE_BOOL(opt_prof_gdump, "prof_gdump") CONF_HANDLE_BOOL(opt_prof_final, "prof_final") CONF_HANDLE_BOOL(opt_prof_leak, "prof_leak") } malloc_conf_error("Invalid conf pair", k, klen, v, vlen); #undef CONF_HANDLE_BOOL #undef CONF_HANDLE_SIZE_T #undef CONF_HANDLE_SSIZE_T #undef CONF_HANDLE_CHAR_P } } } static bool malloc_init_hard(void) { arena_t *init_arenas[1]; malloc_mutex_lock(&init_lock); if (malloc_initialized || IS_INITIALIZER) { /* * Another thread initialized the allocator before this one * acquired init_lock, or this thread is the initializing * thread, and it is recursively allocating. */ malloc_mutex_unlock(&init_lock); return (false); } #ifdef JEMALLOC_THREADED_INIT if (malloc_initializer != NO_INITIALIZER && IS_INITIALIZER == false) { /* Busy-wait until the initializing thread completes. */ do { malloc_mutex_unlock(&init_lock); CPU_SPINWAIT; malloc_mutex_lock(&init_lock); } while (malloc_initialized == false); malloc_mutex_unlock(&init_lock); return (false); } #endif malloc_initializer = INITIALIZER; malloc_tsd_boot(); if (config_prof) prof_boot0(); malloc_conf_init(); if (opt_stats_print) { /* Print statistics at exit. */ if (atexit(stats_print_atexit) != 0) { malloc_write(": Error in atexit()\n"); if (opt_abort) abort(); } } if (base_boot()) { malloc_mutex_unlock(&init_lock); return (true); } if (chunk_boot()) { malloc_mutex_unlock(&init_lock); return (true); } if (ctl_boot()) { malloc_mutex_unlock(&init_lock); return (true); } if (config_prof) prof_boot1(); arena_boot(); if (config_tcache && tcache_boot0()) { malloc_mutex_unlock(&init_lock); return (true); } if (huge_boot()) { malloc_mutex_unlock(&init_lock); return (true); } if (malloc_mutex_init(&arenas_lock)) { malloc_mutex_unlock(&init_lock); return (true); } /* * Create enough scaffolding to allow recursive allocation in * malloc_ncpus(). */ narenas_total = narenas_auto = 1; arenas = init_arenas; memset(arenas, 0, sizeof(arena_t *) * narenas_auto); /* * Initialize one arena here. The rest are lazily created in * choose_arena_hard(). */ arenas_extend(0); if (arenas[0] == NULL) { malloc_mutex_unlock(&init_lock); return (true); } /* Initialize allocation counters before any allocations can occur. */ if (config_stats && thread_allocated_tsd_boot()) { malloc_mutex_unlock(&init_lock); return (true); } if (arenas_tsd_boot()) { malloc_mutex_unlock(&init_lock); return (true); } if (config_tcache && tcache_boot1()) { malloc_mutex_unlock(&init_lock); return (true); } if (config_fill && quarantine_boot()) { malloc_mutex_unlock(&init_lock); return (true); } if (config_prof && prof_boot2()) { malloc_mutex_unlock(&init_lock); return (true); } malloc_mutex_unlock(&init_lock); /**********************************************************************/ /* Recursive allocation may follow. */ ncpus = malloc_ncpus(); #if (!defined(JEMALLOC_MUTEX_INIT_CB) && !defined(JEMALLOC_ZONE) \ && !defined(_WIN32)) /* LinuxThreads's pthread_atfork() allocates. */ if (pthread_atfork(jemalloc_prefork, jemalloc_postfork_parent, jemalloc_postfork_child) != 0) { malloc_write(": Error in pthread_atfork()\n"); if (opt_abort) abort(); } #endif /* Done recursively allocating. */ /**********************************************************************/ malloc_mutex_lock(&init_lock); if (mutex_boot()) { malloc_mutex_unlock(&init_lock); return (true); } if (opt_narenas == 0) { /* * For SMP systems, create more than one arena per CPU by * default. */ if (ncpus > 1) opt_narenas = ncpus << 2; else opt_narenas = 1; } narenas_auto = opt_narenas; /* * Make sure that the arenas array can be allocated. In practice, this * limit is enough to allow the allocator to function, but the ctl * machinery will fail to allocate memory at far lower limits. */ if (narenas_auto > chunksize / sizeof(arena_t *)) { narenas_auto = chunksize / sizeof(arena_t *); malloc_printf(": Reducing narenas to limit (%d)\n", narenas_auto); } narenas_total = narenas_auto; /* Allocate and initialize arenas. */ arenas = (arena_t **)base_alloc(sizeof(arena_t *) * narenas_total); if (arenas == NULL) { malloc_mutex_unlock(&init_lock); return (true); } /* * Zero the array. In practice, this should always be pre-zeroed, * since it was just mmap()ed, but let's be sure. */ memset(arenas, 0, sizeof(arena_t *) * narenas_total); /* Copy the pointer to the one arena that was already initialized. */ arenas[0] = init_arenas[0]; malloc_initialized = true; malloc_mutex_unlock(&init_lock); return (false); } /* * End initialization functions. */ /******************************************************************************/ /* * Begin malloc(3)-compatible functions. */ static void * imalloc_prof_sample(size_t usize, prof_thr_cnt_t *cnt) { void *p; if (cnt == NULL) return (NULL); if (prof_promote && usize <= SMALL_MAXCLASS) { p = imalloc(SMALL_MAXCLASS+1); if (p == NULL) return (NULL); arena_prof_promoted(p, usize); } else p = imalloc(usize); return (p); } JEMALLOC_ALWAYS_INLINE_C void * imalloc_prof(size_t usize, prof_thr_cnt_t *cnt) { void *p; if ((uintptr_t)cnt != (uintptr_t)1U) p = imalloc_prof_sample(usize, cnt); else p = imalloc(usize); if (p == NULL) return (NULL); prof_malloc(p, usize, cnt); return (p); } /* * MALLOC_BODY() is a macro rather than a function because its contents are in * the fast path, but inlining would cause reliability issues when determining * how many frames to discard from heap profiling backtraces. */ #define MALLOC_BODY(ret, size, usize) do { \ if (malloc_init()) \ ret = NULL; \ else { \ if (config_prof && opt_prof) { \ prof_thr_cnt_t *cnt; \ \ usize = s2u(size); \ /* \ * Call PROF_ALLOC_PREP() here rather than in \ * imalloc_prof() so that imalloc_prof() can be \ * inlined without introducing uncertainty \ * about the number of backtrace frames to \ * ignore. imalloc_prof() is in the fast path \ * when heap profiling is enabled, so inlining \ * is critical to performance. (For \ * consistency all callers of PROF_ALLOC_PREP() \ * are structured similarly, even though e.g. \ * realloc() isn't called enough for inlining \ * to be critical.) \ */ \ PROF_ALLOC_PREP(1, usize, cnt); \ ret = imalloc_prof(usize, cnt); \ } else { \ if (config_stats || (config_valgrind && \ opt_valgrind)) \ usize = s2u(size); \ ret = imalloc(size); \ } \ } \ } while (0) void * je_malloc(size_t size) { void *ret; size_t usize JEMALLOC_CC_SILENCE_INIT(0); if (size == 0) size = 1; MALLOC_BODY(ret, size, usize); if (ret == NULL) { if (config_xmalloc && opt_xmalloc) { malloc_write(": Error in malloc(): " "out of memory\n"); abort(); } set_errno(ENOMEM); } if (config_stats && ret != NULL) { assert(usize == isalloc(ret, config_prof)); thread_allocated_tsd_get()->allocated += usize; } UTRACE(0, size, ret); JEMALLOC_VALGRIND_MALLOC(ret != NULL, ret, usize, false); return (ret); } static void * imemalign_prof_sample(size_t alignment, size_t usize, prof_thr_cnt_t *cnt) { void *p; if (cnt == NULL) return (NULL); if (prof_promote && usize <= SMALL_MAXCLASS) { assert(sa2u(SMALL_MAXCLASS+1, alignment) != 0); p = ipalloc(sa2u(SMALL_MAXCLASS+1, alignment), alignment, false); if (p == NULL) return (NULL); arena_prof_promoted(p, usize); } else p = ipalloc(usize, alignment, false); return (p); } JEMALLOC_ALWAYS_INLINE_C void * imemalign_prof(size_t alignment, size_t usize, prof_thr_cnt_t *cnt) { void *p; if ((uintptr_t)cnt != (uintptr_t)1U) p = imemalign_prof_sample(alignment, usize, cnt); else p = ipalloc(usize, alignment, false); if (p == NULL) return (NULL); prof_malloc(p, usize, cnt); return (p); } JEMALLOC_ATTR(nonnull(1)) #ifdef JEMALLOC_PROF /* * Avoid any uncertainty as to how many backtrace frames to ignore in * PROF_ALLOC_PREP(). */ JEMALLOC_NOINLINE #endif static int imemalign(void **memptr, size_t alignment, size_t size, size_t min_alignment) { int ret; size_t usize; void *result; assert(min_alignment != 0); if (malloc_init()) { result = NULL; goto label_oom; } else { if (size == 0) size = 1; /* Make sure that alignment is a large enough power of 2. */ if (((alignment - 1) & alignment) != 0 || (alignment < min_alignment)) { if (config_xmalloc && opt_xmalloc) { malloc_write(": Error allocating " "aligned memory: invalid alignment\n"); abort(); } result = NULL; ret = EINVAL; goto label_return; } usize = sa2u(size, alignment); if (usize == 0) { result = NULL; goto label_oom; } if (config_prof && opt_prof) { prof_thr_cnt_t *cnt; PROF_ALLOC_PREP(2, usize, cnt); result = imemalign_prof(alignment, usize, cnt); } else result = ipalloc(usize, alignment, false); if (result == NULL) goto label_oom; } *memptr = result; ret = 0; label_return: if (config_stats && result != NULL) { assert(usize == isalloc(result, config_prof)); thread_allocated_tsd_get()->allocated += usize; } UTRACE(0, size, result); return (ret); label_oom: assert(result == NULL); if (config_xmalloc && opt_xmalloc) { malloc_write(": Error allocating aligned memory: " "out of memory\n"); abort(); } ret = ENOMEM; goto label_return; } int je_posix_memalign(void **memptr, size_t alignment, size_t size) { int ret = imemalign(memptr, alignment, size, sizeof(void *)); JEMALLOC_VALGRIND_MALLOC(ret == 0, *memptr, isalloc(*memptr, config_prof), false); return (ret); } void * je_aligned_alloc(size_t alignment, size_t size) { void *ret; int err; if ((err = imemalign(&ret, alignment, size, 1)) != 0) { ret = NULL; set_errno(err); } JEMALLOC_VALGRIND_MALLOC(err == 0, ret, isalloc(ret, config_prof), false); return (ret); } static void * icalloc_prof_sample(size_t usize, prof_thr_cnt_t *cnt) { void *p; if (cnt == NULL) return (NULL); if (prof_promote && usize <= SMALL_MAXCLASS) { p = icalloc(SMALL_MAXCLASS+1); if (p == NULL) return (NULL); arena_prof_promoted(p, usize); } else p = icalloc(usize); return (p); } JEMALLOC_ALWAYS_INLINE_C void * icalloc_prof(size_t usize, prof_thr_cnt_t *cnt) { void *p; if ((uintptr_t)cnt != (uintptr_t)1U) p = icalloc_prof_sample(usize, cnt); else p = icalloc(usize); if (p == NULL) return (NULL); prof_malloc(p, usize, cnt); return (p); } void * je_calloc(size_t num, size_t size) { void *ret; size_t num_size; size_t usize JEMALLOC_CC_SILENCE_INIT(0); if (malloc_init()) { num_size = 0; ret = NULL; goto label_return; } num_size = num * size; if (num_size == 0) { if (num == 0 || size == 0) num_size = 1; else { ret = NULL; goto label_return; } /* * Try to avoid division here. We know that it isn't possible to * overflow during multiplication if neither operand uses any of the * most significant half of the bits in a size_t. */ } else if (((num | size) & (SIZE_T_MAX << (sizeof(size_t) << 2))) && (num_size / size != num)) { /* size_t overflow. */ ret = NULL; goto label_return; } if (config_prof && opt_prof) { prof_thr_cnt_t *cnt; usize = s2u(num_size); PROF_ALLOC_PREP(1, usize, cnt); ret = icalloc_prof(usize, cnt); } else { if (config_stats || (config_valgrind && opt_valgrind)) usize = s2u(num_size); ret = icalloc(num_size); } label_return: if (ret == NULL) { if (config_xmalloc && opt_xmalloc) { malloc_write(": Error in calloc(): out of " "memory\n"); abort(); } set_errno(ENOMEM); } if (config_stats && ret != NULL) { assert(usize == isalloc(ret, config_prof)); thread_allocated_tsd_get()->allocated += usize; } UTRACE(0, num_size, ret); JEMALLOC_VALGRIND_MALLOC(ret != NULL, ret, usize, true); return (ret); } static void * irealloc_prof_sample(void *oldptr, size_t usize, prof_thr_cnt_t *cnt) { void *p; if (cnt == NULL) return (NULL); if (prof_promote && usize <= SMALL_MAXCLASS) { p = iralloc(oldptr, SMALL_MAXCLASS+1, 0, 0, false); if (p == NULL) return (NULL); arena_prof_promoted(p, usize); } else p = iralloc(oldptr, usize, 0, 0, false); return (p); } JEMALLOC_ALWAYS_INLINE_C void * irealloc_prof(void *oldptr, size_t old_usize, size_t usize, prof_thr_cnt_t *cnt) { void *p; prof_ctx_t *old_ctx; old_ctx = prof_ctx_get(oldptr); if ((uintptr_t)cnt != (uintptr_t)1U) p = irealloc_prof_sample(oldptr, usize, cnt); else p = iralloc(oldptr, usize, 0, 0, false); if (p == NULL) return (NULL); prof_realloc(p, usize, cnt, old_usize, old_ctx); return (p); } JEMALLOC_INLINE_C void ifree(void *ptr) { size_t usize; UNUSED size_t rzsize JEMALLOC_CC_SILENCE_INIT(0); assert(ptr != NULL); assert(malloc_initialized || IS_INITIALIZER); if (config_prof && opt_prof) { usize = isalloc(ptr, config_prof); prof_free(ptr, usize); } else if (config_stats || config_valgrind) usize = isalloc(ptr, config_prof); if (config_stats) thread_allocated_tsd_get()->deallocated += usize; if (config_valgrind && opt_valgrind) rzsize = p2rz(ptr); iqalloc(ptr); JEMALLOC_VALGRIND_FREE(ptr, rzsize); } void * je_realloc(void *ptr, size_t size) { void *ret; size_t usize JEMALLOC_CC_SILENCE_INIT(0); size_t old_usize = 0; UNUSED size_t old_rzsize JEMALLOC_CC_SILENCE_INIT(0); if (size == 0) { if (ptr != NULL) { /* realloc(ptr, 0) is equivalent to free(ptr). */ UTRACE(ptr, 0, 0); ifree(ptr); return (NULL); } size = 1; } if (ptr != NULL) { assert(malloc_initialized || IS_INITIALIZER); malloc_thread_init(); if ((config_prof && opt_prof) || config_stats || (config_valgrind && opt_valgrind)) old_usize = isalloc(ptr, config_prof); if (config_valgrind && opt_valgrind) old_rzsize = config_prof ? p2rz(ptr) : u2rz(old_usize); if (config_prof && opt_prof) { prof_thr_cnt_t *cnt; usize = s2u(size); PROF_ALLOC_PREP(1, usize, cnt); ret = irealloc_prof(ptr, old_usize, usize, cnt); } else { if (config_stats || (config_valgrind && opt_valgrind)) usize = s2u(size); ret = iralloc(ptr, size, 0, 0, false); } } else { /* realloc(NULL, size) is equivalent to malloc(size). */ MALLOC_BODY(ret, size, usize); } if (ret == NULL) { if (config_xmalloc && opt_xmalloc) { malloc_write(": Error in realloc(): " "out of memory\n"); abort(); } set_errno(ENOMEM); } if (config_stats && ret != NULL) { thread_allocated_t *ta; assert(usize == isalloc(ret, config_prof)); ta = thread_allocated_tsd_get(); ta->allocated += usize; ta->deallocated += old_usize; } UTRACE(ptr, size, ret); JEMALLOC_VALGRIND_REALLOC(ret, usize, ptr, old_usize, old_rzsize, false); return (ret); } void je_free(void *ptr) { UTRACE(ptr, 0, 0); if (ptr != NULL) ifree(ptr); } /* * End malloc(3)-compatible functions. */ /******************************************************************************/ /* * Begin non-standard override functions. */ #ifdef JEMALLOC_OVERRIDE_MEMALIGN void * je_memalign(size_t alignment, size_t size) { void *ret JEMALLOC_CC_SILENCE_INIT(NULL); imemalign(&ret, alignment, size, 1); JEMALLOC_VALGRIND_MALLOC(ret != NULL, ret, size, false); return (ret); } #endif #ifdef JEMALLOC_OVERRIDE_VALLOC void * je_valloc(size_t size) { void *ret JEMALLOC_CC_SILENCE_INIT(NULL); imemalign(&ret, PAGE, size, 1); JEMALLOC_VALGRIND_MALLOC(ret != NULL, ret, size, false); return (ret); } #endif /* * is_malloc(je_malloc) is some macro magic to detect if jemalloc_defs.h has * #define je_malloc malloc */ #define malloc_is_malloc 1 #define is_malloc_(a) malloc_is_ ## a #define is_malloc(a) is_malloc_(a) #if ((is_malloc(je_malloc) == 1) && defined(__GLIBC__) && !defined(__UCLIBC__)) /* * glibc provides the RTLD_DEEPBIND flag for dlopen which can make it possible * to inconsistently reference libc's malloc(3)-compatible functions * (https://bugzilla.mozilla.org/show_bug.cgi?id=493541). * * These definitions interpose hooks in glibc. The functions are actually * passed an extra argument for the caller return address, which will be * ignored. */ JEMALLOC_EXPORT void (* __free_hook)(void *ptr) = je_free; JEMALLOC_EXPORT void *(* __malloc_hook)(size_t size) = je_malloc; JEMALLOC_EXPORT void *(* __realloc_hook)(void *ptr, size_t size) = je_realloc; JEMALLOC_EXPORT void *(* __memalign_hook)(size_t alignment, size_t size) = je_memalign; #endif /* * End non-standard override functions. */ /******************************************************************************/ /* * Begin non-standard functions. */ JEMALLOC_ALWAYS_INLINE_C void * imallocx(size_t usize, size_t alignment, bool zero, bool try_tcache, arena_t *arena) { assert(usize == ((alignment == 0) ? s2u(usize) : sa2u(usize, alignment))); if (alignment != 0) return (ipalloct(usize, alignment, zero, try_tcache, arena)); else if (zero) return (icalloct(usize, try_tcache, arena)); else return (imalloct(usize, try_tcache, arena)); } static void * imallocx_prof_sample(size_t usize, size_t alignment, bool zero, bool try_tcache, arena_t *arena, prof_thr_cnt_t *cnt) { void *p; if (cnt == NULL) return (NULL); if (prof_promote && usize <= SMALL_MAXCLASS) { size_t usize_promoted = (alignment == 0) ? s2u(SMALL_MAXCLASS+1) : sa2u(SMALL_MAXCLASS+1, alignment); assert(usize_promoted != 0); p = imallocx(usize_promoted, alignment, zero, try_tcache, arena); if (p == NULL) return (NULL); arena_prof_promoted(p, usize); } else p = imallocx(usize, alignment, zero, try_tcache, arena); return (p); } JEMALLOC_ALWAYS_INLINE_C void * imallocx_prof(size_t usize, size_t alignment, bool zero, bool try_tcache, arena_t *arena, prof_thr_cnt_t *cnt) { void *p; if ((uintptr_t)cnt != (uintptr_t)1U) { p = imallocx_prof_sample(usize, alignment, zero, try_tcache, arena, cnt); } else p = imallocx(usize, alignment, zero, try_tcache, arena); if (p == NULL) return (NULL); prof_malloc(p, usize, cnt); return (p); } void * je_mallocx(size_t size, int flags) { void *p; size_t usize; size_t alignment = (ZU(1) << (flags & MALLOCX_LG_ALIGN_MASK) & (SIZE_T_MAX-1)); bool zero = flags & MALLOCX_ZERO; unsigned arena_ind = ((unsigned)(flags >> 8)) - 1; arena_t *arena; bool try_tcache; assert(size != 0); if (malloc_init()) goto label_oom; if (arena_ind != UINT_MAX) { arena = arenas[arena_ind]; try_tcache = false; } else { arena = NULL; try_tcache = true; } usize = (alignment == 0) ? s2u(size) : sa2u(size, alignment); assert(usize != 0); if (config_prof && opt_prof) { prof_thr_cnt_t *cnt; PROF_ALLOC_PREP(1, usize, cnt); p = imallocx_prof(usize, alignment, zero, try_tcache, arena, cnt); } else p = imallocx(usize, alignment, zero, try_tcache, arena); if (p == NULL) goto label_oom; if (config_stats) { assert(usize == isalloc(p, config_prof)); thread_allocated_tsd_get()->allocated += usize; } UTRACE(0, size, p); JEMALLOC_VALGRIND_MALLOC(true, p, usize, zero); return (p); label_oom: if (config_xmalloc && opt_xmalloc) { malloc_write(": Error in mallocx(): out of memory\n"); abort(); } UTRACE(0, size, 0); return (NULL); } static void * irallocx_prof_sample(void *oldptr, size_t size, size_t alignment, size_t usize, bool zero, bool try_tcache_alloc, bool try_tcache_dalloc, arena_t *arena, prof_thr_cnt_t *cnt) { void *p; if (cnt == NULL) return (NULL); if (prof_promote && usize <= SMALL_MAXCLASS) { p = iralloct(oldptr, SMALL_MAXCLASS+1, (SMALL_MAXCLASS+1 >= size) ? 0 : size - (SMALL_MAXCLASS+1), alignment, zero, try_tcache_alloc, try_tcache_dalloc, arena); if (p == NULL) return (NULL); arena_prof_promoted(p, usize); } else { p = iralloct(oldptr, size, 0, alignment, zero, try_tcache_alloc, try_tcache_dalloc, arena); } return (p); } JEMALLOC_ALWAYS_INLINE_C void * irallocx_prof(void *oldptr, size_t old_usize, size_t size, size_t alignment, size_t *usize, bool zero, bool try_tcache_alloc, bool try_tcache_dalloc, arena_t *arena, prof_thr_cnt_t *cnt) { void *p; prof_ctx_t *old_ctx; old_ctx = prof_ctx_get(oldptr); if ((uintptr_t)cnt != (uintptr_t)1U) p = irallocx_prof_sample(oldptr, size, alignment, *usize, zero, try_tcache_alloc, try_tcache_dalloc, arena, cnt); else { p = iralloct(oldptr, size, 0, alignment, zero, try_tcache_alloc, try_tcache_dalloc, arena); } if (p == NULL) return (NULL); if (p == oldptr && alignment != 0) { /* * The allocation did not move, so it is possible that the size * class is smaller than would guarantee the requested * alignment, and that the alignment constraint was * serendipitously satisfied. Additionally, old_usize may not * be the same as the current usize because of in-place large * reallocation. Therefore, query the actual value of usize. */ *usize = isalloc(p, config_prof); } prof_realloc(p, *usize, cnt, old_usize, old_ctx); return (p); } void * je_rallocx(void *ptr, size_t size, int flags) { void *p; size_t usize, old_usize; UNUSED size_t old_rzsize JEMALLOC_CC_SILENCE_INIT(0); size_t alignment = (ZU(1) << (flags & MALLOCX_LG_ALIGN_MASK) & (SIZE_T_MAX-1)); bool zero = flags & MALLOCX_ZERO; unsigned arena_ind = ((unsigned)(flags >> 8)) - 1; bool try_tcache_alloc, try_tcache_dalloc; arena_t *arena; assert(ptr != NULL); assert(size != 0); assert(malloc_initialized || IS_INITIALIZER); malloc_thread_init(); if (arena_ind != UINT_MAX) { arena_chunk_t *chunk; try_tcache_alloc = false; chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); try_tcache_dalloc = (chunk == ptr || chunk->arena != arenas[arena_ind]); arena = arenas[arena_ind]; } else { try_tcache_alloc = true; try_tcache_dalloc = true; arena = NULL; } if ((config_prof && opt_prof) || config_stats || (config_valgrind && opt_valgrind)) old_usize = isalloc(ptr, config_prof); if (config_valgrind && opt_valgrind) old_rzsize = u2rz(old_usize); if (config_prof && opt_prof) { prof_thr_cnt_t *cnt; usize = (alignment == 0) ? s2u(size) : sa2u(size, alignment); assert(usize != 0); PROF_ALLOC_PREP(1, usize, cnt); p = irallocx_prof(ptr, old_usize, size, alignment, &usize, zero, try_tcache_alloc, try_tcache_dalloc, arena, cnt); if (p == NULL) goto label_oom; } else { p = iralloct(ptr, size, 0, alignment, zero, try_tcache_alloc, try_tcache_dalloc, arena); if (p == NULL) goto label_oom; if (config_stats || (config_valgrind && opt_valgrind)) usize = isalloc(p, config_prof); } if (config_stats) { thread_allocated_t *ta; ta = thread_allocated_tsd_get(); ta->allocated += usize; ta->deallocated += old_usize; } UTRACE(ptr, size, p); JEMALLOC_VALGRIND_REALLOC(p, usize, ptr, old_usize, old_rzsize, zero); return (p); label_oom: if (config_xmalloc && opt_xmalloc) { malloc_write(": Error in rallocx(): out of memory\n"); abort(); } UTRACE(ptr, size, 0); return (NULL); } JEMALLOC_ALWAYS_INLINE_C size_t ixallocx_helper(void *ptr, size_t old_usize, size_t size, size_t extra, size_t alignment, bool zero, arena_t *arena) { size_t usize; if (ixalloc(ptr, size, extra, alignment, zero)) return (old_usize); usize = isalloc(ptr, config_prof); return (usize); } static size_t ixallocx_prof_sample(void *ptr, size_t old_usize, size_t size, size_t extra, size_t alignment, size_t max_usize, bool zero, arena_t *arena, prof_thr_cnt_t *cnt) { size_t usize; if (cnt == NULL) return (old_usize); /* Use minimum usize to determine whether promotion may happen. */ if (prof_promote && ((alignment == 0) ? s2u(size) : sa2u(size, alignment)) <= SMALL_MAXCLASS) { if (ixalloc(ptr, SMALL_MAXCLASS+1, (SMALL_MAXCLASS+1 >= size+extra) ? 0 : size+extra - (SMALL_MAXCLASS+1), alignment, zero)) return (old_usize); usize = isalloc(ptr, config_prof); if (max_usize < PAGE) arena_prof_promoted(ptr, usize); } else { usize = ixallocx_helper(ptr, old_usize, size, extra, alignment, zero, arena); } return (usize); } JEMALLOC_ALWAYS_INLINE_C size_t ixallocx_prof(void *ptr, size_t old_usize, size_t size, size_t extra, size_t alignment, size_t max_usize, bool zero, arena_t *arena, prof_thr_cnt_t *cnt) { size_t usize; prof_ctx_t *old_ctx; old_ctx = prof_ctx_get(ptr); if ((uintptr_t)cnt != (uintptr_t)1U) { usize = ixallocx_prof_sample(ptr, old_usize, size, extra, alignment, zero, max_usize, arena, cnt); } else { usize = ixallocx_helper(ptr, old_usize, size, extra, alignment, zero, arena); } if (usize == old_usize) return (usize); prof_realloc(ptr, usize, cnt, old_usize, old_ctx); return (usize); } size_t je_xallocx(void *ptr, size_t size, size_t extra, int flags) { size_t usize, old_usize; UNUSED size_t old_rzsize JEMALLOC_CC_SILENCE_INIT(0); size_t alignment = (ZU(1) << (flags & MALLOCX_LG_ALIGN_MASK) & (SIZE_T_MAX-1)); bool zero = flags & MALLOCX_ZERO; unsigned arena_ind = ((unsigned)(flags >> 8)) - 1; arena_t *arena; assert(ptr != NULL); assert(size != 0); assert(SIZE_T_MAX - size >= extra); assert(malloc_initialized || IS_INITIALIZER); malloc_thread_init(); if (arena_ind != UINT_MAX) arena = arenas[arena_ind]; else arena = NULL; old_usize = isalloc(ptr, config_prof); if (config_valgrind && opt_valgrind) old_rzsize = u2rz(old_usize); if (config_prof && opt_prof) { prof_thr_cnt_t *cnt; /* * usize isn't knowable before ixalloc() returns when extra is * non-zero. Therefore, compute its maximum possible value and * use that in PROF_ALLOC_PREP() to decide whether to capture a * backtrace. prof_realloc() will use the actual usize to * decide whether to sample. */ size_t max_usize = (alignment == 0) ? s2u(size+extra) : sa2u(size+extra, alignment); PROF_ALLOC_PREP(1, max_usize, cnt); usize = ixallocx_prof(ptr, old_usize, size, extra, alignment, max_usize, zero, arena, cnt); } else { usize = ixallocx_helper(ptr, old_usize, size, extra, alignment, zero, arena); } if (usize == old_usize) goto label_not_resized; if (config_stats) { thread_allocated_t *ta; ta = thread_allocated_tsd_get(); ta->allocated += usize; ta->deallocated += old_usize; } JEMALLOC_VALGRIND_REALLOC(ptr, usize, ptr, old_usize, old_rzsize, zero); label_not_resized: UTRACE(ptr, size, ptr); return (usize); } size_t je_sallocx(const void *ptr, int flags) { size_t usize; assert(malloc_initialized || IS_INITIALIZER); malloc_thread_init(); if (config_ivsalloc) usize = ivsalloc(ptr, config_prof); else { assert(ptr != NULL); usize = isalloc(ptr, config_prof); } return (usize); } void je_dallocx(void *ptr, int flags) { size_t usize; UNUSED size_t rzsize JEMALLOC_CC_SILENCE_INIT(0); unsigned arena_ind = ((unsigned)(flags >> 8)) - 1; bool try_tcache; assert(ptr != NULL); assert(malloc_initialized || IS_INITIALIZER); if (arena_ind != UINT_MAX) { arena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); try_tcache = (chunk == ptr || chunk->arena != arenas[arena_ind]); } else try_tcache = true; UTRACE(ptr, 0, 0); if (config_stats || config_valgrind) usize = isalloc(ptr, config_prof); if (config_prof && opt_prof) { if (config_stats == false && config_valgrind == false) usize = isalloc(ptr, config_prof); prof_free(ptr, usize); } if (config_stats) thread_allocated_tsd_get()->deallocated += usize; if (config_valgrind && opt_valgrind) rzsize = p2rz(ptr); iqalloct(ptr, try_tcache); JEMALLOC_VALGRIND_FREE(ptr, rzsize); } size_t je_nallocx(size_t size, int flags) { size_t usize; size_t alignment = (ZU(1) << (flags & MALLOCX_LG_ALIGN_MASK) & (SIZE_T_MAX-1)); assert(size != 0); if (malloc_init()) return (0); usize = (alignment == 0) ? s2u(size) : sa2u(size, alignment); assert(usize != 0); return (usize); } int je_mallctl(const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { if (malloc_init()) return (EAGAIN); return (ctl_byname(name, oldp, oldlenp, newp, newlen)); } int je_mallctlnametomib(const char *name, size_t *mibp, size_t *miblenp) { if (malloc_init()) return (EAGAIN); return (ctl_nametomib(name, mibp, miblenp)); } int je_mallctlbymib(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { if (malloc_init()) return (EAGAIN); return (ctl_bymib(mib, miblen, oldp, oldlenp, newp, newlen)); } void je_malloc_stats_print(void (*write_cb)(void *, const char *), void *cbopaque, const char *opts) { stats_print(write_cb, cbopaque, opts); } size_t je_malloc_usable_size(JEMALLOC_USABLE_SIZE_CONST void *ptr) { size_t ret; assert(malloc_initialized || IS_INITIALIZER); malloc_thread_init(); if (config_ivsalloc) ret = ivsalloc(ptr, config_prof); else ret = (ptr != NULL) ? isalloc(ptr, config_prof) : 0; return (ret); } /* * End non-standard functions. */ /******************************************************************************/ /* * Begin experimental functions. */ #ifdef JEMALLOC_EXPERIMENTAL int je_allocm(void **ptr, size_t *rsize, size_t size, int flags) { void *p; assert(ptr != NULL); p = je_mallocx(size, flags); if (p == NULL) return (ALLOCM_ERR_OOM); if (rsize != NULL) *rsize = isalloc(p, config_prof); *ptr = p; return (ALLOCM_SUCCESS); } int je_rallocm(void **ptr, size_t *rsize, size_t size, size_t extra, int flags) { int ret; bool no_move = flags & ALLOCM_NO_MOVE; assert(ptr != NULL); assert(*ptr != NULL); assert(size != 0); assert(SIZE_T_MAX - size >= extra); if (no_move) { size_t usize = je_xallocx(*ptr, size, extra, flags); ret = (usize >= size) ? ALLOCM_SUCCESS : ALLOCM_ERR_NOT_MOVED; if (rsize != NULL) *rsize = usize; } else { void *p = je_rallocx(*ptr, size+extra, flags); if (p != NULL) { *ptr = p; ret = ALLOCM_SUCCESS; } else ret = ALLOCM_ERR_OOM; if (rsize != NULL) *rsize = isalloc(*ptr, config_prof); } return (ret); } int je_sallocm(const void *ptr, size_t *rsize, int flags) { assert(rsize != NULL); *rsize = je_sallocx(ptr, flags); return (ALLOCM_SUCCESS); } int je_dallocm(void *ptr, int flags) { je_dallocx(ptr, flags); return (ALLOCM_SUCCESS); } int je_nallocm(size_t *rsize, size_t size, int flags) { size_t usize; usize = je_nallocx(size, flags); if (usize == 0) return (ALLOCM_ERR_OOM); if (rsize != NULL) *rsize = usize; return (ALLOCM_SUCCESS); } #endif /* * End experimental functions. */ /******************************************************************************/ /* * The following functions are used by threading libraries for protection of * malloc during fork(). */ /* * If an application creates a thread before doing any allocation in the main * thread, then calls fork(2) in the main thread followed by memory allocation * in the child process, a race can occur that results in deadlock within the * child: the main thread may have forked while the created thread had * partially initialized the allocator. Ordinarily jemalloc prevents * fork/malloc races via the following functions it registers during * initialization using pthread_atfork(), but of course that does no good if * the allocator isn't fully initialized at fork time. The following library * constructor is a partial solution to this problem. It may still possible to * trigger the deadlock described above, but doing so would involve forking via * a library constructor that runs before jemalloc's runs. */ JEMALLOC_ATTR(constructor) static void jemalloc_constructor(void) { malloc_init(); } #ifndef JEMALLOC_MUTEX_INIT_CB void jemalloc_prefork(void) #else JEMALLOC_EXPORT void _malloc_prefork(void) #endif { unsigned i; #ifdef JEMALLOC_MUTEX_INIT_CB if (malloc_initialized == false) return; #endif assert(malloc_initialized); /* Acquire all mutexes in a safe order. */ ctl_prefork(); prof_prefork(); malloc_mutex_prefork(&arenas_lock); for (i = 0; i < narenas_total; i++) { if (arenas[i] != NULL) arena_prefork(arenas[i]); } chunk_prefork(); base_prefork(); huge_prefork(); } #ifndef JEMALLOC_MUTEX_INIT_CB void jemalloc_postfork_parent(void) #else JEMALLOC_EXPORT void _malloc_postfork(void) #endif { unsigned i; #ifdef JEMALLOC_MUTEX_INIT_CB if (malloc_initialized == false) return; #endif assert(malloc_initialized); /* Release all mutexes, now that fork() has completed. */ huge_postfork_parent(); base_postfork_parent(); chunk_postfork_parent(); for (i = 0; i < narenas_total; i++) { if (arenas[i] != NULL) arena_postfork_parent(arenas[i]); } malloc_mutex_postfork_parent(&arenas_lock); prof_postfork_parent(); ctl_postfork_parent(); } void jemalloc_postfork_child(void) { unsigned i; assert(malloc_initialized); /* Release all mutexes, now that fork() has completed. */ huge_postfork_child(); base_postfork_child(); chunk_postfork_child(); for (i = 0; i < narenas_total; i++) { if (arenas[i] != NULL) arena_postfork_child(arenas[i]); } malloc_mutex_postfork_child(&arenas_lock); prof_postfork_child(); ctl_postfork_child(); } +void +_malloc_first_thread(void) +{ + + (void)malloc_mutex_first_thread(); +} + /******************************************************************************/ /* * The following functions are used for TLS allocation/deallocation in static * binaries on FreeBSD. The primary difference between these and i[mcd]alloc() * is that these avoid accessing TLS variables. */ static void * a0alloc(size_t size, bool zero) { if (malloc_init()) return (NULL); if (size == 0) size = 1; if (size <= arena_maxclass) return (arena_malloc(arenas[0], size, zero, false)); else return (huge_malloc(size, zero, huge_dss_prec_get(arenas[0]))); } void * a0malloc(size_t size) { return (a0alloc(size, false)); } void * a0calloc(size_t num, size_t size) { return (a0alloc(num * size, true)); } void a0free(void *ptr) { arena_chunk_t *chunk; if (ptr == NULL) return; chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); if (chunk != ptr) arena_dalloc(chunk->arena, chunk, ptr, false); else huge_dalloc(ptr, true); } /******************************************************************************/ Index: head/contrib/jemalloc/src/mutex.c =================================================================== --- head/contrib/jemalloc/src/mutex.c (revision 276629) +++ head/contrib/jemalloc/src/mutex.c (revision 276630) @@ -1,160 +1,171 @@ #define JEMALLOC_MUTEX_C_ #include "jemalloc/internal/jemalloc_internal.h" #if defined(JEMALLOC_LAZY_LOCK) && !defined(_WIN32) #include #endif #ifndef _CRT_SPINCOUNT #define _CRT_SPINCOUNT 4000 #endif /******************************************************************************/ /* Data. */ #ifdef JEMALLOC_LAZY_LOCK bool isthreaded = false; #endif #ifdef JEMALLOC_MUTEX_INIT_CB static bool postpone_init = true; static malloc_mutex_t *postponed_mutexes = NULL; #endif #if defined(JEMALLOC_LAZY_LOCK) && !defined(_WIN32) static void pthread_create_once(void); #endif /******************************************************************************/ /* * We intercept pthread_create() calls in order to toggle isthreaded if the * process goes multi-threaded. */ #if defined(JEMALLOC_LAZY_LOCK) && !defined(_WIN32) static int (*pthread_create_fptr)(pthread_t *__restrict, const pthread_attr_t *, void *(*)(void *), void *__restrict); static void pthread_create_once(void) { pthread_create_fptr = dlsym(RTLD_NEXT, "pthread_create"); if (pthread_create_fptr == NULL) { malloc_write(": Error in dlsym(RTLD_NEXT, " "\"pthread_create\")\n"); abort(); } isthreaded = true; } JEMALLOC_EXPORT int pthread_create(pthread_t *__restrict thread, const pthread_attr_t *__restrict attr, void *(*start_routine)(void *), void *__restrict arg) { static pthread_once_t once_control = PTHREAD_ONCE_INIT; pthread_once(&once_control, pthread_create_once); return (pthread_create_fptr(thread, attr, start_routine, arg)); } #endif /******************************************************************************/ #ifdef JEMALLOC_MUTEX_INIT_CB JEMALLOC_EXPORT int _pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex, void *(calloc_cb)(size_t, size_t)); -__weak_reference(_pthread_mutex_init_calloc_cb_stub, - _pthread_mutex_init_calloc_cb); - +#pragma weak _pthread_mutex_init_calloc_cb int -_pthread_mutex_init_calloc_cb_stub(pthread_mutex_t *mutex, +_pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex, void *(calloc_cb)(size_t, size_t)) { - return (0); + return (((int (*)(pthread_mutex_t *, void *(*)(size_t, size_t))) + __libc_interposing[INTERPOS__pthread_mutex_init_calloc_cb])( + mutex, calloc_cb)); } #endif bool malloc_mutex_init(malloc_mutex_t *mutex) { #ifdef _WIN32 if (!InitializeCriticalSectionAndSpinCount(&mutex->lock, _CRT_SPINCOUNT)) return (true); #elif (defined(JEMALLOC_OSSPIN)) mutex->lock = 0; #elif (defined(JEMALLOC_MUTEX_INIT_CB)) if (postpone_init) { mutex->postponed_next = postponed_mutexes; postponed_mutexes = mutex; } else { if (_pthread_mutex_init_calloc_cb(&mutex->lock, base_calloc) != 0) return (true); } #else pthread_mutexattr_t attr; if (pthread_mutexattr_init(&attr) != 0) return (true); pthread_mutexattr_settype(&attr, MALLOC_MUTEX_TYPE); if (pthread_mutex_init(&mutex->lock, &attr) != 0) { pthread_mutexattr_destroy(&attr); return (true); } pthread_mutexattr_destroy(&attr); #endif return (false); } void malloc_mutex_prefork(malloc_mutex_t *mutex) { malloc_mutex_lock(mutex); } void malloc_mutex_postfork_parent(malloc_mutex_t *mutex) { malloc_mutex_unlock(mutex); } void malloc_mutex_postfork_child(malloc_mutex_t *mutex) { #ifdef JEMALLOC_MUTEX_INIT_CB malloc_mutex_unlock(mutex); #else if (malloc_mutex_init(mutex)) { malloc_printf(": Error re-initializing mutex in " "child\n"); if (opt_abort) abort(); } #endif } bool -mutex_boot(void) +malloc_mutex_first_thread(void) { #ifdef JEMALLOC_MUTEX_INIT_CB postpone_init = false; while (postponed_mutexes != NULL) { if (_pthread_mutex_init_calloc_cb(&postponed_mutexes->lock, base_calloc) != 0) return (true); postponed_mutexes = postponed_mutexes->postponed_next; } #endif return (false); +} + +bool +mutex_boot(void) +{ + +#ifndef JEMALLOC_MUTEX_INIT_CB + return (malloc_mutex_first_thread()); +#else + return (false); +#endif } Index: head/lib/libc/Makefile =================================================================== --- head/lib/libc/Makefile (revision 276629) +++ head/lib/libc/Makefile (revision 276630) @@ -1,172 +1,176 @@ # @(#)Makefile 8.2 (Berkeley) 2/3/94 # $FreeBSD$ SHLIBDIR?= /lib .include LIBC_SRCTOP?= ${.CURDIR} # Pick the current architecture directory for libc. In general, this is # named MACHINE_CPUARCH, but some ABIs are different enough to require # their own libc, so allow a directory named MACHINE_ARCH to override this. .if exists(${LIBC_SRCTOP}/${MACHINE_ARCH}) LIBC_ARCH=${MACHINE_ARCH} .else LIBC_ARCH=${MACHINE_CPUARCH} .endif # All library objects contain FreeBSD revision strings by default; they may be # excluded as a space-saving measure. To produce a library that does # not contain these strings, add -DSTRIP_FBSDID (see ) to CFLAGS # below. Note: there are no IDs for syscall stubs whose sources are generated. # To include legacy CSRG sccsid strings, add -DLIBC_SCCS and -DSYSLIBC_SCCS # to CFLAGS below. -DSYSLIBC_SCCS affects just the system call stubs. LIB=c SHLIB_MAJOR= 7 SHLIB_LDSCRIPT=libc.ldscript WARNS?= 2 CFLAGS+=-I${LIBC_SRCTOP}/include -I${LIBC_SRCTOP}/../../include CFLAGS+=-I${LIBC_SRCTOP}/${LIBC_ARCH} .if ${MK_NLS} != "no" CFLAGS+=-DNLS .endif CLEANFILES+=tags INSTALL_PIC_ARCHIVE= PRECIOUSLIB= .ifndef NO_THREAD_STACK_UNWIND CANCELPOINTS_CFLAGS=-fexceptions CFLAGS+=${CANCELPOINTS_CFLAGS} .endif # # Link with static libcompiler_rt.a. # LDFLAGS+= -nodefaultlibs LIBADD+= compiler_rt .if ${MK_SSP} != "no" LIBADD+= ssp_nonshared .endif # Extras that live in either libc.a or libc_nonshared.a LIBC_NONSHARED_SRCS= # Define (empty) variables so that make doesn't give substitution # errors if the included makefiles don't change these: MDSRCS= MISRCS= MDASM= MIASM= NOASM= .include "${LIBC_SRCTOP}/${LIBC_ARCH}/Makefile.inc" .include "${LIBC_SRCTOP}/db/Makefile.inc" .include "${LIBC_SRCTOP}/compat-43/Makefile.inc" .include "${LIBC_SRCTOP}/gdtoa/Makefile.inc" .include "${LIBC_SRCTOP}/gen/Makefile.inc" .include "${LIBC_SRCTOP}/gmon/Makefile.inc" .if ${MK_ICONV} != "no" .include "${LIBC_SRCTOP}/iconv/Makefile.inc" .endif .include "${LIBC_SRCTOP}/inet/Makefile.inc" .include "${LIBC_SRCTOP}/isc/Makefile.inc" .include "${LIBC_SRCTOP}/locale/Makefile.inc" .include "${LIBC_SRCTOP}/md/Makefile.inc" .include "${LIBC_SRCTOP}/nameser/Makefile.inc" .include "${LIBC_SRCTOP}/net/Makefile.inc" .include "${LIBC_SRCTOP}/nls/Makefile.inc" .include "${LIBC_SRCTOP}/posix1e/Makefile.inc" .if ${LIBC_ARCH} != "amd64" && \ ${LIBC_ARCH} != "powerpc64" && \ ${LIBC_ARCH} != "sparc64" && \ ${MACHINE_ARCH:Mmipsn32*} == "" && \ ${MACHINE_ARCH:Mmips64*} == "" .include "${LIBC_SRCTOP}/quad/Makefile.inc" .endif .include "${LIBC_SRCTOP}/regex/Makefile.inc" .include "${LIBC_SRCTOP}/resolv/Makefile.inc" .include "${LIBC_SRCTOP}/stdio/Makefile.inc" .include "${LIBC_SRCTOP}/stdlib/Makefile.inc" .include "${LIBC_SRCTOP}/stdlib/jemalloc/Makefile.inc" .include "${LIBC_SRCTOP}/stdtime/Makefile.inc" .include "${LIBC_SRCTOP}/string/Makefile.inc" .include "${LIBC_SRCTOP}/sys/Makefile.inc" .include "${LIBC_SRCTOP}/rpc/Makefile.inc" .include "${LIBC_SRCTOP}/uuid/Makefile.inc" .include "${LIBC_SRCTOP}/xdr/Makefile.inc" .if (${LIBC_ARCH} == "arm" && ${MACHINE_ARCH} != "armv6hf") ||\ ${LIBC_ARCH} == "mips" .include "${LIBC_SRCTOP}/softfloat/Makefile.inc" .endif .if ${MK_NIS} != "no" CFLAGS+= -DYP .include "${LIBC_SRCTOP}/yp/Makefile.inc" .endif .include "${LIBC_SRCTOP}/capability/Makefile.inc" .if ${MK_HESIOD} != "no" CFLAGS+= -DHESIOD .endif .if ${MK_FP_LIBC} == "no" CFLAGS+= -DNO_FLOATING_POINT .endif .if ${MK_NS_CACHING} != "no" CFLAGS+= -DNS_CACHING .endif .if defined(_FREEFALL_CONFIG) CFLAGS+=-D_FREEFALL_CONFIG .endif STATICOBJS+=${LIBC_NONSHARED_SRCS:S/.c$/.o/} VERSION_DEF=${LIBC_SRCTOP}/Versions.def SYMBOL_MAPS=${SYM_MAPS} CFLAGS+= -DSYMBOL_VERSIONING # If there are no machine dependent sources, append all the # machine-independent sources: .if empty(MDSRCS) SRCS+= ${MISRCS} .else # Append machine-dependent sources, then append machine-independent sources # for which there is no machine-dependent variant. SRCS+= ${MDSRCS} .for _src in ${MISRCS} .if ${MDSRCS:R:M${_src:R}} == "" SRCS+= ${_src} .endif .endfor .endif KQSRCS= adddi3.c anddi3.c ashldi3.c ashrdi3.c cmpdi2.c divdi3.c iordi3.c \ lshldi3.c lshrdi3.c moddi3.c muldi3.c negdi2.c notdi2.c qdivrem.c \ subdi3.c ucmpdi2.c udivdi3.c umoddi3.c xordi3.c KSRCS= bcmp.c ffs.c ffsl.c fls.c flsl.c mcount.c strcat.c strchr.c \ strcmp.c strcpy.c strlen.c strncpy.c strrchr.c libkern: libkern.gen libkern.${LIBC_ARCH} libkern.gen: ${KQSRCS} ${KSRCS} cp -fp ${LIBC_SRCTOP}/quad/quad.h ${.ALLSRC} ${DESTDIR}/sys/libkern libkern.${LIBC_ARCH}:: ${KMSRCS} .if defined(KMSRCS) && !empty(KMSRCS) cp -fp ${.ALLSRC} ${DESTDIR}/sys/libkern/${LIBC_ARCH} .endif +.if ${MK_SYSCALL_COMPAT} != "no" +CFLAGS+=-DSYSCALL_COMPAT +.endif + .include .include # Disable warnings in contributed sources. CWARNFLAGS:= ${.IMPSRC:Ngdtoa_*.c:C/^.+$/${CWARNFLAGS}/:C/^$/-w/} # XXX For now, we don't allow libc to be compiled with # -fstack-protector-all because it breaks rtld. We may want to make a librtld # in the future to circumvent this. SSP_CFLAGS:= ${SSP_CFLAGS:S/^-fstack-protector-all$/-fstack-protector/} # Disable stack protection for SSP symbols. SSP_CFLAGS:= ${.IMPSRC:N*/stack_protector.c:C/^.+$/${SSP_CFLAGS}/} # Generate stack unwinding tables for cancellation points CANCELPOINTS_CFLAGS:= ${.IMPSRC:Mcancelpoints_*:C/^.+$/${CANCELPOINTS_CFLAGS}/:C/^$//} Index: head/lib/libc/compat-43/Symbol.map =================================================================== --- head/lib/libc/compat-43/Symbol.map (revision 276629) +++ head/lib/libc/compat-43/Symbol.map (revision 276630) @@ -1,31 +1,32 @@ /* * $FreeBSD$ */ FBSD_1.0 { creat; gethostid; getwd; killpg; sethostid; setpgrp; setrgid; setruid; sigblock; sigpause; sigsetmask; sigvec; }; FBSD_1.2 { sighold; sigignore; sigrelse; sigset; xsi_sigpause; }; FBSDprivate_1.0 { __creat; _creat; + __libc_creat; }; Index: head/lib/libc/compat-43/creat.c =================================================================== --- head/lib/libc/compat-43/creat.c (revision 276629) +++ head/lib/libc/compat-43/creat.c (revision 276630) @@ -1,46 +1,58 @@ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)creat.c 8.1 (Berkeley) 6/2/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include "un-namespace.h" +#include "libc_private.h" +__weak_reference(__libc_creat, __creat); +__weak_reference(__libc_creat, _creat); + +#pragma weak creat int -__creat(const char *path, mode_t mode) +creat(const char *path, mode_t mode) { - return(_open(path, O_WRONLY|O_CREAT|O_TRUNC, mode)); + + return (((int (*)(const char *, mode_t)) + __libc_interposing[INTERPOS_creat])(path, mode)); } -__weak_reference(__creat, creat); -__weak_reference(__creat, _creat); + +int +__libc_creat(const char *path, mode_t mode) +{ + + return(__sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode)); +} Index: head/lib/libc/gen/swapcontext.c =================================================================== --- head/lib/libc/gen/swapcontext.c (revision 276629) +++ head/lib/libc/gen/swapcontext.c (nonexistent) @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2001 Daniel M. Eischen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Neither the name of the author nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include - -#include -#include - -__weak_reference(__swapcontext, swapcontext); - -int -__swapcontext(ucontext_t *oucp, const ucontext_t *ucp) -{ - int ret; - - if ((oucp == NULL) || (ucp == NULL)) { - errno = EINVAL; - return (-1); - } - oucp->uc_flags &= ~UCF_SWAPPED; - ret = getcontext(oucp); - if ((ret == 0) && !(oucp->uc_flags & UCF_SWAPPED)) { - oucp->uc_flags |= UCF_SWAPPED; - ret = setcontext(ucp); - } - return (ret); -} Property changes on: head/lib/libc/gen/swapcontext.c ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/lib/libc/gen/Makefile.inc =================================================================== --- head/lib/libc/gen/Makefile.inc (revision 276629) +++ head/lib/libc/gen/Makefile.inc (revision 276630) @@ -1,514 +1,515 @@ # @(#)Makefile.inc 8.6 (Berkeley) 5/4/95 # $FreeBSD$ # machine-independent gen sources .PATH: ${LIBC_SRCTOP}/${LIBC_ARCH}/gen ${LIBC_SRCTOP}/gen SRCS+= __getosreldate.c \ + __pthread_mutex_init_calloc_cb_stub.c \ __xuname.c \ _once_stub.c \ _pthread_stubs.c \ _rand48.c \ _spinlock_stub.c \ _thread_init.c \ alarm.c \ arc4random.c \ assert.c \ auxv.c \ basename.c \ cap_sandboxed.c \ check_utility_compat.c \ clock.c \ clock_getcpuclockid.c \ closedir.c \ confstr.c \ crypt.c \ ctermid.c \ daemon.c \ devname.c \ dirfd.c \ dirname.c \ disklabel.c \ dlfcn.c \ drand48.c \ dup3.c \ elf_utils.c \ erand48.c \ err.c \ errlst.c \ errno.c \ exec.c \ fdevname.c \ feature_present.c \ fmtcheck.c \ fmtmsg.c \ fnmatch.c \ fpclassify.c \ frexp.c \ fstab.c \ ftok.c \ fts.c \ fts-compat.c \ ftw.c \ getbootfile.c \ getbsize.c \ getcap.c \ getcwd.c \ getdomainname.c \ getgrent.c \ getgrouplist.c \ gethostname.c \ getloadavg.c \ getlogin.c \ getmntinfo.c \ getnetgrent.c \ getosreldate.c \ getpagesize.c \ getpagesizes.c \ getpeereid.c \ getprogname.c \ getpwent.c \ getttyent.c \ getusershell.c \ getutxent.c \ getvfsbyname.c \ glob.c \ initgroups.c \ isatty.c \ isinf.c \ isnan.c \ jrand48.c \ lcong48.c \ libc_dlopen.c \ lockf.c \ lrand48.c \ mrand48.c \ nftw.c \ nice.c \ nlist.c \ nrand48.c \ opendir.c \ pause.c \ pmadvise.c \ popen.c \ posix_spawn.c \ psignal.c \ pututxline.c \ pw_scan.c \ raise.c \ readdir.c \ readpassphrase.c \ rewinddir.c \ scandir.c \ seed48.c \ seekdir.c \ semctl.c \ setdomainname.c \ sethostname.c \ setjmperr.c \ setmode.c \ setproctitle.c \ setprogname.c \ siginterrupt.c \ siglist.c \ signal.c \ sigsetops.c \ sleep.c \ srand48.c \ statvfs.c \ stringlist.c \ strtofflags.c \ sysconf.c \ sysctl.c \ sysctlbyname.c \ sysctlnametomib.c \ syslog.c \ telldir.c \ termios.c \ time.c \ times.c \ timezone.c \ tls.c \ ttyname.c \ ttyslot.c \ ualarm.c \ ulimit.c \ uname.c \ unvis-compat.c \ usleep.c \ utime.c \ utxdb.c \ valloc.c \ wait.c \ wait3.c \ waitpid.c \ waitid.c \ wordexp.c .PATH: ${LIBC_SRCTOP}/../../contrib/libc-pwcache SRCS+= pwcache.c pwcache.h .PATH: ${LIBC_SRCTOP}/../../contrib/libc-vis CFLAGS+= -I${LIBC_SRCTOP}/../../contrib/libc-vis SRCS+= unvis.c vis.c MISRCS+=modf.c CANCELPOINTS_SRCS=sem.c sem_new.c .for src in ${CANCELPOINTS_SRCS} SRCS+=cancelpoints_${src} CLEANFILES+=cancelpoints_${src} cancelpoints_${src}: ln -sf ${LIBC_SRCTOP}/gen/${src} ${.TARGET} .endfor SYM_MAPS+=${LIBC_SRCTOP}/gen/Symbol.map # machine-dependent gen sources .sinclude "${LIBC_SRCTOP}/${LIBC_ARCH}/gen/Makefile.inc" MAN+= alarm.3 \ arc4random.3 \ basename.3 \ cap_rights_get.3 \ cap_sandboxed.3 \ check_utility_compat.3 \ clock.3 \ clock_getcpuclockid.3 \ confstr.3 \ ctermid.3 \ daemon.3 \ devname.3 \ directory.3 \ dirname.3 \ dl_iterate_phdr.3 \ dladdr.3 \ dlinfo.3 \ dllockinit.3 \ dlopen.3 \ dup3.3 \ err.3 \ exec.3 \ feature_present.3 \ fmtcheck.3 \ fmtmsg.3 \ fnmatch.3 \ fpclassify.3 \ frexp.3 \ ftok.3 \ fts.3 \ ftw.3 \ getbootfile.3 \ getbsize.3 \ getcap.3 \ getcontext.3 \ getcwd.3 \ getdiskbyname.3 \ getdomainname.3 \ getfsent.3 \ getgrent.3 \ getgrouplist.3 \ gethostname.3 \ getloadavg.3 \ getmntinfo.3 \ getnetgrent.3 \ getosreldate.3 \ getpagesize.3 \ getpagesizes.3 \ getpass.3 \ getpeereid.3 \ getprogname.3 \ getpwent.3 \ getttyent.3 \ getusershell.3 \ getutxent.3 \ getvfsbyname.3 \ glob.3 \ initgroups.3 \ isgreater.3 \ ldexp.3 \ lockf.3 \ makecontext.3 \ modf.3 \ nice.3 \ nlist.3 \ pause.3 \ popen.3 \ posix_spawn.3 \ posix_spawn_file_actions_addopen.3 \ posix_spawn_file_actions_init.3 \ posix_spawnattr_getflags.3 \ posix_spawnattr_getpgroup.3 \ posix_spawnattr_getschedparam.3 \ posix_spawnattr_getschedpolicy.3 \ posix_spawnattr_init.3 \ posix_spawnattr_getsigdefault.3 \ posix_spawnattr_getsigmask.3 \ psignal.3 \ pwcache.3 \ raise.3 \ rand48.3 \ readpassphrase.3 \ rfork_thread.3 \ scandir.3 \ sem_destroy.3 \ sem_getvalue.3 \ sem_init.3 \ sem_open.3 \ sem_post.3 \ sem_timedwait.3 \ sem_wait.3 \ setjmp.3 \ setmode.3 \ setproctitle.3 \ siginterrupt.3 \ signal.3 \ sigsetops.3 \ sleep.3 \ statvfs.3 \ stringlist.3 \ strtofflags.3 \ sysconf.3 \ sysctl.3 \ syslog.3 \ tcgetpgrp.3 \ tcgetsid.3 \ tcsendbreak.3 \ tcsetattr.3 \ tcsetpgrp.3 \ tcsetsid.3 \ time.3 \ times.3 \ timezone.3 \ ttyname.3 \ tzset.3 \ ualarm.3 \ ucontext.3 \ ulimit.3 \ uname.3 \ unvis.3 \ usleep.3 \ utime.3 \ valloc.3 \ vis.3 \ wordexp.3 MLINKS+=arc4random.3 arc4random_addrandom.3 \ arc4random.3 arc4random_stir.3 \ arc4random.3 arc4random_buf.3 \ arc4random.3 arc4random_uniform.3 MLINKS+=basename.3 basename_r.3 MLINKS+=ctermid.3 ctermid_r.3 MLINKS+=devname.3 devname_r.3 MLINKS+=devname.3 fdevname.3 MLINKS+=devname.3 fdevname_r.3 MLINKS+=directory.3 closedir.3 \ directory.3 dirfd.3 \ directory.3 fdclosedir.3 \ directory.3 fdopendir.3 \ directory.3 opendir.3 \ directory.3 readdir.3 \ directory.3 readdir_r.3 \ directory.3 rewinddir.3 \ directory.3 seekdir.3 \ directory.3 telldir.3 MLINKS+=dlopen.3 fdlopen.3 \ dlopen.3 dlclose.3 \ dlopen.3 dlerror.3 \ dlopen.3 dlfunc.3 \ dlopen.3 dlsym.3 MLINKS+=err.3 err_set_exit.3 \ err.3 err_set_file.3 \ err.3 errc.3 \ err.3 errx.3 \ err.3 verr.3 \ err.3 verrc.3 \ err.3 verrx.3 \ err.3 vwarn.3 \ err.3 vwarnc.3 \ err.3 vwarnx.3 \ err.3 warnc.3 \ err.3 warn.3 \ err.3 warnx.3 MLINKS+=exec.3 execl.3 \ exec.3 execle.3 \ exec.3 execlp.3 \ exec.3 exect.3 \ exec.3 execv.3 \ exec.3 execvP.3 \ exec.3 execvp.3 MLINKS+=fpclassify.3 finite.3 \ fpclassify.3 finitef.3 \ fpclassify.3 isfinite.3 \ fpclassify.3 isinf.3 \ fpclassify.3 isnan.3 \ fpclassify.3 isnormal.3 MLINKS+=frexp.3 frexpf.3 \ frexp.3 frexpl.3 MLINKS+=fts.3 fts_children.3 \ fts.3 fts_close.3 \ fts.3 fts_open.3 \ fts.3 fts_read.3 \ fts.3 fts_set.3 \ fts.3 fts_set_clientptr.3 \ fts.3 fts_get_clientptr.3 \ fts.3 fts_get_stream.3 MLINKS+=ftw.3 nftw.3 MLINKS+=getcap.3 cgetcap.3 \ getcap.3 cgetclose.3 \ getcap.3 cgetent.3 \ getcap.3 cgetfirst.3 \ getcap.3 cgetmatch.3 \ getcap.3 cgetnext.3 \ getcap.3 cgetnum.3 \ getcap.3 cgetset.3 \ getcap.3 cgetstr.3 \ getcap.3 cgetustr.3 MLINKS+=getcwd.3 getwd.3 MLINKS+=getcontext.3 getcontextx.3 MLINKS+=getcontext.3 setcontext.3 MLINKS+=getdomainname.3 setdomainname.3 MLINKS+=getfsent.3 endfsent.3 \ getfsent.3 getfsfile.3 \ getfsent.3 getfsspec.3 \ getfsent.3 getfstype.3 \ getfsent.3 setfsent.3 \ getfsent.3 setfstab.3 \ getfsent.3 getfstab.3 MLINKS+=getgrent.3 endgrent.3 \ getgrent.3 getgrgid.3 \ getgrent.3 getgrnam.3 \ getgrent.3 setgrent.3 \ getgrent.3 setgroupent.3 \ getgrent.3 getgrent_r.3 \ getgrent.3 getgrnam_r.3 \ getgrent.3 getgrgid_r.3 MLINKS+=gethostname.3 sethostname.3 MLINKS+=getnetgrent.3 endnetgrent.3 \ getnetgrent.3 innetgr.3 \ getnetgrent.3 setnetgrent.3 MLINKS+=getprogname.3 setprogname.3 MLINKS+=getpwent.3 endpwent.3 \ getpwent.3 getpwnam.3 \ getpwent.3 getpwuid.3 \ getpwent.3 setpassent.3 \ getpwent.3 setpwent.3 \ getpwent.3 setpwfile.3 \ getpwent.3 getpwent_r.3 \ getpwent.3 getpwnam_r.3 \ getpwent.3 getpwuid_r.3 MLINKS+=getttyent.3 endttyent.3 \ getttyent.3 getttynam.3 \ getttyent.3 isdialuptty.3 \ getttyent.3 isnettty.3 \ getttyent.3 setttyent.3 MLINKS+=getusershell.3 endusershell.3 \ getusershell.3 setusershell.3 MLINKS+=getutxent.3 endutxent.3 \ getutxent.3 getutxid.3 \ getutxent.3 getutxline.3 \ getutxent.3 getutxuser.3 \ getutxent.3 pututxline.3 \ getutxent.3 setutxdb.3 \ getutxent.3 setutxent.3 \ getutxent.3 utmpx.3 MLINKS+=glob.3 globfree.3 MLINKS+=isgreater.3 isgreaterequal.3 \ isgreater.3 isless.3 \ isgreater.3 islessequal.3 \ isgreater.3 islessgreater.3 \ isgreater.3 isunordered.3 MLINKS+=ldexp.3 ldexpf.3 \ ldexp.3 ldexpl.3 MLINKS+=makecontext.3 swapcontext.3 MLINKS+=modf.3 modff.3 \ modf.3 modfl.3 MLINKS+=popen.3 pclose.3 MLINKS+=posix_spawn.3 posix_spawnp.3 \ posix_spawn_file_actions_addopen.3 posix_spawn_file_actions_addclose.3 \ posix_spawn_file_actions_addopen.3 posix_spawn_file_actions_adddup2.3 \ posix_spawn_file_actions_init.3 posix_spawn_file_actions_destroy.3 \ posix_spawnattr_getflags.3 posix_spawnattr_setflags.3 \ posix_spawnattr_getpgroup.3 posix_spawnattr_setpgroup.3 \ posix_spawnattr_getschedparam.3 posix_spawnattr_setschedparam.3 \ posix_spawnattr_getschedpolicy.3 posix_spawnattr_setschedpolicy.3 \ posix_spawnattr_getsigdefault.3 posix_spawnattr_setsigdefault.3 \ posix_spawnattr_getsigmask.3 posix_spawnattr_setsigmask.3 \ posix_spawnattr_init.3 posix_spawnattr_destroy.3 MLINKS+=psignal.3 strsignal.3 \ psignal.3 sys_siglist.3 \ psignal.3 sys_signame.3 MLINKS+=pwcache.3 group_from_gid.3 \ pwcache.3 user_from_uid.3 MLINKS+=rand48.3 _rand48.3 \ rand48.3 drand48.3 \ rand48.3 erand48.3 \ rand48.3 jrand48.3 \ rand48.3 lcong48.3 \ rand48.3 lrand48.3 \ rand48.3 mrand48.3 \ rand48.3 nrand48.3 \ rand48.3 seed48.3 \ rand48.3 srand48.3 MLINKS+=scandir.3 alphasort.3 MLINKS+=sem_open.3 sem_close.3 \ sem_open.3 sem_unlink.3 MLINKS+=sem_wait.3 sem_trywait.3 MLINKS+=setjmp.3 _longjmp.3 \ setjmp.3 _setjmp.3 \ setjmp.3 longjmp.3 \ setjmp.3 longjmperr.3 \ setjmp.3 longjmperror.3 \ setjmp.3 siglongjmp.3 \ setjmp.3 sigsetjmp.3 MLINKS+=setmode.3 getmode.3 MLINKS+=sigsetops.3 sigaddset.3 \ sigsetops.3 sigdelset.3 \ sigsetops.3 sigemptyset.3 \ sigsetops.3 sigfillset.3 \ sigsetops.3 sigismember.3 MLINKS+=statvfs.3 fstatvfs.3 MLINKS+=stringlist.3 sl_add.3 \ stringlist.3 sl_find.3 \ stringlist.3 sl_free.3 \ stringlist.3 sl_init.3 MLINKS+=strtofflags.3 fflagstostr.3 MLINKS+=sysctl.3 sysctlbyname.3 \ sysctl.3 sysctlnametomib.3 MLINKS+=syslog.3 closelog.3 \ syslog.3 openlog.3 \ syslog.3 setlogmask.3 \ syslog.3 vsyslog.3 MLINKS+=tcsendbreak.3 tcdrain.3 \ tcsendbreak.3 tcflow.3 \ tcsendbreak.3 tcflush.3 MLINKS+=tcsetattr.3 cfgetispeed.3 \ tcsetattr.3 cfgetospeed.3 \ tcsetattr.3 cfmakeraw.3 \ tcsetattr.3 cfmakesane.3 \ tcsetattr.3 cfsetispeed.3 \ tcsetattr.3 cfsetospeed.3 \ tcsetattr.3 cfsetspeed.3 \ tcsetattr.3 tcgetattr.3 MLINKS+=ttyname.3 isatty.3 \ ttyname.3 ttyname_r.3 MLINKS+=tzset.3 tzsetwall.3 MLINKS+=unvis.3 strunvis.3 \ unvis.3 strunvisx.3 MLINKS+=vis.3 nvis.3 \ vis.3 snvis.3 \ vis.3 strenvisx.3 \ vis.3 strnunvis.3 \ vis.3 strnunvisx.3 \ vis.3 strnvis.3 \ vis.3 strnvisx.3 \ vis.3 strsenvisx.3 \ vis.3 strsnvis.3 \ vis.3 strsnvisx.3 \ vis.3 strsvis.3 \ vis.3 strsvisx.3 \ vis.3 strvis.3 \ vis.3 strvisx.3 \ vis.3 svis.3 MLINKS+=wordexp.3 wordfree.3 Index: head/lib/libc/gen/Symbol.map =================================================================== --- head/lib/libc/gen/Symbol.map (revision 276629) +++ head/lib/libc/gen/Symbol.map (revision 276630) @@ -1,541 +1,550 @@ /* * $FreeBSD$ */ FBSD_1.0 { __xuname; pthread_atfork; pthread_attr_destroy; pthread_attr_getdetachstate; pthread_attr_getguardsize; pthread_attr_getinheritsched; pthread_attr_getschedparam; pthread_attr_getschedpolicy; pthread_attr_getscope; pthread_attr_getstackaddr; pthread_attr_getstacksize; pthread_attr_init; pthread_attr_setdetachstate; pthread_attr_setguardsize; pthread_attr_setinheritsched; pthread_attr_setschedparam; pthread_attr_setschedpolicy; pthread_attr_setscope; pthread_attr_setstackaddr; pthread_attr_setstacksize; pthread_cancel; pthread_cleanup_pop; pthread_cleanup_push; pthread_cond_broadcast; pthread_cond_destroy; pthread_cond_init; pthread_cond_signal; pthread_cond_timedwait; pthread_cond_wait; pthread_detach; pthread_equal; pthread_exit; pthread_getspecific; pthread_join; pthread_key_create; pthread_key_delete; pthread_kill; pthread_main_np; pthread_mutex_destroy; pthread_mutex_init; pthread_mutex_lock; pthread_mutex_trylock; pthread_mutex_unlock; pthread_mutexattr_destroy; pthread_mutexattr_init; pthread_mutexattr_settype; pthread_once; pthread_rwlock_destroy; pthread_rwlock_init; pthread_rwlock_rdlock; pthread_rwlock_tryrdlock; pthread_rwlock_trywrlock; pthread_rwlock_unlock; pthread_rwlock_wrlock; pthread_self; pthread_setcancelstate; pthread_setcanceltype; pthread_setspecific; pthread_sigmask; pthread_testcancel; alarm; arc4random; arc4random_addrandom; arc4random_stir; __assert; basename; check_utility_compat; clock; closedir; confstr; encrypt; des_setkey; des_cipher; setkey; ctermid; ctermid_r; daemon; devname; devname_r; dirname; getdiskbyname; dladdr; dlclose; dlerror; dlfunc; dllockinit; dlopen; dlsym; dlvsym; dlinfo; dl_iterate_phdr; drand48; erand48; err_set_file; err_set_exit; err; verr; errc; verrc; errx; verrx; warn; vwarn; warnc; vwarnc; warnx; vwarnx; sys_errlist; sys_nerr; errno; execl; execle; execlp; execv; execvp; execvP; fmtcheck; fmtmsg; fnmatch; __fpclassifyf; __fpclassifyd; __fpclassifyl; frexp; setfstab; getfstab; getfsent; getfsspec; getfsfile; setfsent; endfsent; ftok; ftw; glob; globfree; getbootfile; getbsize; cgetset; cgetcap; cgetent; cgetmatch; cgetfirst; cgetclose; cgetnext; cgetstr; cgetustr; cgetnum; getcwd; getdomainname; setgrent; setgroupent; endgrent; getgrent_r; getgrnam_r; getgrgid_r; getgrnam; getgrgid; getgrent; /* * Why are __gr_parse_entry() and __gr_match_entry() not static in * gen/getgrent.c? */ getgrouplist; gethostname; getloadavg; getlogin; getlogin_r; getmntinfo; setnetgrent; getnetgrent; endnetgrent; innetgr; getosreldate; getpagesize; getpeereid; _getprogname; getprogname; setpwent; setpassent; endpwent; getpwent_r; getpwnam_r; getpwuid_r; getpwnam; getpwuid; getpwent; getttynam; getttyent; setttyent; endttyent; isdialuptty; isnettty; getusershell; endusershell; setusershell; getvfsbyname; __isnan; isnan; __isnanf; isnanf; __isinf; isinf; __isinff; __isinfl; isatty; initgroups; jrand48; lcong48; ldexp; lockf; lrand48; modf; mrand48; nftw; nice; nlist; nrand48; opendir; pause; posix_madvise; popen; pclose; psignal; raise; readdir; readdir_r; readpassphrase; getpass; rewinddir; scandir; alphasort; seed48; seekdir; user_from_uid; group_from_gid; setdomainname; sethostname; longjmperror; getmode; setmode; setproctitle; setprogname; siginterrupt; sys_signame; sys_siglist; sys_nsig; signal; sigaddset; sigdelset; sigemptyset; sigfillset; sigismember; sleep; srand48; fstatvfs; statvfs; sl_init; sl_add; sl_free; sl_find; fflagstostr; strtofflags; sysconf; sysctl; sysctlbyname; sysctlnametomib; syslog; vsyslog; openlog; closelog; setlogmask; ttyname_r; ttyname; timezone; times; time; telldir; tcgetattr; tcsetattr; tcsetpgrp; tcgetpgrp; cfgetospeed; cfgetispeed; cfsetospeed; cfsetispeed; cfsetspeed; cfmakeraw; tcsendbreak; _init_tls; __tls_get_addr; tcdrain; tcflush; tcflow; ualarm; ulimit; uname; strunvis; strunvisx; usleep; utime; valloc; vis; strvis; strvisx; wait; wait3; waitpid; wordexp; wordfree; }; FBSD_1.1 { arc4random_buf; arc4random_uniform; fdevname; fdevname_r; fdopendir; feature_present; fts_children; fts_close; fts_get_clientptr; fts_get_stream; fts_open; fts_read; fts_set; fts_set_clientptr; posix_spawn; posix_spawn_file_actions_addclose; posix_spawn_file_actions_adddup2; posix_spawn_file_actions_addopen; posix_spawn_file_actions_destroy; posix_spawn_file_actions_init; posix_spawnattr_destroy; posix_spawnattr_getflags; posix_spawnattr_getpgroup; posix_spawnattr_getschedparam; posix_spawnattr_getschedpolicy; posix_spawnattr_getsigdefault; posix_spawnattr_getsigmask; posix_spawnattr_init; posix_spawnattr_setflags; posix_spawnattr_setpgroup; posix_spawnattr_setschedparam; posix_spawnattr_setschedpolicy; posix_spawnattr_setsigdefault; posix_spawnattr_setsigmask; posix_spawnp; semctl; tcgetsid; tcsetsid; __pthread_cleanup_pop_imp; __pthread_cleanup_push_imp; }; FBSD_1.2 { basename_r; cfmakesane; endutxent; getpagesizes; getutxent; getutxid; getutxline; getutxuser; pututxline; sem_close; sem_destroy; sem_getvalue; sem_init; sem_open; sem_post; sem_timedwait; sem_trywait; sem_unlink; sem_wait; setutxdb; setutxent; }; FBSD_1.3 { clock_getcpuclockid; dirfd; dup3; fdclosedir; fdlopen; __FreeBSD_libc_enter_restricted_mode; getcontextx; gid_from_group; nvis; pwcache_userdb; pwcache_groupdb; snvis; strenvisx; strnunvis; strnunvisx; strnvis; strnvisx; strsenvisx; strsnvis; strsnvisx; strsvis; strsvisx; svis; uid_from_user; unvis; waitid; }; FBSD_1.4 { scandir_b; }; FBSDprivate_1.0 { /* needed by thread libraries */ __thr_jtable; _pthread_atfork; _pthread_attr_destroy; _pthread_attr_getdetachstate; _pthread_attr_getguardsize; _pthread_attr_getinheritsched; _pthread_attr_getschedparam; _pthread_attr_getschedpolicy; _pthread_attr_getscope; _pthread_attr_getstackaddr; _pthread_attr_getstacksize; _pthread_attr_init; _pthread_attr_setdetachstate; _pthread_attr_setguardsize; _pthread_attr_setinheritsched; _pthread_attr_setschedparam; _pthread_attr_setschedpolicy; _pthread_attr_setscope; _pthread_attr_setstackaddr; _pthread_attr_setstacksize; _pthread_cancel; _pthread_cancel_enter; _pthread_cancel_leave; _pthread_cleanup_pop; _pthread_cleanup_push; _pthread_cond_broadcast; _pthread_cond_destroy; _pthread_cond_init; _pthread_cond_signal; _pthread_cond_timedwait; _pthread_cond_wait; _pthread_detach; _pthread_equal; _pthread_exit; _pthread_getspecific; _pthread_join; _pthread_key_create; _pthread_key_delete; _pthread_kill; _pthread_main_np; _pthread_mutex_destroy; _pthread_mutex_init_calloc_cb; _pthread_mutex_init; _pthread_mutex_lock; _pthread_mutex_trylock; _pthread_mutex_unlock; _pthread_mutexattr_destroy; _pthread_mutexattr_init; _pthread_mutexattr_settype; _pthread_once; _pthread_rwlock_destroy; _pthread_rwlock_init; _pthread_rwlock_rdlock; _pthread_rwlock_tryrdlock; _pthread_rwlock_trywrlock; _pthread_rwlock_unlock; _pthread_rwlock_wrlock; _pthread_self; _pthread_setcancelstate; _pthread_setcanceltype; _pthread_setspecific; _pthread_sigmask; _pthread_testcancel; _spinlock; _spinlock_debug; _spinunlock; _rtld_addr_phdr; _rtld_atfork_pre; _rtld_atfork_post; _rtld_error; /* for private use */ _rtld_get_stack_prot; _rtld_is_dlopened; _rtld_thread_init; /* for private use */ __elf_phdr_match_addr; _err; _warn; __fmtcheck; /* __pw_match_entry; */ /* __pw_parse_entry; */ __fdnlist; /* used by libkvm */ /* __aout_fdnlist; */ /* __elf_is_okay__; */ /* __elf_fdnlist; */ __opendir2; __pause; _pause; __pw_scan; /* Used by (at least) libutil */ __raise; _raise; __sleep; _sleep; _rtld_allocate_tls; _rtld_free_tls; #if defined(i386) ___libc_tls_get_addr; /* x86 only */ #endif __libc_tls_get_addr; __tcdrain; _tcdrain; __usleep; _usleep; __wait; _wait; __waitpid; _waitpid; _libc_sem_init_compat; _libc_sem_destroy_compat; _libc_sem_open_compat; _libc_sem_close_compat; _libc_sem_unlink_compat; _libc_sem_wait_compat; _libc_sem_trywait_compat; _libc_sem_timedwait_compat; _libc_sem_post_compat; _libc_sem_getvalue_compat; + __libc_pause; + __libc_raise; + __libc_sleep; + __libc_tcdrain; + __libc_usleep; + __libc_wait; + __libc_wait3; + __libc_waitpid; + __elf_aux_vector; __pthread_map_stacks_exec; __fillcontextx; __fillcontextx2; __getcontextx_size; }; Index: head/lib/libc/gen/__pthread_mutex_init_calloc_cb_stub.c =================================================================== --- head/lib/libc/gen/__pthread_mutex_init_calloc_cb_stub.c (nonexistent) +++ head/lib/libc/gen/__pthread_mutex_init_calloc_cb_stub.c (revision 276630) @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include "libc_private.h" + +int +_pthread_mutex_init_calloc_cb_stub(pthread_mutex_t *mutex, + void *(calloc_cb)(size_t, size_t)) +{ + + return (0); +} Property changes on: head/lib/libc/gen/__pthread_mutex_init_calloc_cb_stub.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/gen/pause.c =================================================================== --- head/lib/libc/gen/pause.c (revision 276629) +++ head/lib/libc/gen/pause.c (revision 276630) @@ -1,54 +1,66 @@ /* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)pause.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include "un-namespace.h" +#include "libc_private.h" + /* * Backwards compatible pause. */ int -__pause(void) +__libc_pause(void) { sigset_t oset; if (_sigprocmask(SIG_BLOCK, NULL, &oset) == -1) return (-1); return (_sigsuspend(&oset)); } -__weak_reference(__pause, pause); -__weak_reference(__pause, _pause); + +#pragma weak pause +int +pause(void) +{ + + return (((int (*)(void)) + __libc_interposing[INTERPOS_pause])()); +} + +__weak_reference(__libc_pause, __pause); +__weak_reference(__libc_pause, _pause); Index: head/lib/libc/gen/raise.c =================================================================== --- head/lib/libc/gen/raise.c (revision 276629) +++ head/lib/libc/gen/raise.c (revision 276630) @@ -1,46 +1,58 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)raise.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include #include -__weak_reference(__raise, raise); -__weak_reference(__raise, _raise); +#include "libc_private.h" +__weak_reference(__libc_raise, __raise); +__weak_reference(__libc_raise, _raise); + +#pragma weak raise int -__raise(int s) +raise(int s) { - return(kill(getpid(), s)); + + return (((int (*)(int)) + __libc_interposing[INTERPOS_raise])(s)); +} + +int +__libc_raise(int s) +{ + + return (kill(getpid(), s)); } Index: head/lib/libc/gen/sleep.c =================================================================== --- head/lib/libc/gen/sleep.c (revision 276629) +++ head/lib/libc/gen/sleep.c (revision 276630) @@ -1,67 +1,78 @@ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)sleep.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include "un-namespace.h" +#include "libc_private.h" + +#pragma weak sleep unsigned int -__sleep(unsigned int seconds) +sleep(unsigned int seconds) { + + return (((unsigned int (*)(unsigned int)) + __libc_interposing[INTERPOS_sleep])(seconds)); +} + +unsigned int +__libc_sleep(unsigned int seconds) +{ struct timespec time_to_sleep; struct timespec time_remaining; /* * Avoid overflow when `seconds' is huge. This assumes that * the maximum value for a time_t is >= INT_MAX. */ if (seconds > INT_MAX) - return (seconds - INT_MAX + __sleep(INT_MAX)); + return (seconds - INT_MAX + __libc_sleep(INT_MAX)); time_to_sleep.tv_sec = seconds; time_to_sleep.tv_nsec = 0; if (_nanosleep(&time_to_sleep, &time_remaining) != -1) return (0); if (errno != EINTR) return (seconds); /* best guess */ return (time_remaining.tv_sec + (time_remaining.tv_nsec != 0)); /* round up */ } -__weak_reference(__sleep, sleep); -__weak_reference(__sleep, _sleep); +__weak_reference(__libc_sleep, __sleep); +__weak_reference(__libc_sleep, _sleep); Index: head/lib/libc/gen/termios.c =================================================================== --- head/lib/libc/gen/termios.c (revision 276629) +++ head/lib/libc/gen/termios.c (revision 276630) @@ -1,265 +1,277 @@ /*- * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)termios.c 8.2 (Berkeley) 2/21/94"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #define TTYDEFCHARS #include #include #include "un-namespace.h" +#include "libc_private.h" + int tcgetattr(int fd, struct termios *t) { return (_ioctl(fd, TIOCGETA, t)); } int tcsetattr(int fd, int opt, const struct termios *t) { struct termios localterm; if (opt & TCSASOFT) { localterm = *t; localterm.c_cflag |= CIGNORE; t = &localterm; } switch (opt & ~TCSASOFT) { case TCSANOW: return (_ioctl(fd, TIOCSETA, t)); case TCSADRAIN: return (_ioctl(fd, TIOCSETAW, t)); case TCSAFLUSH: return (_ioctl(fd, TIOCSETAF, t)); default: errno = EINVAL; return (-1); } } int tcsetpgrp(int fd, pid_t pgrp) { int s; s = pgrp; return (_ioctl(fd, TIOCSPGRP, &s)); } pid_t tcgetpgrp(int fd) { int s; if (_ioctl(fd, TIOCGPGRP, &s) < 0) return ((pid_t)-1); return ((pid_t)s); } pid_t tcgetsid(int fd) { int s; if (_ioctl(fd, TIOCGSID, &s) < 0) return ((pid_t)-1); return ((pid_t)s); } int tcsetsid(int fd, pid_t pid) { if (pid != getsid(0)) { errno = EINVAL; return (-1); } return (_ioctl(fd, TIOCSCTTY, NULL)); } speed_t cfgetospeed(const struct termios *t) { return (t->c_ospeed); } speed_t cfgetispeed(const struct termios *t) { return (t->c_ispeed); } int cfsetospeed(struct termios *t, speed_t speed) { t->c_ospeed = speed; return (0); } int cfsetispeed(struct termios *t, speed_t speed) { t->c_ispeed = speed; return (0); } int cfsetspeed(struct termios *t, speed_t speed) { t->c_ispeed = t->c_ospeed = speed; return (0); } /* * Make a pre-existing termios structure into "raw" mode: character-at-a-time * mode with no characters interpreted, 8-bit data path. */ void cfmakeraw(struct termios *t) { t->c_iflag &= ~(IMAXBEL|IXOFF|INPCK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IGNPAR); t->c_iflag |= IGNBRK; t->c_oflag &= ~OPOST; t->c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|ICANON|ISIG|IEXTEN|NOFLSH|TOSTOP|PENDIN); t->c_cflag &= ~(CSIZE|PARENB); t->c_cflag |= CS8|CREAD; t->c_cc[VMIN] = 1; t->c_cc[VTIME] = 0; } /* * Obtain a termios structure which is similar to the one provided by * the kernel. */ void cfmakesane(struct termios *t) { t->c_cflag = TTYDEF_CFLAG; t->c_iflag = TTYDEF_IFLAG; t->c_lflag = TTYDEF_LFLAG; t->c_oflag = TTYDEF_OFLAG; t->c_ispeed = TTYDEF_SPEED; t->c_ospeed = TTYDEF_SPEED; memcpy(&t->c_cc, ttydefchars, sizeof ttydefchars); } int tcsendbreak(int fd, int len __unused) { struct timeval sleepytime; sleepytime.tv_sec = 0; sleepytime.tv_usec = 400000; if (_ioctl(fd, TIOCSBRK, 0) == -1) return (-1); (void)_select(0, 0, 0, 0, &sleepytime); if (_ioctl(fd, TIOCCBRK, 0) == -1) return (-1); return (0); } int -__tcdrain(int fd) +__libc_tcdrain(int fd) { + return (_ioctl(fd, TIOCDRAIN, 0)); } -__weak_reference(__tcdrain, tcdrain); -__weak_reference(__tcdrain, _tcdrain); +#pragma weak tcdrain +int +tcdrain(int fd) +{ + + return (((int (*)(int)) + __libc_interposing[INTERPOS_tcdrain])(fd)); +} + +__weak_reference(__libc_tcdrain, __tcdrain); +__weak_reference(__libc_tcdrain, _tcdrain); int tcflush(int fd, int which) { int com; switch (which) { case TCIFLUSH: com = FREAD; break; case TCOFLUSH: com = FWRITE; break; case TCIOFLUSH: com = FREAD | FWRITE; break; default: errno = EINVAL; return (-1); } return (_ioctl(fd, TIOCFLUSH, &com)); } int tcflow(int fd, int action) { struct termios term; u_char c; switch (action) { case TCOOFF: return (_ioctl(fd, TIOCSTOP, 0)); case TCOON: return (_ioctl(fd, TIOCSTART, 0)); case TCION: case TCIOFF: if (tcgetattr(fd, &term) == -1) return (-1); c = term.c_cc[action == TCIOFF ? VSTOP : VSTART]; if (c != _POSIX_VDISABLE && _write(fd, &c, sizeof(c)) == -1) return (-1); return (0); default: errno = EINVAL; return (-1); } /* NOTREACHED */ } Index: head/lib/libc/gen/usleep.c =================================================================== --- head/lib/libc/gen/usleep.c (revision 276629) +++ head/lib/libc/gen/usleep.c (revision 276630) @@ -1,52 +1,63 @@ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)usleep.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include "un-namespace.h" +#include "libc_private.h" + +#pragma weak usleep int -__usleep(useconds_t useconds) +usleep(useconds_t useconds) { + + return (((int (*)(useconds_t)) + __libc_interposing[INTERPOS_usleep])(useconds)); +} + +int +__libc_usleep(useconds_t useconds) +{ struct timespec time_to_sleep; time_to_sleep.tv_nsec = (useconds % 1000000) * 1000; time_to_sleep.tv_sec = useconds / 1000000; return (_nanosleep(&time_to_sleep, NULL)); } -__weak_reference(__usleep, usleep); -__weak_reference(__usleep, _usleep); +__weak_reference(__libc_usleep, __usleep); +__weak_reference(__libc_usleep, _usleep); Index: head/lib/libc/gen/wait.c =================================================================== --- head/lib/libc/gen/wait.c (revision 276629) +++ head/lib/libc/gen/wait.c (revision 276630) @@ -1,50 +1,62 @@ /* * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)wait.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include "un-namespace.h" +#include "libc_private.h" + +#pragma weak wait pid_t -__wait(int *istat) +wait(int *istat) { - return (_wait4(WAIT_ANY, istat, 0, (struct rusage *)0)); + + return (((pid_t (*)(int *)) + __libc_interposing[INTERPOS_wait])(istat)); } -__weak_reference(__wait, wait); -__weak_reference(__wait, _wait); +pid_t +__libc_wait(int *istat) +{ + + return (__sys_wait4(WAIT_ANY, istat, 0, NULL)); +} + +__weak_reference(__libc_wait, __wait); +__weak_reference(__libc_wait, _wait); Index: head/lib/libc/gen/wait3.c =================================================================== --- head/lib/libc/gen/wait3.c (revision 276629) +++ head/lib/libc/gen/wait3.c (revision 276630) @@ -1,50 +1,61 @@ /* * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)wait3.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include "un-namespace.h" +#include "libc_private.h" + +#pragma weak wait3 pid_t -wait3(istat, options, rup) - int *istat; - int options; - struct rusage *rup; +wait3(int *istat, int options, struct rusage *rup) { - return (_wait4(WAIT_ANY, istat, options, rup)); + + return (((pid_t (*)(int *, int, struct rusage *)) + __libc_interposing[INTERPOS_wait3])(istat, options, rup)); +} + +__weak_reference(__libc_wait3, __wait3); + +pid_t +__libc_wait3(int *istat, int options, struct rusage *rup) +{ + + return (__sys_wait4(WAIT_ANY, istat, options, rup)); } Index: head/lib/libc/gen/waitpid.c =================================================================== --- head/lib/libc/gen/waitpid.c (revision 276629) +++ head/lib/libc/gen/waitpid.c (revision 276630) @@ -1,50 +1,62 @@ /* * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)waitpid.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include "un-namespace.h" +#include "libc_private.h" + +#pragma weak waitpid pid_t -__waitpid(pid_t pid, int *istat, int options) +waitpid(pid_t pid, int *istat, int options) { - return (_wait4(pid, istat, options, (struct rusage *)0)); + + return (((pid_t (*)(pid_t, int *, int)) + __libc_interposing[INTERPOS_waitpid])(pid, istat, options)); } -__weak_reference(__waitpid, waitpid); -__weak_reference(__waitpid, _waitpid); +pid_t +__libc_waitpid(pid_t pid, int *istat, int options) +{ + + return (__sys_wait4(pid, istat, options, NULL)); +} + +__weak_reference(__libc_waitpid, __waitpid); +__weak_reference(__libc_waitpid, _waitpid); Index: head/lib/libc/include/libc_private.h =================================================================== --- head/lib/libc/include/libc_private.h (revision 276629) +++ head/lib/libc/include/libc_private.h (revision 276630) @@ -1,266 +1,386 @@ /* * Copyright (c) 1998 John Birrell . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ * * Private definitions for libc, libc_r and libpthread. * */ #ifndef _LIBC_PRIVATE_H_ #define _LIBC_PRIVATE_H_ #include #include /* * This global flag is non-zero when a process has created one * or more threads. It is used to avoid calling locking functions * when they are not required. */ extern int __isthreaded; /* * Elf_Auxinfo *__elf_aux_vector, the pointer to the ELF aux vector * provided by kernel. Either set for us by rtld, or found at runtime * on stack for static binaries. * * Type is void to avoid polluting whole libc with ELF types. */ extern void *__elf_aux_vector; /* * libc should use libc_dlopen internally, which respects a global * flag where loading of new shared objects can be restricted. */ void *libc_dlopen(const char *, int); /* * For dynamic linker. */ void _rtld_error(const char *fmt, ...); /* * File lock contention is difficult to diagnose without knowing * where locks were set. Allow a debug library to be built which * records the source file and line number of each lock call. */ #ifdef _FLOCK_DEBUG #define _FLOCKFILE(x) _flockfile_debug(x, __FILE__, __LINE__) #else #define _FLOCKFILE(x) _flockfile(x) #endif /* * Macros for locking and unlocking FILEs. These test if the * process is threaded to avoid locking when not required. */ #define FLOCKFILE(fp) if (__isthreaded) _FLOCKFILE(fp) #define FUNLOCKFILE(fp) if (__isthreaded) _funlockfile(fp) struct _spinlock; extern struct _spinlock __stdio_thread_lock __hidden; #define STDIO_THREAD_LOCK() \ do { \ if (__isthreaded) \ _SPINLOCK(&__stdio_thread_lock); \ } while (0) #define STDIO_THREAD_UNLOCK() \ do { \ if (__isthreaded) \ _SPINUNLOCK(&__stdio_thread_lock); \ } while (0) /* * Indexes into the pthread jump table. * * Warning! If you change this type, you must also change the threads * libraries that reference it (libc_r, libpthread). */ typedef enum { PJT_ATFORK, PJT_ATTR_DESTROY, PJT_ATTR_GETDETACHSTATE, PJT_ATTR_GETGUARDSIZE, PJT_ATTR_GETINHERITSCHED, PJT_ATTR_GETSCHEDPARAM, PJT_ATTR_GETSCHEDPOLICY, PJT_ATTR_GETSCOPE, PJT_ATTR_GETSTACKADDR, PJT_ATTR_GETSTACKSIZE, PJT_ATTR_INIT, PJT_ATTR_SETDETACHSTATE, PJT_ATTR_SETGUARDSIZE, PJT_ATTR_SETINHERITSCHED, PJT_ATTR_SETSCHEDPARAM, PJT_ATTR_SETSCHEDPOLICY, PJT_ATTR_SETSCOPE, PJT_ATTR_SETSTACKADDR, PJT_ATTR_SETSTACKSIZE, PJT_CANCEL, PJT_CLEANUP_POP, PJT_CLEANUP_PUSH, PJT_COND_BROADCAST, PJT_COND_DESTROY, PJT_COND_INIT, PJT_COND_SIGNAL, PJT_COND_TIMEDWAIT, PJT_COND_WAIT, PJT_DETACH, PJT_EQUAL, PJT_EXIT, PJT_GETSPECIFIC, PJT_JOIN, PJT_KEY_CREATE, PJT_KEY_DELETE, PJT_KILL, PJT_MAIN_NP, PJT_MUTEXATTR_DESTROY, PJT_MUTEXATTR_INIT, PJT_MUTEXATTR_SETTYPE, PJT_MUTEX_DESTROY, PJT_MUTEX_INIT, PJT_MUTEX_LOCK, PJT_MUTEX_TRYLOCK, PJT_MUTEX_UNLOCK, PJT_ONCE, PJT_RWLOCK_DESTROY, PJT_RWLOCK_INIT, PJT_RWLOCK_RDLOCK, PJT_RWLOCK_TRYRDLOCK, PJT_RWLOCK_TRYWRLOCK, PJT_RWLOCK_UNLOCK, PJT_RWLOCK_WRLOCK, PJT_SELF, PJT_SETCANCELSTATE, PJT_SETCANCELTYPE, PJT_SETSPECIFIC, PJT_SIGMASK, PJT_TESTCANCEL, PJT_CLEANUP_POP_IMP, PJT_CLEANUP_PUSH_IMP, PJT_CANCEL_ENTER, PJT_CANCEL_LEAVE, PJT_MAX } pjt_index_t; typedef int (*pthread_func_t)(void); typedef pthread_func_t pthread_func_entry_t[2]; extern pthread_func_entry_t __thr_jtable[]; +extern int *(*__error_selector)(void); +int _pthread_mutex_init_calloc_cb_stub(pthread_mutex_t *mutex, + void *(calloc_cb)(__size_t, __size_t)); + +typedef int (*interpos_func_t)(void); +interpos_func_t *__libc_interposing_slot(int interposno); +extern interpos_func_t __libc_interposing[]; + +enum { + INTERPOS_accept, + INTERPOS_accept4, + INTERPOS_aio_suspend, + INTERPOS_close, + INTERPOS_connect, + INTERPOS_creat, + INTERPOS_fcntl, + INTERPOS_fsync, + INTERPOS_fork, + INTERPOS_msync, + INTERPOS_nanosleep, + INTERPOS_open, + INTERPOS_openat, + INTERPOS_poll, + INTERPOS_pselect, + INTERPOS_raise, + INTERPOS_recvfrom, + INTERPOS_recvmsg, + INTERPOS_select, + INTERPOS_sendmsg, + INTERPOS_sendto, + INTERPOS_setcontext, + INTERPOS_sigaction, + INTERPOS_sigprocmask, + INTERPOS_sigsuspend, + INTERPOS_sigwait, + INTERPOS_sigtimedwait, + INTERPOS_sigwaitinfo, + INTERPOS_swapcontext, + INTERPOS_system, + INTERPOS_sleep, + INTERPOS_tcdrain, + INTERPOS_usleep, + INTERPOS_pause, + INTERPOS_read, + INTERPOS_readv, + INTERPOS_wait, + INTERPOS_wait3, + INTERPOS_wait4, + INTERPOS_waitpid, + INTERPOS_write, + INTERPOS_writev, + INTERPOS__pthread_mutex_init_calloc_cb, + INTERPOS_MAX +}; + /* * yplib internal interfaces */ #ifdef YP int _yp_check(char **); #endif /* * Initialise TLS for static programs */ void _init_tls(void); /* * Provides pthread_once()-like functionality for both single-threaded * and multi-threaded applications. */ int _once(pthread_once_t *, void (*)(void)); /* * Set the TLS thread pointer */ void _set_tp(void *tp); /* * This is a pointer in the C run-time startup code. It is used * by getprogname() and setprogname(). */ extern const char *__progname; /* * This function is used by the threading libraries to notify malloc that a * thread is exiting. */ void _malloc_thread_cleanup(void); /* * These functions are used by the threading libraries in order to protect * malloc across fork(). */ void _malloc_prefork(void); void _malloc_postfork(void); +void _malloc_first_thread(void); + /* * Function to clean up streams, called from abort() and exit(). */ -extern void (*__cleanup)(void) __hidden; +void (*__cleanup)(void) __hidden; /* * Get kern.osreldate to detect ABI revisions. Explicitly * ignores value of $OSVERSION and caches result. Prototypes * for the wrapped "new" pad-less syscalls are here for now. */ -extern int __getosreldate(void); +int __getosreldate(void); #include -/* Without pad */ -extern __off_t __sys_lseek(int, __off_t, int); -extern int __sys_ftruncate(int, __off_t); -extern int __sys_truncate(const char *, __off_t); -extern __ssize_t __sys_pread(int, void *, __size_t, __off_t); -extern __ssize_t __sys_pwrite(int, const void *, __size_t, __off_t); -extern void * __sys_mmap(void *, __size_t, int, int, int, __off_t); +#include /* With pad */ -extern __off_t __sys_freebsd6_lseek(int, int, __off_t, int); -extern int __sys_freebsd6_ftruncate(int, int, __off_t); -extern int __sys_freebsd6_truncate(const char *, int, __off_t); -extern __ssize_t __sys_freebsd6_pread(int, void *, __size_t, int, __off_t); -extern __ssize_t __sys_freebsd6_pwrite(int, const void *, __size_t, int, __off_t); -extern void * __sys_freebsd6_mmap(void *, __size_t, int, int, int, int, __off_t); +__off_t __sys_freebsd6_lseek(int, int, __off_t, int); +int __sys_freebsd6_ftruncate(int, int, __off_t); +int __sys_freebsd6_truncate(const char *, int, __off_t); +__ssize_t __sys_freebsd6_pread(int, void *, __size_t, int, __off_t); +__ssize_t __sys_freebsd6_pwrite(int, const void *, __size_t, int, __off_t); +void * __sys_freebsd6_mmap(void *, __size_t, int, int, int, int, __off_t); -/* Without back-compat translation */ -extern int __sys_fcntl(int, int, ...); - +struct aiocb; +struct fd_set; +struct iovec; +struct msghdr; +struct pollfd; +struct rusage; +struct sigaction; +struct sockaddr; struct timespec; struct timeval; struct timezone; -int __sys_gettimeofday(struct timeval *, struct timezone *); -int __sys_clock_gettime(__clockid_t, struct timespec *ts); +struct __siginfo; +struct __ucontext; +int __sys_aio_suspend(const struct aiocb * const[], int, + const struct timespec *); +int __sys_accept(int, struct sockaddr *, __socklen_t *); +int __sys_accept4(int, struct sockaddr *, __socklen_t *, int); +int __sys_clock_gettime(__clockid_t, struct timespec *ts); +int __sys_close(int); +int __sys_connect(int, const struct sockaddr *, __socklen_t); +int __sys_fcntl(int, int, ...); +int __sys_fsync(int); +__pid_t __sys_fork(void); +int __sys_ftruncate(int, __off_t); +int __sys_gettimeofday(struct timeval *, struct timezone *); +__off_t __sys_lseek(int, __off_t, int); +void *__sys_mmap(void *, __size_t, int, int, int, __off_t); +int __sys_msync(void *, __size_t, int); +int __sys_nanosleep(const struct timespec *, struct timespec *); +int __sys_open(const char *, int, ...); +int __sys_openat(int, const char *, int, ...); +int __sys_pselect(int, struct fd_set *, struct fd_set *, + struct fd_set *, const struct timespec *, + const __sigset_t *); +int __sys_poll(struct pollfd *, unsigned, int); +__ssize_t __sys_pread(int, void *, __size_t, __off_t); +__ssize_t __sys_pwrite(int, const void *, __size_t, __off_t); +__ssize_t __sys_read(int, void *, __size_t); +__ssize_t __sys_readv(int, const struct iovec *, int); +__ssize_t __sys_recv(int, void *, __size_t, int); +__ssize_t __sys_recvfrom(int, void *, __size_t, int, struct sockaddr *, + __socklen_t *); +__ssize_t __sys_recvmsg(int, struct msghdr *, int); +int __sys_select(int, struct fd_set *, struct fd_set *, + struct fd_set *, struct timeval *); +__ssize_t __sys_sendmsg(int, const struct msghdr *, int); +__ssize_t __sys_sendto(int, const void *, __size_t, int, + const struct sockaddr *, __socklen_t); +int __sys_setcontext(const struct __ucontext *); +int __sys_sigaction(int, const struct sigaction *, + struct sigaction *); +int __sys_sigprocmask(int, const __sigset_t *, __sigset_t *); +int __sys_sigsuspend(const __sigset_t *); +int __sys_sigtimedwait(const __sigset_t *, struct __siginfo *, + const struct timespec *); +int __sys_sigwait(const __sigset_t *, int *); +int __sys_sigwaitinfo(const __sigset_t *, struct __siginfo *); +int __sys_swapcontext(struct __ucontext *, + const struct __ucontext *); +int __sys_truncate(const char *, __off_t); +__pid_t __sys_wait4(__pid_t, int *, int, struct rusage *); +__ssize_t __sys_write(int, const void *, __size_t); +__ssize_t __sys_writev(int, const struct iovec *, int); + +int __libc_creat(const char *path, __mode_t mode); +int __libc_pause(void); +int __libc_raise(int); +int __libc_sigwait(const __sigset_t * __restrict, + int * restrict sig); +int __libc_system(const char *); +unsigned int __libc_sleep(unsigned int); +int __libc_tcdrain(int); +int __libc_usleep(__useconds_t); +__pid_t __libc_wait(int *); +__pid_t __libc_wait3(int *, int, struct rusage *); +__pid_t __libc_waitpid(__pid_t, int *, int); +int __fcntl_compat(int fd, int cmd, ...); /* execve() with PATH processing to implement posix_spawnp() */ int _execvpe(const char *, char * const *, char * const *); int _elf_aux_info(int aux, void *buf, int buflen); struct dl_phdr_info; int __elf_phdr_match_addr(struct dl_phdr_info *, void *); void __init_elf_aux_vector(void); void _pthread_cancel_enter(int); void _pthread_cancel_leave(int); #endif /* _LIBC_PRIVATE_H_ */ Index: head/lib/libc/stdlib/Symbol.map =================================================================== --- head/lib/libc/stdlib/Symbol.map (revision 276629) +++ head/lib/libc/stdlib/Symbol.map (revision 276630) @@ -1,121 +1,122 @@ /* * $FreeBSD$ */ FBSD_1.0 { _Exit; a64l; abort; abs; atexit; __cxa_atexit; __cxa_finalize; atof; atoi; atol; atoll; bsearch; div; __isthreaded; exit; getenv; opterr; optind; optopt; optreset; optarg; getopt; getopt_long; getopt_long_only; suboptarg; getsubopt; grantpt; ptsname; unlockpt; hcreate; hdestroy; hsearch; heapsort; imaxabs; imaxdiv; insque; l64a; l64a_r; labs; ldiv; llabs; lldiv; lsearch; lfind; mergesort; putenv; qsort_r; qsort; radixsort; sradixsort; rand_r; rand; srand; sranddev; srandom; srandomdev; initstate; setstate; random; reallocf; realpath; remque; setenv; unsetenv; strfmon; strtoimax; strtol; strtoll; strtonum; strtoq; strtoul; strtoull; strtoumax; strtouq; system; tdelete; tfind; tsearch; twalk; }; FBSD_1.3 { at_quick_exit; atof_l; atoi_l; atol_l; atoll_l; quick_exit; strtod_l; strtof_l; strtoimax_l; strtol_l; strtold_l; strtoll_l; strtoq_l; strtoul_l; strtoull_l; strtoumax_l; strtouq_l; }; FBSD_1.4 { atexit_b; bsearch_b; heapsort_b; mergesort_b; qsort_b; hcreate_r; hdestroy_r; hsearch_r; }; FBSDprivate_1.0 { __system; _system; + __libc_system; }; Index: head/lib/libc/stdlib/jemalloc/Symbol.map =================================================================== --- head/lib/libc/stdlib/jemalloc/Symbol.map (revision 276629) +++ head/lib/libc/stdlib/jemalloc/Symbol.map (revision 276630) @@ -1,58 +1,59 @@ /* * $FreeBSD$ */ FBSD_1.0 { _malloc_options; _malloc_message; malloc; posix_memalign; calloc; realloc; free; malloc_usable_size; }; FBSD_1.3 { malloc_conf; malloc_message; aligned_alloc; malloc_stats_print; mallctl; mallctlnametomib; mallctlbymib; mallocx; rallocx; xallocx; sallocx; dallocx; nallocx; allocm; rallocm; sallocm; dallocm; nallocm; __malloc; __calloc; __realloc; __free; __posix_memalign; __malloc_usable_size; __mallocx; __rallocx; __xallocx; __sallocx; __dallocx; __nallocx; __allocm; __rallocm; __sallocm; __dallocm; __nallocm; }; FBSDprivate_1.0 { _malloc_thread_cleanup; _malloc_prefork; _malloc_postfork; + _malloc_first_thread; }; Index: head/lib/libc/stdlib/system.c =================================================================== --- head/lib/libc/stdlib/system.c (revision 276629) +++ head/lib/libc/stdlib/system.c (revision 276630) @@ -1,99 +1,108 @@ /* * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)system.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #include #include #include #include "un-namespace.h" #include "libc_private.h" +#pragma weak system int -__system(const char *command) +system(const char *command) { + + return (((int (*)(const char *)) + __libc_interposing[INTERPOS_system])(command)); +} + +int +__libc_system(const char *command) +{ pid_t pid, savedpid; int pstat; struct sigaction ign, intact, quitact; sigset_t newsigblock, oldsigblock; if (!command) /* just checking... */ return(1); (void)sigemptyset(&newsigblock); (void)sigaddset(&newsigblock, SIGCHLD); (void)sigaddset(&newsigblock, SIGINT); (void)sigaddset(&newsigblock, SIGQUIT); (void)_sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock); switch(pid = vfork()) { case -1: /* error */ (void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); return (-1); case 0: /* child */ /* * Restore original signal dispositions and exec the command. */ (void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); execl(_PATH_BSHELL, "sh", "-c", command, (char *)NULL); _exit(127); } /* * If we are running means that the child has either completed * its execve, or has failed. * Block SIGINT/QUIT because sh -c handles it and wait for * it to clean up. */ memset(&ign, 0, sizeof(ign)); ign.sa_handler = SIG_IGN; (void)sigemptyset(&ign.sa_mask); (void)_sigaction(SIGINT, &ign, &intact); (void)_sigaction(SIGQUIT, &ign, &quitact); savedpid = pid; do { pid = _wait4(savedpid, &pstat, 0, (struct rusage *)0); } while (pid == -1 && errno == EINTR); (void)_sigaction(SIGINT, &intact, NULL); (void)_sigaction(SIGQUIT, &quitact, NULL); (void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); return(pid == -1 ? -1 : pstat); } -__weak_reference(__system, system); -__weak_reference(__system, _system); +__weak_reference(__libc_system, __system); +__weak_reference(__libc_system, _system); Index: head/lib/libc/sys/Makefile.inc =================================================================== --- head/lib/libc/sys/Makefile.inc (revision 276629) +++ head/lib/libc/sys/Makefile.inc (revision 276630) @@ -1,411 +1,455 @@ # @(#)Makefile.inc 8.3 (Berkeley) 10/24/94 # $FreeBSD$ # sys sources .PATH: ${LIBC_SRCTOP}/${LIBC_ARCH}/sys ${LIBC_SRCTOP}/sys # Include the generated makefile containing the *complete* list # of syscall names in MIASM. .include "${LIBC_SRCTOP}/../../sys/sys/syscall.mk" # Include machine dependent definitions. # # MDASM names override the default syscall names in MIASM. # NOASM will prevent the default syscall code from being generated. # .sinclude "${LIBC_SRCTOP}/${LIBC_ARCH}/sys/Makefile.inc" SRCS+= clock_gettime.c gettimeofday.c __vdso_gettimeofday.c NOASM+= clock_gettime.o gettimeofday.o PSEUDO+= _clock_gettime.o _gettimeofday.o # Sources common to both syscall interfaces: -SRCS+= stack_protector.c stack_protector_compat.c __error.c +SRCS+= \ + stack_protector.c \ + stack_protector_compat.c \ + __error.c \ + interposing_table.c + .if ${MK_SYSCALL_COMPAT} != "no" -SYSCALL_COMPAT_SRCS= fcntl.c ftruncate.c lseek.c mmap.c pread.c \ - pwrite.c truncate.c +SYSCALL_COMPAT_SRCS= \ + ftruncate.c \ + lseek.c \ + mmap.c \ + pread.c \ + pwrite.c \ + truncate.c SRCS+= ${SYSCALL_COMPAT_SRCS} NOASM+= ${SYSCALL_COMPAT_SRCS:S/.c/.o/} -PSEUDO+= _fcntl.o .endif -SRCS+= sigwait.c -NOASM+= sigwait.o -PSEUDO+= _sigwait.o + +INTERPOSED = \ + accept \ + accept4 \ + aio_suspend \ + close \ + connect \ + fcntl \ + fsync \ + fork \ + msync \ + nanosleep \ + open \ + openat \ + poll \ + pselect \ + read \ + readv \ + recvfrom \ + recvmsg \ + select \ + sendmsg \ + sendto \ + setcontext \ + sigaction \ + sigprocmask \ + sigsuspend \ + sigtimedwait \ + sigwait \ + sigwaitinfo \ + swapcontext \ + wait4 \ + write \ + writev + +SRCS+= ${INTERPOSED:S/$/.c/} +NOASM+= ${INTERPOSED:S/$/.o/} +PSEUDO+= ${INTERPOSED:C/^.*$/_&.o/} # Add machine dependent asm sources: SRCS+=${MDASM} # Look though the complete list of syscalls (MIASM) for names that are # not defined with machine dependent implementations (MDASM) and are # not declared for no generation of default code (NOASM). Add each # syscall that satisfies these conditions to the ASM list. .for _asm in ${MIASM} .if (${MDASM:R:M${_asm:R}} == "") .if (${NOASM:R:M${_asm:R}} == "") ASM+=$(_asm) .endif .endif .endfor OBJS+= ${ASM} ${PSEUDO} SASM= ${ASM:S/.o/.S/} SPSEUDO= ${PSEUDO:S/.o/.S/} SRCS+= ${SASM} ${SPSEUDO} SYM_MAPS+= ${LIBC_SRCTOP}/sys/Symbol.map # Generated files CLEANFILES+= ${SASM} ${SPSEUDO} .if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" || \ ${MACHINE_CPUARCH} == "powerpc" NOTE_GNU_STACK='\t.section .note.GNU-stack,"",%%progbits\n' .else NOTE_GNU_STACK='' .endif ${SASM}: printf '#include "compat.h"\n' > ${.TARGET} printf '#include "SYS.h"\nRSYSCALL(${.PREFIX})\n' >> ${.TARGET} printf ${NOTE_GNU_STACK} >>${.TARGET} ${SPSEUDO}: printf '#include "compat.h"\n' > ${.TARGET} printf '#include "SYS.h"\nPSEUDO(${.PREFIX:S/_//})\n' \ >> ${.TARGET} printf ${NOTE_GNU_STACK} >>${.TARGET} MAN+= abort2.2 \ accept.2 \ access.2 \ acct.2 \ adjtime.2 \ aio_cancel.2 \ aio_error.2 \ aio_fsync.2 \ aio_mlock.2 \ aio_read.2 \ aio_return.2 \ aio_suspend.2 \ aio_waitcomplete.2 \ aio_write.2 \ bind.2 \ bindat.2 \ brk.2 \ cap_enter.2 \ cap_fcntls_limit.2 \ cap_ioctls_limit.2 \ cap_rights_limit.2 \ chdir.2 \ chflags.2 \ chmod.2 \ chown.2 \ chroot.2 \ clock_gettime.2 \ close.2 \ closefrom.2 \ connect.2 \ connectat.2 \ cpuset.2 \ cpuset_getaffinity.2 \ dup.2 \ execve.2 \ _exit.2 \ extattr_get_file.2 \ fcntl.2 \ ffclock.2 \ fhopen.2 \ flock.2 \ fork.2 \ fsync.2 \ getdirentries.2 \ getdtablesize.2 \ getfh.2 \ getfsstat.2 \ getgid.2 \ getgroups.2 \ getitimer.2 \ getlogin.2 \ getloginclass.2 \ getpeername.2 \ getpgrp.2 \ getpid.2 \ getpriority.2 \ getrlimit.2 \ getrusage.2 \ getsid.2 \ getsockname.2 \ getsockopt.2 \ gettimeofday.2 \ getuid.2 \ intro.2 \ ioctl.2 \ issetugid.2 \ jail.2 \ kenv.2 \ kill.2 \ kldfind.2 \ kldfirstmod.2 \ kldload.2 \ kldnext.2 \ kldstat.2 \ kldsym.2 \ kldunload.2 \ kqueue.2 \ ktrace.2 \ link.2 \ lio_listio.2 \ listen.2 \ lseek.2 \ madvise.2 \ mincore.2 \ minherit.2 \ mkdir.2 \ mkfifo.2 \ mknod.2 \ mlock.2 \ mlockall.2 \ mmap.2 \ modfind.2 \ modnext.2 \ modstat.2 \ mount.2 \ mprotect.2 \ mq_close.2 \ mq_getattr.2 \ mq_notify.2 \ mq_open.2 \ mq_receive.2 \ mq_send.2 \ mq_setattr.2 \ msgctl.2 \ msgget.2 \ msgrcv.2 \ msgsnd.2 \ msync.2 \ munmap.2 \ nanosleep.2 \ nfssvc.2 \ ntp_adjtime.2 \ open.2 \ pathconf.2 \ pdfork.2 \ pipe.2 \ poll.2 \ posix_fadvise.2 \ posix_fallocate.2 \ posix_openpt.2 \ procctl.2 \ profil.2 \ pselect.2 \ ptrace.2 \ quotactl.2 \ read.2 \ readlink.2 \ reboot.2 \ recv.2 \ rename.2 \ revoke.2 \ rfork.2 \ rmdir.2 \ rtprio.2 .if !defined(NO_P1003_1B) MAN+= sched_get_priority_max.2 \ sched_setparam.2 \ sched_setscheduler.2 \ sched_yield.2 .endif MAN+= sctp_generic_recvmsg.2 \ sctp_generic_sendmsg.2 \ sctp_peeloff.2 \ select.2 \ semctl.2 \ semget.2 \ semop.2 \ send.2 \ setfib.2 \ sendfile.2 \ setgroups.2 \ setpgid.2 \ setregid.2 \ setresuid.2 \ setreuid.2 \ setsid.2 \ setuid.2 \ shmat.2 \ shmctl.2 \ shmget.2 \ shm_open.2 \ shutdown.2 \ sigaction.2 \ sigaltstack.2 \ sigpending.2 \ sigprocmask.2 \ sigqueue.2 \ sigreturn.2 \ sigstack.2 \ sigsuspend.2 \ sigwait.2 \ sigwaitinfo.2 \ socket.2 \ socketpair.2 \ stat.2 \ statfs.2 \ swapon.2 \ symlink.2 \ sync.2 \ sysarch.2 \ syscall.2 \ timer_create.2 \ timer_delete.2 \ timer_settime.2 \ truncate.2 \ umask.2 \ undelete.2 \ unlink.2 \ utimes.2 \ utrace.2 \ uuidgen.2 \ vfork.2 \ wait.2 \ write.2 MLINKS+=accept.2 accept4.2 MLINKS+=access.2 eaccess.2 \ access.2 faccessat.2 MLINKS+=brk.2 sbrk.2 MLINKS+=cap_enter.2 cap_getmode.2 MLINKS+=cap_fcntls_limit.2 cap_fcntls_get.2 MLINKS+=cap_ioctls_limit.2 cap_ioctls_get.2 MLINKS+=cap_rights_limit.2 cap_rights_get.2 MLINKS+=chdir.2 fchdir.2 MLINKS+=chflags.2 chflagsat.2 \ chflags.2 fchflags.2 \ chflags.2 lchflags.2 MLINKS+=chmod.2 fchmod.2 \ chmod.2 fchmodat.2 \ chmod.2 lchmod.2 MLINKS+=chown.2 fchown.2 \ chown.2 fchownat.2 \ chown.2 lchown.2 MLINKS+=clock_gettime.2 clock_getres.2 \ clock_gettime.2 clock_settime.2 MLINKS+=cpuset.2 cpuset_getid.2 \ cpuset.2 cpuset_setid.2 MLINKS+=cpuset_getaffinity.2 cpuset_setaffinity.2 MLINKS+=dup.2 dup2.2 MLINKS+=execve.2 fexecve.2 MLINKS+=extattr_get_file.2 extattr.2 \ extattr_get_file.2 extattr_delete_fd.2 \ extattr_get_file.2 extattr_delete_file.2 \ extattr_get_file.2 extattr_delete_link.2 \ extattr_get_file.2 extattr_get_fd.2 \ extattr_get_file.2 extattr_get_link.2 \ extattr_get_file.2 extattr_list_fd.2 \ extattr_get_file.2 extattr_list_file.2 \ extattr_get_file.2 extattr_list_link.2 \ extattr_get_file.2 extattr_set_fd.2 \ extattr_get_file.2 extattr_set_file.2 \ extattr_get_file.2 extattr_set_link.2 MLINKS+=ffclock.2 ffclock_getcounter.2 \ ffclock.2 ffclock_getestimate.2 \ ffclock.2 ffclock_setestimate.2 MLINKS+=fhopen.2 fhstat.2 fhopen.2 fhstatfs.2 MLINKS+=getdirentries.2 getdents.2 MLINKS+=getfh.2 lgetfh.2 MLINKS+=getgid.2 getegid.2 MLINKS+=getitimer.2 setitimer.2 MLINKS+=getlogin.2 getlogin_r.3 MLINKS+=getlogin.2 setlogin.2 MLINKS+=getloginclass.2 setloginclass.2 MLINKS+=getpgrp.2 getpgid.2 MLINKS+=getpid.2 getppid.2 MLINKS+=getpriority.2 setpriority.2 MLINKS+=getrlimit.2 setrlimit.2 MLINKS+=getsockopt.2 setsockopt.2 MLINKS+=gettimeofday.2 settimeofday.2 MLINKS+=getuid.2 geteuid.2 MLINKS+=intro.2 errno.2 MLINKS+=jail.2 jail_attach.2 \ jail.2 jail_get.2 \ jail.2 jail_remove.2 \ jail.2 jail_set.2 MLINKS+=kldunload.2 kldunloadf.2 MLINKS+=kqueue.2 kevent.2 \ kqueue.2 EV_SET.3 MLINKS+=link.2 linkat.2 MLINKS+=madvise.2 posix_madvise.2 MLINKS+=mkdir.2 mkdirat.2 MLINKS+=mkfifo.2 mkfifoat.2 MLINKS+=mknod.2 mknodat.2 MLINKS+=mlock.2 munlock.2 MLINKS+=mlockall.2 munlockall.2 MLINKS+=modnext.2 modfnext.2 MLINKS+=mount.2 nmount.2 \ mount.2 unmount.2 MLINKS+=mq_receive.2 mq_timedreceive.2 MLINKS+=mq_send.2 mq_timedsend.2 MLINKS+=ntp_adjtime.2 ntp_gettime.2 MLINKS+=open.2 openat.2 MLINKS+=pathconf.2 fpathconf.2 MLINKS+=pathconf.2 lpathconf.2 MLINKS+=pdfork.2 pdgetpid.2\ pdfork.2 pdkill.2 \ pdfork.2 pdwait4.2 MLINKS+=pipe.2 pipe2.2 MLINKS+=poll.2 ppoll.2 MLINKS+=read.2 pread.2 \ read.2 preadv.2 \ read.2 readv.2 MLINKS+=readlink.2 readlinkat.2 MLINKS+=recv.2 recvfrom.2 \ recv.2 recvmsg.2 MLINKS+=rename.2 renameat.2 MLINKS+=rtprio.2 rtprio_thread.2 .if !defined(NO_P1003_1B) MLINKS+=sched_get_priority_max.2 sched_get_priority_min.2 \ sched_get_priority_max.2 sched_rr_get_interval.2 MLINKS+=sched_setparam.2 sched_getparam.2 MLINKS+=sched_setscheduler.2 sched_getscheduler.2 .endif MLINKS+=select.2 FD_CLR.3 \ select.2 FD_ISSET.3 \ select.2 FD_SET.3 \ select.2 FD_ZERO.3 MLINKS+=send.2 sendmsg.2 \ send.2 sendto.2 MLINKS+=setpgid.2 setpgrp.2 MLINKS+=setresuid.2 getresgid.2 \ setresuid.2 getresuid.2 \ setresuid.2 setresgid.2 MLINKS+=setuid.2 setegid.2 \ setuid.2 seteuid.2 \ setuid.2 setgid.2 MLINKS+=shmat.2 shmdt.2 MLINKS+=shm_open.2 shm_unlink.2 MLINKS+=sigwaitinfo.2 sigtimedwait.2 MLINKS+=stat.2 fstat.2 \ stat.2 fstatat.2 \ stat.2 lstat.2 MLINKS+=statfs.2 fstatfs.2 MLINKS+=swapon.2 swapoff.2 MLINKS+=symlink.2 symlinkat.2 MLINKS+=syscall.2 __syscall.2 MLINKS+=timer_settime.2 timer_getoverrun.2 \ timer_settime.2 timer_gettime.2 MLINKS+=truncate.2 ftruncate.2 MLINKS+=unlink.2 unlinkat.2 MLINKS+=utimes.2 futimes.2 \ utimes.2 futimesat.2 \ utimes.2 lutimes.2 MLINKS+=wait.2 wait3.2 \ wait.2 wait4.2 \ wait.2 waitpid.2 \ wait.2 waitid.2 \ wait.2 wait6.2 MLINKS+=write.2 pwrite.2 \ write.2 pwritev.2 \ write.2 writev.2 Index: head/lib/libc/sys/Symbol.map =================================================================== --- head/lib/libc/sys/Symbol.map (revision 276629) +++ head/lib/libc/sys/Symbol.map (revision 276630) @@ -1,1054 +1,1054 @@ /* * $FreeBSD$ */ /* * It'd be nice to have this automatically generated, but we don't * know to what version they will eventually belong, so for now * it has to be manual. */ FBSD_1.0 { __acl_aclcheck_fd; __acl_aclcheck_file; __acl_aclcheck_link; __acl_delete_fd; __acl_delete_file; __acl_delete_link; __acl_get_fd; __acl_get_file; __acl_get_link; __acl_set_fd; __acl_set_file; __acl_set_link; __getcwd; __mac_execve; __mac_get_fd; __mac_get_file; __mac_get_link; __mac_get_pid; __mac_get_proc; __mac_set_fd; __mac_set_file; __mac_set_link; __mac_set_proc; __setugid; __syscall; __sysctl; _umtx_lock; _umtx_op; _umtx_unlock; abort2; accept; access; acct; adjtime; aio_cancel; aio_error; aio_fsync; aio_read; aio_return; aio_suspend; aio_waitcomplete; aio_write; audit; auditctl; auditon; bind; chdir; chflags; __chk_fail; chmod; chown; chroot; clock_getres; clock_gettime; clock_settime; close; connect; dup; dup2; eaccess; execve; extattr_delete_fd; extattr_delete_file; extattr_delete_link; extattr_get_fd; extattr_get_file; extattr_get_link; extattr_list_fd; extattr_list_file; extattr_list_link; extattr_set_fd; extattr_set_file; extattr_set_link; extattrctl; fchdir; fchflags; fchmod; fchown; fcntl; fhopen; fhstat; fhstatfs; flock; fork; fpathconf; fstat; fstatfs; fsync; futimes; getaudit; getaudit_addr; getauid; getcontext; getdents; getdirentries; getdtablesize; getegid; geteuid; getfh; getfsstat; getgid; getgroups; getitimer; getpeername; getpgid; getpgrp; getpid; getppid; getpriority; getresgid; getresuid; getrlimit; getrusage; getsid; getsockname; getsockopt; gettimeofday; getuid; ioctl; issetugid; jail; jail_attach; kenv; kevent; kill; kldfind; kldfirstmod; kldload; kldnext; kldstat; kldsym; kldunload; kldunloadf; kqueue; kmq_notify; /* Do we want these to be public interfaces? */ kmq_open; /* librt uses them to provide mq_xxx. */ kmq_setattr; kmq_timedreceive; kmq_timedsend; kmq_unlink; ksem_close; ksem_destroy; ksem_getvalue; ksem_init; ksem_open; ksem_post; ksem_timedwait; ksem_trywait; ksem_unlink; ksem_wait; ktrace; lchflags; lchmod; lchown; lgetfh; link; lio_listio; listen; lstat; lutimes; mac_syscall; madvise; mincore; minherit; mkdir; mkfifo; mknod; mlock; mlockall; modfind; modfnext; modnext; modstat; mount; mprotect; msgget; msgrcv; msgsnd; msgsys; msync; munlock; munlockall; munmap; nanosleep; netbsd_lchown; netbsd_msync; nfssvc; nfstat; nlstat; nmount; nstat; ntp_adjtime; ntp_gettime; oaio_read; oaio_write; olio_listio; open; pathconf; pipe; poll; posix_openpt; preadv; profil; pselect; ptrace; pwritev; quotactl; read; readlink; readv; reboot; recvfrom; recvmsg; rename; revoke; rfork; rmdir; rtprio; rtprio_thread; sched_get_priority_max; sched_get_priority_min; sched_getparam; sched_getscheduler; sched_rr_get_interval; sched_setparam; sched_setscheduler; sched_yield; select; semget; semop; semsys; sendfile; sendmsg; sendto; setaudit; setaudit_addr; setauid; - setcontext; setegid; seteuid; setgid; setgroups; setitimer; setlogin; setpgid; setpriority; setregid; setresgid; setresuid; setreuid; setrlimit; setsid; setsockopt; settimeofday; setuid; shm_open; shm_unlink; shmat; shmdt; shmget; shmsys; shutdown; sigaction; sigaltstack; sigpending; sigprocmask; sigqueue; sigreturn; sigsuspend; sigtimedwait; sigwait; sigwaitinfo; socket; socketpair; __stack_chk_fail; __stack_chk_guard; stat; statfs; - swapcontext; swapoff; swapon; symlink; sync; sysarch; syscall; thr_create; thr_exit; thr_kill; thr_kill2; thr_new; thr_self; thr_set_name; thr_suspend; thr_wake; ktimer_create; /* Do we want these to be public interfaces? */ ktimer_delete; /* librt uses them to provide timer_xxx. */ ktimer_getoverrun; ktimer_gettime; ktimer_settime; umask; undelete; unlink; unmount; utimes; utrace; uuidgen; vadvise; wait4; write; writev; __error; ftruncate; lseek; mmap; pread; pwrite; truncate; }; FBSD_1.1 { __semctl; closefrom; cpuset; cpuset_getid; cpuset_setid; cpuset_getaffinity; cpuset_setaffinity; faccessat; fchmodat; fchownat; fexecve; fstatat; futimesat; jail_get; jail_set; jail_remove; linkat; lpathconf; mkdirat; mkfifoat; mknodat; msgctl; - openat; readlinkat; renameat; setfib; shmctl; symlinkat; unlinkat; }; FBSD_1.2 { cap_enter; cap_getmode; getloginclass; pdfork; pdgetpid; pdkill; posix_fallocate; rctl_get_racct; rctl_get_rules; rctl_get_limits; rctl_add_rule; rctl_remove_rule; setloginclass; }; FBSD_1.3 { accept4; aio_mlock; bindat; cap_fcntls_get; cap_fcntls_limit; cap_ioctls_get; cap_ioctls_limit; __cap_rights_get; cap_rights_limit; cap_sandboxed; chflagsat; clock_getcpuclockid2; connectat; ffclock_getcounter; ffclock_getestimate; ffclock_setestimate; pipe2; posix_fadvise; procctl; wait6; }; FBSD_1.4 { ppoll; }; FBSDprivate_1.0 { ___acl_aclcheck_fd; __sys___acl_aclcheck_fd; ___acl_aclcheck_file; __sys___acl_aclcheck_file; ___acl_aclcheck_link; __sys___acl_aclcheck_link; ___acl_delete_fd; __sys___acl_delete_fd; ___acl_delete_file; __sys___acl_delete_file; ___acl_delete_link; __sys___acl_delete_link; ___acl_get_fd; __sys___acl_get_fd; ___acl_get_file; __sys___acl_get_file; ___acl_get_link; __sys___acl_get_link; ___acl_set_fd; __sys___acl_set_fd; ___acl_set_file; __sys___acl_set_file; ___acl_set_link; __sys___acl_set_link; ___getcwd; __sys___getcwd; ___mac_execve; __sys___mac_execve; ___mac_get_fd; __sys___mac_get_fd; ___mac_get_file; __sys___mac_get_file; ___mac_get_link; __sys___mac_get_link; ___mac_get_pid; __sys___mac_get_pid; ___mac_get_proc; __sys___mac_get_proc; ___mac_set_fd; __sys___mac_set_fd; ___mac_set_file; __sys___mac_set_file; ___mac_set_link; __sys___mac_set_link; ___mac_set_proc; __sys___mac_set_proc; ___semctl; __sys___semctl; ___setugid; __sys___setugid; ___syscall; __sys___syscall; ___sysctl; __sys___sysctl; __umtx_lock; __sys__umtx_lock; __umtx_op; __sys__umtx_op; __umtx_unlock; __sys__umtx_unlock; _abort2; __sys_abort2; _accept; __sys_accept; _accept4; __sys_accept4; _access; __sys_access; _acct; __sys_acct; _adjtime; __sys_adjtime; _aio_cancel; __sys_aio_cancel; _aio_error; __sys_aio_error; _aio_fsync; __sys_aio_fsync; _aio_read; __sys_aio_read; _aio_return; __sys_aio_return; _aio_suspend; __sys_aio_suspend; _aio_waitcomplete; __sys_aio_waitcomplete; _aio_write; __sys_aio_write; _audit; __sys_audit; _auditctl; __sys_auditctl; _auditon; __sys_auditon; _bind; __sys_bind; _chdir; __sys_chdir; _chflags; __sys_chflags; _chmod; __sys_chmod; _chown; __sys_chown; _chroot; __sys_chroot; _clock_getcpuclockid2; __sys_clock_getcpuclockid2; _clock_getres; __sys_clock_getres; _clock_gettime; __sys_clock_gettime; _clock_settime; __sys_clock_settime; _close; __sys_close; _closefrom; __sys_closefrom; _connect; __sys_connect; _cpuset; __sys_cpuset; _cpuset_getid; __sys_cpuset_getid; _cpuset_setid; __sys_cpuset_setid; _cpuset_getaffinity; __sys_cpuset_getaffinity; _cpuset_setaffinity; __sys_cpuset_setaffinity; _dup; __sys_dup; _dup2; __sys_dup2; _eaccess; __sys_eaccess; _execve; __sys_execve; _extattr_delete_fd; __sys_extattr_delete_fd; _extattr_delete_file; __sys_extattr_delete_file; _extattr_delete_link; __sys_extattr_delete_link; _extattr_get_fd; __sys_extattr_get_fd; _extattr_get_file; __sys_extattr_get_file; _extattr_get_link; __sys_extattr_get_link; _extattr_list_fd; __sys_extattr_list_fd; _extattr_list_file; __sys_extattr_list_file; _extattr_list_link; __sys_extattr_list_link; _extattr_set_fd; __sys_extattr_set_fd; _extattr_set_file; __sys_extattr_set_file; _extattr_set_link; __sys_extattr_set_link; _extattrctl; __sys_extattrctl; _fchdir; __sys_fchdir; _fchflags; __sys_fchflags; _fchmod; __sys_fchmod; _fchown; __sys_fchown; _fcntl; __sys_fcntl; __fcntl_compat; _fhopen; __sys_fhopen; _fhstat; __sys_fhstat; _fhstatfs; __sys_fhstatfs; _flock; __sys_flock; _fork; __sys_fork; _fpathconf; __sys_fpathconf; _fstat; __sys_fstat; _fstatfs; __sys_fstatfs; _fsync; __sys_fsync; _futimes; __sys_futimes; _getaudit; __sys_getaudit; _getaudit_addr; __sys_getaudit_addr; _getauid; __sys_getauid; _getcontext; __sys_getcontext; _getdents; __sys_getdents; _getdirentries; __sys_getdirentries; _getdtablesize; __sys_getdtablesize; _getegid; __sys_getegid; _geteuid; __sys_geteuid; _getfh; __sys_getfh; _getfsstat; __sys_getfsstat; _getgid; __sys_getgid; _getgroups; __sys_getgroups; _getitimer; __sys_getitimer; _getpeername; __sys_getpeername; _getpgid; __sys_getpgid; _getpgrp; __sys_getpgrp; _getpid; __sys_getpid; _getppid; __sys_getppid; _getpriority; __sys_getpriority; _getresgid; __sys_getresgid; _getresuid; __sys_getresuid; _getrlimit; __sys_getrlimit; _getrusage; __sys_getrusage; _getsid; __sys_getsid; _getsockname; __sys_getsockname; _getsockopt; __sys_getsockopt; _gettimeofday; __sys_gettimeofday; _getuid; __sys_getuid; _ioctl; __sys_ioctl; _issetugid; __sys_issetugid; _jail; __sys_jail; _jail_attach; __sys_jail_attach; _kenv; __sys_kenv; _kevent; __sys_kevent; _kill; __sys_kill; _kldfind; __sys_kldfind; _kldfirstmod; __sys_kldfirstmod; _kldload; __sys_kldload; _kldnext; __sys_kldnext; _kldstat; __sys_kldstat; _kldsym; __sys_kldsym; _kldunload; __sys_kldunload; _kldunloadf; __sys_kldunloadf; _kmq_notify; __sys_kmq_notify; _kmq_open; __sys_kmq_open; _kmq_setattr; __sys_kmq_setattr; _kmq_timedreceive; __sys_kmq_timedreceive; _kmq_timedsend; __sys_kmq_timedsend; _kmq_unlink; __sys_kmq_unlink; _kqueue; __sys_kqueue; _ksem_close; __sys_ksem_close; _ksem_destroy; __sys_ksem_destroy; _ksem_getvalue; __sys_ksem_getvalue; _ksem_init; __sys_ksem_init; _ksem_open; __sys_ksem_open; _ksem_post; __sys_ksem_post; _ksem_timedwait; __sys_ksem_timedwait; _ksem_trywait; __sys_ksem_trywait; _ksem_unlink; __sys_ksem_unlink; _ksem_wait; __sys_ksem_wait; _ktrace; __sys_ktrace; _lchflags; __sys_lchflags; _lchmod; __sys_lchmod; _lchown; __sys_lchown; _lgetfh; __sys_lgetfh; _link; __sys_link; _lio_listio; __sys_lio_listio; _listen; __sys_listen; _lstat; __sys_lstat; _lutimes; __sys_lutimes; _mac_syscall; __sys_mac_syscall; _madvise; __sys_madvise; _mincore; __sys_mincore; _minherit; __sys_minherit; _mkdir; __sys_mkdir; _mkfifo; __sys_mkfifo; _mknod; __sys_mknod; _mlock; __sys_mlock; _mlockall; __sys_mlockall; _modfind; __sys_modfind; _modfnext; __sys_modfnext; _modnext; __sys_modnext; _modstat; __sys_modstat; _mount; __sys_mount; _mprotect; __sys_mprotect; _msgctl; __sys_msgctl; _msgget; __sys_msgget; _msgrcv; __sys_msgrcv; _msgsnd; __sys_msgsnd; _msgsys; __sys_msgsys; _msync; __sys_msync; _munlock; __sys_munlock; _munlockall; __sys_munlockall; _munmap; __sys_munmap; _nanosleep; __sys_nanosleep; _netbsd_lchown; __sys_netbsd_lchown; _netbsd_msync; __sys_netbsd_msync; _nfssvc; __sys_nfssvc; _nfstat; __sys_nfstat; _nlstat; __sys_nlstat; _nmount; __sys_nmount; _nstat; __sys_nstat; _ntp_adjtime; __sys_ntp_adjtime; _ntp_gettime; __sys_ntp_gettime; _oaio_read; __sys_oaio_read; _oaio_write; __sys_oaio_write; _olio_listio; __sys_olio_listio; _open; __sys_open; _openat; __sys_openat; _pathconf; __sys_pathconf; _pipe; __sys_pipe; _poll; __sys_poll; _ppoll; __sys_ppoll; _preadv; __sys_preadv; _procctl; __sys_procctl; _profil; __sys_profil; _pselect; __sys_pselect; _ptrace; __sys_ptrace; _pwritev; __sys_pwritev; _quotactl; __sys_quotactl; _read; __sys_read; _readlink; __sys_readlink; _readv; __sys_readv; _reboot; __sys_reboot; _recvfrom; __sys_recvfrom; _recvmsg; __sys_recvmsg; _rename; __sys_rename; _revoke; __sys_revoke; _rfork; __sys_rfork; _rmdir; __sys_rmdir; _rtprio; __sys_rtprio; _rtprio_thread; __sys_rtprio_thread; _sched_get_priority_max; __sys_sched_get_priority_max; _sched_get_priority_min; __sys_sched_get_priority_min; _sched_getparam; __sys_sched_getparam; _sched_getscheduler; __sys_sched_getscheduler; _sched_rr_get_interval; __sys_sched_rr_get_interval; _sched_setparam; __sys_sched_setparam; _sched_setscheduler; __sys_sched_setscheduler; _sched_yield; __sys_sched_yield; _select; __sys_select; _semget; __sys_semget; _semop; __sys_semop; _semsys; __sys_semsys; _sendfile; __sys_sendfile; _sendmsg; __sys_sendmsg; _sendto; __sys_sendto; _setaudit; __sys_setaudit; _setaudit_addr; __sys_setaudit_addr; _setauid; __sys_setauid; _setcontext; __sys_setcontext; _setegid; __sys_setegid; _seteuid; __sys_seteuid; _setgid; __sys_setgid; _setgroups; __sys_setgroups; _setitimer; __sys_setitimer; _setlogin; __sys_setlogin; _setpgid; __sys_setpgid; _setpriority; __sys_setpriority; _setregid; __sys_setregid; _setresgid; __sys_setresgid; _setresuid; __sys_setresuid; _setreuid; __sys_setreuid; _setrlimit; __sys_setrlimit; _setsid; __sys_setsid; _setsockopt; __sys_setsockopt; _settimeofday; __sys_settimeofday; _setuid; __sys_setuid; _shm_open; __sys_shm_open; _shm_unlink; __sys_shm_unlink; _shmat; __sys_shmat; _shmctl; __sys_shmctl; _shmdt; __sys_shmdt; _shmget; __sys_shmget; _shmsys; __sys_shmsys; _shutdown; __sys_shutdown; _sigaction; __sys_sigaction; _sigaltstack; __sys_sigaltstack; _sigpending; __sys_sigpending; _sigprocmask; __sys_sigprocmask; _sigqueue; __sys_sigqueue; _sigreturn; __sys_sigreturn; _sigsuspend; __sys_sigsuspend; _sigtimedwait; __sys_sigtimedwait; _sigwait; __sigwait; __sys_sigwait; _sigwaitinfo; __sys_sigwaitinfo; _socket; __sys_socket; _socketpair; __sys_socketpair; _stat; __sys_stat; _statfs; __sys_statfs; _swapcontext; __sys_swapcontext; _swapoff; __sys_swapoff; _swapon; __sys_swapon; _symlink; __sys_symlink; _sync; __sys_sync; _sysarch; __sys_sysarch; _syscall; __sys_syscall; _thr_create; __sys_thr_create; _thr_exit; __sys_thr_exit; _thr_kill; __sys_thr_kill; _thr_kill2; __sys_thr_kill2; _thr_new; __sys_thr_new; _thr_self; __sys_thr_self; _thr_set_name; __sys_thr_set_name; _thr_suspend; __sys_thr_suspend; _thr_wake; __sys_thr_wake; _ktimer_create; __sys_ktimer_create; _ktimer_delete; __sys_ktimer_delete; _ktimer_getoverrun; __sys_ktimer_getoverrun; _ktimer_gettime; __sys_ktimer_gettime; _ktimer_settime; __sys_ktimer_settime; _umask; __sys_umask; _undelete; __sys_undelete; _unlink; __sys_unlink; _unmount; __sys_unmount; _utimes; __sys_utimes; _utrace; __sys_utrace; _uuidgen; __sys_uuidgen; _vadvise; __sys_vadvise; _wait4; __sys_wait4; _wait6; __sys_wait6; _write; __sys_write; _writev; __sys_writev; __error_unthreaded; + __error_selector; nlm_syscall; gssd_syscall; + __libc_interposing_slot; + __libc_sigwait; }; Index: head/lib/libc/sys/__error.c =================================================================== --- head/lib/libc/sys/__error.c (revision 276629) +++ head/lib/libc/sys/__error.c (revision 276630) @@ -1,45 +1,48 @@ /* * Copyright (c) 1997 John Birrell . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); extern int errno; -/* - * Declare a weak reference in case the application is not linked - * with libpthread. - */ -__weak_reference(__error_unthreaded, __error); - int * __error_unthreaded(void) { return(&errno); +} + +int *(*__error_selector)(void) = __error_unthreaded; + +int * +__error(void) +{ + + return (__error_selector()); } Index: head/lib/libc/sys/accept.c =================================================================== --- head/lib/libc/sys/accept.c (nonexistent) +++ head/lib/libc/sys/accept.c (revision 276630) @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_accept, __accept); + +#pragma weak accept +int +accept(int s, struct sockaddr *addr, socklen_t *addrlen) +{ + + return (((int (*)(int, struct sockaddr *, socklen_t *)) + __libc_interposing[INTERPOS_accept])(s, addr, addrlen)); +} Property changes on: head/lib/libc/sys/accept.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/accept4.c =================================================================== --- head/lib/libc/sys/accept4.c (nonexistent) +++ head/lib/libc/sys/accept4.c (revision 276630) @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_accept4, __accept4); + +#pragma weak accept4 +int +accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags) +{ + + return (((int (*)(int, struct sockaddr *, socklen_t *, int)) + __libc_interposing[INTERPOS_accept4])(s, addr, addrlen, flags)); +} Property changes on: head/lib/libc/sys/accept4.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/aio_suspend.c =================================================================== --- head/lib/libc/sys/aio_suspend.c (nonexistent) +++ head/lib/libc/sys/aio_suspend.c (revision 276630) @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_aio_suspend, __aio_suspend); + +#pragma weak aio_suspend +int +aio_suspend(const struct aiocb * const iocbs[], int niocb, + const struct timespec *timeout) +{ + + return (((int (*)(const struct aiocb * const[], int, + const struct timespec *)) + __libc_interposing[INTERPOS_aio_suspend])(iocbs, niocb, timeout)); +} Property changes on: head/lib/libc/sys/aio_suspend.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/close.c =================================================================== --- head/lib/libc/sys/close.c (nonexistent) +++ head/lib/libc/sys/close.c (revision 276630) @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_close, __close); + +#pragma weak close +int +close(int fd) +{ + + return (((int (*)(int))__libc_interposing[INTERPOS_close])(fd)); +} Property changes on: head/lib/libc/sys/close.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/connect.c =================================================================== --- head/lib/libc/sys/connect.c (nonexistent) +++ head/lib/libc/sys/connect.c (revision 276630) @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_connect, __connect); + +#pragma weak connect +int +connect(int s, const struct sockaddr *addr, socklen_t addrlen) +{ + + return (((int (*)(int, const struct sockaddr *, socklen_t)) + __libc_interposing[INTERPOS_connect])(s, addr, addrlen)); +} Property changes on: head/lib/libc/sys/connect.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/fcntl.c =================================================================== --- head/lib/libc/sys/fcntl.c (revision 276629) +++ head/lib/libc/sys/fcntl.c (revision 276630) @@ -1,89 +1,109 @@ /*- * Copyright (c) 2008 Isilon Inc http://www.isilon.com/ * Authors: Doug Rabson * Developed with Red Inc: Alfred Perlstein * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include "libc_private.h" -__weak_reference(__fcntl_compat, fcntl); +#pragma weak fcntl +int +fcntl(int fd, int cmd, ...) +{ + va_list args; + long arg; + va_start(args, cmd); + arg = va_arg(args, long); + va_end(args); + + return (((int (*)(int, int, ...)) + __libc_interposing[INTERPOS_fcntl])(fd, cmd, arg)); +} + +#ifdef SYSCALL_COMPAT +__weak_reference(__fcntl_compat, __fcntl); + int __fcntl_compat(int fd, int cmd, ...) { va_list args; long arg; struct __oflock ofl; struct flock *flp; int res; va_start(args, cmd); arg = va_arg(args, long); va_end(args); if (__getosreldate() >= 800028) { return (__sys_fcntl(fd, cmd, arg)); } else { if (cmd == F_GETLK || cmd == F_SETLK || cmd == F_SETLKW) { /* * Convert new-style struct flock (which * includes l_sysid) to old-style. */ flp = (struct flock *) (uintptr_t) arg; ofl.l_start = flp->l_start; ofl.l_len = flp->l_len; ofl.l_pid = flp->l_pid; ofl.l_type = flp->l_type; ofl.l_whence = flp->l_whence; switch (cmd) { case F_GETLK: res = __sys_fcntl(fd, F_OGETLK, &ofl); if (res >= 0) { flp->l_start = ofl.l_start; flp->l_len = ofl.l_len; flp->l_pid = ofl.l_pid; flp->l_type = ofl.l_type; flp->l_whence = ofl.l_whence; flp->l_sysid = 0; } return (res); case F_SETLK: return (__sys_fcntl(fd, F_OSETLK, &ofl)); case F_SETLKW: return (__sys_fcntl(fd, F_OSETLKW, &ofl)); } } return (__sys_fcntl(fd, cmd, arg)); } } +#else +__weak_reference(__sys_fcntl, __fcntl_compat); +__weak_reference(__sys_fcntl, __fcntl); +#endif Index: head/lib/libc/sys/fork.c =================================================================== --- head/lib/libc/sys/fork.c (nonexistent) +++ head/lib/libc/sys/fork.c (revision 276630) @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_fork, __fork); + +#pragma weak fork +pid_t +fork(void) +{ + + return (((pid_t (*)(void))__libc_interposing[INTERPOS_fork])()); +} Property changes on: head/lib/libc/sys/fork.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/fsync.c =================================================================== --- head/lib/libc/sys/fsync.c (nonexistent) +++ head/lib/libc/sys/fsync.c (revision 276630) @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_fsync, __fsync); + +int +fsync(int fd) +{ + + return (((int (*)(int))__libc_interposing[INTERPOS_fsync])(fd)); +} Property changes on: head/lib/libc/sys/fsync.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/interposing_table.c =================================================================== --- head/lib/libc/sys/interposing_table.c (nonexistent) +++ head/lib/libc/sys/interposing_table.c (revision 276630) @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include "libc_private.h" + +#define SLOT(a, b) \ + [INTERPOS_##a] = (interpos_func_t)b +interpos_func_t __libc_interposing[INTERPOS_MAX] = { + SLOT(accept, __sys_accept), + SLOT(accept4, __sys_accept4), + SLOT(aio_suspend, __sys_aio_suspend), + SLOT(close, __sys_close), + SLOT(connect, __sys_connect), + SLOT(creat, __libc_creat), + SLOT(fcntl, __fcntl_compat), + SLOT(fsync, __sys_fsync), + SLOT(fork, __sys_fork), + SLOT(msync, __sys_msync), + SLOT(nanosleep, __sys_nanosleep), + SLOT(open, __sys_open), + SLOT(openat, __sys_openat), + SLOT(poll, __sys_poll), + SLOT(pselect, __sys_pselect), + SLOT(raise, __libc_raise), + SLOT(read, __sys_read), + SLOT(readv, __sys_readv), + SLOT(recvfrom, __sys_recvfrom), + SLOT(recvmsg, __sys_recvmsg), + SLOT(select, __sys_select), + SLOT(sendmsg, __sys_sendmsg), + SLOT(sendto, __sys_sendto), + SLOT(setcontext, __sys_setcontext), + SLOT(sigaction, __sys_sigaction), + SLOT(sigprocmask, __sys_sigprocmask), + SLOT(sigsuspend, __sys_sigsuspend), + SLOT(sigwait, __libc_sigwait), + SLOT(sigtimedwait, __sys_sigtimedwait), + SLOT(sigwaitinfo, __sys_sigwaitinfo), + SLOT(swapcontext, __sys_swapcontext), + SLOT(system, __libc_system), + SLOT(sleep, __libc_sleep), + SLOT(tcdrain, __libc_tcdrain), + SLOT(usleep, __libc_usleep), + SLOT(pause, __libc_pause), + SLOT(wait, __libc_wait), + SLOT(wait3, __libc_wait3), + SLOT(wait4, __sys_wait4), + SLOT(waitpid, __libc_waitpid), + SLOT(write, __sys_write), + SLOT(writev, __sys_writev), + SLOT(_pthread_mutex_init_calloc_cb, _pthread_mutex_init_calloc_cb_stub), +}; +#undef SLOT + +interpos_func_t * +__libc_interposing_slot(int interposno) +{ + + return (&__libc_interposing[interposno]); +} Property changes on: head/lib/libc/sys/interposing_table.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/msync.c =================================================================== --- head/lib/libc/sys/msync.c (nonexistent) +++ head/lib/libc/sys/msync.c (revision 276630) @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_msync, __msync); + +#pragma weak msync +int +msync(void *addr, size_t len, int flags) +{ + + return (((int (*)(void *, size_t, int)) + __libc_interposing[INTERPOS_msync])(addr, len, flags)); +} Property changes on: head/lib/libc/sys/msync.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/nanosleep.c =================================================================== --- head/lib/libc/sys/nanosleep.c (nonexistent) +++ head/lib/libc/sys/nanosleep.c (revision 276630) @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_nanosleep, __nanosleep); + +#pragma weak nanosleep +int +nanosleep(const struct timespec *rqtp, struct timespec *rmtp) +{ + + return (((int (*)(const struct timespec *, struct timespec *)) + __libc_interposing[INTERPOS_nanosleep])(rqtp, rmtp)); +} Property changes on: head/lib/libc/sys/nanosleep.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/open.c =================================================================== --- head/lib/libc/sys/open.c (nonexistent) +++ head/lib/libc/sys/open.c (revision 276630) @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_open, __open); + +#pragma weak open +int +open(const char *path, int flags, ...) +{ + va_list ap; + int mode; + + if ((flags & O_CREAT) != 0) { + va_start(ap, flags); + mode = va_arg(ap, int); + va_end(ap); + } else { + mode = 0; + } + return (((int (*)(const char *, int, ...)) + __libc_interposing[INTERPOS_open])(path, flags, mode)); +} Property changes on: head/lib/libc/sys/open.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/openat.c =================================================================== --- head/lib/libc/sys/openat.c (nonexistent) +++ head/lib/libc/sys/openat.c (revision 276630) @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_openat, __openat); +__sym_compat(openat, __impl_openat, FBSD_1.1); +__weak_reference(openat, __impl_openat); +__sym_default(openat, openat, FBSD_1.2); + +#pragma weak openat +int +openat(int fd, const char *path, int flags, ...) +{ + va_list ap; + int mode; + + if ((flags & O_CREAT) != 0) { + va_start(ap, flags); + mode = va_arg(ap, int); + va_end(ap); + } else { + mode = 0; + } + return (((int (*)(int, const char *, int, ...)) + __libc_interposing[INTERPOS_openat])(fd, path, flags, mode)); +} Property changes on: head/lib/libc/sys/openat.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/poll.c =================================================================== --- head/lib/libc/sys/poll.c (nonexistent) +++ head/lib/libc/sys/poll.c (revision 276630) @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_poll, __poll); + +#pragma weak poll +int +poll(struct pollfd pfd[], nfds_t nfds, int timeout) +{ + + return (((int (*)(struct pollfd *, nfds_t, int)) + __libc_interposing[INTERPOS_poll])(pfd, nfds, timeout)); +} Property changes on: head/lib/libc/sys/poll.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/pselect.c =================================================================== --- head/lib/libc/sys/pselect.c (nonexistent) +++ head/lib/libc/sys/pselect.c (revision 276630) @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_pselect, __pselect); + +#pragma weak pselect +int +pselect(int n, fd_set *rs, fd_set *ws, fd_set *es, const struct timespec *t, + const sigset_t *s) +{ + + return (((int (*)(int, fd_set *, fd_set *, fd_set *, + const struct timespec *, const sigset_t *)) + __libc_interposing[INTERPOS_pselect])(n, rs, ws, es, t, s)); +} Property changes on: head/lib/libc/sys/pselect.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/read.c =================================================================== --- head/lib/libc/sys/read.c (nonexistent) +++ head/lib/libc/sys/read.c (revision 276630) @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_read, __read); + +#pragma weak read +ssize_t +read(int fd, void *buf, size_t nbytes) +{ + + return (((ssize_t (*)(int, void *, size_t)) + __libc_interposing[INTERPOS_read])(fd, buf, nbytes)); +} Property changes on: head/lib/libc/sys/read.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/readv.c =================================================================== --- head/lib/libc/sys/readv.c (nonexistent) +++ head/lib/libc/sys/readv.c (revision 276630) @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_readv, __readv); + +#pragma weak readv +ssize_t +readv(int fd, const struct iovec *iov, int iovcnt) +{ + + return (((ssize_t (*)(int, const struct iovec *, int)) + __libc_interposing[INTERPOS_readv])(fd, iov, iovcnt)); +} Property changes on: head/lib/libc/sys/readv.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/recvfrom.c =================================================================== --- head/lib/libc/sys/recvfrom.c (nonexistent) +++ head/lib/libc/sys/recvfrom.c (revision 276630) @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_recvfrom, __recvfrom); + +#pragma weak recvfrom +ssize_t +recvfrom(int s, void *buf, size_t len, int flags, + struct sockaddr * __restrict from, socklen_t * __restrict fromlen) +{ + + return (((ssize_t (*)(int, void *, size_t, int, + struct sockaddr *, socklen_t *)) + __libc_interposing[INTERPOS_recvfrom])(s, buf, len, flags, + from, fromlen)); +} Property changes on: head/lib/libc/sys/recvfrom.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/recvmsg.c =================================================================== --- head/lib/libc/sys/recvmsg.c (nonexistent) +++ head/lib/libc/sys/recvmsg.c (revision 276630) @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_recvmsg, __recvmsg); + +#pragma weak recvmsg +ssize_t +recvmsg(int s, struct msghdr *msg, int flags) +{ + + return (((int (*)(int, struct msghdr *, int)) + __libc_interposing[INTERPOS_recvmsg])(s, msg, flags)); +} Property changes on: head/lib/libc/sys/recvmsg.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/select.c =================================================================== --- head/lib/libc/sys/select.c (nonexistent) +++ head/lib/libc/sys/select.c (revision 276630) @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_select, __select); + +#pragma weak select +int +select(int n, fd_set *rs, fd_set *ws, fd_set *es, struct timeval *t) +{ + + return (((int (*)(int, fd_set *, fd_set *, fd_set *, struct timeval *)) + __libc_interposing[INTERPOS_select])(n, rs, ws, es, t)); +} Property changes on: head/lib/libc/sys/select.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/sendmsg.c =================================================================== --- head/lib/libc/sys/sendmsg.c (nonexistent) +++ head/lib/libc/sys/sendmsg.c (revision 276630) @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_sendmsg, __sendmsg); + +#pragma weak sendmsg +ssize_t +sendmsg(int s, const struct msghdr *msg, int flags) +{ + + return (((int (*)(int, const struct msghdr *, int)) + __libc_interposing[INTERPOS_sendmsg])(s, msg, flags)); +} Property changes on: head/lib/libc/sys/sendmsg.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/sendto.c =================================================================== --- head/lib/libc/sys/sendto.c (nonexistent) +++ head/lib/libc/sys/sendto.c (revision 276630) @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_sendto, __sendto); + +#pragma weak sendto +ssize_t +sendto(int s, const void *msg, size_t len, int flags, + const struct sockaddr *to, socklen_t tolen) +{ + + return (((ssize_t (*)(int, const void *, size_t, int, + const struct sockaddr *, socklen_t)) + __libc_interposing[INTERPOS_sendto])(s, msg, len, flags, + to, tolen)); +} Property changes on: head/lib/libc/sys/sendto.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/setcontext.c =================================================================== --- head/lib/libc/sys/setcontext.c (nonexistent) +++ head/lib/libc/sys/setcontext.c (revision 276630) @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_setcontext, __setcontext); +__sym_compat(setcontext, __impl_setcontext, FBSD_1.0); +__weak_reference(setcontext, __impl_setcontext); +__sym_default(setcontext, setcontext, FBSD_1.2); + +#pragma weak setcontext +int +setcontext(const ucontext_t *uc) +{ + + return (((int (*)(const ucontext_t *)) + __libc_interposing[INTERPOS_setcontext])(uc)); +} Property changes on: head/lib/libc/sys/setcontext.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/sigaction.c =================================================================== --- head/lib/libc/sys/sigaction.c (nonexistent) +++ head/lib/libc/sys/sigaction.c (revision 276630) @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_sigaction, __sigaction); + +#pragma weak sigaction +int +sigaction(int sig, const struct sigaction *act, struct sigaction *oact) +{ + + return (((int (*)(int, const struct sigaction *, struct sigaction *)) + __libc_interposing[INTERPOS_sigaction])(sig, act, oact)); +} Property changes on: head/lib/libc/sys/sigaction.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/sigprocmask.c =================================================================== --- head/lib/libc/sys/sigprocmask.c (nonexistent) +++ head/lib/libc/sys/sigprocmask.c (revision 276630) @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_sigprocmask, __sigprocmask); + +#pragma weak sigprocmask +int +sigprocmask(int how, const sigset_t *set, sigset_t *oset) +{ + + return (((int (*)(int, const sigset_t *, sigset_t *)) + __libc_interposing[INTERPOS_sigprocmask])(how, set, oset)); +} Property changes on: head/lib/libc/sys/sigprocmask.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/sigsuspend.c =================================================================== --- head/lib/libc/sys/sigsuspend.c (nonexistent) +++ head/lib/libc/sys/sigsuspend.c (revision 276630) @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_sigsuspend, __sigsuspend); + +#pragma weak sigsuspend +int +sigsuspend(const sigset_t *set) +{ + + return (((int (*)(const sigset_t *)) + __libc_interposing[INTERPOS_sigsuspend])(set)); +} Property changes on: head/lib/libc/sys/sigsuspend.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/sigtimedwait.c =================================================================== --- head/lib/libc/sys/sigtimedwait.c (nonexistent) +++ head/lib/libc/sys/sigtimedwait.c (revision 276630) @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_sigtimedwait, __sigtimedwait); + +#pragma weak sigtimedwait +int +sigtimedwait(const sigset_t * __restrict set, siginfo_t * __restrict info, + const struct timespec * __restrict t) +{ + + return (((int (*)(const sigset_t *, siginfo_t *, + const struct timespec *)) + __libc_interposing[INTERPOS_sigtimedwait])(set, info, t)); +} Property changes on: head/lib/libc/sys/sigtimedwait.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/sigwait.c =================================================================== --- head/lib/libc/sys/sigwait.c (revision 276629) +++ head/lib/libc/sys/sigwait.c (revision 276630) @@ -1,46 +1,54 @@ /*- * Copyright (c) 2010 davidxu@freebsd.org * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include +#include "libc_private.h" -int __sys_sigwait(const sigset_t * restrict, int * restrict); +__weak_reference(__libc_sigwait, __sigwait); -__weak_reference(__sigwait, sigwait); +#pragma weak sigwait +int +sigwait(const sigset_t *set, int *sig) +{ + return (((int (*)(const sigset_t *, int *)) + __libc_interposing[INTERPOS_sigwait])(set, sig)); +} + int -__sigwait(const sigset_t * restrict set, int * restrict sig) +__libc_sigwait(const sigset_t *set, int *sig) { int ret; /* POSIX does not allow EINTR to be returned */ do { ret = __sys_sigwait(set, sig); } while (ret == EINTR); return (ret); } Index: head/lib/libc/sys/sigwaitinfo.c =================================================================== --- head/lib/libc/sys/sigwaitinfo.c (nonexistent) +++ head/lib/libc/sys/sigwaitinfo.c (revision 276630) @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_sigwaitinfo, __sigwaitinfo); + +#pragma weak sigwaitinfo +int +sigwaitinfo(const sigset_t * __restrict set, siginfo_t * __restrict info) +{ + + return (((int (*)(const sigset_t *, siginfo_t *)) + __libc_interposing[INTERPOS_sigwaitinfo])(set, info)); +} Property changes on: head/lib/libc/sys/sigwaitinfo.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/swapcontext.c =================================================================== --- head/lib/libc/sys/swapcontext.c (nonexistent) +++ head/lib/libc/sys/swapcontext.c (revision 276630) @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2001 Daniel M. Eischen + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Neither the name of the author nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_swapcontext, __swapcontext); +__sym_compat(swapcontext, __impl_swapcontext, FBSD_1.0); +__weak_reference(swapcontext, __impl_swapcontext); +__sym_default(swapcontext, swapcontext, FBSD_1.2); + +#pragma weak swapcontext +int +swapcontext(ucontext_t *oucp, const ucontext_t *ucp) +{ + + return (((int (*)(ucontext_t *, const ucontext_t *)) + __libc_interposing[INTERPOS_swapcontext])(oucp, ucp)); +} Property changes on: head/lib/libc/sys/swapcontext.c ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/lib/libc/sys/wait4.c =================================================================== --- head/lib/libc/sys/wait4.c (nonexistent) +++ head/lib/libc/sys/wait4.c (revision 276630) @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_wait4, __wait4); + +#pragma weak wait4 +pid_t +wait4(pid_t pid, int *status, int options, struct rusage *ru) +{ + + return (((pid_t (*)(pid_t, int *, int, struct rusage *)) + __libc_interposing[INTERPOS_wait4])(pid, status, options, ru)); +} Property changes on: head/lib/libc/sys/wait4.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/write.c =================================================================== --- head/lib/libc/sys/write.c (nonexistent) +++ head/lib/libc/sys/write.c (revision 276630) @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_write, __write); + +#pragma weak write +ssize_t +write(int fd, const void *buf, size_t nbytes) +{ + + return (((ssize_t (*)(int, const void *, size_t)) + __libc_interposing[INTERPOS_write])(fd, buf, nbytes)); +} Property changes on: head/lib/libc/sys/write.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libc/sys/writev.c =================================================================== --- head/lib/libc/sys/writev.c (nonexistent) +++ head/lib/libc/sys/writev.c (revision 276630) @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include "libc_private.h" + +__weak_reference(__sys_writev, __writev); + +#pragma weak writev +ssize_t +writev(int fd, const struct iovec *iov, int iovcnt) +{ + + return (((ssize_t (*)(int, const struct iovec *, int)) + __libc_interposing[INTERPOS_writev])(fd, iov, iovcnt)); +} Property changes on: head/lib/libc/sys/writev.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/lib/libthr/Makefile =================================================================== --- head/lib/libthr/Makefile (revision 276629) +++ head/lib/libthr/Makefile (revision 276630) @@ -1,69 +1,68 @@ # $FreeBSD$ # # All library objects contain FreeBSD revision strings by default; they may be # excluded as a space-saving measure. To produce a library that does # not contain these strings, add -DSTRIP_FBSDID (see ) to CFLAGS # below. Note, there are no IDs for syscall stubs whose sources are generated. # To included legacy CSRG sccsid strings, add -DLIBC_SCCS and -DSYSLIBC_SCCS # (for system call stubs) to CFLAGS below. -DSYSLIBC_SCCS affects just the # system call stubs. SHLIBDIR?= /lib .include MK_SSP= no LIB=thr SHLIB_MAJOR= 3 WARNS?= 3 CFLAGS+=-DPTHREAD_KERNEL CFLAGS+=-I${.CURDIR}/../libc/include -I${.CURDIR}/thread \ -I${.CURDIR}/../../include CFLAGS+=-I${.CURDIR}/arch/${MACHINE_CPUARCH}/include CFLAGS+=-I${.CURDIR}/sys CFLAGS+=-I${.CURDIR}/../../libexec/rtld-elf CFLAGS+=-I${.CURDIR}/../../libexec/rtld-elf/${MACHINE_CPUARCH} CFLAGS+=-I${.CURDIR}/../libthread_db CFLAGS+=-Winline .ifndef NO_THREAD_UNWIND_STACK CFLAGS+=-fexceptions CFLAGS+=-D_PTHREAD_FORCED_UNWIND .endif LDFLAGS+=-Wl,-znodelete VERSION_DEF=${.CURDIR}/../libc/Versions.def SYMBOL_MAPS=${.CURDIR}/pthread.map MAN= libthr.3 # enable extra internal consistancy checks CFLAGS+=-D_PTHREADS_INVARIANTS -#CFLAGS+=-g PRECIOUSLIB= .PATH: ${.CURDIR}/arch/${MACHINE_CPUARCH}/${MACHINE_CPUARCH} .include "${.CURDIR}/arch/${MACHINE_CPUARCH}/Makefile.inc" .include "${.CURDIR}/sys/Makefile.inc" .include "${.CURDIR}/thread/Makefile.inc" .if ${MK_INSTALLLIB} != "no" SYMLINKS+=lib${LIB}.a ${LIBDIR}/libpthread.a .endif .if !defined(NO_PIC) SYMLINKS+=lib${LIB}.so ${LIBDIR}/libpthread.so .endif .if ${MK_PROFILE} != "no" SYMLINKS+=lib${LIB}_p.a ${LIBDIR}/libpthread_p.a .endif .if ${MK_SYSCALL_COMPAT} != "no" CFLAGS+=-DSYSCALL_COMPAT .endif .include .include Index: head/lib/libthr/pthread.map =================================================================== --- head/lib/libthr/pthread.map (revision 276629) +++ head/lib/libthr/pthread.map (revision 276630) @@ -1,415 +1,319 @@ /* * $FreeBSD$ */ /* * Use the same naming scheme as libc. */ FBSD_1.0 { - __error; - accept; - aio_suspend; - close; - connect; - creat; - execve; - fcntl; - fork; - fsync; - msync; - nanosleep; - open; - pause; - poll; - pselect; pthread_atfork; pthread_barrier_destroy; pthread_barrier_init; pthread_barrier_wait; pthread_barrierattr_destroy; pthread_barrierattr_getpshared; pthread_barrierattr_init; pthread_barrierattr_setpshared; pthread_attr_destroy; pthread_attr_get_np; pthread_attr_getdetachstate; pthread_attr_getguardsize; pthread_attr_getinheritsched; pthread_attr_getschedparam; pthread_attr_getschedpolicy; pthread_attr_getscope; pthread_attr_getstack; pthread_attr_getstackaddr; pthread_attr_getstacksize; pthread_attr_init; pthread_attr_setcreatesuspend_np; pthread_attr_setdetachstate; pthread_attr_setguardsize; pthread_attr_setinheritsched; pthread_attr_setschedparam; pthread_attr_setschedpolicy; pthread_attr_setscope; pthread_attr_setstack; pthread_attr_setstackaddr; pthread_attr_setstacksize; pthread_cancel; pthread_cleanup_pop; pthread_cleanup_push; pthread_cond_broadcast; pthread_cond_destroy; pthread_cond_init; pthread_cond_signal; pthread_cond_timedwait; pthread_cond_wait; pthread_condattr_destroy; pthread_condattr_getclock; pthread_condattr_getpshared; pthread_condattr_init; pthread_condattr_setclock; pthread_condattr_setpshared; pthread_create; pthread_detach; pthread_equal; pthread_exit; pthread_getconcurrency; pthread_getprio; pthread_getschedparam; pthread_getspecific; pthread_join; pthread_key_create; pthread_key_delete; pthread_kill; pthread_main_np; pthread_multi_np; pthread_mutex_destroy; pthread_mutex_getprioceiling; pthread_mutex_init; pthread_mutex_lock; pthread_mutex_setprioceiling; pthread_mutex_timedlock; pthread_mutex_trylock; pthread_mutex_unlock; pthread_mutexattr_destroy; pthread_mutexattr_getkind_np; pthread_mutexattr_getprioceiling; pthread_mutexattr_getpshared; pthread_mutexattr_getprotocol; pthread_mutexattr_gettype; pthread_mutexattr_init; pthread_mutexattr_setkind_np; pthread_mutexattr_setprioceiling; pthread_mutexattr_setprotocol; pthread_mutexattr_setpshared; pthread_mutexattr_settype; pthread_once; pthread_resume_all_np; pthread_resume_np; pthread_rwlock_destroy; pthread_rwlock_init; pthread_rwlock_rdlock; pthread_rwlock_timedrdlock; pthread_rwlock_timedwrlock; pthread_rwlock_tryrdlock; pthread_rwlock_trywrlock; pthread_rwlock_unlock; pthread_rwlock_wrlock; pthread_rwlockattr_destroy; pthread_rwlockattr_getpshared; pthread_rwlockattr_init; pthread_rwlockattr_setpshared; pthread_set_name_np; pthread_self; pthread_setcancelstate; pthread_setcanceltype; pthread_setconcurrency; pthread_setprio; pthread_setschedparam; pthread_setspecific; pthread_sigmask; pthread_single_np; pthread_spin_destroy; pthread_spin_init; pthread_spin_lock; pthread_spin_trylock; pthread_spin_unlock; pthread_suspend_all_np; pthread_suspend_np; pthread_switch_add_np; pthread_switch_delete_np; pthread_testcancel; pthread_timedjoin_np; pthread_yield; - raise; - read; - readv; - recvfrom; - recvmsg; - select; - sendmsg; - sendto; - sigaction; - sigprocmask; - sigsuspend; - sigwait; - sigwaitinfo; - sigtimedwait; - sleep; - system; - tcdrain; - usleep; - wait; - wait3; - wait4; - waitpid; - write; - writev; }; /* * List the private interfaces reserved for use in FreeBSD libraries. * These are not part of our application ABI. */ FBSDprivate_1.0 { - ___creat; - ___pause; - ___pselect; - ___sigwait; - ___sleep; - ___system; - ___tcdrain; - ___usleep; - ___wait; - ___waitpid; - __accept; - __accept4; - __aio_suspend; - __close; - __connect; - __fcntl; - __fsync; - __msync; - __nanosleep; - __open; - __openat; - __poll; __pthread_cond_timedwait; __pthread_cond_wait; __pthread_cxa_finalize; __pthread_mutex_init; __pthread_mutex_lock; __pthread_mutex_timedlock; __pthread_mutex_trylock; - __read; - __readv; - __recvfrom; - __recvmsg; - __select; - __sendmsg; - __sendto; - __sigsuspend; - __sigtimedwait; - __sigwaitinfo; - __wait3; - __wait4; - __write; - __writev; - _fork; _pthread_atfork; _pthread_barrier_destroy; _pthread_barrier_init; _pthread_barrier_wait; _pthread_barrierattr_destroy; _pthread_barrierattr_getpshared; _pthread_barrierattr_init; _pthread_barrierattr_setpshared; _pthread_attr_destroy; _pthread_attr_get_np; _pthread_attr_getaffinity_np; _pthread_attr_getdetachstate; _pthread_attr_getguardsize; _pthread_attr_getinheritsched; _pthread_attr_getschedparam; _pthread_attr_getschedpolicy; _pthread_attr_getscope; _pthread_attr_getstack; _pthread_attr_getstackaddr; _pthread_attr_getstacksize; _pthread_attr_init; _pthread_attr_setaffinity_np; _pthread_attr_setcreatesuspend_np; _pthread_attr_setdetachstate; _pthread_attr_setguardsize; _pthread_attr_setinheritsched; _pthread_attr_setschedparam; _pthread_attr_setschedpolicy; _pthread_attr_setscope; _pthread_attr_setstack; _pthread_attr_setstackaddr; _pthread_attr_setstacksize; _pthread_cancel; _pthread_cancel_enter; _pthread_cancel_leave; _pthread_cleanup_pop; _pthread_cleanup_push; _pthread_cond_broadcast; _pthread_cond_destroy; _pthread_cond_init; _pthread_cond_signal; _pthread_cond_timedwait; _pthread_cond_wait; _pthread_condattr_destroy; _pthread_condattr_getclock; _pthread_condattr_getpshared; _pthread_condattr_init; _pthread_condattr_setclock; _pthread_condattr_setpshared; _pthread_create; _pthread_detach; _pthread_equal; _pthread_exit; _pthread_getaffinity_np; _pthread_getconcurrency; _pthread_getcpuclockid; _pthread_getprio; _pthread_getschedparam; _pthread_getspecific; _pthread_getthreadid_np; _pthread_join; _pthread_key_create; _pthread_key_delete; _pthread_kill; _pthread_main_np; _pthread_multi_np; _pthread_mutex_destroy; _pthread_mutex_getprioceiling; _pthread_mutex_getspinloops_np; _pthread_mutex_getyieldloops_np; _pthread_mutex_init; _pthread_mutex_init_calloc_cb; _pthread_mutex_isowned_np; _pthread_mutex_lock; _pthread_mutex_setprioceiling; _pthread_mutex_setspinloops_np; _pthread_mutex_setyieldloops_np; _pthread_mutex_timedlock; _pthread_mutex_trylock; _pthread_mutex_unlock; _pthread_mutexattr_destroy; _pthread_mutexattr_getkind_np; _pthread_mutexattr_getprioceiling; _pthread_mutexattr_getprotocol; _pthread_mutexattr_getpshared; _pthread_mutexattr_gettype; _pthread_mutexattr_init; _pthread_mutexattr_setkind_np; _pthread_mutexattr_setprioceiling; _pthread_mutexattr_setprotocol; _pthread_mutexattr_setpshared; _pthread_mutexattr_settype; _pthread_once; _pthread_resume_all_np; _pthread_resume_np; _pthread_rwlock_destroy; _pthread_rwlock_init; _pthread_rwlock_rdlock; _pthread_rwlock_timedrdlock; _pthread_rwlock_timedwrlock; _pthread_rwlock_tryrdlock; _pthread_rwlock_trywrlock; _pthread_rwlock_unlock; _pthread_rwlock_wrlock; _pthread_rwlockattr_destroy; _pthread_rwlockattr_getpshared; _pthread_rwlockattr_init; _pthread_rwlockattr_setpshared; _pthread_self; _pthread_set_name_np; _pthread_setaffinity_np; _pthread_setcancelstate; _pthread_setcanceltype; _pthread_setconcurrency; _pthread_setprio; _pthread_setschedparam; _pthread_setspecific; _pthread_sigmask; _pthread_single_np; _pthread_spin_destroy; _pthread_spin_init; _pthread_spin_lock; _pthread_spin_trylock; _pthread_spin_unlock; _pthread_suspend_all_np; _pthread_suspend_np; _pthread_switch_add_np; _pthread_switch_delete_np; _pthread_testcancel; _pthread_timedjoin_np; _pthread_yield; - _raise; - _setcontext; - _sigaction; - _sigprocmask; - _sigsuspend; - _sigtimedwait; - _sigwait; - _sigwaitinfo; - _spinlock; - _spinlock_debug; - _spinunlock; - _swapcontext; /* Debugger needs these. */ _libthr_debug; _thread_active_threads; _thread_bp_create; _thread_bp_death; _thread_event_mask; _thread_keytable; _thread_last_event; _thread_list; _thread_max_keys; _thread_off_attr_flags; _thread_off_dtv; _thread_off_event_buf; _thread_off_event_mask; _thread_off_key_allocated; _thread_off_key_destructor; _thread_off_linkmap; _thread_off_next; _thread_off_report_events; _thread_off_state; _thread_off_tcb; _thread_off_tid; _thread_off_tlsindex; _thread_size_key; _thread_state_running; _thread_state_zoombie; __pthread_map_stacks_exec; }; FBSD_1.1 { __pthread_cleanup_pop_imp; __pthread_cleanup_push_imp; pthread_attr_getaffinity_np; pthread_attr_setaffinity_np; pthread_getaffinity_np; pthread_getcpuclockid; pthread_setaffinity_np; pthread_mutex_getspinloops_np; pthread_mutex_getyieldloops_np; pthread_mutex_isowned_np; pthread_mutex_setspinloops_np; pthread_mutex_setyieldloops_np; }; FBSD_1.2 { - openat; pthread_getthreadid_np; - setcontext; - swapcontext; -}; - -FBSD_1.3 { - accept4; }; Index: head/lib/libthr/sys/thr_error.c =================================================================== --- head/lib/libthr/sys/thr_error.c (revision 276629) +++ head/lib/libthr/sys/thr_error.c (revision 276630) @@ -1,56 +1,57 @@ /* * Copyright (c) 1995 John Birrell . * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by John Birrell * and Chris Provenzano. * 4. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #include #include "libc_private.h" #include "thr_private.h" #undef errno extern int errno; +__weak_reference(__error_threaded, __error); int * -__error(void) +__error_threaded(void) { struct pthread *curthread; if (_thr_initial != NULL) { curthread = _get_curthread(); if (curthread != NULL && curthread != _thr_initial) return (&curthread->error); } return (&errno); } Index: head/lib/libthr/thread/thr_create.c =================================================================== --- head/lib/libthr/thread/thr_create.c (revision 276629) +++ head/lib/libthr/thread/thr_create.c (revision 276630) @@ -1,288 +1,292 @@ /* * Copyright (c) 2003 Daniel M. Eischen * Copyright (c) 2005, David Xu * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice unmodified, this list of conditions, and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD$ */ #include "namespace.h" #include #include #include #include #include #include #include #include #include #include #include "un-namespace.h" +#include "libc_private.h" #include "thr_private.h" static int create_stack(struct pthread_attr *pattr); static void thread_start(struct pthread *curthread); __weak_reference(_pthread_create, pthread_create); int _pthread_create(pthread_t * thread, const pthread_attr_t * attr, void *(*start_routine) (void *), void *arg) { struct pthread *curthread, *new_thread; struct thr_param param; struct sched_param sched_param; struct rtprio rtp; int ret = 0, locked, create_suspended; sigset_t set, oset; cpuset_t *cpusetp = NULL; int cpusetsize = 0; int old_stack_prot; _thr_check_init(); /* * Tell libc and others now they need lock to protect their data. */ - if (_thr_isthreaded() == 0 && _thr_setthreaded(1)) - return (EAGAIN); + if (_thr_isthreaded() == 0) { + _malloc_first_thread(); + if (_thr_setthreaded(1)) + return (EAGAIN); + } curthread = _get_curthread(); if ((new_thread = _thr_alloc(curthread)) == NULL) return (EAGAIN); memset(¶m, 0, sizeof(param)); if (attr == NULL || *attr == NULL) /* Use the default thread attributes: */ new_thread->attr = _pthread_attr_default; else { new_thread->attr = *(*attr); cpusetp = new_thread->attr.cpuset; cpusetsize = new_thread->attr.cpusetsize; new_thread->attr.cpuset = NULL; new_thread->attr.cpusetsize = 0; } if (new_thread->attr.sched_inherit == PTHREAD_INHERIT_SCHED) { /* inherit scheduling contention scope */ if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) new_thread->attr.flags |= PTHREAD_SCOPE_SYSTEM; else new_thread->attr.flags &= ~PTHREAD_SCOPE_SYSTEM; new_thread->attr.prio = curthread->attr.prio; new_thread->attr.sched_policy = curthread->attr.sched_policy; } new_thread->tid = TID_TERMINATED; old_stack_prot = _rtld_get_stack_prot(); if (create_stack(&new_thread->attr) != 0) { /* Insufficient memory to create a stack: */ _thr_free(curthread, new_thread); return (EAGAIN); } /* * Write a magic value to the thread structure * to help identify valid ones: */ new_thread->magic = THR_MAGIC; new_thread->start_routine = start_routine; new_thread->arg = arg; new_thread->cancel_enable = 1; new_thread->cancel_async = 0; /* Initialize the mutex queue: */ TAILQ_INIT(&new_thread->mutexq); TAILQ_INIT(&new_thread->pp_mutexq); /* Initialise hooks in the thread structure: */ if (new_thread->attr.suspend == THR_CREATE_SUSPENDED) { new_thread->flags = THR_FLAGS_NEED_SUSPEND; create_suspended = 1; } else { create_suspended = 0; } new_thread->state = PS_RUNNING; if (new_thread->attr.flags & PTHREAD_CREATE_DETACHED) new_thread->flags |= THR_FLAGS_DETACHED; /* Add the new thread. */ new_thread->refcount = 1; _thr_link(curthread, new_thread); /* * Handle the race between __pthread_map_stacks_exec and * thread linkage. */ if (old_stack_prot != _rtld_get_stack_prot()) _thr_stack_fix_protection(new_thread); /* Return thread pointer eariler so that new thread can use it. */ (*thread) = new_thread; if (SHOULD_REPORT_EVENT(curthread, TD_CREATE) || cpusetp != NULL) { THR_THREAD_LOCK(curthread, new_thread); locked = 1; } else locked = 0; param.start_func = (void (*)(void *)) thread_start; param.arg = new_thread; param.stack_base = new_thread->attr.stackaddr_attr; param.stack_size = new_thread->attr.stacksize_attr; param.tls_base = (char *)new_thread->tcb; param.tls_size = sizeof(struct tcb); param.child_tid = &new_thread->tid; param.parent_tid = &new_thread->tid; param.flags = 0; if (new_thread->attr.flags & PTHREAD_SCOPE_SYSTEM) param.flags |= THR_SYSTEM_SCOPE; if (new_thread->attr.sched_inherit == PTHREAD_INHERIT_SCHED) param.rtp = NULL; else { sched_param.sched_priority = new_thread->attr.prio; _schedparam_to_rtp(new_thread->attr.sched_policy, &sched_param, &rtp); param.rtp = &rtp; } /* Schedule the new thread. */ if (create_suspended) { SIGFILLSET(set); SIGDELSET(set, SIGTRAP); __sys_sigprocmask(SIG_SETMASK, &set, &oset); new_thread->sigmask = oset; SIGDELSET(new_thread->sigmask, SIGCANCEL); } ret = thr_new(¶m, sizeof(param)); if (ret != 0) { ret = errno; /* * Translate EPROCLIM into well-known POSIX code EAGAIN. */ if (ret == EPROCLIM) ret = EAGAIN; } if (create_suspended) __sys_sigprocmask(SIG_SETMASK, &oset, NULL); if (ret != 0) { if (!locked) THR_THREAD_LOCK(curthread, new_thread); new_thread->state = PS_DEAD; new_thread->tid = TID_TERMINATED; new_thread->flags |= THR_FLAGS_DETACHED; new_thread->refcount--; if (new_thread->flags & THR_FLAGS_NEED_SUSPEND) { new_thread->cycle++; _thr_umtx_wake(&new_thread->cycle, INT_MAX, 0); } _thr_try_gc(curthread, new_thread); /* thread lock released */ atomic_add_int(&_thread_active_threads, -1); } else if (locked) { if (cpusetp != NULL) { if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, TID(new_thread), cpusetsize, cpusetp)) { ret = errno; /* kill the new thread */ new_thread->force_exit = 1; new_thread->flags |= THR_FLAGS_DETACHED; _thr_try_gc(curthread, new_thread); /* thread lock released */ goto out; } } _thr_report_creation(curthread, new_thread); THR_THREAD_UNLOCK(curthread, new_thread); } out: if (ret) (*thread) = 0; return (ret); } static int create_stack(struct pthread_attr *pattr) { int ret; /* Check if a stack was specified in the thread attributes: */ if ((pattr->stackaddr_attr) != NULL) { pattr->guardsize_attr = 0; pattr->flags |= THR_STACK_USER; ret = 0; } else ret = _thr_stack_alloc(pattr); return (ret); } static void thread_start(struct pthread *curthread) { sigset_t set; if (curthread->attr.suspend == THR_CREATE_SUSPENDED) set = curthread->sigmask; /* * This is used as a serialization point to allow parent * to report 'new thread' event to debugger or tweak new thread's * attributes before the new thread does real-world work. */ THR_LOCK(curthread); THR_UNLOCK(curthread); if (curthread->force_exit) _pthread_exit(PTHREAD_CANCELED); if (curthread->attr.suspend == THR_CREATE_SUSPENDED) { #if 0 /* Done in THR_UNLOCK() */ _thr_ast(curthread); #endif /* * Parent thread have stored signal mask for us, * we should restore it now. */ __sys_sigprocmask(SIG_SETMASK, &set, NULL); } #ifdef _PTHREAD_FORCED_UNWIND curthread->unwind_stackend = (char *)curthread->attr.stackaddr_attr + curthread->attr.stacksize_attr; #endif /* Run the current thread's start routine with argument: */ _pthread_exit(curthread->start_routine(curthread->arg)); /* This point should never be reached. */ PANIC("Thread has resumed after exit"); } Index: head/lib/libthr/thread/thr_fork.c =================================================================== --- head/lib/libthr/thread/thr_fork.c (revision 276629) +++ head/lib/libthr/thread/thr_fork.c (revision 276630) @@ -1,262 +1,260 @@ /* * Copyright (c) 2005 David Xu * Copyright (c) 2003 Daniel Eischen * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ /* * Copyright (c) 1995-1998 John Birrell * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include #include "namespace.h" #include #include #include #include #include #include #include #include "un-namespace.h" #include "libc_private.h" #include "rtld_lock.h" #include "thr_private.h" __weak_reference(_pthread_atfork, pthread_atfork); int _pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void)) { struct pthread *curthread; struct pthread_atfork *af; _thr_check_init(); if ((af = malloc(sizeof(struct pthread_atfork))) == NULL) return (ENOMEM); curthread = _get_curthread(); af->prepare = prepare; af->parent = parent; af->child = child; THR_CRITICAL_ENTER(curthread); _thr_rwl_wrlock(&_thr_atfork_lock); TAILQ_INSERT_TAIL(&_thr_atfork_list, af, qe); _thr_rwl_unlock(&_thr_atfork_lock); THR_CRITICAL_LEAVE(curthread); return (0); } void __pthread_cxa_finalize(struct dl_phdr_info *phdr_info) { atfork_head temp_list = TAILQ_HEAD_INITIALIZER(temp_list); struct pthread *curthread; struct pthread_atfork *af, *af1; _thr_check_init(); curthread = _get_curthread(); THR_CRITICAL_ENTER(curthread); _thr_rwl_wrlock(&_thr_atfork_lock); TAILQ_FOREACH_SAFE(af, &_thr_atfork_list, qe, af1) { if (__elf_phdr_match_addr(phdr_info, af->prepare) || __elf_phdr_match_addr(phdr_info, af->parent) || __elf_phdr_match_addr(phdr_info, af->child)) { TAILQ_REMOVE(&_thr_atfork_list, af, qe); TAILQ_INSERT_TAIL(&temp_list, af, qe); } } _thr_rwl_unlock(&_thr_atfork_lock); THR_CRITICAL_LEAVE(curthread); while ((af = TAILQ_FIRST(&temp_list)) != NULL) { TAILQ_REMOVE(&temp_list, af, qe); free(af); } _thr_tsd_unload(phdr_info); _thr_sigact_unload(phdr_info); } -__weak_reference(_fork, fork); +__weak_reference(__thr_fork, _fork); -pid_t _fork(void); - pid_t -_fork(void) +__thr_fork(void) { struct pthread *curthread; struct pthread_atfork *af; pid_t ret; int errsave, cancelsave; int was_threaded; int rtld_locks[MAX_RTLD_LOCKS]; if (!_thr_is_inited()) return (__sys_fork()); curthread = _get_curthread(); cancelsave = curthread->no_cancel; curthread->no_cancel = 1; _thr_rwl_rdlock(&_thr_atfork_lock); /* Run down atfork prepare handlers. */ TAILQ_FOREACH_REVERSE(af, &_thr_atfork_list, atfork_head, qe) { if (af->prepare != NULL) af->prepare(); } /* * Block all signals until we reach a safe point. */ _thr_signal_block(curthread); _thr_signal_prefork(); /* * All bets are off as to what should happen soon if the parent * process was not so kindly as to set up pthread fork hooks to * relinquish all running threads. */ if (_thr_isthreaded() != 0) { was_threaded = 1; _malloc_prefork(); _rtld_atfork_pre(rtld_locks); } else { was_threaded = 0; } /* * Fork a new process. * There is no easy way to pre-resolve the __sys_fork symbol * without performing the fork. Use the syscall(2) * indirection, the syscall symbol is resolved in * _thr_rtld_init() with side-effect free call. */ ret = syscall(SYS_fork); if (ret == 0) { /* Child process */ errsave = errno; curthread->cancel_pending = 0; curthread->flags &= ~(THR_FLAGS_NEED_SUSPEND|THR_FLAGS_DETACHED); /* * Thread list will be reinitialized, and later we call * _libpthread_init(), it will add us back to list. */ curthread->tlflags &= ~TLFLAGS_IN_TDLIST; /* child is a new kernel thread. */ thr_self(&curthread->tid); /* clear other threads locked us. */ _thr_umutex_init(&curthread->lock); _mutex_fork(curthread); _thr_signal_postfork_child(); if (was_threaded) _rtld_atfork_post(rtld_locks); _thr_setthreaded(0); /* reinitalize library. */ _libpthread_init(curthread); /* atfork is reinitializeded by _libpthread_init()! */ _thr_rwl_rdlock(&_thr_atfork_lock); if (was_threaded) { __isthreaded = 1; _malloc_postfork(); __isthreaded = 0; } /* Ready to continue, unblock signals. */ _thr_signal_unblock(curthread); /* Run down atfork child handlers. */ TAILQ_FOREACH(af, &_thr_atfork_list, qe) { if (af->child != NULL) af->child(); } _thr_rwlock_unlock(&_thr_atfork_lock); curthread->no_cancel = cancelsave; } else { /* Parent process */ errsave = errno; _thr_signal_postfork(); if (was_threaded) { _rtld_atfork_post(rtld_locks); _malloc_postfork(); } /* Ready to continue, unblock signals. */ _thr_signal_unblock(curthread); /* Run down atfork parent handlers. */ TAILQ_FOREACH(af, &_thr_atfork_list, qe) { if (af->parent != NULL) af->parent(); } _thr_rwlock_unlock(&_thr_atfork_lock); curthread->no_cancel = cancelsave; /* test async cancel */ if (curthread->cancel_async) _thr_testcancel(curthread); } errno = errsave; return (ret); } Index: head/lib/libthr/thread/thr_init.c =================================================================== --- head/lib/libthr/thread/thr_init.c (revision 276629) +++ head/lib/libthr/thread/thr_init.c (revision 276630) @@ -1,502 +1,508 @@ /* * Copyright (c) 2003 Daniel M. Eischen * Copyright (c) 1995-1998 John Birrell * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by John Birrell. * 4. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #include "namespace.h" #include #include #include +#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "un-namespace.h" #include "libc_private.h" #include "thr_private.h" char *_usrstack; struct pthread *_thr_initial; int _libthr_debug; int _thread_event_mask; struct pthread *_thread_last_event; pthreadlist _thread_list = TAILQ_HEAD_INITIALIZER(_thread_list); pthreadlist _thread_gc_list = TAILQ_HEAD_INITIALIZER(_thread_gc_list); int _thread_active_threads = 1; atfork_head _thr_atfork_list = TAILQ_HEAD_INITIALIZER(_thr_atfork_list); struct urwlock _thr_atfork_lock = DEFAULT_URWLOCK; struct pthread_prio _thr_priorities[3] = { {RTP_PRIO_MIN, RTP_PRIO_MAX, 0}, /* FIFO */ {0, 0, 63}, /* OTHER */ {RTP_PRIO_MIN, RTP_PRIO_MAX, 0} /* RR */ }; struct pthread_attr _pthread_attr_default = { .sched_policy = SCHED_OTHER, .sched_inherit = PTHREAD_INHERIT_SCHED, .prio = 0, .suspend = THR_CREATE_RUNNING, .flags = PTHREAD_SCOPE_SYSTEM, .stackaddr_attr = NULL, .stacksize_attr = THR_STACK_DEFAULT, .guardsize_attr = 0, .cpusetsize = 0, .cpuset = NULL }; struct pthread_mutex_attr _pthread_mutexattr_default = { .m_type = PTHREAD_MUTEX_DEFAULT, .m_protocol = PTHREAD_PRIO_NONE, .m_ceiling = 0 }; struct pthread_mutex_attr _pthread_mutexattr_adaptive_default = { .m_type = PTHREAD_MUTEX_ADAPTIVE_NP, .m_protocol = PTHREAD_PRIO_NONE, .m_ceiling = 0 }; /* Default condition variable attributes: */ struct pthread_cond_attr _pthread_condattr_default = { .c_pshared = PTHREAD_PROCESS_PRIVATE, .c_clockid = CLOCK_REALTIME }; pid_t _thr_pid; int _thr_is_smp = 0; size_t _thr_guard_default; size_t _thr_stack_default = THR_STACK_DEFAULT; size_t _thr_stack_initial = THR_STACK_INITIAL; int _thr_page_size; int _thr_spinloops; int _thr_yieldloops; int _thr_queuefifo = 4; int _gc_count; struct umutex _mutex_static_lock = DEFAULT_UMUTEX; struct umutex _cond_static_lock = DEFAULT_UMUTEX; struct umutex _rwlock_static_lock = DEFAULT_UMUTEX; struct umutex _keytable_lock = DEFAULT_UMUTEX; struct urwlock _thr_list_lock = DEFAULT_URWLOCK; struct umutex _thr_event_lock = DEFAULT_UMUTEX; struct umutex _suspend_all_lock = DEFAULT_UMUTEX; struct pthread *_single_thread; int _suspend_all_cycle; int _suspend_all_waiters; int __pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *); int __pthread_mutex_lock(pthread_mutex_t *); int __pthread_mutex_trylock(pthread_mutex_t *); void _thread_init_hack(void) __attribute__ ((constructor)); static void init_private(void); static void init_main_thread(struct pthread *thread); /* * All weak references used within libc should be in this table. * This is so that static libraries will work. */ STATIC_LIB_REQUIRE(_fork); STATIC_LIB_REQUIRE(_pthread_getspecific); STATIC_LIB_REQUIRE(_pthread_key_create); STATIC_LIB_REQUIRE(_pthread_key_delete); STATIC_LIB_REQUIRE(_pthread_mutex_destroy); STATIC_LIB_REQUIRE(_pthread_mutex_init); STATIC_LIB_REQUIRE(_pthread_mutex_lock); STATIC_LIB_REQUIRE(_pthread_mutex_trylock); STATIC_LIB_REQUIRE(_pthread_mutex_unlock); STATIC_LIB_REQUIRE(_pthread_mutexattr_init); STATIC_LIB_REQUIRE(_pthread_mutexattr_destroy); STATIC_LIB_REQUIRE(_pthread_mutexattr_settype); STATIC_LIB_REQUIRE(_pthread_once); STATIC_LIB_REQUIRE(_pthread_setspecific); STATIC_LIB_REQUIRE(_raise); STATIC_LIB_REQUIRE(_sem_destroy); STATIC_LIB_REQUIRE(_sem_getvalue); STATIC_LIB_REQUIRE(_sem_init); STATIC_LIB_REQUIRE(_sem_post); STATIC_LIB_REQUIRE(_sem_timedwait); STATIC_LIB_REQUIRE(_sem_trywait); STATIC_LIB_REQUIRE(_sem_wait); STATIC_LIB_REQUIRE(_sigaction); STATIC_LIB_REQUIRE(_sigprocmask); STATIC_LIB_REQUIRE(_sigsuspend); STATIC_LIB_REQUIRE(_sigtimedwait); STATIC_LIB_REQUIRE(_sigwait); STATIC_LIB_REQUIRE(_sigwaitinfo); STATIC_LIB_REQUIRE(_spinlock); STATIC_LIB_REQUIRE(_spinlock_debug); STATIC_LIB_REQUIRE(_spinunlock); STATIC_LIB_REQUIRE(_thread_init_hack); /* * These are needed when linking statically. All references within * libgcc (and in the future libc) to these routines are weak, but * if they are not (strongly) referenced by the application or other * libraries, then the actual functions will not be loaded. */ STATIC_LIB_REQUIRE(_pthread_once); STATIC_LIB_REQUIRE(_pthread_key_create); STATIC_LIB_REQUIRE(_pthread_key_delete); STATIC_LIB_REQUIRE(_pthread_getspecific); STATIC_LIB_REQUIRE(_pthread_setspecific); STATIC_LIB_REQUIRE(_pthread_mutex_init); STATIC_LIB_REQUIRE(_pthread_mutex_destroy); STATIC_LIB_REQUIRE(_pthread_mutex_lock); STATIC_LIB_REQUIRE(_pthread_mutex_trylock); STATIC_LIB_REQUIRE(_pthread_mutex_unlock); STATIC_LIB_REQUIRE(_pthread_create); /* Pull in all symbols required by libthread_db */ STATIC_LIB_REQUIRE(_thread_state_running); #define DUAL_ENTRY(entry) \ (pthread_func_t)entry, (pthread_func_t)entry static pthread_func_t jmp_table[][2] = { {DUAL_ENTRY(_pthread_atfork)}, /* PJT_ATFORK */ {DUAL_ENTRY(_pthread_attr_destroy)}, /* PJT_ATTR_DESTROY */ {DUAL_ENTRY(_pthread_attr_getdetachstate)}, /* PJT_ATTR_GETDETACHSTATE */ {DUAL_ENTRY(_pthread_attr_getguardsize)}, /* PJT_ATTR_GETGUARDSIZE */ {DUAL_ENTRY(_pthread_attr_getinheritsched)}, /* PJT_ATTR_GETINHERITSCHED */ {DUAL_ENTRY(_pthread_attr_getschedparam)}, /* PJT_ATTR_GETSCHEDPARAM */ {DUAL_ENTRY(_pthread_attr_getschedpolicy)}, /* PJT_ATTR_GETSCHEDPOLICY */ {DUAL_ENTRY(_pthread_attr_getscope)}, /* PJT_ATTR_GETSCOPE */ {DUAL_ENTRY(_pthread_attr_getstackaddr)}, /* PJT_ATTR_GETSTACKADDR */ {DUAL_ENTRY(_pthread_attr_getstacksize)}, /* PJT_ATTR_GETSTACKSIZE */ {DUAL_ENTRY(_pthread_attr_init)}, /* PJT_ATTR_INIT */ {DUAL_ENTRY(_pthread_attr_setdetachstate)}, /* PJT_ATTR_SETDETACHSTATE */ {DUAL_ENTRY(_pthread_attr_setguardsize)}, /* PJT_ATTR_SETGUARDSIZE */ {DUAL_ENTRY(_pthread_attr_setinheritsched)}, /* PJT_ATTR_SETINHERITSCHED */ {DUAL_ENTRY(_pthread_attr_setschedparam)}, /* PJT_ATTR_SETSCHEDPARAM */ {DUAL_ENTRY(_pthread_attr_setschedpolicy)}, /* PJT_ATTR_SETSCHEDPOLICY */ {DUAL_ENTRY(_pthread_attr_setscope)}, /* PJT_ATTR_SETSCOPE */ {DUAL_ENTRY(_pthread_attr_setstackaddr)}, /* PJT_ATTR_SETSTACKADDR */ {DUAL_ENTRY(_pthread_attr_setstacksize)}, /* PJT_ATTR_SETSTACKSIZE */ {DUAL_ENTRY(_pthread_cancel)}, /* PJT_CANCEL */ {DUAL_ENTRY(_pthread_cleanup_pop)}, /* PJT_CLEANUP_POP */ {DUAL_ENTRY(_pthread_cleanup_push)}, /* PJT_CLEANUP_PUSH */ {DUAL_ENTRY(_pthread_cond_broadcast)}, /* PJT_COND_BROADCAST */ {DUAL_ENTRY(_pthread_cond_destroy)}, /* PJT_COND_DESTROY */ {DUAL_ENTRY(_pthread_cond_init)}, /* PJT_COND_INIT */ {DUAL_ENTRY(_pthread_cond_signal)}, /* PJT_COND_SIGNAL */ {DUAL_ENTRY(_pthread_cond_timedwait)}, /* PJT_COND_TIMEDWAIT */ {(pthread_func_t)__pthread_cond_wait, (pthread_func_t)_pthread_cond_wait}, /* PJT_COND_WAIT */ {DUAL_ENTRY(_pthread_detach)}, /* PJT_DETACH */ {DUAL_ENTRY(_pthread_equal)}, /* PJT_EQUAL */ {DUAL_ENTRY(_pthread_exit)}, /* PJT_EXIT */ {DUAL_ENTRY(_pthread_getspecific)}, /* PJT_GETSPECIFIC */ {DUAL_ENTRY(_pthread_join)}, /* PJT_JOIN */ {DUAL_ENTRY(_pthread_key_create)}, /* PJT_KEY_CREATE */ {DUAL_ENTRY(_pthread_key_delete)}, /* PJT_KEY_DELETE*/ {DUAL_ENTRY(_pthread_kill)}, /* PJT_KILL */ {DUAL_ENTRY(_pthread_main_np)}, /* PJT_MAIN_NP */ {DUAL_ENTRY(_pthread_mutexattr_destroy)}, /* PJT_MUTEXATTR_DESTROY */ {DUAL_ENTRY(_pthread_mutexattr_init)}, /* PJT_MUTEXATTR_INIT */ {DUAL_ENTRY(_pthread_mutexattr_settype)}, /* PJT_MUTEXATTR_SETTYPE */ {DUAL_ENTRY(_pthread_mutex_destroy)}, /* PJT_MUTEX_DESTROY */ {DUAL_ENTRY(_pthread_mutex_init)}, /* PJT_MUTEX_INIT */ {(pthread_func_t)__pthread_mutex_lock, (pthread_func_t)_pthread_mutex_lock}, /* PJT_MUTEX_LOCK */ {(pthread_func_t)__pthread_mutex_trylock, (pthread_func_t)_pthread_mutex_trylock},/* PJT_MUTEX_TRYLOCK */ {DUAL_ENTRY(_pthread_mutex_unlock)}, /* PJT_MUTEX_UNLOCK */ {DUAL_ENTRY(_pthread_once)}, /* PJT_ONCE */ {DUAL_ENTRY(_pthread_rwlock_destroy)}, /* PJT_RWLOCK_DESTROY */ {DUAL_ENTRY(_pthread_rwlock_init)}, /* PJT_RWLOCK_INIT */ {DUAL_ENTRY(_pthread_rwlock_rdlock)}, /* PJT_RWLOCK_RDLOCK */ {DUAL_ENTRY(_pthread_rwlock_tryrdlock)},/* PJT_RWLOCK_TRYRDLOCK */ {DUAL_ENTRY(_pthread_rwlock_trywrlock)},/* PJT_RWLOCK_TRYWRLOCK */ {DUAL_ENTRY(_pthread_rwlock_unlock)}, /* PJT_RWLOCK_UNLOCK */ {DUAL_ENTRY(_pthread_rwlock_wrlock)}, /* PJT_RWLOCK_WRLOCK */ {DUAL_ENTRY(_pthread_self)}, /* PJT_SELF */ {DUAL_ENTRY(_pthread_setcancelstate)}, /* PJT_SETCANCELSTATE */ {DUAL_ENTRY(_pthread_setcanceltype)}, /* PJT_SETCANCELTYPE */ {DUAL_ENTRY(_pthread_setspecific)}, /* PJT_SETSPECIFIC */ {DUAL_ENTRY(_pthread_sigmask)}, /* PJT_SIGMASK */ {DUAL_ENTRY(_pthread_testcancel)}, /* PJT_TESTCANCEL */ {DUAL_ENTRY(__pthread_cleanup_pop_imp)},/* PJT_CLEANUP_POP_IMP */ {DUAL_ENTRY(__pthread_cleanup_push_imp)},/* PJT_CLEANUP_PUSH_IMP */ {DUAL_ENTRY(_pthread_cancel_enter)}, /* PJT_CANCEL_ENTER */ {DUAL_ENTRY(_pthread_cancel_leave)} /* PJT_CANCEL_LEAVE */ }; static int init_once = 0; /* * For the shared version of the threads library, the above is sufficient. * But for the archive version of the library, we need a little bit more. * Namely, we must arrange for this particular module to be pulled in from * the archive library at link time. To accomplish that, we define and * initialize a variable, "_thread_autoinit_dummy_decl". This variable is * referenced (as an extern) from libc/stdlib/exit.c. This will always * create a need for this module, ensuring that it is present in the * executable. */ extern int _thread_autoinit_dummy_decl; int _thread_autoinit_dummy_decl = 0; void _thread_init_hack(void) { _libpthread_init(NULL); } /* * Threaded process initialization. * * This is only called under two conditions: * * 1) Some thread routines have detected that the library hasn't yet * been initialized (_thr_initial == NULL && curthread == NULL), or * * 2) An explicit call to reinitialize after a fork (indicated * by curthread != NULL) */ void _libpthread_init(struct pthread *curthread) { - int fd, first = 0; + int fd, first, dlopened; /* Check if this function has already been called: */ if ((_thr_initial != NULL) && (curthread == NULL)) /* Only initialize the threaded application once. */ return; /* * Check the size of the jump table to make sure it is preset * with the correct number of entries. */ if (sizeof(jmp_table) != (sizeof(pthread_func_t) * PJT_MAX * 2)) PANIC("Thread jump table not properly initialized"); memcpy(__thr_jtable, jmp_table, sizeof(jmp_table)); + __thr_interpose_libc(); /* * Check for the special case of this process running as * or in place of init as pid = 1: */ if ((_thr_pid = getpid()) == 1) { /* * Setup a new session for this process which is * assumed to be running as root. */ if (setsid() == -1) PANIC("Can't set session ID"); if (revoke(_PATH_CONSOLE) != 0) PANIC("Can't revoke console"); if ((fd = __sys_open(_PATH_CONSOLE, O_RDWR)) < 0) PANIC("Can't open console"); if (setlogin("root") == -1) PANIC("Can't set login to root"); if (_ioctl(fd, TIOCSCTTY, (char *) NULL) == -1) PANIC("Can't set controlling terminal"); } /* Initialize pthread private data. */ init_private(); /* Set the initial thread. */ if (curthread == NULL) { first = 1; /* Create and initialize the initial thread. */ curthread = _thr_alloc(NULL); if (curthread == NULL) PANIC("Can't allocate initial thread"); init_main_thread(curthread); + } else { + first = 0; } + /* * Add the thread to the thread list queue. */ THR_LIST_ADD(curthread); _thread_active_threads = 1; /* Setup the thread specific data */ _tcb_set(curthread->tcb); if (first) { _thr_initial = curthread; - _thr_signal_init(); + dlopened = _rtld_is_dlopened(&_thread_autoinit_dummy_decl) != 0; + _thr_signal_init(dlopened); if (_thread_event_mask & TD_CREATE) _thr_report_creation(curthread, curthread); /* * Always use our rtld lock implementation. * It is faster because it postpones signal handlers * instead of calling sigprocmask(2). */ _thr_rtld_init(); } } /* * This function and pthread_create() do a lot of the same things. * It'd be nice to consolidate the common stuff in one place. */ static void init_main_thread(struct pthread *thread) { struct sched_param sched_param; /* Setup the thread attributes. */ thr_self(&thread->tid); thread->attr = _pthread_attr_default; /* * Set up the thread stack. * * Create a red zone below the main stack. All other stacks * are constrained to a maximum size by the parameters * passed to mmap(), but this stack is only limited by * resource limits, so this stack needs an explicitly mapped * red zone to protect the thread stack that is just beyond. */ if (mmap(_usrstack - _thr_stack_initial - _thr_guard_default, _thr_guard_default, 0, MAP_ANON, -1, 0) == MAP_FAILED) PANIC("Cannot allocate red zone for initial thread"); /* * Mark the stack as an application supplied stack so that it * isn't deallocated. * * XXX - I'm not sure it would hurt anything to deallocate * the main thread stack because deallocation doesn't * actually free() it; it just puts it in the free * stack queue for later reuse. */ thread->attr.stackaddr_attr = _usrstack - _thr_stack_initial; thread->attr.stacksize_attr = _thr_stack_initial; thread->attr.guardsize_attr = _thr_guard_default; thread->attr.flags |= THR_STACK_USER; /* * Write a magic value to the thread structure * to help identify valid ones: */ thread->magic = THR_MAGIC; thread->cancel_enable = 1; thread->cancel_async = 0; /* Initialize the mutex queue: */ TAILQ_INIT(&thread->mutexq); TAILQ_INIT(&thread->pp_mutexq); thread->state = PS_RUNNING; _thr_getscheduler(thread->tid, &thread->attr.sched_policy, &sched_param); thread->attr.prio = sched_param.sched_priority; #ifdef _PTHREAD_FORCED_UNWIND thread->unwind_stackend = _usrstack; #endif /* Others cleared to zero by thr_alloc() */ } static void init_private(void) { struct rlimit rlim; size_t len; int mib[2]; char *env, *env_bigstack, *env_splitstack; _thr_umutex_init(&_mutex_static_lock); _thr_umutex_init(&_cond_static_lock); _thr_umutex_init(&_rwlock_static_lock); _thr_umutex_init(&_keytable_lock); _thr_urwlock_init(&_thr_atfork_lock); _thr_umutex_init(&_thr_event_lock); _thr_umutex_init(&_suspend_all_lock); _thr_once_init(); _thr_spinlock_init(); _thr_list_init(); _thr_wake_addr_init(); _sleepq_init(); _single_thread = NULL; _suspend_all_waiters = 0; /* * Avoid reinitializing some things if they don't need to be, * e.g. after a fork(). */ if (init_once == 0) { /* Find the stack top */ mib[0] = CTL_KERN; mib[1] = KERN_USRSTACK; len = sizeof (_usrstack); if (sysctl(mib, 2, &_usrstack, &len, NULL, 0) == -1) PANIC("Cannot get kern.usrstack from sysctl"); env_bigstack = getenv("LIBPTHREAD_BIGSTACK_MAIN"); env_splitstack = getenv("LIBPTHREAD_SPLITSTACK_MAIN"); if (env_bigstack != NULL || env_splitstack == NULL) { if (getrlimit(RLIMIT_STACK, &rlim) == -1) PANIC("Cannot get stack rlimit"); _thr_stack_initial = rlim.rlim_cur; } len = sizeof(_thr_is_smp); sysctlbyname("kern.smp.cpus", &_thr_is_smp, &len, NULL, 0); _thr_is_smp = (_thr_is_smp > 1); _thr_page_size = getpagesize(); _thr_guard_default = _thr_page_size; _pthread_attr_default.guardsize_attr = _thr_guard_default; _pthread_attr_default.stacksize_attr = _thr_stack_default; env = getenv("LIBPTHREAD_SPINLOOPS"); if (env) _thr_spinloops = atoi(env); env = getenv("LIBPTHREAD_YIELDLOOPS"); if (env) _thr_yieldloops = atoi(env); env = getenv("LIBPTHREAD_QUEUE_FIFO"); if (env) _thr_queuefifo = atoi(env); TAILQ_INIT(&_thr_atfork_list); } init_once = 1; } Index: head/lib/libthr/thread/thr_printf.c =================================================================== --- head/lib/libthr/thread/thr_printf.c (revision 276629) +++ head/lib/libthr/thread/thr_printf.c (revision 276630) @@ -1,135 +1,136 @@ /*- * Copyright (c) 2002 Jonathan Mini * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #include #include #include #include +#include "libc_private.h" #include "thr_private.h" static void pchar(int fd, char c); static void pstr(int fd, const char *s); /* * Write formatted output to stdout, in a thread-safe manner. * * Recognises the following conversions: * %c -> char * %d -> signed int (base 10) * %s -> string * %u -> unsigned int (base 10) * %x -> unsigned int (base 16) * %p -> unsigned int (base 16) */ void _thread_printf(int fd, const char *fmt, ...) { static const char digits[16] = "0123456789abcdef"; va_list ap; char buf[20]; char *s; unsigned long r, u; int c; long d; int islong; va_start(ap, fmt); while ((c = *fmt++)) { islong = 0; if (c == '%') { next: c = *fmt++; if (c == '\0') goto out; switch (c) { case 'c': pchar(fd, va_arg(ap, int)); continue; case 's': pstr(fd, va_arg(ap, char *)); continue; case 'l': islong = 1; goto next; case 'p': islong = 1; case 'd': case 'u': case 'x': r = ((c == 'u') || (c == 'd')) ? 10 : 16; if (c == 'd') { if (islong) d = va_arg(ap, unsigned long); else d = va_arg(ap, unsigned); if (d < 0) { pchar(fd, '-'); u = (unsigned long)(d * -1); } else u = (unsigned long)d; } else { if (islong) u = va_arg(ap, unsigned long); else u = va_arg(ap, unsigned); } s = buf; do { *s++ = digits[u % r]; } while (u /= r); while (--s >= buf) pchar(fd, *s); continue; } } pchar(fd, c); } out: va_end(ap); } /* * Write a single character to stdout, in a thread-safe manner. */ static void pchar(int fd, char c) { __sys_write(fd, &c, 1); } /* * Write a string to stdout, in a thread-safe manner. */ static void pstr(int fd, const char *s) { __sys_write(fd, s, strlen(s)); } Index: head/lib/libthr/thread/thr_private.h =================================================================== --- head/lib/libthr/thread/thr_private.h (revision 276629) +++ head/lib/libthr/thread/thr_private.h (revision 276630) @@ -1,917 +1,935 @@ /* * Copyright (C) 2005 Daniel M. Eischen * Copyright (c) 2005 David Xu * Copyright (c) 1995-1998 John Birrell . * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice unmodified, this list of conditions, and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD$ */ #ifndef _THR_PRIVATE_H #define _THR_PRIVATE_H /* * Include files. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define SYM_FB10(sym) __CONCAT(sym, _fb10) #define SYM_FBP10(sym) __CONCAT(sym, _fbp10) #define WEAK_REF(sym, alias) __weak_reference(sym, alias) #define SYM_COMPAT(sym, impl, ver) __sym_compat(sym, impl, ver) #define SYM_DEFAULT(sym, impl, ver) __sym_default(sym, impl, ver) #define FB10_COMPAT(func, sym) \ WEAK_REF(func, SYM_FB10(sym)); \ SYM_COMPAT(sym, SYM_FB10(sym), FBSD_1.0) #define FB10_COMPAT_PRIVATE(func, sym) \ WEAK_REF(func, SYM_FBP10(sym)); \ SYM_DEFAULT(sym, SYM_FBP10(sym), FBSDprivate_1.0) #include "pthread_md.h" #include "thr_umtx.h" #include "thread_db.h" #ifdef _PTHREAD_FORCED_UNWIND #define _BSD_SOURCE #include #endif typedef TAILQ_HEAD(pthreadlist, pthread) pthreadlist; typedef TAILQ_HEAD(atfork_head, pthread_atfork) atfork_head; TAILQ_HEAD(mutex_queue, pthread_mutex); /* Signal to do cancellation */ #define SIGCANCEL SIGTHR /* * Kernel fatal error handler macro. */ #define PANIC(string) _thread_exit(__FILE__,__LINE__,string) /* Output debug messages like this: */ #define stdout_debug(args...) _thread_printf(STDOUT_FILENO, ##args) #define stderr_debug(args...) _thread_printf(STDERR_FILENO, ##args) #ifdef _PTHREADS_INVARIANTS #define THR_ASSERT(cond, msg) do { \ if (__predict_false(!(cond))) \ PANIC(msg); \ } while (0) #else #define THR_ASSERT(cond, msg) #endif #ifdef PIC # define STATIC_LIB_REQUIRE(name) #else # define STATIC_LIB_REQUIRE(name) __asm (".globl " #name) #endif #define TIMESPEC_ADD(dst, src, val) \ do { \ (dst)->tv_sec = (src)->tv_sec + (val)->tv_sec; \ (dst)->tv_nsec = (src)->tv_nsec + (val)->tv_nsec; \ if ((dst)->tv_nsec >= 1000000000) { \ (dst)->tv_sec++; \ (dst)->tv_nsec -= 1000000000; \ } \ } while (0) #define TIMESPEC_SUB(dst, src, val) \ do { \ (dst)->tv_sec = (src)->tv_sec - (val)->tv_sec; \ (dst)->tv_nsec = (src)->tv_nsec - (val)->tv_nsec; \ if ((dst)->tv_nsec < 0) { \ (dst)->tv_sec--; \ (dst)->tv_nsec += 1000000000; \ } \ } while (0) /* XXX These values should be same as those defined in pthread.h */ #define THR_MUTEX_INITIALIZER ((struct pthread_mutex *)NULL) #define THR_ADAPTIVE_MUTEX_INITIALIZER ((struct pthread_mutex *)1) #define THR_MUTEX_DESTROYED ((struct pthread_mutex *)2) #define THR_COND_INITIALIZER ((struct pthread_cond *)NULL) #define THR_COND_DESTROYED ((struct pthread_cond *)1) #define THR_RWLOCK_INITIALIZER ((struct pthread_rwlock *)NULL) #define THR_RWLOCK_DESTROYED ((struct pthread_rwlock *)1) #define PMUTEX_FLAG_TYPE_MASK 0x0ff #define PMUTEX_FLAG_PRIVATE 0x100 #define PMUTEX_FLAG_DEFERED 0x200 #define PMUTEX_TYPE(mtxflags) ((mtxflags) & PMUTEX_FLAG_TYPE_MASK) #define MAX_DEFER_WAITERS 50 struct pthread_mutex { /* * Lock for accesses to this structure. */ struct umutex m_lock; int m_flags; struct pthread *m_owner; int m_count; int m_spinloops; int m_yieldloops; /* * Link for all mutexes a thread currently owns. */ TAILQ_ENTRY(pthread_mutex) m_qe; }; struct pthread_mutex_attr { enum pthread_mutextype m_type; int m_protocol; int m_ceiling; }; #define PTHREAD_MUTEXATTR_STATIC_INITIALIZER \ { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, MUTEX_FLAGS_PRIVATE } struct pthread_cond { __uint32_t __has_user_waiters; __uint32_t __has_kern_waiters; __uint32_t __flags; __uint32_t __clock_id; }; struct pthread_cond_attr { int c_pshared; int c_clockid; }; struct pthread_barrier { struct umutex b_lock; struct ucond b_cv; int64_t b_cycle; int b_count; int b_waiters; int b_refcount; int b_destroying; }; struct pthread_barrierattr { int pshared; }; struct pthread_spinlock { struct umutex s_lock; }; /* * Flags for condition variables. */ #define COND_FLAGS_PRIVATE 0x01 #define COND_FLAGS_INITED 0x02 #define COND_FLAGS_BUSY 0x04 /* * Cleanup definitions. */ struct pthread_cleanup { struct pthread_cleanup *prev; void (*routine)(void *); void *routine_arg; int onheap; }; #define THR_CLEANUP_PUSH(td, func, arg) { \ struct pthread_cleanup __cup; \ \ __cup.routine = func; \ __cup.routine_arg = arg; \ __cup.onheap = 0; \ __cup.prev = (td)->cleanup; \ (td)->cleanup = &__cup; #define THR_CLEANUP_POP(td, exec) \ (td)->cleanup = __cup.prev; \ if ((exec) != 0) \ __cup.routine(__cup.routine_arg); \ } struct pthread_atfork { TAILQ_ENTRY(pthread_atfork) qe; void (*prepare)(void); void (*parent)(void); void (*child)(void); }; struct pthread_attr { #define pthread_attr_start_copy sched_policy int sched_policy; int sched_inherit; int prio; int suspend; #define THR_STACK_USER 0x100 /* 0xFF reserved for */ int flags; void *stackaddr_attr; size_t stacksize_attr; size_t guardsize_attr; #define pthread_attr_end_copy cpuset cpuset_t *cpuset; size_t cpusetsize; }; struct wake_addr { struct wake_addr *link; unsigned int value; char pad[12]; }; struct sleepqueue { TAILQ_HEAD(, pthread) sq_blocked; SLIST_HEAD(, sleepqueue) sq_freeq; LIST_ENTRY(sleepqueue) sq_hash; SLIST_ENTRY(sleepqueue) sq_flink; void *sq_wchan; int sq_type; }; /* * Thread creation state attributes. */ #define THR_CREATE_RUNNING 0 #define THR_CREATE_SUSPENDED 1 /* * Miscellaneous definitions. */ #define THR_STACK_DEFAULT (sizeof(void *) / 4 * 1024 * 1024) /* * Maximum size of initial thread's stack. This perhaps deserves to be larger * than the stacks of other threads, since many applications are likely to run * almost entirely on this stack. */ #define THR_STACK_INITIAL (THR_STACK_DEFAULT * 2) /* * Define priorities returned by kernel. */ #define THR_MIN_PRIORITY (_thr_priorities[SCHED_OTHER-1].pri_min) #define THR_MAX_PRIORITY (_thr_priorities[SCHED_OTHER-1].pri_max) #define THR_DEF_PRIORITY (_thr_priorities[SCHED_OTHER-1].pri_default) #define THR_MIN_RR_PRIORITY (_thr_priorities[SCHED_RR-1].pri_min) #define THR_MAX_RR_PRIORITY (_thr_priorities[SCHED_RR-1].pri_max) #define THR_DEF_RR_PRIORITY (_thr_priorities[SCHED_RR-1].pri_default) /* XXX The SCHED_FIFO should have same priority range as SCHED_RR */ #define THR_MIN_FIFO_PRIORITY (_thr_priorities[SCHED_FIFO_1].pri_min) #define THR_MAX_FIFO_PRIORITY (_thr_priorities[SCHED_FIFO-1].pri_max) #define THR_DEF_FIFO_PRIORITY (_thr_priorities[SCHED_FIFO-1].pri_default) struct pthread_prio { int pri_min; int pri_max; int pri_default; }; struct pthread_rwlockattr { int pshared; }; struct pthread_rwlock { struct urwlock lock; struct pthread *owner; }; /* * Thread states. */ enum pthread_state { PS_RUNNING, PS_DEAD }; struct pthread_specific_elem { const void *data; int seqno; }; struct pthread_key { volatile int allocated; int seqno; void (*destructor)(void *); }; /* * lwpid_t is 32bit but kernel thr API exports tid as long type * in very earily date. */ #define TID(thread) ((uint32_t) ((thread)->tid)) /* * Thread structure. */ struct pthread { #define _pthread_startzero tid /* Kernel thread id. */ long tid; #define TID_TERMINATED 1 /* * Lock for accesses to this thread structure. */ struct umutex lock; /* Internal condition variable cycle number. */ uint32_t cycle; /* How many low level locks the thread held. */ int locklevel; /* * Set to non-zero when this thread has entered a critical * region. We allow for recursive entries into critical regions. */ int critical_count; /* Signal blocked counter. */ int sigblock; /* Queue entry for list of all threads. */ TAILQ_ENTRY(pthread) tle; /* link for all threads in process */ /* Queue entry for GC lists. */ TAILQ_ENTRY(pthread) gcle; /* Hash queue entry. */ LIST_ENTRY(pthread) hle; /* Sleep queue entry */ TAILQ_ENTRY(pthread) wle; /* Threads reference count. */ int refcount; /* * Thread start routine, argument, stack pointer and thread * attributes. */ void *(*start_routine)(void *); void *arg; struct pthread_attr attr; #define SHOULD_CANCEL(thr) \ ((thr)->cancel_pending && (thr)->cancel_enable && \ (thr)->no_cancel == 0) /* Cancellation is enabled */ int cancel_enable; /* Cancellation request is pending */ int cancel_pending; /* Thread is at cancellation point */ int cancel_point; /* Cancellation is temporarily disabled */ int no_cancel; /* Asynchronouse cancellation is enabled */ int cancel_async; /* Cancellation is in progress */ int cancelling; /* Thread temporary signal mask. */ sigset_t sigmask; /* Thread should unblock SIGCANCEL. */ int unblock_sigcancel; /* In sigsuspend state */ int in_sigsuspend; /* deferred signal info */ siginfo_t deferred_siginfo; /* signal mask to restore. */ sigset_t deferred_sigmask; /* the sigaction should be used for deferred signal. */ struct sigaction deferred_sigact; /* deferred signal delivery is performed, do not reenter. */ int deferred_run; /* Force new thread to exit. */ int force_exit; /* Thread state: */ enum pthread_state state; /* * Error variable used instead of errno. The function __error() * returns a pointer to this. */ int error; /* * The joiner is the thread that is joining to this thread. The * join status keeps track of a join operation to another thread. */ struct pthread *joiner; /* Miscellaneous flags; only set with scheduling lock held. */ int flags; #define THR_FLAGS_PRIVATE 0x0001 #define THR_FLAGS_NEED_SUSPEND 0x0002 /* thread should be suspended */ #define THR_FLAGS_SUSPENDED 0x0004 /* thread is suspended */ #define THR_FLAGS_DETACHED 0x0008 /* thread is detached */ /* Thread list flags; only set with thread list lock held. */ int tlflags; #define TLFLAGS_GC_SAFE 0x0001 /* thread safe for cleaning */ #define TLFLAGS_IN_TDLIST 0x0002 /* thread in all thread list */ #define TLFLAGS_IN_GCLIST 0x0004 /* thread in gc list */ /* Queue of currently owned NORMAL or PRIO_INHERIT type mutexes. */ struct mutex_queue mutexq; /* Queue of all owned PRIO_PROTECT mutexes. */ struct mutex_queue pp_mutexq; void *ret; struct pthread_specific_elem *specific; int specific_data_count; /* Number rwlocks rdlocks held. */ int rdlock_count; /* * Current locks bitmap for rtld. */ int rtld_bits; /* Thread control block */ struct tcb *tcb; /* Cleanup handlers Link List */ struct pthread_cleanup *cleanup; #ifdef _PTHREAD_FORCED_UNWIND struct _Unwind_Exception ex; void *unwind_stackend; int unwind_disabled; #endif /* * Magic value to help recognize a valid thread structure * from an invalid one: */ #define THR_MAGIC ((u_int32_t) 0xd09ba115) u_int32_t magic; /* Enable event reporting */ int report_events; /* Event mask */ int event_mask; /* Event */ td_event_msg_t event_buf; /* Wait channel */ void *wchan; /* Referenced mutex. */ struct pthread_mutex *mutex_obj; /* Thread will sleep. */ int will_sleep; /* Number of threads deferred. */ int nwaiter_defer; /* Deferred threads from pthread_cond_signal. */ unsigned int *defer_waiters[MAX_DEFER_WAITERS]; #define _pthread_endzero wake_addr struct wake_addr *wake_addr; #define WAKE_ADDR(td) ((td)->wake_addr) /* Sleep queue */ struct sleepqueue *sleepqueue; }; #define THR_SHOULD_GC(thrd) \ ((thrd)->refcount == 0 && (thrd)->state == PS_DEAD && \ ((thrd)->flags & THR_FLAGS_DETACHED) != 0) #define THR_IN_CRITICAL(thrd) \ (((thrd)->locklevel > 0) || \ ((thrd)->critical_count > 0)) #define THR_CRITICAL_ENTER(thrd) \ (thrd)->critical_count++ #define THR_CRITICAL_LEAVE(thrd) \ do { \ (thrd)->critical_count--; \ _thr_ast(thrd); \ } while (0) #define THR_UMUTEX_TRYLOCK(thrd, lck) \ _thr_umutex_trylock((lck), TID(thrd)) #define THR_UMUTEX_LOCK(thrd, lck) \ _thr_umutex_lock((lck), TID(thrd)) #define THR_UMUTEX_TIMEDLOCK(thrd, lck, timo) \ _thr_umutex_timedlock((lck), TID(thrd), (timo)) #define THR_UMUTEX_UNLOCK(thrd, lck) \ _thr_umutex_unlock((lck), TID(thrd)) #define THR_LOCK_ACQUIRE(thrd, lck) \ do { \ (thrd)->locklevel++; \ _thr_umutex_lock(lck, TID(thrd)); \ } while (0) #define THR_LOCK_ACQUIRE_SPIN(thrd, lck) \ do { \ (thrd)->locklevel++; \ _thr_umutex_lock_spin(lck, TID(thrd)); \ } while (0) #ifdef _PTHREADS_INVARIANTS #define THR_ASSERT_LOCKLEVEL(thrd) \ do { \ if (__predict_false((thrd)->locklevel <= 0)) \ _thr_assert_lock_level(); \ } while (0) #else #define THR_ASSERT_LOCKLEVEL(thrd) #endif #define THR_LOCK_RELEASE(thrd, lck) \ do { \ THR_ASSERT_LOCKLEVEL(thrd); \ _thr_umutex_unlock((lck), TID(thrd)); \ (thrd)->locklevel--; \ _thr_ast(thrd); \ } while (0) #define THR_LOCK(curthrd) THR_LOCK_ACQUIRE(curthrd, &(curthrd)->lock) #define THR_UNLOCK(curthrd) THR_LOCK_RELEASE(curthrd, &(curthrd)->lock) #define THR_THREAD_LOCK(curthrd, thr) THR_LOCK_ACQUIRE(curthrd, &(thr)->lock) #define THR_THREAD_UNLOCK(curthrd, thr) THR_LOCK_RELEASE(curthrd, &(thr)->lock) #define THREAD_LIST_RDLOCK(curthrd) \ do { \ (curthrd)->locklevel++; \ _thr_rwl_rdlock(&_thr_list_lock); \ } while (0) #define THREAD_LIST_WRLOCK(curthrd) \ do { \ (curthrd)->locklevel++; \ _thr_rwl_wrlock(&_thr_list_lock); \ } while (0) #define THREAD_LIST_UNLOCK(curthrd) \ do { \ _thr_rwl_unlock(&_thr_list_lock); \ (curthrd)->locklevel--; \ _thr_ast(curthrd); \ } while (0) /* * Macros to insert/remove threads to the all thread list and * the gc list. */ #define THR_LIST_ADD(thrd) do { \ if (((thrd)->tlflags & TLFLAGS_IN_TDLIST) == 0) { \ TAILQ_INSERT_HEAD(&_thread_list, thrd, tle); \ _thr_hash_add(thrd); \ (thrd)->tlflags |= TLFLAGS_IN_TDLIST; \ } \ } while (0) #define THR_LIST_REMOVE(thrd) do { \ if (((thrd)->tlflags & TLFLAGS_IN_TDLIST) != 0) { \ TAILQ_REMOVE(&_thread_list, thrd, tle); \ _thr_hash_remove(thrd); \ (thrd)->tlflags &= ~TLFLAGS_IN_TDLIST; \ } \ } while (0) #define THR_GCLIST_ADD(thrd) do { \ if (((thrd)->tlflags & TLFLAGS_IN_GCLIST) == 0) { \ TAILQ_INSERT_HEAD(&_thread_gc_list, thrd, gcle);\ (thrd)->tlflags |= TLFLAGS_IN_GCLIST; \ _gc_count++; \ } \ } while (0) #define THR_GCLIST_REMOVE(thrd) do { \ if (((thrd)->tlflags & TLFLAGS_IN_GCLIST) != 0) { \ TAILQ_REMOVE(&_thread_gc_list, thrd, gcle); \ (thrd)->tlflags &= ~TLFLAGS_IN_GCLIST; \ _gc_count--; \ } \ } while (0) #define THR_REF_ADD(curthread, pthread) { \ THR_CRITICAL_ENTER(curthread); \ pthread->refcount++; \ } while (0) #define THR_REF_DEL(curthread, pthread) { \ pthread->refcount--; \ THR_CRITICAL_LEAVE(curthread); \ } while (0) #define GC_NEEDED() (_gc_count >= 5) #define SHOULD_REPORT_EVENT(curthr, e) \ (curthr->report_events && \ (((curthr)->event_mask | _thread_event_mask ) & e) != 0) extern int __isthreaded; /* * Global variables for the pthread kernel. */ extern char *_usrstack __hidden; extern struct pthread *_thr_initial __hidden; /* For debugger */ extern int _libthr_debug; extern int _thread_event_mask; extern struct pthread *_thread_last_event; /* List of all threads: */ extern pthreadlist _thread_list; /* List of threads needing GC: */ extern pthreadlist _thread_gc_list __hidden; extern int _thread_active_threads; extern atfork_head _thr_atfork_list __hidden; extern struct urwlock _thr_atfork_lock __hidden; /* Default thread attributes: */ extern struct pthread_attr _pthread_attr_default __hidden; /* Default mutex attributes: */ extern struct pthread_mutex_attr _pthread_mutexattr_default __hidden; extern struct pthread_mutex_attr _pthread_mutexattr_adaptive_default __hidden; /* Default condition variable attributes: */ extern struct pthread_cond_attr _pthread_condattr_default __hidden; extern struct pthread_prio _thr_priorities[] __hidden; extern pid_t _thr_pid __hidden; extern int _thr_is_smp __hidden; extern size_t _thr_guard_default __hidden; extern size_t _thr_stack_default __hidden; extern size_t _thr_stack_initial __hidden; extern int _thr_page_size __hidden; extern int _thr_spinloops __hidden; extern int _thr_yieldloops __hidden; extern int _thr_queuefifo __hidden; /* Garbage thread count. */ extern int _gc_count __hidden; extern struct umutex _mutex_static_lock __hidden; extern struct umutex _cond_static_lock __hidden; extern struct umutex _rwlock_static_lock __hidden; extern struct umutex _keytable_lock __hidden; extern struct urwlock _thr_list_lock __hidden; extern struct umutex _thr_event_lock __hidden; extern struct umutex _suspend_all_lock __hidden; extern int _suspend_all_waiters __hidden; extern int _suspend_all_cycle __hidden; extern struct pthread *_single_thread __hidden; /* * Function prototype definitions. */ __BEGIN_DECLS int _thr_setthreaded(int) __hidden; int _mutex_cv_lock(struct pthread_mutex *, int) __hidden; int _mutex_cv_unlock(struct pthread_mutex *, int *, int *) __hidden; int _mutex_cv_attach(struct pthread_mutex *, int) __hidden; int _mutex_cv_detach(struct pthread_mutex *, int *) __hidden; int _mutex_owned(struct pthread *, const struct pthread_mutex *) __hidden; int _mutex_reinit(pthread_mutex_t *) __hidden; void _mutex_fork(struct pthread *curthread) __hidden; void _libpthread_init(struct pthread *) __hidden; struct pthread *_thr_alloc(struct pthread *) __hidden; void _thread_exit(const char *, int, const char *) __hidden __dead2; int _thr_ref_add(struct pthread *, struct pthread *, int) __hidden; void _thr_ref_delete(struct pthread *, struct pthread *) __hidden; void _thr_ref_delete_unlocked(struct pthread *, struct pthread *) __hidden; int _thr_find_thread(struct pthread *, struct pthread *, int) __hidden; void _thr_rtld_init(void) __hidden; void _thr_rtld_postfork_child(void) __hidden; int _thr_stack_alloc(struct pthread_attr *) __hidden; void _thr_stack_free(struct pthread_attr *) __hidden; void _thr_free(struct pthread *, struct pthread *) __hidden; void _thr_gc(struct pthread *) __hidden; void _thread_cleanupspecific(void) __hidden; void _thread_printf(int, const char *, ...) __hidden; void _thr_spinlock_init(void) __hidden; void _thr_cancel_enter(struct pthread *) __hidden; void _thr_cancel_enter2(struct pthread *, int) __hidden; void _thr_cancel_leave(struct pthread *, int) __hidden; void _thr_testcancel(struct pthread *) __hidden; void _thr_signal_block(struct pthread *) __hidden; void _thr_signal_unblock(struct pthread *) __hidden; -void _thr_signal_init(void) __hidden; +void _thr_signal_init(int) __hidden; void _thr_signal_deinit(void) __hidden; int _thr_send_sig(struct pthread *, int sig) __hidden; void _thr_list_init(void) __hidden; void _thr_hash_add(struct pthread *) __hidden; void _thr_hash_remove(struct pthread *) __hidden; struct pthread *_thr_hash_find(struct pthread *) __hidden; void _thr_link(struct pthread *, struct pthread *) __hidden; void _thr_unlink(struct pthread *, struct pthread *) __hidden; void _thr_assert_lock_level(void) __hidden __dead2; void _thr_ast(struct pthread *) __hidden; void _thr_once_init(void) __hidden; void _thr_report_creation(struct pthread *curthread, struct pthread *newthread) __hidden; void _thr_report_death(struct pthread *curthread) __hidden; int _thr_getscheduler(lwpid_t, int *, struct sched_param *) __hidden; int _thr_setscheduler(lwpid_t, int, const struct sched_param *) __hidden; void _thr_signal_prefork(void) __hidden; void _thr_signal_postfork(void) __hidden; void _thr_signal_postfork_child(void) __hidden; void _thr_suspend_all_lock(struct pthread *) __hidden; void _thr_suspend_all_unlock(struct pthread *) __hidden; void _thr_try_gc(struct pthread *, struct pthread *) __hidden; int _rtp_to_schedparam(const struct rtprio *rtp, int *policy, struct sched_param *param) __hidden; int _schedparam_to_rtp(int policy, const struct sched_param *param, struct rtprio *rtp) __hidden; void _thread_bp_create(void); void _thread_bp_death(void); int _sched_yield(void); void _pthread_cleanup_push(void (*)(void *), void *); void _pthread_cleanup_pop(int); void _pthread_exit_mask(void *status, sigset_t *mask) __dead2 __hidden; void _pthread_cancel_enter(int maycancel); void _pthread_cancel_leave(int maycancel); /* #include */ #ifdef _SYS_FCNTL_H_ int __sys_fcntl(int, int, ...); int __sys_open(const char *, int, ...); int __sys_openat(int, const char *, int, ...); #endif /* #include */ #ifdef _SIGNAL_H_ int __sys_kill(pid_t, int); int __sys_sigaction(int, const struct sigaction *, struct sigaction *); int __sys_sigpending(sigset_t *); int __sys_sigprocmask(int, const sigset_t *, sigset_t *); int __sys_sigsuspend(const sigset_t *); int __sys_sigreturn(const ucontext_t *); int __sys_sigaltstack(const struct sigaltstack *, struct sigaltstack *); int __sys_sigwait(const sigset_t *, int *); int __sys_sigtimedwait(const sigset_t *, siginfo_t *, const struct timespec *); int __sys_sigwaitinfo(const sigset_t *set, siginfo_t *info); #endif /* #include */ #ifdef _TIME_H_ int __sys_nanosleep(const struct timespec *, struct timespec *); #endif /* #include */ #ifdef _SYS_UCONTEXT_H_ int __sys_setcontext(const ucontext_t *ucp); int __sys_swapcontext(ucontext_t *oucp, const ucontext_t *ucp); #endif /* #include */ #ifdef _UNISTD_H_ int __sys_close(int); int __sys_fork(void); pid_t __sys_getpid(void); ssize_t __sys_read(int, void *, size_t); -ssize_t __sys_write(int, const void *, size_t); void __sys_exit(int); #endif static inline int _thr_isthreaded(void) { return (__isthreaded != 0); } static inline int _thr_is_inited(void) { return (_thr_initial != NULL); } static inline void _thr_check_init(void) { if (_thr_initial == NULL) _libpthread_init(NULL); } struct wake_addr *_thr_alloc_wake_addr(void); void _thr_release_wake_addr(struct wake_addr *); int _thr_sleep(struct pthread *, int, const struct timespec *); void _thr_wake_addr_init(void) __hidden; static inline void _thr_clear_wake(struct pthread *td) { td->wake_addr->value = 0; } static inline int _thr_is_woken(struct pthread *td) { return td->wake_addr->value != 0; } static inline void _thr_set_wake(unsigned int *waddr) { *waddr = 1; _thr_umtx_wake(waddr, INT_MAX, 0); } void _thr_wake_all(unsigned int *waddrs[], int) __hidden; static inline struct pthread * _sleepq_first(struct sleepqueue *sq) { return TAILQ_FIRST(&sq->sq_blocked); } void _sleepq_init(void) __hidden; struct sleepqueue *_sleepq_alloc(void) __hidden; void _sleepq_free(struct sleepqueue *) __hidden; void _sleepq_lock(void *) __hidden; void _sleepq_unlock(void *) __hidden; struct sleepqueue *_sleepq_lookup(void *) __hidden; void _sleepq_add(void *, struct pthread *) __hidden; int _sleepq_remove(struct sleepqueue *, struct pthread *) __hidden; void _sleepq_drop(struct sleepqueue *, void (*cb)(struct pthread *, void *arg), void *) __hidden; +int _pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex, + void *(calloc_cb)(size_t, size_t)); + struct dl_phdr_info; void __pthread_cxa_finalize(struct dl_phdr_info *phdr_info); void _thr_tsd_unload(struct dl_phdr_info *phdr_info) __hidden; void _thr_sigact_unload(struct dl_phdr_info *phdr_info) __hidden; void _thr_stack_fix_protection(struct pthread *thrd); + +int *__error_threaded(void); +void __thr_interpose_libc(void) __hidden; +pid_t __thr_fork(void); +int __thr_pause(void) __hidden; +int __thr_raise(int sig); +int __thr_setcontext(const ucontext_t *ucp); +int __thr_sigaction(int sig, const struct sigaction *act, + struct sigaction *oact) __hidden; +int __thr_sigprocmask(int how, const sigset_t *set, sigset_t *oset); +int __thr_sigsuspend(const sigset_t * set); +int __thr_sigtimedwait(const sigset_t *set, siginfo_t *info, + const struct timespec * timeout); +int __thr_sigwait(const sigset_t *set, int *sig); +int __thr_sigwaitinfo(const sigset_t *set, siginfo_t *info); +int __thr_swapcontext(ucontext_t *oucp, const ucontext_t *ucp); __END_DECLS #endif /* !_THR_PRIVATE_H */ Index: head/lib/libthr/thread/thr_sig.c =================================================================== --- head/lib/libthr/thread/thr_sig.c (revision 276629) +++ head/lib/libthr/thread/thr_sig.c (revision 276630) @@ -1,757 +1,777 @@ /* * Copyright (c) 2005, David Xu * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice unmodified, this list of conditions, and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD$ */ #include "namespace.h" #include #include #include #include #include #include #include #include #include "un-namespace.h" #include "libc_private.h" +#include "libc_private.h" #include "thr_private.h" /* #define DEBUG_SIGNAL */ #ifdef DEBUG_SIGNAL #define DBG_MSG stdout_debug #else #define DBG_MSG(x...) #endif struct usigaction { struct sigaction sigact; struct urwlock lock; }; static struct usigaction _thr_sigact[_SIG_MAXSIG]; +static inline struct usigaction * +__libc_sigaction_slot(int signo) +{ + + return (&_thr_sigact[signo - 1]); +} + static void thr_sighandler(int, siginfo_t *, void *); static void handle_signal(struct sigaction *, int, siginfo_t *, ucontext_t *); static void check_deferred_signal(struct pthread *); static void check_suspend(struct pthread *); static void check_cancel(struct pthread *curthread, ucontext_t *ucp); -int ___pause(void); -int _raise(int); -int __sigtimedwait(const sigset_t *set, siginfo_t *info, - const struct timespec * timeout); int _sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec * timeout); -int __sigwaitinfo(const sigset_t *set, siginfo_t *info); int _sigwaitinfo(const sigset_t *set, siginfo_t *info); -int ___sigwait(const sigset_t *set, int *sig); int _sigwait(const sigset_t *set, int *sig); -int __sigsuspend(const sigset_t *sigmask); -int _sigaction(int, const struct sigaction *, struct sigaction *); int _setcontext(const ucontext_t *); int _swapcontext(ucontext_t *, const ucontext_t *); static const sigset_t _thr_deferset={{ 0xffffffff & ~(_SIG_BIT(SIGBUS)|_SIG_BIT(SIGILL)|_SIG_BIT(SIGFPE)| _SIG_BIT(SIGSEGV)|_SIG_BIT(SIGTRAP)|_SIG_BIT(SIGSYS)), 0xffffffff, 0xffffffff, 0xffffffff}}; static const sigset_t _thr_maskset={{ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}}; void _thr_signal_block(struct pthread *curthread) { if (curthread->sigblock > 0) { curthread->sigblock++; return; } __sys_sigprocmask(SIG_BLOCK, &_thr_maskset, &curthread->sigmask); curthread->sigblock++; } void _thr_signal_unblock(struct pthread *curthread) { if (--curthread->sigblock == 0) __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL); } int _thr_send_sig(struct pthread *thread, int sig) { return thr_kill(thread->tid, sig); } static inline void remove_thr_signals(sigset_t *set) { if (SIGISMEMBER(*set, SIGCANCEL)) SIGDELSET(*set, SIGCANCEL); } static const sigset_t * thr_remove_thr_signals(const sigset_t *set, sigset_t *newset) { *newset = *set; remove_thr_signals(newset); return (newset); } static void sigcancel_handler(int sig __unused, siginfo_t *info __unused, ucontext_t *ucp) { struct pthread *curthread = _get_curthread(); int err; if (THR_IN_CRITICAL(curthread)) return; err = errno; check_suspend(curthread); check_cancel(curthread, ucp); errno = err; } -typedef void (*ohandler)(int sig, int code, - struct sigcontext *scp, char *addr, __sighandler_t *catcher); +typedef void (*ohandler)(int sig, int code, struct sigcontext *scp, + char *addr, __sighandler_t *catcher); /* * The signal handler wrapper is entered with all signal masked. */ static void thr_sighandler(int sig, siginfo_t *info, void *_ucp) { - struct pthread *curthread = _get_curthread(); - ucontext_t *ucp = _ucp; + struct pthread *curthread; + ucontext_t *ucp; struct sigaction act; + struct usigaction *usa; int err; err = errno; - _thr_rwl_rdlock(&_thr_sigact[sig-1].lock); - act = _thr_sigact[sig-1].sigact; - _thr_rwl_unlock(&_thr_sigact[sig-1].lock); + curthread = _get_curthread(); + ucp = _ucp; + usa = __libc_sigaction_slot(sig); + _thr_rwl_rdlock(&usa->lock); + act = usa->sigact; + _thr_rwl_unlock(&usa->lock); errno = err; curthread->deferred_run = 0; /* * if a thread is in critical region, for example it holds low level locks, * try to defer the signal processing, however if the signal is synchronous * signal, it means a bad thing has happened, this is a programming error, * resuming fault point can not help anything (normally causes deadloop), * so here we let user code handle it immediately. */ if (THR_IN_CRITICAL(curthread) && SIGISMEMBER(_thr_deferset, sig)) { memcpy(&curthread->deferred_sigact, &act, sizeof(struct sigaction)); memcpy(&curthread->deferred_siginfo, info, sizeof(siginfo_t)); curthread->deferred_sigmask = ucp->uc_sigmask; /* mask all signals, we will restore it later. */ ucp->uc_sigmask = _thr_deferset; return; } handle_signal(&act, sig, info, ucp); } static void handle_signal(struct sigaction *actp, int sig, siginfo_t *info, ucontext_t *ucp) { struct pthread *curthread = _get_curthread(); ucontext_t uc2; __siginfohandler_t *sigfunc; int cancel_point; int cancel_async; int cancel_enable; int in_sigsuspend; int err; /* add previous level mask */ SIGSETOR(actp->sa_mask, ucp->uc_sigmask); /* add this signal's mask */ if (!(actp->sa_flags & SA_NODEFER)) SIGADDSET(actp->sa_mask, sig); in_sigsuspend = curthread->in_sigsuspend; curthread->in_sigsuspend = 0; /* * If thread is in deferred cancellation mode, disable cancellation * in signal handler. * If user signal handler calls a cancellation point function, e.g, * it calls write() to write data to file, because write() is a * cancellation point, the thread is immediately cancelled if * cancellation is pending, to avoid this problem while thread is in * deferring mode, cancellation is temporarily disabled. */ cancel_point = curthread->cancel_point; cancel_async = curthread->cancel_async; cancel_enable = curthread->cancel_enable; curthread->cancel_point = 0; if (!cancel_async) curthread->cancel_enable = 0; /* restore correct mask before calling user handler */ __sys_sigprocmask(SIG_SETMASK, &actp->sa_mask, NULL); sigfunc = actp->sa_sigaction; /* * We have already reset cancellation point flags, so if user's code * longjmp()s out of its signal handler, wish its jmpbuf was set * outside of a cancellation point, in most cases, this would be * true. However, there is no way to save cancel_enable in jmpbuf, * so after setjmps() returns once more, the user code may need to * re-set cancel_enable flag by calling pthread_setcancelstate(). */ - if ((actp->sa_flags & SA_SIGINFO) != 0) - (*(sigfunc))(sig, info, ucp); - else { - ((ohandler)(*sigfunc))( - sig, info->si_code, (struct sigcontext *)ucp, - info->si_addr, (__sighandler_t *)sigfunc); + if ((actp->sa_flags & SA_SIGINFO) != 0) { + sigfunc(sig, info, ucp); + } else { + ((ohandler)sigfunc)(sig, info->si_code, + (struct sigcontext *)ucp, info->si_addr, + (__sighandler_t *)sigfunc); } err = errno; curthread->in_sigsuspend = in_sigsuspend; curthread->cancel_point = cancel_point; curthread->cancel_enable = cancel_enable; memcpy(&uc2, ucp, sizeof(uc2)); SIGDELSET(uc2.uc_sigmask, SIGCANCEL); /* reschedule cancellation */ check_cancel(curthread, &uc2); errno = err; __sys_sigreturn(&uc2); } void _thr_ast(struct pthread *curthread) { if (!THR_IN_CRITICAL(curthread)) { check_deferred_signal(curthread); check_suspend(curthread); check_cancel(curthread, NULL); } } /* reschedule cancellation */ static void check_cancel(struct pthread *curthread, ucontext_t *ucp) { if (__predict_true(!curthread->cancel_pending || !curthread->cancel_enable || curthread->no_cancel)) return; /* * Otherwise, we are in defer mode, and we are at * cancel point, tell kernel to not block the current * thread on next cancelable system call. * * There are three cases we should call thr_wake() to * turn on TDP_WAKEUP or send SIGCANCEL in kernel: * 1) we are going to call a cancelable system call, * non-zero cancel_point means we are already in * cancelable state, next system call is cancelable. * 2) because _thr_ast() may be called by * THR_CRITICAL_LEAVE() which is used by rtld rwlock * and any libthr internal locks, when rtld rwlock * is used, it is mostly caused my an unresolved PLT. * those routines may clear the TDP_WAKEUP flag by * invoking some system calls, in those cases, we * also should reenable the flag. * 3) thread is in sigsuspend(), and the syscall insists * on getting a signal before it agrees to return. */ if (curthread->cancel_point) { if (curthread->in_sigsuspend && ucp) { SIGADDSET(ucp->uc_sigmask, SIGCANCEL); curthread->unblock_sigcancel = 1; _thr_send_sig(curthread, SIGCANCEL); } else thr_wake(curthread->tid); } else if (curthread->cancel_async) { /* * asynchronous cancellation mode, act upon * immediately. */ _pthread_exit_mask(PTHREAD_CANCELED, ucp? &ucp->uc_sigmask : NULL); } } static void check_deferred_signal(struct pthread *curthread) { ucontext_t *uc; struct sigaction act; siginfo_t info; int uc_len; if (__predict_true(curthread->deferred_siginfo.si_signo == 0 || curthread->deferred_run)) return; curthread->deferred_run = 1; uc_len = __getcontextx_size(); uc = alloca(uc_len); getcontext(uc); if (curthread->deferred_siginfo.si_signo == 0) { curthread->deferred_run = 0; return; } __fillcontextx2((char *)uc); act = curthread->deferred_sigact; uc->uc_sigmask = curthread->deferred_sigmask; memcpy(&info, &curthread->deferred_siginfo, sizeof(siginfo_t)); /* remove signal */ curthread->deferred_siginfo.si_signo = 0; handle_signal(&act, info.si_signo, &info, uc); } static void check_suspend(struct pthread *curthread) { uint32_t cycle; if (__predict_true((curthread->flags & (THR_FLAGS_NEED_SUSPEND | THR_FLAGS_SUSPENDED)) != THR_FLAGS_NEED_SUSPEND)) return; if (curthread == _single_thread) return; if (curthread->force_exit) return; /* * Blocks SIGCANCEL which other threads must send. */ _thr_signal_block(curthread); /* * Increase critical_count, here we don't use THR_LOCK/UNLOCK * because we are leaf code, we don't want to recursively call * ourself. */ curthread->critical_count++; THR_UMUTEX_LOCK(curthread, &(curthread)->lock); while ((curthread->flags & (THR_FLAGS_NEED_SUSPEND | THR_FLAGS_SUSPENDED)) == THR_FLAGS_NEED_SUSPEND) { curthread->cycle++; cycle = curthread->cycle; /* Wake the thread suspending us. */ _thr_umtx_wake(&curthread->cycle, INT_MAX, 0); /* * if we are from pthread_exit, we don't want to * suspend, just go and die. */ if (curthread->state == PS_DEAD) break; curthread->flags |= THR_FLAGS_SUSPENDED; THR_UMUTEX_UNLOCK(curthread, &(curthread)->lock); _thr_umtx_wait_uint(&curthread->cycle, cycle, NULL, 0); THR_UMUTEX_LOCK(curthread, &(curthread)->lock); curthread->flags &= ~THR_FLAGS_SUSPENDED; } THR_UMUTEX_UNLOCK(curthread, &(curthread)->lock); curthread->critical_count--; _thr_signal_unblock(curthread); } void -_thr_signal_init(void) +_thr_signal_init(int dlopened) { - struct sigaction act; + struct sigaction act, nact, oact; + struct usigaction *usa; + sigset_t oldset; + int sig, error; + if (dlopened) { + __sys_sigprocmask(SIG_SETMASK, &_thr_maskset, &oldset); + for (sig = 1; sig <= _SIG_MAXSIG; sig++) { + if (sig == SIGCANCEL) + continue; + error = __sys_sigaction(sig, NULL, &oact); + if (error == -1 || oact.sa_handler == SIG_DFL || + oact.sa_handler == SIG_IGN) + continue; + usa = __libc_sigaction_slot(sig); + usa->sigact = oact; + nact = oact; + remove_thr_signals(&usa->sigact.sa_mask); + nact.sa_flags &= ~SA_NODEFER; + nact.sa_flags |= SA_SIGINFO; + nact.sa_sigaction = thr_sighandler; + nact.sa_mask = _thr_maskset; + (void)__sys_sigaction(sig, &nact, NULL); + } + __sys_sigprocmask(SIG_SETMASK, &oldset, NULL); + } + /* Install SIGCANCEL handler. */ SIGFILLSET(act.sa_mask); act.sa_flags = SA_SIGINFO; act.sa_sigaction = (__siginfohandler_t *)&sigcancel_handler; __sys_sigaction(SIGCANCEL, &act, NULL); /* Unblock SIGCANCEL */ SIGEMPTYSET(act.sa_mask); SIGADDSET(act.sa_mask, SIGCANCEL); __sys_sigprocmask(SIG_UNBLOCK, &act.sa_mask, NULL); } void _thr_sigact_unload(struct dl_phdr_info *phdr_info) { #if 0 struct pthread *curthread = _get_curthread(); struct urwlock *rwlp; struct sigaction *actp; + struct usigaction *usa; struct sigaction kact; void (*handler)(int); int sig; _thr_signal_block(curthread); for (sig = 1; sig <= _SIG_MAXSIG; sig++) { - actp = &_thr_sigact[sig-1].sigact; + usa = __libc_sigaction_slot(sig); + actp = &usa->sigact; retry: handler = actp->sa_handler; if (handler != SIG_DFL && handler != SIG_IGN && __elf_phdr_match_addr(phdr_info, handler)) { - rwlp = &_thr_sigact[sig-1].lock; + rwlp = &usa->lock; _thr_rwl_wrlock(rwlp); if (handler != actp->sa_handler) { _thr_rwl_unlock(rwlp); goto retry; } actp->sa_handler = SIG_DFL; actp->sa_flags = SA_SIGINFO; SIGEMPTYSET(actp->sa_mask); if (__sys_sigaction(sig, NULL, &kact) == 0 && kact.sa_handler != SIG_DFL && kact.sa_handler != SIG_IGN) __sys_sigaction(sig, actp, NULL); _thr_rwl_unlock(rwlp); } } _thr_signal_unblock(curthread); #endif } void _thr_signal_prefork(void) { int i; for (i = 1; i <= _SIG_MAXSIG; ++i) - _thr_rwl_rdlock(&_thr_sigact[i-1].lock); + _thr_rwl_rdlock(&__libc_sigaction_slot(i)->lock); } void _thr_signal_postfork(void) { int i; for (i = 1; i <= _SIG_MAXSIG; ++i) - _thr_rwl_unlock(&_thr_sigact[i-1].lock); + _thr_rwl_unlock(&__libc_sigaction_slot(i)->lock); } void _thr_signal_postfork_child(void) { int i; - for (i = 1; i <= _SIG_MAXSIG; ++i) - bzero(&_thr_sigact[i-1].lock, sizeof(struct urwlock)); + for (i = 1; i <= _SIG_MAXSIG; ++i) { + bzero(&__libc_sigaction_slot(i) -> lock, + sizeof(struct urwlock)); + } } void _thr_signal_deinit(void) { } -__weak_reference(___pause, pause); - int -___pause(void) +__thr_pause(void) { sigset_t oset; if (_sigprocmask(SIG_BLOCK, NULL, &oset) == -1) return (-1); - return (__sigsuspend(&oset)); + return (__thr_sigsuspend(&oset)); } -__weak_reference(_raise, raise); - int -_raise(int sig) +__thr_raise(int sig) { - return _thr_send_sig(_get_curthread(), sig); + + return (_thr_send_sig(_get_curthread(), sig)); } -__weak_reference(_sigaction, sigaction); - int -_sigaction(int sig, const struct sigaction * act, struct sigaction * oact) +__thr_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { struct sigaction newact, oldact, oldact2; sigset_t oldset; - int ret = 0, err = 0; + struct usigaction *usa; + int ret, err; if (!_SIG_VALID(sig) || sig == SIGCANCEL) { errno = EINVAL; return (-1); } - if (act) - newact = *act; + ret = 0; + err = 0; + usa = __libc_sigaction_slot(sig); __sys_sigprocmask(SIG_SETMASK, &_thr_maskset, &oldset); - _thr_rwl_wrlock(&_thr_sigact[sig-1].lock); + _thr_rwl_wrlock(&usa->lock); if (act != NULL) { - oldact2 = _thr_sigact[sig-1].sigact; + oldact2 = usa->sigact; + newact = *act; /* * if a new sig handler is SIG_DFL or SIG_IGN, - * don't remove old handler from _thr_sigact[], + * don't remove old handler from __libc_sigact[], * so deferred signals still can use the handlers, * multiple threads invoking sigaction itself is * a race condition, so it is not a problem. */ if (newact.sa_handler != SIG_DFL && newact.sa_handler != SIG_IGN) { - _thr_sigact[sig-1].sigact = newact; - remove_thr_signals( - &_thr_sigact[sig-1].sigact.sa_mask); + usa->sigact = newact; + remove_thr_signals(&usa->sigact.sa_mask); newact.sa_flags &= ~SA_NODEFER; newact.sa_flags |= SA_SIGINFO; newact.sa_sigaction = thr_sighandler; newact.sa_mask = _thr_maskset; /* mask all signals */ } - if ((ret = __sys_sigaction(sig, &newact, &oldact))) { + ret = __sys_sigaction(sig, &newact, &oldact); + if (ret == -1) { err = errno; - _thr_sigact[sig-1].sigact = oldact2; + usa->sigact = oldact2; } } else if (oact != NULL) { ret = __sys_sigaction(sig, NULL, &oldact); err = errno; } - if (oldact.sa_handler != SIG_DFL && - oldact.sa_handler != SIG_IGN) { + if (oldact.sa_handler != SIG_DFL && oldact.sa_handler != SIG_IGN) { if (act != NULL) oldact = oldact2; else if (oact != NULL) - oldact = _thr_sigact[sig-1].sigact; + oldact = usa->sigact; } - _thr_rwl_unlock(&_thr_sigact[sig-1].lock); + _thr_rwl_unlock(&usa->lock); __sys_sigprocmask(SIG_SETMASK, &oldset, NULL); if (ret == 0) { if (oact != NULL) *oact = oldact; } else { errno = err; } return (ret); } -__weak_reference(_sigprocmask, sigprocmask); - int -_sigprocmask(int how, const sigset_t *set, sigset_t *oset) +__thr_sigprocmask(int how, const sigset_t *set, sigset_t *oset) { const sigset_t *p = set; sigset_t newset; if (how != SIG_UNBLOCK) { if (set != NULL) { newset = *set; SIGDELSET(newset, SIGCANCEL); p = &newset; } } return (__sys_sigprocmask(how, p, oset)); } __weak_reference(_pthread_sigmask, pthread_sigmask); int _pthread_sigmask(int how, const sigset_t *set, sigset_t *oset) { if (_sigprocmask(how, set, oset)) return (errno); return (0); } -__weak_reference(__sigsuspend, sigsuspend); - int _sigsuspend(const sigset_t * set) { sigset_t newset; return (__sys_sigsuspend(thr_remove_thr_signals(set, &newset))); } int -__sigsuspend(const sigset_t * set) +__thr_sigsuspend(const sigset_t * set) { struct pthread *curthread; sigset_t newset; int ret, old; curthread = _get_curthread(); old = curthread->in_sigsuspend; curthread->in_sigsuspend = 1; _thr_cancel_enter(curthread); ret = __sys_sigsuspend(thr_remove_thr_signals(set, &newset)); _thr_cancel_leave(curthread, 1); curthread->in_sigsuspend = old; if (curthread->unblock_sigcancel) { curthread->unblock_sigcancel = 0; SIGEMPTYSET(newset); SIGADDSET(newset, SIGCANCEL); __sys_sigprocmask(SIG_UNBLOCK, &newset, NULL); } return (ret); } -__weak_reference(___sigwait, sigwait); -__weak_reference(__sigtimedwait, sigtimedwait); -__weak_reference(__sigwaitinfo, sigwaitinfo); - int _sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec * timeout) { sigset_t newset; return (__sys_sigtimedwait(thr_remove_thr_signals(set, &newset), info, timeout)); } /* * Cancellation behavior: * Thread may be canceled at start, if thread got signal, * it is not canceled. */ int -__sigtimedwait(const sigset_t *set, siginfo_t *info, - const struct timespec * timeout) +__thr_sigtimedwait(const sigset_t *set, siginfo_t *info, + const struct timespec * timeout) { struct pthread *curthread = _get_curthread(); sigset_t newset; int ret; _thr_cancel_enter(curthread); ret = __sys_sigtimedwait(thr_remove_thr_signals(set, &newset), info, timeout); _thr_cancel_leave(curthread, (ret == -1)); return (ret); } int _sigwaitinfo(const sigset_t *set, siginfo_t *info) { sigset_t newset; return (__sys_sigwaitinfo(thr_remove_thr_signals(set, &newset), info)); } /* * Cancellation behavior: * Thread may be canceled at start, if thread got signal, * it is not canceled. */ int -__sigwaitinfo(const sigset_t *set, siginfo_t *info) +__thr_sigwaitinfo(const sigset_t *set, siginfo_t *info) { struct pthread *curthread = _get_curthread(); sigset_t newset; int ret; _thr_cancel_enter(curthread); ret = __sys_sigwaitinfo(thr_remove_thr_signals(set, &newset), info); _thr_cancel_leave(curthread, ret == -1); return (ret); } int _sigwait(const sigset_t *set, int *sig) { sigset_t newset; return (__sys_sigwait(thr_remove_thr_signals(set, &newset), sig)); } /* * Cancellation behavior: * Thread may be canceled at start, if thread got signal, * it is not canceled. */ int -___sigwait(const sigset_t *set, int *sig) +__thr_sigwait(const sigset_t *set, int *sig) { struct pthread *curthread = _get_curthread(); sigset_t newset; int ret; do { _thr_cancel_enter(curthread); ret = __sys_sigwait(thr_remove_thr_signals(set, &newset), sig); _thr_cancel_leave(curthread, (ret != 0)); } while (ret == EINTR); return (ret); } -__weak_reference(_setcontext, setcontext); int -_setcontext(const ucontext_t *ucp) +__thr_setcontext(const ucontext_t *ucp) { ucontext_t uc; if (ucp == NULL) { errno = EINVAL; return (-1); } if (!SIGISMEMBER(uc.uc_sigmask, SIGCANCEL)) return __sys_setcontext(ucp); (void) memcpy(&uc, ucp, sizeof(uc)); SIGDELSET(uc.uc_sigmask, SIGCANCEL); - return __sys_setcontext(&uc); + return (__sys_setcontext(&uc)); } -__weak_reference(_swapcontext, swapcontext); int -_swapcontext(ucontext_t *oucp, const ucontext_t *ucp) +__thr_swapcontext(ucontext_t *oucp, const ucontext_t *ucp) { ucontext_t uc; if (oucp == NULL || ucp == NULL) { errno = EINVAL; return (-1); } if (SIGISMEMBER(ucp->uc_sigmask, SIGCANCEL)) { (void) memcpy(&uc, ucp, sizeof(uc)); SIGDELSET(uc.uc_sigmask, SIGCANCEL); ucp = &uc; } - return __sys_swapcontext(oucp, ucp); + return (__sys_swapcontext(oucp, ucp)); } Index: head/lib/libthr/thread/thr_syscalls.c =================================================================== --- head/lib/libthr/thread/thr_syscalls.c (revision 276629) +++ head/lib/libthr/thread/thr_syscalls.c (revision 276630) @@ -1,785 +1,745 @@ /* + * Copyright (c) 2014 The FreeBSD Foundation. * Copyright (C) 2005 David Xu . * Copyright (c) 2003 Daniel Eischen . * Copyright (C) 2000 Jason Evans . * All rights reserved. * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ */ /* * Copyright (c) 1995-1998 John Birrell * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ +#include +__FBSDID("$FreeBSD$"); + #include "namespace.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "un-namespace.h" +#include "libc_private.h" #include "thr_private.h" -extern int __creat(const char *, mode_t); -extern int __pselect(int, fd_set *, fd_set *, fd_set *, - const struct timespec *, const sigset_t *); -extern unsigned __sleep(unsigned int); -extern int __system(const char *); -extern int __tcdrain(int); -extern int __usleep(useconds_t); -extern pid_t __wait(int *); -extern pid_t __waitpid(pid_t, int *, int); -extern int __sys_aio_suspend(const struct aiocb * const[], int, - const struct timespec *); -extern int __sys_accept(int, struct sockaddr *, socklen_t *); -extern int __sys_accept4(int, struct sockaddr *, socklen_t *, int); -extern int __sys_connect(int, const struct sockaddr *, socklen_t); -extern int __sys_fsync(int); -extern int __sys_msync(void *, size_t, int); -extern int __sys_pselect(int, fd_set *, fd_set *, fd_set *, - const struct timespec *, const sigset_t *); -extern int __sys_poll(struct pollfd *, unsigned, int); -extern ssize_t __sys_recv(int, void *, size_t, int); -extern ssize_t __sys_recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *); -extern ssize_t __sys_recvmsg(int, struct msghdr *, int); -extern int __sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *); -extern int __sys_sendfile(int, int, off_t, size_t, struct sf_hdtr *, - off_t *, int); -extern ssize_t __sys_sendmsg(int, const struct msghdr *, int); -extern ssize_t __sys_sendto(int, const void *,size_t, int, const struct sockaddr *, socklen_t); -extern ssize_t __sys_readv(int, const struct iovec *, int); -extern pid_t __sys_wait4(pid_t, int *, int, struct rusage *); -extern ssize_t __sys_writev(int, const struct iovec *, int); - -int ___creat(const char *, mode_t); -int ___pselect(int, fd_set *, fd_set *, fd_set *, - const struct timespec *, const sigset_t *); -unsigned ___sleep(unsigned); -int ___system(const char *); -int ___tcdrain(int); -int ___usleep(useconds_t useconds); -pid_t ___wait(int *); -pid_t ___waitpid(pid_t, int *, int); -int __accept(int, struct sockaddr *, socklen_t *); -int __accept4(int, struct sockaddr *, socklen_t *, int); -int __aio_suspend(const struct aiocb * const iocbs[], int, - const struct timespec *); -int __close(int); -int __connect(int, const struct sockaddr *, socklen_t); -int __fcntl(int, int,...); #ifdef SYSCALL_COMPAT -extern int __fcntl_compat(int, int,...); +extern int __fcntl_compat(int, int, ...); #endif -int __fsync(int); -int __msync(void *, size_t, int); -int __nanosleep(const struct timespec *, struct timespec *); -int __open(const char *, int,...); -int __openat(int, const char *, int,...); -int __poll(struct pollfd *, unsigned int, int); -ssize_t __read(int, void *buf, size_t); -ssize_t __readv(int, const struct iovec *, int); -ssize_t __recvfrom(int, void *, size_t, int f, struct sockaddr *, socklen_t *); -ssize_t __recvmsg(int, struct msghdr *, int); -int __select(int, fd_set *, fd_set *, fd_set *, struct timeval *); -ssize_t __sendmsg(int, const struct msghdr *, int); -ssize_t __sendto(int, const void *, size_t, int, - const struct sockaddr *, socklen_t); -pid_t __wait3(int *, int, struct rusage *); -pid_t __wait4(pid_t, int *, int, struct rusage *); -ssize_t __write(int, const void *, size_t); -ssize_t __writev(int, const struct iovec *, int); -__weak_reference(__accept, accept); - /* * Cancellation behavior: * If thread is canceled, no socket is created. */ -int -__accept(int s, struct sockaddr *addr, socklen_t *addrlen) +static int +__thr_accept(int s, struct sockaddr *addr, socklen_t *addrlen) { struct pthread *curthread; int ret; curthread = _get_curthread(); _thr_cancel_enter(curthread); ret = __sys_accept(s, addr, addrlen); _thr_cancel_leave(curthread, ret == -1); return (ret); } -__weak_reference(__accept4, accept4); - /* * Cancellation behavior: * If thread is canceled, no socket is created. */ -int -__accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags) +static int +__thr_accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags) { struct pthread *curthread; int ret; curthread = _get_curthread(); _thr_cancel_enter(curthread); ret = __sys_accept4(s, addr, addrlen, flags); _thr_cancel_leave(curthread, ret == -1); return (ret); } -__weak_reference(__aio_suspend, aio_suspend); - -int -__aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct +static int +__thr_aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct timespec *timeout) { - struct pthread *curthread = _get_curthread(); + struct pthread *curthread; int ret; + curthread = _get_curthread(); _thr_cancel_enter(curthread); ret = __sys_aio_suspend(iocbs, niocb, timeout); _thr_cancel_leave(curthread, 1); return (ret); } -__weak_reference(__close, close); - /* * Cancellation behavior: * According to manual of close(), the file descriptor is always deleted. * Here, thread is only canceled after the system call, so the file * descriptor is always deleted despite whether the thread is canceled * or not. */ -int -__close(int fd) +static int +__thr_close(int fd) { - struct pthread *curthread = _get_curthread(); - int ret; + struct pthread *curthread; + int ret; + curthread = _get_curthread(); _thr_cancel_enter2(curthread, 0); ret = __sys_close(fd); _thr_cancel_leave(curthread, 1); return (ret); } -__weak_reference(__connect, connect); - /* * Cancellation behavior: * If the thread is canceled, connection is not made. */ -int -__connect(int fd, const struct sockaddr *name, socklen_t namelen) +static int +__thr_connect(int fd, const struct sockaddr *name, socklen_t namelen) { - struct pthread *curthread = _get_curthread(); + struct pthread *curthread; int ret; + curthread = _get_curthread(); _thr_cancel_enter(curthread); ret = __sys_connect(fd, name, namelen); _thr_cancel_leave(curthread, ret == -1); return (ret); } -__weak_reference(___creat, creat); /* * Cancellation behavior: * If thread is canceled, file is not created. */ -int -___creat(const char *path, mode_t mode) +static int +__thr_creat(const char *path, mode_t mode) { - struct pthread *curthread = _get_curthread(); + struct pthread *curthread; int ret; + curthread = _get_curthread(); _thr_cancel_enter(curthread); - ret = __creat(path, mode); + ret = __libc_creat(path, mode); _thr_cancel_leave(curthread, ret == -1); - return ret; + return (ret); } -__weak_reference(__fcntl, fcntl); - /* * Cancellation behavior: * According to specification, only F_SETLKW is a cancellation point. * Thread is only canceled at start, or canceled if the system call * is failure, this means the function does not generate side effect * if it is canceled. */ -int -__fcntl(int fd, int cmd,...) +static int +__thr_fcntl(int fd, int cmd, ...) { - struct pthread *curthread = _get_curthread(); - int ret; + struct pthread *curthread; + int ret; va_list ap; + curthread = _get_curthread(); va_start(ap, cmd); if (cmd == F_OSETLKW || cmd == F_SETLKW) { _thr_cancel_enter(curthread); #ifdef SYSCALL_COMPAT ret = __fcntl_compat(fd, cmd, va_arg(ap, void *)); #else ret = __sys_fcntl(fd, cmd, va_arg(ap, void *)); #endif _thr_cancel_leave(curthread, ret == -1); } else { #ifdef SYSCALL_COMPAT ret = __fcntl_compat(fd, cmd, va_arg(ap, void *)); #else ret = __sys_fcntl(fd, cmd, va_arg(ap, void *)); #endif } va_end(ap); return (ret); } -__weak_reference(__fsync, fsync); - /* * Cancellation behavior: * Thread may be canceled after system call. */ -int -__fsync(int fd) +static int +__thr_fsync(int fd) { - struct pthread *curthread = _get_curthread(); - int ret; + struct pthread *curthread; + int ret; + curthread = _get_curthread(); _thr_cancel_enter2(curthread, 0); ret = __sys_fsync(fd); _thr_cancel_leave(curthread, 1); return (ret); } -__weak_reference(__msync, msync); - /* * Cancellation behavior: * Thread may be canceled after system call. */ -int -__msync(void *addr, size_t len, int flags) +static int +__thr_msync(void *addr, size_t len, int flags) { - struct pthread *curthread = _get_curthread(); - int ret; + struct pthread *curthread; + int ret; + curthread = _get_curthread(); _thr_cancel_enter2(curthread, 0); ret = __sys_msync(addr, len, flags); _thr_cancel_leave(curthread, 1); - return ret; + return (ret); } -__weak_reference(__nanosleep, nanosleep); - -int -__nanosleep(const struct timespec *time_to_sleep, +static int +__thr_nanosleep(const struct timespec *time_to_sleep, struct timespec *time_remaining) { - struct pthread *curthread = _get_curthread(); - int ret; + struct pthread *curthread; + int ret; + curthread = _get_curthread(); _thr_cancel_enter(curthread); ret = __sys_nanosleep(time_to_sleep, time_remaining); _thr_cancel_leave(curthread, 1); return (ret); } -__weak_reference(__open, open); - /* * Cancellation behavior: * If the thread is canceled, file is not opened. */ -int -__open(const char *path, int flags,...) +static int +__thr_open(const char *path, int flags,...) { - struct pthread *curthread = _get_curthread(); - int ret; - int mode = 0; + struct pthread *curthread; + int mode, ret; va_list ap; /* Check if the file is being created: */ - if (flags & O_CREAT) { + if ((flags & O_CREAT) != 0) { /* Get the creation mode: */ va_start(ap, flags); mode = va_arg(ap, int); va_end(ap); + } else { + mode = 0; } + curthread = _get_curthread(); _thr_cancel_enter(curthread); ret = __sys_open(path, flags, mode); _thr_cancel_leave(curthread, ret == -1); - return ret; + return (ret); } -__weak_reference(__openat, openat); - /* * Cancellation behavior: * If the thread is canceled, file is not opened. */ -int -__openat(int fd, const char *path, int flags, ...) +static int +__thr_openat(int fd, const char *path, int flags, ...) { - struct pthread *curthread = _get_curthread(); - int ret; - int mode = 0; + struct pthread *curthread; + int mode, ret; va_list ap; /* Check if the file is being created: */ - if (flags & O_CREAT) { + if ((flags & O_CREAT) != 0) { /* Get the creation mode: */ va_start(ap, flags); mode = va_arg(ap, int); va_end(ap); + } else { + mode = 0; } + curthread = _get_curthread(); _thr_cancel_enter(curthread); ret = __sys_openat(fd, path, flags, mode); _thr_cancel_leave(curthread, ret == -1); - return ret; + return (ret); } -__weak_reference(__poll, poll); - /* * Cancellation behavior: * Thread may be canceled at start, but if the system call returns something, * the thread is not canceled. */ -int -__poll(struct pollfd *fds, unsigned int nfds, int timeout) +static int +__thr_poll(struct pollfd *fds, unsigned int nfds, int timeout) { - struct pthread *curthread = _get_curthread(); + struct pthread *curthread; int ret; + curthread = _get_curthread(); _thr_cancel_enter(curthread); ret = __sys_poll(fds, nfds, timeout); _thr_cancel_leave(curthread, ret == -1); - return ret; + return (ret); } -__weak_reference(___pselect, pselect); - /* * Cancellation behavior: * Thread may be canceled at start, but if the system call returns something, * the thread is not canceled. */ -int -___pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds, +static int +__thr_pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds, const struct timespec *timo, const sigset_t *mask) { - struct pthread *curthread = _get_curthread(); + struct pthread *curthread; int ret; + curthread = _get_curthread(); _thr_cancel_enter(curthread); ret = __sys_pselect(count, rfds, wfds, efds, timo, mask); _thr_cancel_leave(curthread, ret == -1); return (ret); } -__weak_reference(__read, read); - /* * Cancellation behavior: * Thread may be canceled at start, but if the system call got some data, * the thread is not canceled. */ -ssize_t -__read(int fd, void *buf, size_t nbytes) +static ssize_t +__thr_read(int fd, void *buf, size_t nbytes) { - struct pthread *curthread = _get_curthread(); + struct pthread *curthread; ssize_t ret; + curthread = _get_curthread(); _thr_cancel_enter(curthread); ret = __sys_read(fd, buf, nbytes); _thr_cancel_leave(curthread, ret == -1); - return ret; + return (ret); } -__weak_reference(__readv, readv); - /* * Cancellation behavior: * Thread may be canceled at start, but if the system call got some data, * the thread is not canceled. */ -ssize_t -__readv(int fd, const struct iovec *iov, int iovcnt) +static ssize_t +__thr_readv(int fd, const struct iovec *iov, int iovcnt) { - struct pthread *curthread = _get_curthread(); + struct pthread *curthread; ssize_t ret; + curthread = _get_curthread(); _thr_cancel_enter(curthread); ret = __sys_readv(fd, iov, iovcnt); _thr_cancel_leave(curthread, ret == -1); - return ret; + return (ret); } -__weak_reference(__recvfrom, recvfrom); - /* * Cancellation behavior: * Thread may be canceled at start, but if the system call got some data, * the thread is not canceled. */ -ssize_t -__recvfrom(int s, void *b, size_t l, int f, struct sockaddr *from, +static ssize_t +__thr_recvfrom(int s, void *b, size_t l, int f, struct sockaddr *from, socklen_t *fl) { - struct pthread *curthread = _get_curthread(); + struct pthread *curthread; ssize_t ret; + curthread = _get_curthread(); _thr_cancel_enter(curthread); ret = __sys_recvfrom(s, b, l, f, from, fl); _thr_cancel_leave(curthread, ret == -1); return (ret); } -__weak_reference(__recvmsg, recvmsg); - /* * Cancellation behavior: * Thread may be canceled at start, but if the system call got some data, * the thread is not canceled. */ -ssize_t -__recvmsg(int s, struct msghdr *m, int f) +static ssize_t +__thr_recvmsg(int s, struct msghdr *m, int f) { - struct pthread *curthread = _get_curthread(); + struct pthread *curthread; ssize_t ret; + curthread = _get_curthread(); _thr_cancel_enter(curthread); ret = __sys_recvmsg(s, m, f); _thr_cancel_leave(curthread, ret == -1); return (ret); } -__weak_reference(__select, select); - /* * Cancellation behavior: * Thread may be canceled at start, but if the system call returns something, * the thread is not canceled. */ -int -__select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, +static int +__thr_select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { - struct pthread *curthread = _get_curthread(); + struct pthread *curthread; int ret; + curthread = _get_curthread(); _thr_cancel_enter(curthread); ret = __sys_select(numfds, readfds, writefds, exceptfds, timeout); _thr_cancel_leave(curthread, ret == -1); - return ret; + return (ret); } -__weak_reference(__sendmsg, sendmsg); - /* * Cancellation behavior: * Thread may be canceled at start, but if the system call sent * data, the thread is not canceled. */ -ssize_t -__sendmsg(int s, const struct msghdr *m, int f) +static ssize_t +__thr_sendmsg(int s, const struct msghdr *m, int f) { - struct pthread *curthread = _get_curthread(); + struct pthread *curthread; ssize_t ret; + curthread = _get_curthread(); _thr_cancel_enter(curthread); ret = __sys_sendmsg(s, m, f); _thr_cancel_leave(curthread, ret <= 0); return (ret); } -__weak_reference(__sendto, sendto); - /* * Cancellation behavior: * Thread may be canceled at start, but if the system call sent some * data, the thread is not canceled. */ -ssize_t -__sendto(int s, const void *m, size_t l, int f, const struct sockaddr *t, +static ssize_t +__thr_sendto(int s, const void *m, size_t l, int f, const struct sockaddr *t, socklen_t tl) { - struct pthread *curthread = _get_curthread(); + struct pthread *curthread; ssize_t ret; + curthread = _get_curthread(); _thr_cancel_enter(curthread); ret = __sys_sendto(s, m, l, f, t, tl); _thr_cancel_leave(curthread, ret <= 0); return (ret); } -__weak_reference(___sleep, sleep); - -unsigned int -___sleep(unsigned int seconds) +static unsigned int +__thr_sleep(unsigned int seconds) { - struct pthread *curthread = _get_curthread(); - unsigned int ret; + struct pthread *curthread; + unsigned int ret; + curthread = _get_curthread(); _thr_cancel_enter(curthread); - ret = __sleep(seconds); + ret = __libc_sleep(seconds); _thr_cancel_leave(curthread, 1); - return (ret); } -__weak_reference(___system, system); - -int -___system(const char *string) +static int +__thr_system(const char *string) { - struct pthread *curthread = _get_curthread(); - int ret; + struct pthread *curthread; + int ret; + curthread = _get_curthread(); _thr_cancel_enter(curthread); - ret = __system(string); + ret = __libc_system(string); _thr_cancel_leave(curthread, 1); - - return ret; + return (ret); } -__weak_reference(___tcdrain, tcdrain); - /* * Cancellation behavior: * If thread is canceled, the system call is not completed, * this means not all bytes were drained. */ -int -___tcdrain(int fd) +static int +__thr_tcdrain(int fd) { - struct pthread *curthread = _get_curthread(); - int ret; + struct pthread *curthread; + int ret; + curthread = _get_curthread(); _thr_cancel_enter(curthread); - ret = __tcdrain(fd); + ret = __libc_tcdrain(fd); _thr_cancel_leave(curthread, ret == -1); return (ret); } -__weak_reference(___usleep, usleep); - -int -___usleep(useconds_t useconds) +static int +__thr_usleep(useconds_t useconds) { - struct pthread *curthread = _get_curthread(); - int ret; + struct pthread *curthread; + int ret; + curthread = _get_curthread(); _thr_cancel_enter(curthread); - ret = __usleep(useconds); + ret = __libc_usleep(useconds); _thr_cancel_leave(curthread, 1); - return (ret); } -__weak_reference(___wait, wait); - /* * Cancellation behavior: * Thread may be canceled at start, but if the system call returns * a child pid, the thread is not canceled. */ -pid_t -___wait(int *istat) +static pid_t +__thr_wait(int *istat) { - struct pthread *curthread = _get_curthread(); - pid_t ret; + struct pthread *curthread; + pid_t ret; + curthread = _get_curthread(); _thr_cancel_enter(curthread); - ret = __wait(istat); + ret = __libc_wait(istat); _thr_cancel_leave(curthread, ret <= 0); - - return ret; + return (ret); } -__weak_reference(__wait3, wait3); - /* * Cancellation behavior: * Thread may be canceled at start, but if the system call returns * a child pid, the thread is not canceled. */ -pid_t -__wait3(int *status, int options, struct rusage *rusage) +static pid_t +__thr_wait3(int *status, int options, struct rusage *rusage) { - struct pthread *curthread = _get_curthread(); + struct pthread *curthread; pid_t ret; + curthread = _get_curthread(); _thr_cancel_enter(curthread); - ret = _wait4(WAIT_ANY, status, options, rusage); + ret = __libc_wait3(status, options, rusage); _thr_cancel_leave(curthread, ret <= 0); - return (ret); } -__weak_reference(__wait4, wait4); - /* * Cancellation behavior: * Thread may be canceled at start, but if the system call returns * a child pid, the thread is not canceled. */ -pid_t -__wait4(pid_t pid, int *status, int options, struct rusage *rusage) +static pid_t +__thr_wait4(pid_t pid, int *status, int options, struct rusage *rusage) { - struct pthread *curthread = _get_curthread(); + struct pthread *curthread; pid_t ret; + curthread = _get_curthread(); _thr_cancel_enter(curthread); ret = __sys_wait4(pid, status, options, rusage); _thr_cancel_leave(curthread, ret <= 0); - - return ret; + return (ret); } -__weak_reference(___waitpid, waitpid); - /* * Cancellation behavior: * Thread may be canceled at start, but if the system call returns * a child pid, the thread is not canceled. */ -pid_t -___waitpid(pid_t wpid, int *status, int options) +static pid_t +__thr_waitpid(pid_t wpid, int *status, int options) { - struct pthread *curthread = _get_curthread(); - pid_t ret; + struct pthread *curthread; + pid_t ret; + curthread = _get_curthread(); _thr_cancel_enter(curthread); - ret = __waitpid(wpid, status, options); + ret = __libc_waitpid(wpid, status, options); _thr_cancel_leave(curthread, ret <= 0); - - return ret; + return (ret); } -__weak_reference(__write, write); - /* * Cancellation behavior: * Thread may be canceled at start, but if the thread wrote some data, * it is not canceled. */ -ssize_t -__write(int fd, const void *buf, size_t nbytes) +static ssize_t +__thr_write(int fd, const void *buf, size_t nbytes) { - struct pthread *curthread = _get_curthread(); + struct pthread *curthread; ssize_t ret; + curthread = _get_curthread(); _thr_cancel_enter(curthread); ret = __sys_write(fd, buf, nbytes); _thr_cancel_leave(curthread, (ret <= 0)); - return ret; + return (ret); } -__weak_reference(__writev, writev); - /* * Cancellation behavior: * Thread may be canceled at start, but if the thread wrote some data, * it is not canceled. */ -ssize_t -__writev(int fd, const struct iovec *iov, int iovcnt) +static ssize_t +__thr_writev(int fd, const struct iovec *iov, int iovcnt) { - struct pthread *curthread = _get_curthread(); + struct pthread *curthread; ssize_t ret; + curthread = _get_curthread(); _thr_cancel_enter(curthread); ret = __sys_writev(fd, iov, iovcnt); _thr_cancel_leave(curthread, (ret <= 0)); - return ret; + return (ret); +} + +void +__thr_interpose_libc(void) +{ + + __error_selector = __error_threaded; +#define SLOT(name) \ + *(__libc_interposing_slot(INTERPOS_##name)) = \ + (interpos_func_t)__thr_##name; + SLOT(accept); + SLOT(accept4); + SLOT(aio_suspend); + SLOT(close); + SLOT(connect); + SLOT(creat); + SLOT(fcntl); + SLOT(fsync); + SLOT(fork); + SLOT(msync); + SLOT(nanosleep); + SLOT(open); + SLOT(openat); + SLOT(poll); + SLOT(pselect); + SLOT(raise); + SLOT(read); + SLOT(readv); + SLOT(recvfrom); + SLOT(recvmsg); + SLOT(select); + SLOT(sendmsg); + SLOT(sendto); + SLOT(setcontext); + SLOT(sigaction); + SLOT(sigprocmask); + SLOT(sigsuspend); + SLOT(sigwait); + SLOT(sigtimedwait); + SLOT(sigwaitinfo); + SLOT(swapcontext); + SLOT(system); + SLOT(sleep); + SLOT(tcdrain); + SLOT(usleep); + SLOT(pause); + SLOT(wait); + SLOT(wait3); + SLOT(wait4); + SLOT(waitpid); + SLOT(write); + SLOT(writev); +#undef SLOT + *(__libc_interposing_slot( + INTERPOS__pthread_mutex_init_calloc_cb)) = + (interpos_func_t)_pthread_mutex_init_calloc_cb; }