static void maybe_resize(uv_loop_t* loop, unsigned int len) { uv__io_t** watchers; void* fake_watcher_list; void* fake_watcher_count; unsigned int nwatchers; unsigned int i; if (len <= loop->nwatchers) return; /* Preserve fake watcher list and count at the end of the watchers */ if (loop->watchers != NULL) { fake_watcher_list = loop->watchers[loop->nwatchers]; fake_watcher_count = loop->watchers[loop->nwatchers + 1]; } else { fake_watcher_list = NULL; fake_watcher_count = NULL; } nwatchers = next_power_of_two(len + 2) - 2; watchers = uv__realloc(loop->watchers, (nwatchers + 2) * sizeof(loop->watchers[0])); if (watchers == NULL) abort(); for (i = loop->nwatchers; i < nwatchers; i++) watchers[i] = NULL; watchers[nwatchers] = fake_watcher_list; watchers[nwatchers + 1] = fake_watcher_count; loop->watchers = watchers; loop->nwatchers = nwatchers; }
static int uv__loops_add(uv_loop_t* loop) { uv_loop_t** new_loops; int new_capacity, i; uv_mutex_lock(&uv__loops_lock); if (uv__loops_size == uv__loops_capacity) { new_capacity = uv__loops_capacity + UV__LOOPS_CHUNK_SIZE; new_loops = uv__realloc(uv__loops, sizeof(uv_loop_t*) * new_capacity); if (!new_loops) goto failed_loops_realloc; uv__loops = new_loops; for (i = uv__loops_capacity; i < new_capacity; ++i) uv__loops[i] = NULL; uv__loops_capacity = new_capacity; } uv__loops[uv__loops_size] = loop; ++uv__loops_size; uv_mutex_unlock(&uv__loops_lock); return 0; failed_loops_realloc: uv_mutex_unlock(&uv__loops_lock); return ERROR_OUTOFMEMORY; }
int uv_exepath(char* buffer, size_t* size) { int mib[4]; char **argsbuf = NULL; char **argsbuf_tmp; size_t argsbuf_size = 100U; size_t exepath_size; pid_t mypid; int err; if (buffer == NULL || size == NULL || *size == 0) return -EINVAL; mypid = getpid(); for (;;) { err = -ENOMEM; argsbuf_tmp = uv__realloc(argsbuf, argsbuf_size); if (argsbuf_tmp == NULL) goto out; argsbuf = argsbuf_tmp; mib[0] = CTL_KERN; mib[1] = KERN_PROC_ARGS; mib[2] = mypid; mib[3] = KERN_PROC_ARGV; if (sysctl(mib, 4, argsbuf, &argsbuf_size, NULL, 0) == 0) { break; } if (errno != ENOMEM) { err = -errno; goto out; } argsbuf_size *= 2U; } if (argsbuf[0] == NULL) { err = -EINVAL; /* FIXME(bnoordhuis) More appropriate error. */ goto out; } *size -= 1; exepath_size = strlen(argsbuf[0]); if (*size > exepath_size) *size = exepath_size; memcpy(buffer, argsbuf[0], *size); buffer[*size] = '\0'; err = 0; out: uv__free(argsbuf); return err; }
static void uv__loops_remove(uv_loop_t* loop) { int loop_index; int smaller_capacity; uv_loop_t** new_loops; uv_mutex_lock(&uv__loops_lock); for (loop_index = 0; loop_index < uv__loops_size; ++loop_index) { if (uv__loops[loop_index] == loop) break; } /* If loop was not found, ignore */ if (loop_index == uv__loops_size) goto loop_removed; uv__loops[loop_index] = uv__loops[uv__loops_size - 1]; uv__loops[uv__loops_size - 1] = NULL; --uv__loops_size; if (uv__loops_size == 0) { uv__loops_capacity = 0; uv__free(uv__loops); uv__loops = NULL; goto loop_removed; } /* If we didn't grow to big skip downsizing */ if (uv__loops_capacity < 4 * UV__LOOPS_CHUNK_SIZE) goto loop_removed; /* Downsize only if more than half of buffer is free */ smaller_capacity = uv__loops_capacity / 2; if (uv__loops_size >= smaller_capacity) goto loop_removed; new_loops = uv__realloc(uv__loops, sizeof(uv_loop_t*) * smaller_capacity); if (!new_loops) goto loop_removed; uv__loops = new_loops; uv__loops_capacity = smaller_capacity; loop_removed: uv_mutex_unlock(&uv__loops_lock); }
static ssize_t uv__fs_readlink(uv_fs_t* req) { ssize_t maxlen; ssize_t len; char* buf; char* newbuf; #if defined(UV__FS_PATH_MAX_FALLBACK) /* We may not have a real PATH_MAX. Read size of link. */ struct stat st; int ret; ret = lstat(req->path, &st); if (ret != 0) return -1; if (!S_ISLNK(st.st_mode)) { errno = EINVAL; return -1; } maxlen = st.st_size; /* According to readlink(2) lstat can report st_size == 0 for some symlinks, such as those in /proc or /sys. */ if (maxlen == 0) maxlen = uv__fs_pathmax_size(req->path); #else maxlen = uv__fs_pathmax_size(req->path); #endif buf = uv__malloc(maxlen); if (buf == NULL) { errno = ENOMEM; return -1; } #if defined(__MVS__) len = os390_readlink(req->path, buf, maxlen); #else len = readlink(req->path, buf, maxlen); #endif if (len == -1) { uv__free(buf); return -1; } /* Uncommon case: resize to make room for the trailing nul byte. */ if (len == maxlen) { newbuf = uv__realloc(buf, len + 1); if (newbuf == NULL) { uv__free(buf); return -1; } buf = newbuf; } buf[len] = '\0'; req->ptr = buf; return 0; }