1/* Copyright libuv project contributors. All rights reserved. 2 * 3 * Permission is hereby granted, free of charge, to any person obtaining a copy 4 * of this software and associated documentation files (the "Software"), to 5 * deal in the Software without restriction, including without limitation the 6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 * sell copies of the Software, and to permit persons to whom the Software is 8 * furnished to do so, subject to the following conditions: 9 * 10 * The above copyright notice and this permission notice shall be included in 11 * all copies or substantial portions of the Software. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 * IN THE SOFTWARE. 20 */ 21 22#define _GNU_SOURCE 1 23 24#include "uv.h" 25#include "internal.h" 26 27#include <hurd.h> 28#include <hurd/process.h> 29#include <mach/task_info.h> 30#include <mach/vm_statistics.h> 31#include <mach/vm_param.h> 32 33#include <inttypes.h> 34#include <stddef.h> 35#include <unistd.h> 36#include <string.h> 37#include <limits.h> 38 39int uv_exepath(char* buffer, size_t* size) { 40 kern_return_t err; 41 /* XXX in current Hurd, strings are char arrays of 1024 elements */ 42 string_t exepath; 43 ssize_t copied; 44 45 if (buffer == NULL || size == NULL || *size == 0) 46 return UV_EINVAL; 47 48 if (*size - 1 > 0) { 49 /* XXX limited length of buffer in current Hurd, this API will probably 50 * evolve in the future */ 51 err = proc_get_exe(getproc(), getpid(), exepath); 52 53 if (err) 54 return UV__ERR(err); 55 } 56 57 copied = uv__strscpy(buffer, exepath, *size); 58 59 /* do not return error on UV_E2BIG failure */ 60 *size = copied < 0 ? strlen(buffer) : (size_t) copied; 61 62 return 0; 63} 64 65int uv_resident_set_memory(size_t* rss) { 66 kern_return_t err; 67 struct task_basic_info bi; 68 mach_msg_type_number_t count; 69 70 count = TASK_BASIC_INFO_COUNT; 71 err = task_info(mach_task_self(), TASK_BASIC_INFO, 72 (task_info_t) &bi, &count); 73 74 if (err) 75 return UV__ERR(err); 76 77 *rss = bi.resident_size; 78 79 return 0; 80} 81 82uint64_t uv_get_free_memory(void) { 83 kern_return_t err; 84 struct vm_statistics vmstats; 85 86 err = vm_statistics(mach_task_self(), &vmstats); 87 88 if (err) 89 return 0; 90 91 return vmstats.free_count * vm_page_size; 92} 93 94 95uint64_t uv_get_total_memory(void) { 96 kern_return_t err; 97 host_basic_info_data_t hbi; 98 mach_msg_type_number_t cnt; 99 100 cnt = HOST_BASIC_INFO_COUNT; 101 err = host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t) &hbi, &cnt); 102 103 if (err) 104 return 0; 105 106 return hbi.memory_size; 107} 108 109 110int uv_uptime(double* uptime) { 111 char buf[128]; 112 113 /* Try /proc/uptime first */ 114 if (0 == uv__slurp("/proc/uptime", buf, sizeof(buf))) 115 if (1 == sscanf(buf, "%lf", uptime)) 116 return 0; 117 118 /* Reimplement here code from procfs to calculate uptime if not mounted? */ 119 120 return UV__ERR(EIO); 121} 122 123void uv_loadavg(double avg[3]) { 124 char buf[128]; /* Large enough to hold all of /proc/loadavg. */ 125 126 if (0 == uv__slurp("/proc/loadavg", buf, sizeof(buf))) 127 if (3 == sscanf(buf, "%lf %lf %lf", &avg[0], &avg[1], &avg[2])) 128 return; 129 130 /* Reimplement here code from procfs to calculate loadavg if not mounted? */ 131} 132 133 134int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { 135 kern_return_t err; 136 host_basic_info_data_t hbi; 137 mach_msg_type_number_t cnt; 138 139 /* Get count of cpus */ 140 cnt = HOST_BASIC_INFO_COUNT; 141 err = host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t) &hbi, &cnt); 142 143 if (err) { 144 err = UV__ERR(err); 145 goto abort; 146 } 147 148 /* XXX not implemented on the Hurd */ 149 *cpu_infos = uv__calloc(hbi.avail_cpus, sizeof(**cpu_infos)); 150 if (*cpu_infos == NULL) { 151 err = UV_ENOMEM; 152 goto abort; 153 } 154 155 *count = hbi.avail_cpus; 156 157 return 0; 158 159 abort: 160 *cpu_infos = NULL; 161 *count = 0; 162 return err; 163} 164 165uint64_t uv_get_constrained_memory(void) { 166 return 0; /* Memory constraints are unknown. */ 167} 168