Mercurial
comparison third_party/libuv/src/unix/ibmi.c @ 160:948de3f54cea
[ThirdParty] Added libuv
| author | June Park <parkjune1995@gmail.com> |
|---|---|
| date | Wed, 14 Jan 2026 19:39:52 -0800 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 159:05cf9467a1c3 | 160:948de3f54cea |
|---|---|
| 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 #include "uv.h" | |
| 23 #include "internal.h" | |
| 24 | |
| 25 #include <stdio.h> | |
| 26 #include <stdint.h> | |
| 27 #include <stdlib.h> | |
| 28 #include <string.h> | |
| 29 #include <errno.h> | |
| 30 | |
| 31 #include <sys/types.h> | |
| 32 #include <sys/socket.h> | |
| 33 #include <sys/ioctl.h> | |
| 34 #include <net/if.h> | |
| 35 #include <netinet/in.h> | |
| 36 #include <arpa/inet.h> | |
| 37 | |
| 38 #include <sys/time.h> | |
| 39 #include <unistd.h> | |
| 40 #include <fcntl.h> | |
| 41 #include <utmp.h> | |
| 42 #include <libgen.h> | |
| 43 | |
| 44 #include <sys/protosw.h> | |
| 45 #include <procinfo.h> | |
| 46 #include <sys/proc.h> | |
| 47 #include <sys/procfs.h> | |
| 48 | |
| 49 #include <ctype.h> | |
| 50 | |
| 51 #include <sys/mntctl.h> | |
| 52 #include <sys/vmount.h> | |
| 53 #include <limits.h> | |
| 54 #include <strings.h> | |
| 55 #include <sys/vnode.h> | |
| 56 | |
| 57 #include <as400_protos.h> | |
| 58 #include <as400_types.h> | |
| 59 | |
| 60 char* original_exepath = NULL; | |
| 61 uv_mutex_t process_title_mutex; | |
| 62 uv_once_t process_title_mutex_once = UV_ONCE_INIT; | |
| 63 | |
| 64 typedef struct { | |
| 65 int bytes_available; | |
| 66 int bytes_returned; | |
| 67 char current_date_and_time[8]; | |
| 68 char system_name[8]; | |
| 69 char elapsed_time[6]; | |
| 70 char restricted_state_flag; | |
| 71 char reserved; | |
| 72 int percent_processing_unit_used; | |
| 73 int jobs_in_system; | |
| 74 int percent_permanent_addresses; | |
| 75 int percent_temporary_addresses; | |
| 76 int system_asp; | |
| 77 int percent_system_asp_used; | |
| 78 int total_auxiliary_storage; | |
| 79 int current_unprotected_storage_used; | |
| 80 int maximum_unprotected_storage_used; | |
| 81 int percent_db_capability; | |
| 82 int main_storage_size; | |
| 83 int number_of_partitions; | |
| 84 int partition_identifier; | |
| 85 int reserved1; | |
| 86 int current_processing_capacity; | |
| 87 char processor_sharing_attribute; | |
| 88 char reserved2[3]; | |
| 89 int number_of_processors; | |
| 90 int active_jobs_in_system; | |
| 91 int active_threads_in_system; | |
| 92 int maximum_jobs_in_system; | |
| 93 int percent_temporary_256mb_segments_used; | |
| 94 int percent_temporary_4gb_segments_used; | |
| 95 int percent_permanent_256mb_segments_used; | |
| 96 int percent_permanent_4gb_segments_used; | |
| 97 int percent_current_interactive_performance; | |
| 98 int percent_uncapped_cpu_capacity_used; | |
| 99 int percent_shared_processor_pool_used; | |
| 100 long main_storage_size_long; | |
| 101 } SSTS0200; | |
| 102 | |
| 103 | |
| 104 typedef struct { | |
| 105 char header[208]; | |
| 106 unsigned char loca_adapter_address[12]; | |
| 107 } LIND0500; | |
| 108 | |
| 109 | |
| 110 typedef struct { | |
| 111 int bytes_provided; | |
| 112 int bytes_available; | |
| 113 char msgid[7]; | |
| 114 } errcode_s; | |
| 115 | |
| 116 | |
| 117 static const unsigned char e2a[256] = { | |
| 118 0, 1, 2, 3, 156, 9, 134, 127, 151, 141, 142, 11, 12, 13, 14, 15, | |
| 119 16, 17, 18, 19, 157, 133, 8, 135, 24, 25, 146, 143, 28, 29, 30, 31, | |
| 120 128, 129, 130, 131, 132, 10, 23, 27, 136, 137, 138, 139, 140, 5, 6, 7, | |
| 121 144, 145, 22, 147, 148, 149, 150, 4, 152, 153, 154, 155, 20, 21, 158, 26, | |
| 122 32, 160, 161, 162, 163, 164, 165, 166, 167, 168, 91, 46, 60, 40, 43, 33, | |
| 123 38, 169, 170, 171, 172, 173, 174, 175, 176, 177, 93, 36, 42, 41, 59, 94, | |
| 124 45, 47, 178, 179, 180, 181, 182, 183, 184, 185, 124, 44, 37, 95, 62, 63, | |
| 125 186, 187, 188, 189, 190, 191, 192, 193, 194, 96, 58, 35, 64, 39, 61, 34, | |
| 126 195, 97, 98, 99, 100, 101, 102, 103, 104, 105, 196, 197, 198, 199, 200, 201, | |
| 127 202, 106, 107, 108, 109, 110, 111, 112, 113, 114, 203, 204, 205, 206, 207, 208, | |
| 128 209, 126, 115, 116, 117, 118, 119, 120, 121, 122, 210, 211, 212, 213, 214, 215, | |
| 129 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, | |
| 130 123, 65, 66, 67, 68, 69, 70, 71, 72, 73, 232, 233, 234, 235, 236, 237, | |
| 131 125, 74, 75, 76, 77, 78, 79, 80, 81, 82, 238, 239, 240, 241, 242, 243, | |
| 132 92, 159, 83, 84, 85, 86, 87, 88, 89, 90, 244, 245, 246, 247, 248, 249, | |
| 133 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 250, 251, 252, 253, 254, 255}; | |
| 134 | |
| 135 | |
| 136 static const unsigned char a2e[256] = { | |
| 137 0, 1, 2, 3, 55, 45, 46, 47, 22, 5, 37, 11, 12, 13, 14, 15, | |
| 138 16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31, | |
| 139 64, 79, 127, 123, 91, 108, 80, 125, 77, 93, 92, 78, 107, 96, 75, 97, | |
| 140 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 122, 94, 76, 126, 110, 111, | |
| 141 124, 193, 194, 195, 196, 197, 198, 199, 200, 201, 209, 210, 211, 212, 213, 214, | |
| 142 215, 216, 217, 226, 227, 228, 229, 230, 231, 232, 233, 74, 224, 90, 95, 109, | |
| 143 121, 129, 130, 131, 132, 133, 134, 135, 136, 137, 145, 146, 147, 148, 149, 150, | |
| 144 151, 152, 153, 162, 163, 164, 165, 166, 167, 168, 169, 192, 106, 208, 161, 7, | |
| 145 32, 33, 34, 35, 36, 21, 6, 23, 40, 41, 42, 43, 44, 9, 10, 27, | |
| 146 48, 49, 26, 51, 52, 53, 54, 8, 56, 57, 58, 59, 4, 20, 62, 225, | |
| 147 65, 66, 67, 68, 69, 70, 71, 72, 73, 81, 82, 83, 84, 85, 86, 87, | |
| 148 88, 89, 98, 99, 100, 101, 102, 103, 104, 105, 112, 113, 114, 115, 116, 117, | |
| 149 118, 119, 120, 128, 138, 139, 140, 141, 142, 143, 144, 154, 155, 156, 157, 158, | |
| 150 159, 160, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, | |
| 151 184, 185, 186, 187, 188, 189, 190, 191, 202, 203, 204, 205, 206, 207, 218, 219, | |
| 152 220, 221, 222, 223, 234, 235, 236, 237, 238, 239, 250, 251, 252, 253, 254, 255}; | |
| 153 | |
| 154 | |
| 155 static void iconv_e2a(unsigned char src[], unsigned char dst[], size_t length) { | |
| 156 size_t i; | |
| 157 for (i = 0; i < length; i++) | |
| 158 dst[i] = e2a[src[i]]; | |
| 159 } | |
| 160 | |
| 161 | |
| 162 static void iconv_a2e(const char* src, unsigned char dst[], size_t length) { | |
| 163 size_t srclen; | |
| 164 size_t i; | |
| 165 | |
| 166 srclen = strlen(src); | |
| 167 if (srclen > length) | |
| 168 srclen = length; | |
| 169 for (i = 0; i < srclen; i++) | |
| 170 dst[i] = a2e[src[i]]; | |
| 171 /* padding the remaining part with spaces */ | |
| 172 for (; i < length; i++) | |
| 173 dst[i] = a2e[' ']; | |
| 174 } | |
| 175 | |
| 176 void init_process_title_mutex_once(void) { | |
| 177 uv_mutex_init(&process_title_mutex); | |
| 178 } | |
| 179 | |
| 180 static int get_ibmi_system_status(SSTS0200* rcvr) { | |
| 181 /* rcvrlen is input parameter 2 to QWCRSSTS */ | |
| 182 unsigned int rcvrlen = sizeof(*rcvr); | |
| 183 unsigned char format[8], reset_status[10]; | |
| 184 | |
| 185 /* format is input parameter 3 to QWCRSSTS */ | |
| 186 iconv_a2e("SSTS0200", format, sizeof(format)); | |
| 187 /* reset_status is input parameter 4 */ | |
| 188 iconv_a2e("*NO", reset_status, sizeof(reset_status)); | |
| 189 | |
| 190 /* errcode is input parameter 5 to QWCRSSTS */ | |
| 191 errcode_s errcode; | |
| 192 | |
| 193 /* qwcrssts_pointer is the 16-byte tagged system pointer to QWCRSSTS */ | |
| 194 ILEpointer __attribute__((aligned(16))) qwcrssts_pointer; | |
| 195 | |
| 196 /* qwcrssts_argv is the array of argument pointers to QWCRSSTS */ | |
| 197 void* qwcrssts_argv[6]; | |
| 198 | |
| 199 /* Set the IBM i pointer to the QSYS/QWCRSSTS *PGM object */ | |
| 200 int rc = _RSLOBJ2(&qwcrssts_pointer, RSLOBJ_TS_PGM, "QWCRSSTS", "QSYS"); | |
| 201 | |
| 202 if (rc != 0) | |
| 203 return rc; | |
| 204 | |
| 205 /* initialize the QWCRSSTS returned info structure */ | |
| 206 memset(rcvr, 0, sizeof(*rcvr)); | |
| 207 | |
| 208 /* initialize the QWCRSSTS error code structure */ | |
| 209 memset(&errcode, 0, sizeof(errcode)); | |
| 210 errcode.bytes_provided = sizeof(errcode); | |
| 211 | |
| 212 /* initialize the array of argument pointers for the QWCRSSTS API */ | |
| 213 qwcrssts_argv[0] = rcvr; | |
| 214 qwcrssts_argv[1] = &rcvrlen; | |
| 215 qwcrssts_argv[2] = &format; | |
| 216 qwcrssts_argv[3] = &reset_status; | |
| 217 qwcrssts_argv[4] = &errcode; | |
| 218 qwcrssts_argv[5] = NULL; | |
| 219 | |
| 220 /* Call the IBM i QWCRSSTS API from PASE */ | |
| 221 rc = _PGMCALL(&qwcrssts_pointer, qwcrssts_argv, 0); | |
| 222 | |
| 223 return rc; | |
| 224 } | |
| 225 | |
| 226 | |
| 227 uint64_t uv_get_free_memory(void) { | |
| 228 SSTS0200 rcvr; | |
| 229 | |
| 230 if (get_ibmi_system_status(&rcvr)) | |
| 231 return 0; | |
| 232 | |
| 233 return (uint64_t)rcvr.main_storage_size * 1024ULL; | |
| 234 } | |
| 235 | |
| 236 | |
| 237 uint64_t uv_get_total_memory(void) { | |
| 238 SSTS0200 rcvr; | |
| 239 | |
| 240 if (get_ibmi_system_status(&rcvr)) | |
| 241 return 0; | |
| 242 | |
| 243 return (uint64_t)rcvr.main_storage_size * 1024ULL; | |
| 244 } | |
| 245 | |
| 246 | |
| 247 uint64_t uv_get_constrained_memory(void) { | |
| 248 return 0; /* Memory constraints are unknown. */ | |
| 249 } | |
| 250 | |
| 251 | |
| 252 uint64_t uv_get_available_memory(void) { | |
| 253 return uv_get_free_memory(); | |
| 254 } | |
| 255 | |
| 256 | |
| 257 void uv_loadavg(double avg[3]) { | |
| 258 SSTS0200 rcvr; | |
| 259 | |
| 260 if (get_ibmi_system_status(&rcvr)) { | |
| 261 avg[0] = avg[1] = avg[2] = 0; | |
| 262 return; | |
| 263 } | |
| 264 | |
| 265 /* The average (in tenths) of the elapsed time during which the processing | |
| 266 * units were in use. For example, a value of 411 in binary would be 41.1%. | |
| 267 * This percentage could be greater than 100% for an uncapped partition. | |
| 268 */ | |
| 269 double processing_unit_used_percent = | |
| 270 rcvr.percent_processing_unit_used / 1000.0; | |
| 271 | |
| 272 avg[0] = avg[1] = avg[2] = processing_unit_used_percent; | |
| 273 } | |
| 274 | |
| 275 | |
| 276 int uv_resident_set_memory(size_t* rss) { | |
| 277 *rss = 0; | |
| 278 return 0; | |
| 279 } | |
| 280 | |
| 281 | |
| 282 int uv_uptime(double* uptime) { | |
| 283 return UV_ENOSYS; | |
| 284 } | |
| 285 | |
| 286 | |
| 287 int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { | |
| 288 unsigned int numcpus, idx = 0; | |
| 289 uv_cpu_info_t* cpu_info; | |
| 290 | |
| 291 *cpu_infos = NULL; | |
| 292 *count = 0; | |
| 293 | |
| 294 numcpus = sysconf(_SC_NPROCESSORS_ONLN); | |
| 295 | |
| 296 *cpu_infos = uv__malloc(numcpus * sizeof(uv_cpu_info_t)); | |
| 297 if (!*cpu_infos) { | |
| 298 return UV_ENOMEM; | |
| 299 } | |
| 300 | |
| 301 cpu_info = *cpu_infos; | |
| 302 for (idx = 0; idx < numcpus; idx++) { | |
| 303 cpu_info->speed = 0; | |
| 304 cpu_info->model = uv__strdup("unknown"); | |
| 305 cpu_info->cpu_times.user = 0; | |
| 306 cpu_info->cpu_times.sys = 0; | |
| 307 cpu_info->cpu_times.idle = 0; | |
| 308 cpu_info->cpu_times.irq = 0; | |
| 309 cpu_info->cpu_times.nice = 0; | |
| 310 cpu_info++; | |
| 311 } | |
| 312 *count = numcpus; | |
| 313 | |
| 314 return 0; | |
| 315 } | |
| 316 | |
| 317 | |
| 318 static int get_ibmi_physical_address(const char* line, char (*phys_addr)[6]) { | |
| 319 LIND0500 rcvr; | |
| 320 /* rcvrlen is input parameter 2 to QDCRLIND */ | |
| 321 unsigned int rcvrlen = sizeof(rcvr); | |
| 322 unsigned char format[8], line_name[10]; | |
| 323 unsigned char mac_addr[sizeof(rcvr.loca_adapter_address)]; | |
| 324 int c[6]; | |
| 325 | |
| 326 /* format is input parameter 3 to QDCRLIND */ | |
| 327 iconv_a2e("LIND0500", format, sizeof(format)); | |
| 328 | |
| 329 /* line_name is input parameter 4 to QDCRLIND */ | |
| 330 iconv_a2e(line, line_name, sizeof(line_name)); | |
| 331 | |
| 332 /* err is input parameter 5 to QDCRLIND */ | |
| 333 errcode_s err; | |
| 334 | |
| 335 /* qwcrssts_pointer is the 16-byte tagged system pointer to QDCRLIND */ | |
| 336 ILEpointer __attribute__((aligned(16))) qdcrlind_pointer; | |
| 337 | |
| 338 /* qwcrssts_argv is the array of argument pointers to QDCRLIND */ | |
| 339 void* qdcrlind_argv[6]; | |
| 340 | |
| 341 /* Set the IBM i pointer to the QSYS/QDCRLIND *PGM object */ | |
| 342 int rc = _RSLOBJ2(&qdcrlind_pointer, RSLOBJ_TS_PGM, "QDCRLIND", "QSYS"); | |
| 343 | |
| 344 if (rc != 0) | |
| 345 return rc; | |
| 346 | |
| 347 /* initialize the QDCRLIND returned info structure */ | |
| 348 memset(&rcvr, 0, sizeof(rcvr)); | |
| 349 | |
| 350 /* initialize the QDCRLIND error code structure */ | |
| 351 memset(&err, 0, sizeof(err)); | |
| 352 err.bytes_provided = sizeof(err); | |
| 353 | |
| 354 /* initialize the array of argument pointers for the QDCRLIND API */ | |
| 355 qdcrlind_argv[0] = &rcvr; | |
| 356 qdcrlind_argv[1] = &rcvrlen; | |
| 357 qdcrlind_argv[2] = &format; | |
| 358 qdcrlind_argv[3] = &line_name; | |
| 359 qdcrlind_argv[4] = &err; | |
| 360 qdcrlind_argv[5] = NULL; | |
| 361 | |
| 362 /* Call the IBM i QDCRLIND API from PASE */ | |
| 363 rc = _PGMCALL(&qdcrlind_pointer, qdcrlind_argv, 0); | |
| 364 if (rc != 0) | |
| 365 return rc; | |
| 366 | |
| 367 if (err.bytes_available > 0) { | |
| 368 return -1; | |
| 369 } | |
| 370 | |
| 371 /* convert ebcdic loca_adapter_address to ascii first */ | |
| 372 iconv_e2a(rcvr.loca_adapter_address, mac_addr, | |
| 373 sizeof(rcvr.loca_adapter_address)); | |
| 374 | |
| 375 /* convert loca_adapter_address(char[12]) to phys_addr(char[6]) */ | |
| 376 int r = sscanf(mac_addr, "%02x%02x%02x%02x%02x%02x", | |
| 377 &c[0], &c[1], &c[2], &c[3], &c[4], &c[5]); | |
| 378 | |
| 379 if (r == ARRAY_SIZE(c)) { | |
| 380 (*phys_addr)[0] = c[0]; | |
| 381 (*phys_addr)[1] = c[1]; | |
| 382 (*phys_addr)[2] = c[2]; | |
| 383 (*phys_addr)[3] = c[3]; | |
| 384 (*phys_addr)[4] = c[4]; | |
| 385 (*phys_addr)[5] = c[5]; | |
| 386 } else { | |
| 387 memset(*phys_addr, 0, sizeof(*phys_addr)); | |
| 388 rc = -1; | |
| 389 } | |
| 390 return rc; | |
| 391 } | |
| 392 | |
| 393 | |
| 394 int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { | |
| 395 uv_interface_address_t* address; | |
| 396 struct ifaddrs_pase *ifap = NULL, *cur; | |
| 397 size_t namelen; | |
| 398 char* name; | |
| 399 int inet6, r = 0; | |
| 400 | |
| 401 *count = 0; | |
| 402 *addresses = NULL; | |
| 403 | |
| 404 if (Qp2getifaddrs(&ifap)) | |
| 405 return UV_ENOSYS; | |
| 406 | |
| 407 /* The first loop to get the size of the array to be allocated */ | |
| 408 namelen = 0; | |
| 409 for (cur = ifap; cur; cur = cur->ifa_next) { | |
| 410 if (!(cur->ifa_addr->sa_family == AF_INET6 || | |
| 411 cur->ifa_addr->sa_family == AF_INET)) | |
| 412 continue; | |
| 413 | |
| 414 if (!(cur->ifa_flags & IFF_UP && cur->ifa_flags & IFF_RUNNING)) | |
| 415 continue; | |
| 416 | |
| 417 namelen += strlen(cur->ifa_name) + 1; | |
| 418 (*count)++; | |
| 419 } | |
| 420 | |
| 421 if (*count == 0) { | |
| 422 Qp2freeifaddrs(ifap); | |
| 423 return 0; | |
| 424 } | |
| 425 | |
| 426 /* Alloc the return interface structs */ | |
| 427 *addresses = uv__calloc(1, *count * sizeof(**addresses) + namelen); | |
| 428 if (*addresses == NULL) { | |
| 429 Qp2freeifaddrs(ifap); | |
| 430 return UV_ENOMEM; | |
| 431 } | |
| 432 | |
| 433 name = (char*) &(*addresses)[*count]; | |
| 434 address = *addresses; | |
| 435 | |
| 436 /* The second loop to fill in the array */ | |
| 437 for (cur = ifap; cur; cur = cur->ifa_next) { | |
| 438 if (!(cur->ifa_addr->sa_family == AF_INET6 || | |
| 439 cur->ifa_addr->sa_family == AF_INET)) | |
| 440 continue; | |
| 441 | |
| 442 if (!(cur->ifa_flags & IFF_UP && cur->ifa_flags & IFF_RUNNING)) | |
| 443 continue; | |
| 444 | |
| 445 namelen = strlen(cur->ifa_name) + 1; | |
| 446 address->name = memcpy(name, cur->ifa_name, namelen); | |
| 447 name += namelen; | |
| 448 | |
| 449 inet6 = (cur->ifa_addr->sa_family == AF_INET6); | |
| 450 | |
| 451 if (inet6) { | |
| 452 address->address.address6 = *((struct sockaddr_in6*)cur->ifa_addr); | |
| 453 address->netmask.netmask6 = *((struct sockaddr_in6*)cur->ifa_netmask); | |
| 454 address->netmask.netmask6.sin6_family = AF_INET6; | |
| 455 } else { | |
| 456 address->address.address4 = *((struct sockaddr_in*)cur->ifa_addr); | |
| 457 address->netmask.netmask4 = *((struct sockaddr_in*)cur->ifa_netmask); | |
| 458 address->netmask.netmask4.sin_family = AF_INET; | |
| 459 } | |
| 460 address->is_internal = cur->ifa_flags & IFF_LOOPBACK ? 1 : 0; | |
| 461 if (!address->is_internal) { | |
| 462 int rc = -1; | |
| 463 size_t name_len = strlen(address->name); | |
| 464 /* To get the associated MAC address, we must convert the address to a | |
| 465 * line description. Normally, the name field contains the line | |
| 466 * description name, but for VLANs it has the VLAN appended with a | |
| 467 * period. Since object names can also contain periods and numbers, there | |
| 468 * is no way to know if a returned name is for a VLAN or not. eg. | |
| 469 * *LIND ETH1.1 and *LIND ETH1, VLAN 1 both have the same name: ETH1.1 | |
| 470 * | |
| 471 * Instead, we apply the same heuristic used by some of the XPF ioctls: | |
| 472 * - names > 10 *must* contain a VLAN | |
| 473 * - assume names <= 10 do not contain a VLAN and try directly | |
| 474 * - if >10 or QDCRLIND returned an error, try to strip off a VLAN | |
| 475 * and try again | |
| 476 * - if we still get an error or couldn't find a period, leave the MAC as | |
| 477 * 00:00:00:00:00:00 | |
| 478 */ | |
| 479 if (name_len <= 10) { | |
| 480 /* Assume name does not contain a VLAN ID */ | |
| 481 rc = get_ibmi_physical_address(address->name, &address->phys_addr); | |
| 482 } | |
| 483 | |
| 484 if (name_len > 10 || rc != 0) { | |
| 485 /* The interface name must contain a VLAN ID suffix. Attempt to strip | |
| 486 * it off so we can get the line description to pass to QDCRLIND. | |
| 487 */ | |
| 488 char* temp_name = uv__strdup(address->name); | |
| 489 char* dot = strrchr(temp_name, '.'); | |
| 490 if (dot != NULL) { | |
| 491 *dot = '\0'; | |
| 492 if (strlen(temp_name) <= 10) { | |
| 493 rc = get_ibmi_physical_address(temp_name, &address->phys_addr); | |
| 494 } | |
| 495 } | |
| 496 uv__free(temp_name); | |
| 497 } | |
| 498 } | |
| 499 | |
| 500 address++; | |
| 501 } | |
| 502 | |
| 503 Qp2freeifaddrs(ifap); | |
| 504 return r; | |
| 505 } | |
| 506 | |
| 507 | |
| 508 void uv_free_interface_addresses(uv_interface_address_t* addresses, | |
| 509 int count) { | |
| 510 uv__free(addresses); | |
| 511 } | |
| 512 | |
| 513 char** uv_setup_args(int argc, char** argv) { | |
| 514 char exepath[UV__PATH_MAX]; | |
| 515 char* s; | |
| 516 size_t size; | |
| 517 | |
| 518 if (argc > 0) { | |
| 519 /* Use argv[0] to determine value for uv_exepath(). */ | |
| 520 size = sizeof(exepath); | |
| 521 if (uv__search_path(argv[0], exepath, &size) == 0) { | |
| 522 uv_once(&process_title_mutex_once, init_process_title_mutex_once); | |
| 523 uv_mutex_lock(&process_title_mutex); | |
| 524 original_exepath = uv__strdup(exepath); | |
| 525 uv_mutex_unlock(&process_title_mutex); | |
| 526 } | |
| 527 } | |
| 528 | |
| 529 return argv; | |
| 530 } | |
| 531 | |
| 532 int uv_set_process_title(const char* title) { | |
| 533 return 0; | |
| 534 } | |
| 535 | |
| 536 int uv_get_process_title(char* buffer, size_t size) { | |
| 537 if (buffer == NULL || size == 0) | |
| 538 return UV_EINVAL; | |
| 539 | |
| 540 buffer[0] = '\0'; | |
| 541 return 0; | |
| 542 } | |
| 543 | |
| 544 void uv__process_title_cleanup(void) { | |
| 545 } |