int uv_set_process_title(const char* title) { char* new_title; /* We cannot free this pointer when libuv shuts down, * the process may still be using it. */ new_title = uv__strdup(title); if (new_title == NULL) return UV_ENOMEM; uv_once(&process_title_mutex_once, init_process_title_mutex_once); uv_mutex_lock(&process_title_mutex); /* If this is the first time this is set, * don't free and set argv[1] to NULL. */ if (process_title_ptr != NULL) uv__free(process_title_ptr); process_title_ptr = new_title; process_argv[0] = process_title_ptr; if (process_argc > 1) process_argv[1] = NULL; uv_mutex_unlock(&process_title_mutex); return 0; }
int uv_set_process_title(const char* title) { if (process_title) uv__free(process_title); process_title = uv__strdup(title); setproctitle("%s", title); return 0; }
int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK), multiplier = ((uint64_t)1000L / ticks), cpuspeed; uint64_t info[CPUSTATES]; char model[512]; int numcpus = 1; int which[] = {CTL_HW,HW_MODEL,0}; size_t size; int i; uv_cpu_info_t* cpu_info; size = sizeof(model); if (sysctl(which, 2, &model, &size, NULL, 0)) return -errno; which[1] = HW_NCPU; size = sizeof(numcpus); if (sysctl(which, 2, &numcpus, &size, NULL, 0)) return -errno; *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos)); if (!(*cpu_infos)) return -ENOMEM; *count = numcpus; which[1] = HW_CPUSPEED; size = sizeof(cpuspeed); if (sysctl(which, 2, &cpuspeed, &size, NULL, 0)) { SAVE_ERRNO(uv__free(*cpu_infos)); return -errno; } size = sizeof(info); which[0] = CTL_KERN; which[1] = KERN_CPTIME2; for (i = 0; i < numcpus; i++) { which[2] = i; size = sizeof(info); if (sysctl(which, 3, &info, &size, NULL, 0)) { SAVE_ERRNO(uv__free(*cpu_infos)); return -errno; } cpu_info = &(*cpu_infos)[i]; cpu_info->cpu_times.user = (uint64_t)(info[CP_USER]) * multiplier; cpu_info->cpu_times.nice = (uint64_t)(info[CP_NICE]) * multiplier; cpu_info->cpu_times.sys = (uint64_t)(info[CP_SYS]) * multiplier; cpu_info->cpu_times.idle = (uint64_t)(info[CP_IDLE]) * multiplier; cpu_info->cpu_times.irq = (uint64_t)(info[CP_INTR]) * multiplier; cpu_info->model = uv__strdup(model); cpu_info->speed = cpuspeed; } return 0; }
int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK); unsigned int multiplier = ((uint64_t)1000L / ticks); unsigned int cur = 0; uv_cpu_info_t* cpu_info; u_int64_t* cp_times; char model[512]; u_int64_t cpuspeed; int numcpus; size_t size; int i; size = sizeof(model); if (sysctlbyname("machdep.cpu_brand", &model, &size, NULL, 0) && sysctlbyname("hw.model", &model, &size, NULL, 0)) { return -errno; } size = sizeof(numcpus); if (sysctlbyname("hw.ncpu", &numcpus, &size, NULL, 0)) return -errno; *count = numcpus; /* Only i386 and amd64 have machdep.tsc_freq */ size = sizeof(cpuspeed); if (sysctlbyname("machdep.tsc_freq", &cpuspeed, &size, NULL, 0)) cpuspeed = 0; size = numcpus * CPUSTATES * sizeof(*cp_times); cp_times = uv__malloc(size); if (cp_times == NULL) return -ENOMEM; if (sysctlbyname("kern.cp_time", cp_times, &size, NULL, 0)) return -errno; *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos)); if (!(*cpu_infos)) { uv__free(cp_times); uv__free(*cpu_infos); return -ENOMEM; } for (i = 0; i < numcpus; i++) { cpu_info = &(*cpu_infos)[i]; cpu_info->cpu_times.user = (uint64_t)(cp_times[CP_USER+cur]) * multiplier; cpu_info->cpu_times.nice = (uint64_t)(cp_times[CP_NICE+cur]) * multiplier; cpu_info->cpu_times.sys = (uint64_t)(cp_times[CP_SYS+cur]) * multiplier; cpu_info->cpu_times.idle = (uint64_t)(cp_times[CP_IDLE+cur]) * multiplier; cpu_info->cpu_times.irq = (uint64_t)(cp_times[CP_INTR+cur]) * multiplier; cpu_info->model = uv__strdup(model); cpu_info->speed = (int)(cpuspeed/(uint64_t) 1e6); cur += CPUSTATES; } uv__free(cp_times); return 0; }
int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl, uv_fs_cb cb) { INIT(MKDTEMP); req->path = uv__strdup(tpl); if (req->path == NULL) return -ENOMEM; POST; }
int uv_pipe_bind(uv_pipe_t* handle, const char* name) { struct sockaddr_un saddr; const char* pipe_fname; int sockfd; int err; size_t name_len; pipe_fname = NULL; sockfd = -1; name_len = strlen(name); if (name_len > sizeof(saddr.sun_path) - 1) return -ENAMETOOLONG; /* Already bound? */ if (uv__stream_fd(handle) >= 0) return -EINVAL; /* Make a copy of the file name, it outlives this function's scope. */ pipe_fname = uv__strdup(name); if (pipe_fname == NULL) return -ENOMEM; /* We've got a copy, don't touch the original any more. */ name = NULL; err = uv__socket(AF_UNIX, SOCK_STREAM, 0); if (err < 0) goto err_socket; sockfd = err; memset(&saddr, 0, sizeof saddr); memcpy(saddr.sun_path, pipe_fname, name_len); saddr.sun_family = AF_UNIX; if (bind(sockfd, (struct sockaddr*)&saddr, sizeof saddr)) { err = -errno; /* Convert ENOENT to EACCES for compatibility with Windows. */ if (err == -ENOENT) err = -EACCES; uv__close(sockfd); goto err_socket; } /* Success. */ handle->flags |= UV_HANDLE_BOUND; handle->pipe_fname = pipe_fname; /* Is a strdup'ed copy. */ handle->io_watcher.fd = sockfd; return 0; err_socket: uv__free((void*)pipe_fname); return err; }
int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { uv_cpu_info_t* cpu_info; perfstat_cpu_total_t ps_total; perfstat_cpu_t* ps_cpus; perfstat_id_t cpu_id; int result, ncpus, idx = 0; result = perfstat_cpu_total(NULL, &ps_total, sizeof(ps_total), 1); if (result == -1) { return UV_ENOSYS; } ncpus = result = perfstat_cpu(NULL, NULL, sizeof(perfstat_cpu_t), 0); if (result == -1) { return UV_ENOSYS; } ps_cpus = (perfstat_cpu_t*) uv__malloc(ncpus * sizeof(perfstat_cpu_t)); if (!ps_cpus) { return UV_ENOMEM; } /* TODO(bnoordhuis) Check uv__strscpy() return value. */ uv__strscpy(cpu_id.name, FIRST_CPU, sizeof(cpu_id.name)); result = perfstat_cpu(&cpu_id, ps_cpus, sizeof(perfstat_cpu_t), ncpus); if (result == -1) { uv__free(ps_cpus); return UV_ENOSYS; } *cpu_infos = (uv_cpu_info_t*) uv__malloc(ncpus * sizeof(uv_cpu_info_t)); if (!*cpu_infos) { uv__free(ps_cpus); return UV_ENOMEM; } *count = ncpus; cpu_info = *cpu_infos; while (idx < ncpus) { cpu_info->speed = (int)(ps_total.processorHZ / 1000000); cpu_info->model = uv__strdup(ps_total.description); cpu_info->cpu_times.user = ps_cpus[idx].user; cpu_info->cpu_times.sys = ps_cpus[idx].sys; cpu_info->cpu_times.idle = ps_cpus[idx].idle; cpu_info->cpu_times.irq = ps_cpus[idx].wait; cpu_info->cpu_times.nice = 0; cpu_info++; idx++; } uv__free(ps_cpus); return 0; }
int uv_set_process_title(const char* title) { char* new_title; new_title = uv__strdup(title); if (process_title == NULL) return -ENOMEM; uv__free(process_title); process_title = new_title; setproctitle("%s", title); return 0; }
int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, const char* filename, unsigned int flags) { #ifdef HAVE_SYS_AHAFS_EVPRODS_H int fd, rc, str_offset = 0; char cwd[PATH_MAX]; char absolute_path[PATH_MAX]; char readlink_cwd[PATH_MAX]; /* Figure out whether filename is absolute or not */ if (filename[0] == '/') { /* We have absolute pathname */ snprintf(absolute_path, sizeof(absolute_path), "%s", filename); } else { /* We have a relative pathname, compose the absolute pathname */ snprintf(cwd, sizeof(cwd), "/proc/%lu/cwd", (unsigned long) getpid()); rc = readlink(cwd, readlink_cwd, sizeof(readlink_cwd) - 1); if (rc < 0) return rc; /* readlink does not null terminate our string */ readlink_cwd[rc] = '\0'; if (filename[0] == '.' && filename[1] == '/') str_offset = 2; snprintf(absolute_path, sizeof(absolute_path), "%s%s", readlink_cwd, filename + str_offset); } if (uv__is_ahafs_mounted() < 0) /* /aha checks failed */ return UV_ENOSYS; /* Setup ahafs */ rc = uv__setup_ahafs((const char *)absolute_path, &fd); if (rc != 0) return rc; /* Setup/Initialize all the libuv routines */ uv__handle_start(handle); uv__io_init(&handle->event_watcher, uv__ahafs_event, fd); handle->path = uv__strdup(filename); handle->cb = cb; handle->dir_filename = NULL; uv__io_start(handle->loop, &handle->event_watcher, POLLIN); return 0; #else return -ENOSYS; #endif }
int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK), multiplier = ((uint64_t)1000L / ticks); char model[512]; uint64_t cpuspeed; size_t size; unsigned int i; natural_t numcpus; mach_msg_type_number_t msg_type; processor_cpu_load_info_data_t *info; uv_cpu_info_t* cpu_info; size = sizeof(model); if (sysctlbyname("machdep.cpu.brand_string", &model, &size, NULL, 0) && sysctlbyname("hw.model", &model, &size, NULL, 0)) { return -errno; } size = sizeof(cpuspeed); if (sysctlbyname("hw.cpufrequency", &cpuspeed, &size, NULL, 0)) return -errno; if (host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &numcpus, (processor_info_array_t*)&info, &msg_type) != KERN_SUCCESS) { return -EINVAL; /* FIXME(bnoordhuis) Translate error. */ } *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos)); if (!(*cpu_infos)) { vm_deallocate(mach_task_self(), (vm_address_t)info, msg_type); return -ENOMEM; } *count = numcpus; for (i = 0; i < numcpus; i++) { cpu_info = &(*cpu_infos)[i]; cpu_info->cpu_times.user = (uint64_t)(info[i].cpu_ticks[0]) * multiplier; cpu_info->cpu_times.nice = (uint64_t)(info[i].cpu_ticks[3]) * multiplier; cpu_info->cpu_times.sys = (uint64_t)(info[i].cpu_ticks[1]) * multiplier; cpu_info->cpu_times.idle = (uint64_t)(info[i].cpu_ticks[2]) * multiplier; cpu_info->cpu_times.irq = 0; cpu_info->model = uv__strdup(model); cpu_info->speed = cpuspeed/1000000; } vm_deallocate(mach_task_self(), (vm_address_t)info, msg_type); return 0; }
int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl, uv_fs_cb cb) { INIT(MKDTEMP); req->path = uv__strdup(tpl); if (req->path == NULL) { if (cb != NULL) uv__req_unregister(loop, req); return -ENOMEM; } POST; }
int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, const char* path, unsigned int flags) { #if defined(__APPLE__) struct stat statbuf; #endif /* defined(__APPLE__) */ int fd; if (uv__is_active(handle)) return -EINVAL; /* TODO open asynchronously - but how do we report back errors? */ fd = open(path, O_RDONLY); if (fd == -1) return -errno; uv__handle_start(handle); uv__io_init(&handle->event_watcher, uv__fs_event, fd); handle->path = uv__strdup(path); handle->cb = cb; #if defined(__APPLE__) /* Nullify field to perform checks later */ handle->cf_cb = NULL; handle->realpath = NULL; handle->realpath_len = 0; handle->cf_flags = flags; if (fstat(fd, &statbuf)) goto fallback; /* FSEvents works only with directories */ if (!(statbuf.st_mode & S_IFDIR)) goto fallback; /* The fallback fd is no longer needed */ uv__close(fd); handle->event_watcher.fd = -1; return uv__fsevents_init(handle); fallback: #endif /* defined(__APPLE__) */ uv__io_start(handle->loop, &handle->event_watcher, POLLIN); return 0; }
int uv_set_process_title(const char* title) { int err; int length; WCHAR* title_w = NULL; uv__once_init(); /* Find out how big the buffer for the wide-char title must be */ length = MultiByteToWideChar(CP_UTF8, 0, title, -1, NULL, 0); if (!length) { err = GetLastError(); goto done; } /* Convert to wide-char string */ title_w = (WCHAR*)uv__malloc(sizeof(WCHAR) * length); if (!title_w) { uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); } length = MultiByteToWideChar(CP_UTF8, 0, title, -1, title_w, length); if (!length) { err = GetLastError(); goto done; } /* If the title must be truncated insert a \0 terminator there */ if (length > MAX_TITLE_LENGTH) { title_w[MAX_TITLE_LENGTH - 1] = L'\0'; } if (!SetConsoleTitleW(title_w)) { err = GetLastError(); goto done; } EnterCriticalSection(&process_title_lock); uv__free(process_title); process_title = uv__strdup(title); LeaveCriticalSection(&process_title_lock); err = 0; done: uv__free(title_w); return uv_translate_sys_error(err); }
static int uv__dlerror(uv_lib_t* lib) { const char* errmsg; if (lib->errmsg) uv__free(lib->errmsg); errmsg = dlerror(); if (errmsg) { lib->errmsg = uv__strdup(errmsg); return -1; } else { lib->errmsg = NULL; return 0; } }
int uv_set_process_title(const char* title) { int oid[4]; uv__free(process_title); process_title = uv__strdup(title); oid[0] = CTL_KERN; oid[1] = KERN_PROC; oid[2] = KERN_PROC_ARGS; oid[3] = getpid(); sysctl(oid, ARRAY_SIZE(oid), NULL, NULL, process_title, strlen(process_title) + 1); return 0; }
int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, const char* path, unsigned int flags) { int portfd; int first_run; int err; if (uv__is_active(handle)) return -EINVAL; first_run = 0; if (handle->loop->fs_fd == -1) { portfd = port_create(); if (portfd == -1) return -errno; handle->loop->fs_fd = portfd; first_run = 1; } uv__handle_start(handle); handle->path = uv__strdup(path); handle->fd = PORT_UNUSED; handle->cb = cb; memset(&handle->fo, 0, sizeof handle->fo); handle->fo.fo_name = handle->path; err = uv__fs_event_rearm(handle); if (err != 0) return err; if (first_run) { uv__io_init(&handle->loop->fs_event_watcher, uv__fs_event_read, portfd); uv__io_start(handle->loop, &handle->loop->fs_event_watcher, UV__POLLIN); } return 0; }
int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, const char* path, unsigned int flags) { int name_size, is_path_dir; DWORD attr, last_error; WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL; WCHAR short_path[MAX_PATH]; if (uv__is_active(handle)) return UV_EINVAL; handle->cb = cb; handle->path = uv__strdup(path); if (!handle->path) { uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); } uv__handle_start(handle); /* Convert name to UTF16. */ name_size = uv_utf8_to_utf16(path, NULL, 0) * sizeof(WCHAR); pathw = (WCHAR*)uv__malloc(name_size); if (!pathw) { uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); } if (!uv_utf8_to_utf16(path, pathw, name_size / sizeof(WCHAR))) { return uv_translate_sys_error(GetLastError()); } /* Determine whether path is a file or a directory. */ attr = GetFileAttributesW(pathw); if (attr == INVALID_FILE_ATTRIBUTES) { last_error = GetLastError(); goto error; } is_path_dir = (attr & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0; if (is_path_dir) { /* path is a directory, so that's the directory that we will watch. */ handle->dirw = pathw; dir_to_watch = pathw; } else { /* * path is a file. So we split path into dir & file parts, and * watch the dir directory. */ /* Convert to short path. */ if (!GetShortPathNameW(pathw, short_path, ARRAY_SIZE(short_path))) { last_error = GetLastError(); goto error; } if (uv_split_path(pathw, &dir, &handle->filew) != 0) { last_error = GetLastError(); goto error; } if (uv_split_path(short_path, NULL, &handle->short_filew) != 0) { last_error = GetLastError(); goto error; } dir_to_watch = dir; uv__free(pathw); pathw = NULL; } handle->dir_handle = CreateFileW(dir_to_watch, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL); if (dir) { uv__free(dir); dir = NULL; } if (handle->dir_handle == INVALID_HANDLE_VALUE) { last_error = GetLastError(); goto error; } if (CreateIoCompletionPort(handle->dir_handle, handle->loop->iocp, (ULONG_PTR)handle, 0) == NULL) { last_error = GetLastError(); goto error; } if (!handle->buffer) { handle->buffer = (char*)uv__malloc(uv_directory_watcher_buffer_size); } if (!handle->buffer) { uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); } memset(&(handle->req.u.io.overlapped), 0, sizeof(handle->req.u.io.overlapped)); if (!ReadDirectoryChangesW(handle->dir_handle, handle->buffer, uv_directory_watcher_buffer_size, (flags & UV_FS_EVENT_RECURSIVE) ? TRUE : FALSE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_LAST_ACCESS | FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_SECURITY, NULL, &handle->req.u.io.overlapped, NULL)) { last_error = GetLastError(); goto error; } handle->req_pending = 1; return 0; error: if (handle->path) { uv__free(handle->path); handle->path = NULL; } if (handle->filew) { uv__free(handle->filew); handle->filew = NULL; } if (handle->short_filew) { uv__free(handle->short_filew); handle->short_filew = NULL; } uv__free(pathw); if (handle->dir_handle != INVALID_HANDLE_VALUE) { CloseHandle(handle->dir_handle); handle->dir_handle = INVALID_HANDLE_VALUE; } if (handle->buffer) { uv__free(handle->buffer); handle->buffer = NULL; } return uv_translate_sys_error(last_error); }
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { struct ifaddrs* addrs; struct ifaddrs* ent; uv_interface_address_t* address; int i; if (getifaddrs(&addrs) != 0) return -errno; *count = 0; /* Count the number of interfaces */ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { if (uv__ifaddr_exclude(ent)) continue; (*count)++; } *addresses = uv__malloc(*count * sizeof(**addresses)); if (*addresses == NULL) { freeifaddrs(addrs); return -ENOMEM; } address = *addresses; for (ent = addrs; ent != NULL; ent = ent->ifa_next) { if (uv__ifaddr_exclude(ent)) continue; address->name = uv__strdup(ent->ifa_name); if (ent->ifa_addr->sa_family == AF_INET6) { address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); } else { address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); } if (ent->ifa_netmask->sa_family == AF_INET6) { address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); } else { address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); } address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); address++; } /* Fill in physical addresses for each interface */ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { if (uv__ifaddr_exclude(ent)) continue; address = *addresses; for (i = 0; i < *count; i++) { if (strcmp(address->name, ent->ifa_name) == 0) { #if defined(__CYGWIN__) || defined(__MSYS__) memset(address->phys_addr, 0, sizeof(address->phys_addr)); #else struct sockaddr_dl* sa_addr; sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); #endif } address++; } } freeifaddrs(addrs); return 0; }
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { #ifndef HAVE_IFADDRS_H return -ENOSYS; #else struct ifaddrs *addrs, *ent; uv_interface_address_t* address; int i; struct sockaddr_ll *sll; if (getifaddrs(&addrs)) return -errno; *count = 0; *addresses = NULL; /* Count the number of interfaces */ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || (ent->ifa_addr == NULL) || (ent->ifa_addr->sa_family == PF_PACKET)) { continue; } (*count)++; } if (*count == 0) return 0; *addresses = uv__malloc(*count * sizeof(**addresses)); if (!(*addresses)) return -ENOMEM; address = *addresses; for (ent = addrs; ent != NULL; ent = ent->ifa_next) { if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) continue; if (ent->ifa_addr == NULL) continue; /* * On Linux getifaddrs returns information related to the raw underlying * devices. We're not interested in this information yet. */ if (ent->ifa_addr->sa_family == PF_PACKET) continue; address->name = uv__strdup(ent->ifa_name); if (ent->ifa_addr->sa_family == AF_INET6) { address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); } else { address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); } if (ent->ifa_netmask->sa_family == AF_INET6) { address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); } else { address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); } address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); address++; } /* Fill in physical addresses for each interface */ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || (ent->ifa_addr == NULL) || (ent->ifa_addr->sa_family != PF_PACKET)) { continue; } address = *addresses; for (i = 0; i < (*count); i++) { if (strcmp(address->name, ent->ifa_name) == 0) { sll = (struct sockaddr_ll*)ent->ifa_addr; memcpy(address->phys_addr, sll->sll_addr, sizeof(address->phys_addr)); } address++; } } freeifaddrs(addrs); return 0; #endif }
/* * We could use a static buffer for the path manipulations that we need outside * of the function, but this function could be called by multiple consumers and * we don't want to potentially create a race condition in the use of snprintf. * There is no direct way of getting the exe path in AIX - either through /procfs * or through some libc APIs. The below approach is to parse the argv[0]'s pattern * and use it in conjunction with PATH environment variable to craft one. */ int uv_exepath(char* buffer, size_t* size) { int res; char args[PATH_MAX]; char abspath[PATH_MAX]; size_t abspath_size; struct procsinfo pi; if (buffer == NULL || size == NULL || *size == 0) return UV_EINVAL; pi.pi_pid = getpid(); res = getargs(&pi, sizeof(pi), args, sizeof(args)); if (res < 0) return UV_EINVAL; /* * Possibilities for args: * i) an absolute path such as: /home/user/myprojects/nodejs/node * ii) a relative path such as: ./node or ../myprojects/nodejs/node * iii) a bare filename such as "node", after exporting PATH variable * to its location. */ /* Case i) and ii) absolute or relative paths */ if (strchr(args, '/') != NULL) { if (realpath(args, abspath) != abspath) return UV__ERR(errno); abspath_size = strlen(abspath); *size -= 1; if (*size > abspath_size) *size = abspath_size; memcpy(buffer, abspath, *size); buffer[*size] = '\0'; return 0; } else { /* Case iii). Search PATH environment variable */ char trypath[PATH_MAX]; char *clonedpath = NULL; char *token = NULL; char *path = getenv("PATH"); if (path == NULL) return UV_EINVAL; clonedpath = uv__strdup(path); if (clonedpath == NULL) return UV_ENOMEM; token = strtok(clonedpath, ":"); while (token != NULL) { snprintf(trypath, sizeof(trypath) - 1, "%s/%s", token, args); if (realpath(trypath, abspath) == abspath) { /* Check the match is executable */ if (access(abspath, X_OK) == 0) { abspath_size = strlen(abspath); *size -= 1; if (*size > abspath_size) *size = abspath_size; memcpy(buffer, abspath, *size); buffer[*size] = '\0'; uv__free(clonedpath); return 0; } } token = strtok(NULL, ":"); } uv__free(clonedpath); /* Out of tokens (path entries), and no match found */ return UV_EINVAL; } }
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { uv_interface_address_t* address; int sockfd, inet6, size = 1; struct ifconf ifc; struct ifreq *ifr, *p, flg; struct sockaddr_dl* sa_addr; *count = 0; *addresses = NULL; if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) { return UV__ERR(errno); } if (ioctl(sockfd, SIOCGSIZIFCONF, &size) == -1) { uv__close(sockfd); return UV__ERR(errno); } ifc.ifc_req = (struct ifreq*)uv__malloc(size); ifc.ifc_len = size; if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) { uv__close(sockfd); return UV__ERR(errno); } #define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p)) /* Count all up and running ipv4/ipv6 addresses */ ifr = ifc.ifc_req; while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) { p = ifr; ifr = (struct ifreq*) ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr)); if (!(p->ifr_addr.sa_family == AF_INET6 || p->ifr_addr.sa_family == AF_INET)) continue; memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name)); if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) { uv__close(sockfd); return UV__ERR(errno); } if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING)) continue; (*count)++; } if (*count == 0) { uv__close(sockfd); return 0; } /* Alloc the return interface structs */ *addresses = uv__malloc(*count * sizeof(uv_interface_address_t)); if (!(*addresses)) { uv__close(sockfd); return UV_ENOMEM; } address = *addresses; ifr = ifc.ifc_req; while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) { p = ifr; ifr = (struct ifreq*) ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr)); if (!(p->ifr_addr.sa_family == AF_INET6 || p->ifr_addr.sa_family == AF_INET)) continue; inet6 = (p->ifr_addr.sa_family == AF_INET6); memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name)); if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) { uv__close(sockfd); return UV_ENOSYS; } if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING)) continue; /* All conditions above must match count loop */ address->name = uv__strdup(p->ifr_name); if (inet6) address->address.address6 = *((struct sockaddr_in6*) &p->ifr_addr); else address->address.address4 = *((struct sockaddr_in*) &p->ifr_addr); sa_addr = (struct sockaddr_dl*) &p->ifr_addr; memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); if (ioctl(sockfd, SIOCGIFNETMASK, p) == -1) { uv__close(sockfd); return UV_ENOSYS; } if (inet6) address->netmask.netmask6 = *((struct sockaddr_in6*) &p->ifr_addr); else address->netmask.netmask4 = *((struct sockaddr_in*) &p->ifr_addr); address->is_internal = flg.ifr_flags & IFF_LOOPBACK ? 1 : 0; address++; } #undef ADDR_SIZE uv__close(sockfd); return 0; }
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { #ifndef HAVE_IFADDRS_H *count = 0; *addresses = NULL; return UV_ENOSYS; #else struct ifaddrs *addrs, *ent; uv_interface_address_t* address; int i; struct sockaddr_ll *sll; *count = 0; *addresses = NULL; if (getifaddrs(&addrs)) return UV__ERR(errno); /* Count the number of interfaces */ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR)) continue; (*count)++; } if (*count == 0) { freeifaddrs(addrs); return 0; } *addresses = uv__malloc(*count * sizeof(**addresses)); if (!(*addresses)) { freeifaddrs(addrs); return UV_ENOMEM; } address = *addresses; for (ent = addrs; ent != NULL; ent = ent->ifa_next) { if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR)) continue; address->name = uv__strdup(ent->ifa_name); if (ent->ifa_addr->sa_family == AF_INET6) { address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); } else { address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); } if (ent->ifa_netmask->sa_family == AF_INET6) { address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); } else { address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); } address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); address++; } /* Fill in physical addresses for each interface */ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFPHYS)) continue; address = *addresses; for (i = 0; i < (*count); i++) { if (strcmp(address->name, ent->ifa_name) == 0) { sll = (struct sockaddr_ll*)ent->ifa_addr; memcpy(address->phys_addr, sll->sll_addr, sizeof(address->phys_addr)); } else { memset(address->phys_addr, 0, sizeof(address->phys_addr)); } address++; } } freeifaddrs(addrs); return 0; #endif }
int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK), multiplier = ((uint64_t)1000L / ticks), cpuspeed, maxcpus, cur = 0; uv_cpu_info_t* cpu_info; const char* maxcpus_key; const char* cptimes_key; char model[512]; long* cp_times; int numcpus; size_t size; int i; #if defined(__DragonFly__) /* This is not quite correct but DragonFlyBSD doesn't seem to have anything * comparable to kern.smp.maxcpus or kern.cp_times (kern.cp_time is a total, * not per CPU). At least this stops uv_cpu_info() from failing completely. */ maxcpus_key = "hw.ncpu"; cptimes_key = "kern.cp_time"; #else maxcpus_key = "kern.smp.maxcpus"; cptimes_key = "kern.cp_times"; #endif size = sizeof(model); if (sysctlbyname("hw.model", &model, &size, NULL, 0)) return -errno; size = sizeof(numcpus); if (sysctlbyname("hw.ncpu", &numcpus, &size, NULL, 0)) return -errno; *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos)); if (!(*cpu_infos)) return -ENOMEM; *count = numcpus; size = sizeof(cpuspeed); if (sysctlbyname("hw.clockrate", &cpuspeed, &size, NULL, 0)) { uv__free(*cpu_infos); return -errno; } /* kern.cp_times on FreeBSD i386 gives an array up to maxcpus instead of * ncpu. */ size = sizeof(maxcpus); if (sysctlbyname(maxcpus_key, &maxcpus, &size, NULL, 0)) { uv__free(*cpu_infos); return -errno; } size = maxcpus * CPUSTATES * sizeof(long); cp_times = uv__malloc(size); if (cp_times == NULL) { uv__free(*cpu_infos); return -ENOMEM; } if (sysctlbyname(cptimes_key, cp_times, &size, NULL, 0)) { uv__free(cp_times); uv__free(*cpu_infos); return -errno; } for (i = 0; i < numcpus; i++) { cpu_info = &(*cpu_infos)[i]; cpu_info->cpu_times.user = (uint64_t)(cp_times[CP_USER+cur]) * multiplier; cpu_info->cpu_times.nice = (uint64_t)(cp_times[CP_NICE+cur]) * multiplier; cpu_info->cpu_times.sys = (uint64_t)(cp_times[CP_SYS+cur]) * multiplier; cpu_info->cpu_times.idle = (uint64_t)(cp_times[CP_IDLE+cur]) * multiplier; cpu_info->cpu_times.irq = (uint64_t)(cp_times[CP_INTR+cur]) * multiplier; cpu_info->model = uv__strdup(model); cpu_info->speed = cpuspeed; cur+=CPUSTATES; } uv__free(cp_times); return 0; }
int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, const char* filename, unsigned int flags) { #ifdef HAVE_SYS_AHAFS_EVPRODS_H int fd, rc, str_offset = 0; char cwd[PATH_MAX]; char absolute_path[PATH_MAX]; char readlink_cwd[PATH_MAX]; struct timeval zt; fd_set pollfd; /* Figure out whether filename is absolute or not */ if (filename[0] == '\0') { /* Missing a pathname */ return UV_ENOENT; } else if (filename[0] == '/') { /* We have absolute pathname */ /* TODO(bnoordhuis) Check uv__strscpy() return value. */ uv__strscpy(absolute_path, filename, sizeof(absolute_path)); } else { /* We have a relative pathname, compose the absolute pathname */ snprintf(cwd, sizeof(cwd), "/proc/%lu/cwd", (unsigned long) getpid()); rc = readlink(cwd, readlink_cwd, sizeof(readlink_cwd) - 1); if (rc < 0) return rc; /* readlink does not null terminate our string */ readlink_cwd[rc] = '\0'; if (filename[0] == '.' && filename[1] == '/') str_offset = 2; snprintf(absolute_path, sizeof(absolute_path), "%s%s", readlink_cwd, filename + str_offset); } if (uv__is_ahafs_mounted() < 0) /* /aha checks failed */ return UV_ENOSYS; /* Setup ahafs */ rc = uv__setup_ahafs((const char *)absolute_path, &fd); if (rc != 0) return rc; /* Setup/Initialize all the libuv routines */ uv__handle_start(handle); uv__io_init(&handle->event_watcher, uv__ahafs_event, fd); handle->path = uv__strdup(filename); handle->cb = cb; handle->dir_filename = NULL; uv__io_start(handle->loop, &handle->event_watcher, POLLIN); /* AHAFS wants someone to poll for it to start mointoring. * so kick-start it so that we don't miss an event in the * eventuality of an event that occurs in the current loop. */ do { memset(&zt, 0, sizeof(zt)); FD_ZERO(&pollfd); FD_SET(fd, &pollfd); rc = select(fd + 1, &pollfd, NULL, NULL, &zt); } while (rc == -1 && errno == EINTR); return 0; #else return UV_ENOSYS; #endif }
int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { int lookup_instance; kstat_ctl_t *kc; kstat_t *ksp; kstat_named_t *knp; uv_cpu_info_t* cpu_info; kc = kstat_open(); if (kc == NULL) return -EPERM; /* Get count of cpus */ lookup_instance = 0; while ((ksp = kstat_lookup(kc, (char*) "cpu_info", lookup_instance, NULL))) { lookup_instance++; } *cpu_infos = uv__malloc(lookup_instance * sizeof(**cpu_infos)); if (!(*cpu_infos)) { kstat_close(kc); return -ENOMEM; } *count = lookup_instance; cpu_info = *cpu_infos; lookup_instance = 0; while ((ksp = kstat_lookup(kc, (char*) "cpu_info", lookup_instance, NULL))) { if (kstat_read(kc, ksp, NULL) == -1) { cpu_info->speed = 0; cpu_info->model = NULL; } else { knp = kstat_data_lookup(ksp, (char*) "clock_MHz"); assert(knp->data_type == KSTAT_DATA_INT32 || knp->data_type == KSTAT_DATA_INT64); cpu_info->speed = (knp->data_type == KSTAT_DATA_INT32) ? knp->value.i32 : knp->value.i64; knp = kstat_data_lookup(ksp, (char*) "brand"); assert(knp->data_type == KSTAT_DATA_STRING); cpu_info->model = uv__strdup(KSTAT_NAMED_STR_PTR(knp)); } lookup_instance++; cpu_info++; } cpu_info = *cpu_infos; lookup_instance = 0; for (;;) { ksp = kstat_lookup(kc, (char*) "cpu", lookup_instance, (char*) "sys"); if (ksp == NULL) break; if (kstat_read(kc, ksp, NULL) == -1) { cpu_info->cpu_times.user = 0; cpu_info->cpu_times.nice = 0; cpu_info->cpu_times.sys = 0; cpu_info->cpu_times.idle = 0; cpu_info->cpu_times.irq = 0; } else { knp = kstat_data_lookup(ksp, (char*) "cpu_ticks_user"); assert(knp->data_type == KSTAT_DATA_UINT64); cpu_info->cpu_times.user = knp->value.ui64; knp = kstat_data_lookup(ksp, (char*) "cpu_ticks_kernel"); assert(knp->data_type == KSTAT_DATA_UINT64); cpu_info->cpu_times.sys = knp->value.ui64; knp = kstat_data_lookup(ksp, (char*) "cpu_ticks_idle"); assert(knp->data_type == KSTAT_DATA_UINT64); cpu_info->cpu_times.idle = knp->value.ui64; knp = kstat_data_lookup(ksp, (char*) "intr"); assert(knp->data_type == KSTAT_DATA_UINT64); cpu_info->cpu_times.irq = knp->value.ui64; cpu_info->cpu_times.nice = 0; } lookup_instance++; cpu_info++; } kstat_close(kc); return 0; }
int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, const char* filename, unsigned int flags) { #ifdef HAVE_SYS_AHAFS_EVPRODS_H int fd, rc, i = 0, res = 0; char cwd[PATH_MAX]; char absolute_path[PATH_MAX]; char fname[PATH_MAX]; char *p; /* Clean all the buffers*/ for(i = 0; i < PATH_MAX; i++) { cwd[i] = 0; absolute_path[i] = 0; fname[i] = 0; } i = 0; /* Figure out whether filename is absolute or not */ if (filename[0] == '/') { /* We have absolute pathname, create the relative pathname*/ sprintf(absolute_path, filename); p = strrchr(filename, '/'); p++; } else { if (filename[0] == '.' && filename[1] == '/') { /* We have a relative pathname, compose the absolute pathname */ sprintf(fname, filename); snprintf(cwd, PATH_MAX-1, "/proc/%lu/cwd", (unsigned long) getpid()); res = readlink(cwd, absolute_path, sizeof(absolute_path) - 1); if (res < 0) return res; p = strrchr(absolute_path, '/'); p++; p++; } else { /* We have a relative pathname, compose the absolute pathname */ sprintf(fname, filename); snprintf(cwd, PATH_MAX-1, "/proc/%lu/cwd", (unsigned long) getpid()); res = readlink(cwd, absolute_path, sizeof(absolute_path) - 1); if (res < 0) return res; p = strrchr(absolute_path, '/'); p++; } /* Copy to filename buffer */ while(filename[i] != NULL) { *p = filename[i]; i++; p++; } } if (uv__is_ahafs_mounted() < 0) /* /aha checks failed */ return UV_ENOSYS; /* Setup ahafs */ rc = uv__setup_ahafs((const char *)absolute_path, &fd); if (rc != 0) return rc; /* Setup/Initialize all the libuv routines */ uv__handle_start(handle); uv__io_init(&handle->event_watcher, uv__ahafs_event, fd); handle->path = uv__strdup((const char*)&absolute_path); handle->cb = cb; uv__io_start(handle->loop, &handle->event_watcher, UV__POLLIN); return 0; #else return -ENOSYS; #endif }
/* * Parse the event occurrence data to figure out what event just occurred * and take proper action. * * The buf is a pointer to the buffer containing the event occurrence data * Returns 0 on success, -1 if unrecoverable error in parsing * */ static int uv__parse_data(char *buf, int *events, uv_fs_event_t* handle) { int evp_rc, i; char *p; char filename[PATH_MAX]; /* To be used when handling directories */ p = buf; *events = 0; /* Clean the filename buffer*/ for(i = 0; i < PATH_MAX; i++) { filename[i] = 0; } i = 0; /* Check for BUF_WRAP */ if (strncmp(buf, "BUF_WRAP", strlen("BUF_WRAP")) == 0) { assert(0 && "Buffer wrap detected, Some event occurrences lost!"); return 0; } /* Since we are using the default buffer size (4K), and have specified * INFO_LVL=1, we won't see any EVENT_OVERFLOW conditions. Applications * should check for this keyword if they are using an INFO_LVL of 2 or * higher, and have a buffer size of <= 4K */ /* Skip to RC_FROM_EVPROD */ if (uv__skip_lines(&p, 9) != 9) return -1; if (sscanf(p, "RC_FROM_EVPROD=%d\nEND_EVENT_DATA", &evp_rc) == 1) { if (uv__path_is_a_directory(handle->path) == 0) { /* Directory */ if (evp_rc == AHAFS_MODDIR_UNMOUNT || evp_rc == AHAFS_MODDIR_REMOVE_SELF) { /* The directory is no longer available for monitoring */ *events = UV_RENAME; handle->dir_filename = NULL; } else { /* A file was added/removed inside the directory */ *events = UV_CHANGE; /* Get the EVPROD_INFO */ if (uv__skip_lines(&p, 1) != 1) return -1; /* Scan out the name of the file that triggered the event*/ if (sscanf(p, "BEGIN_EVPROD_INFO\n%sEND_EVPROD_INFO", filename) == 1) { handle->dir_filename = uv__strdup((const char*)&filename); } else return -1; } } else { /* Regular File */ if (evp_rc == AHAFS_MODFILE_RENAME) *events = UV_RENAME; else *events = UV_CHANGE; } } else return -1; return 0; }
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { struct ifaddrs *addrs, *ent; uv_interface_address_t* address; int i; struct sockaddr_dl *sa_addr; if (getifaddrs(&addrs) != 0) return -errno; *count = 0; /* Count the number of interfaces */ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || (ent->ifa_addr == NULL) || (ent->ifa_addr->sa_family != PF_INET)) { continue; } (*count)++; } *addresses = uv__malloc(*count * sizeof(**addresses)); if (!(*addresses)) return -ENOMEM; address = *addresses; for (ent = addrs; ent != NULL; ent = ent->ifa_next) { if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) continue; if (ent->ifa_addr == NULL) continue; if (ent->ifa_addr->sa_family != PF_INET) continue; address->name = uv__strdup(ent->ifa_name); if (ent->ifa_addr->sa_family == AF_INET6) { address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); } else { address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); } if (ent->ifa_netmask->sa_family == AF_INET6) { address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); } else { address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); } address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); address++; } /* Fill in physical addresses for each interface */ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || (ent->ifa_addr == NULL) || (ent->ifa_addr->sa_family != AF_LINK)) { continue; } address = *addresses; for (i = 0; i < (*count); i++) { if (strcmp(address->name, ent->ifa_name) == 0) { sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); } address++; } } freeifaddrs(addrs); return 0; }