this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Implement several sysctls to make the sysctl command working at least a bit

+351 -8
+1
src/kernel/emulation/linux/CMakeLists.txt
··· 183 183 ioctl/ioctl.c 184 184 ioctl/termios.c 185 185 ioctl/filio.c 186 + ext/sysinfo.c 186 187 ext/uname.c 187 188 ext/epoll_create.c 188 189 ext/epoll_create1.c
+19
src/kernel/emulation/linux/ext/sysinfo.c
··· 1 + #include "sysinfo.h" 2 + #include "../errno.h" 3 + #include "../base.h" 4 + #include <linux-syscalls/linux.h> 5 + 6 + int __linux_sysinfo(struct sysinfo* info) 7 + { 8 + int rv; 9 + 10 + rv = LINUX_SYSCALL(__NR_sysinfo, info); 11 + if (rv < 0) 12 + { 13 + cerror(errno_linux_to_bsd(-rv)); 14 + return -1; 15 + } 16 + 17 + return rv; 18 + } 19 +
+24
src/kernel/emulation/linux/ext/sysinfo.h
··· 1 + #ifndef _SYSINFO_H 2 + #define _SYSINFO_H 3 + 4 + struct sysinfo 5 + { 6 + long uptime; 7 + unsigned long loads[3]; 8 + unsigned long totalram; 9 + unsigned long freeram; 10 + unsigned long sharedram; 11 + unsigned long bufferram; 12 + unsigned long totalswap; 13 + unsigned long freeswap; 14 + unsigned short procs; 15 + unsigned long totalhigh; 16 + unsigned long freehigh; 17 + unsigned int mem_unit; 18 + char _f[20-2*sizeof(long)-sizeof(int)]; 19 + }; 20 + 21 + int __linux_sysinfo(struct sysinfo* info); 22 + 23 + #endif 24 +
+307 -8
src/kernel/emulation/linux/misc/sysctl.c
··· 11 11 #include <stddef.h> 12 12 #include <limits.h> 13 13 #include "../ext/sys/utsname.h" 14 + #include "../ext/sysinfo.h" 14 15 #include "../ext/syslog.h" 16 + #include "../time/gettimeofday.h" 15 17 #include "getrlimit.h" 16 18 #include "darling-config.h" 19 + 20 + // TODO: This file needs a rework to eliminate all the switch()es 21 + // and replace them with lookup tables. 17 22 18 23 static long sysctl_name_to_oid(const char* name, int* oid_name, 19 24 unsigned long* oid_len); 25 + static long sysctl_get_type(const int* oid, int nlen, int* out, unsigned long* outlen); 26 + static long sysctl_oid_to_name(const int* oid, int nlen, char* name, unsigned long* outlen); 20 27 21 28 extern char *strchr(const char *s, int c); 22 29 extern int strncmp(const char *s1, const char *s2, __SIZE_TYPE__ n); ··· 27 34 struct kinfo_proc; 28 35 extern int _sysctl_proc(int what, int flag, struct kinfo_proc* out, unsigned long* buflen); 29 36 extern int _sysctl_procargs(int pid, char* buf, unsigned long* buflen); 37 + static void get_cpu_brand(char* brand); 38 + 39 + extern int cerror(int err); 30 40 31 41 /* Darling specific */ 32 42 enum { ··· 38 48 _HW_CPUSUBTYPE, 39 49 _HW_CPUTHREADTYPE 40 50 }; 51 + 52 + enum { 53 + _CPU_BRAND_STRING = 1000, 54 + }; 41 55 enum { 42 56 _KERN_MSGBUF = 1000, 43 57 }; 44 58 59 + enum { 60 + CTLTYPE_NODE = 1, 61 + CTLTYPE_INT, 62 + CTLTYPE_STRING, 63 + CTLTYPE_QUAD, 64 + CTLTYPE_OPAQUE, 65 + CTLTYPE_STRUCT = CTLTYPE_OPAQUE, 66 + }; 67 + 45 68 static struct linux_utsname lu; 46 69 static void copyout_string(const char* str, char* out, unsigned long* out_len); 47 70 static void need_uname(void); ··· 54 77 if (nlen < 2) 55 78 return -EINVAL; 56 79 57 - if (name[0] == 0 && name[1] == 3) 80 + // __simple_printf("sysctl %d,%d\n", name[0], name[1]); 81 + if (name[0] == CTL_UNSPEC) 58 82 { 59 - return sysctl_name_to_oid((const char*) _new, (int*) old, oldlen); 83 + switch (name[1]) 84 + { 85 + case 1: // oid to name 86 + return sysctl_oid_to_name(name + 2, nlen - 2, (char*) old, oldlen); 87 + case 3: // name to oid 88 + return sysctl_name_to_oid((const char*) _new, (int*) old, oldlen); 89 + case 4: // get data type 90 + return sysctl_get_type(name + 2, nlen - 2, (int*) old, oldlen); 91 + } 60 92 } 61 - 62 - if (name[0] == CTL_HW) 93 + else if (name[0] == CTL_HW) 63 94 { 64 95 int* ovalue = (int*) old; 65 96 struct host_basic_info hinfo; ··· 191 222 if (r < 0) 192 223 return r; 193 224 194 - *ovalue = lim.rlim_cur / 4; 225 + if (ovalue != NULL) 226 + *ovalue = lim.rlim_cur / 4; 227 + *oldlen = sizeof(int); 228 + return 0; 229 + } 230 + case KERN_BOOTTIME: 231 + { 232 + // Fill in struct timeval { tv_sec, tv_usec } 233 + struct sysinfo info; 234 + struct bsd_timeval* tv; 235 + 236 + if (__linux_sysinfo(&info) == -1) 237 + return -errno; 238 + 239 + tv = (struct bsd_timeval*) old; 240 + if (tv != NULL) 241 + { 242 + if (*oldlen < sizeof(*tv)) 243 + return -EINVAL; 244 + sys_gettimeofday(tv, NULL); 245 + 246 + tv->tv_sec -= info.uptime; 247 + } 248 + *oldlen = sizeof(*tv); 249 + 195 250 return 0; 196 251 } 197 252 } ··· 230 285 return 0; 231 286 } 232 287 } 288 + else if (name[0] == CTL_MACHDEP) 289 + { 290 + switch (name[1]) 291 + { 292 + case _CPU_BRAND_STRING: 293 + { 294 + char brand[13]; 295 + get_cpu_brand(brand); 296 + copyout_string(brand, (char*) old, oldlen); 297 + return 0; 298 + } 299 + } 300 + } 233 301 234 302 return -ENOTDIR; 235 303 } ··· 249 317 static void copyout_string(const char* str, char* out, unsigned long* out_len) 250 318 { 251 319 unsigned long len; 252 - len = strlcpy(out, str, *out_len); 320 + if (out != NULL) 321 + len = strlcpy(out, str, *out_len); 322 + else 323 + len = strlen(str); 253 324 254 - if (len < *out_len) 255 - *out_len = len; 325 + *out_len = len; 256 326 } 257 327 258 328 static long sysctl_name_to_oid(const char* name, int* oid_name, ··· 309 379 310 380 if (strcmp(dot+1, "msgbuf") == 0) 311 381 oid_name[1] = _KERN_MSGBUF; 382 + else if (strcmp(dot+1, "boottime") == 0) 383 + oid_name[1] = KERN_BOOTTIME; 312 384 else 313 385 return -ENOTDIR; 314 386 387 + return 0; 388 + } 389 + else if (strncmp(name, "machdep", cat_len) == 0) 390 + { 391 + oid_name[0] = CTL_MACHDEP; 392 + *oid_len = 2 * sizeof(int); 393 + 394 + if (strcmp(dot+1, "cpu.brand_string") == 0) 395 + oid_name[1] = _CPU_BRAND_STRING; 396 + else 397 + return -ENOTDIR; 315 398 return 0; 316 399 } 317 400 ··· 332 415 return sys_sysctl(oid, oid_len, old, oldlen, _new, newlen); 333 416 } 334 417 418 + #define settype(first, str) \ 419 + if (*outlen < sizeof(int) + sizeof(str)) \ 420 + return -EINVAL; \ 421 + out[0] = first; \ 422 + strcpy((char*) &out[1], str); \ 423 + *outlen = sizeof(int) + sizeof(str); 424 + 425 + static long sysctl_get_type(const int* oid, int nlen, int* out, unsigned long* outlen) 426 + { 427 + switch (oid[0]) 428 + { 429 + case CTL_HW: 430 + if (nlen < 2) 431 + { 432 + settype(CTLTYPE_NODE, ""); 433 + return 0; 434 + } 435 + 436 + switch (oid[1]) 437 + { 438 + case HW_AVAILCPU: 439 + case HW_NCPU: 440 + case _HW_PHYSICAL_CPU: 441 + case _HW_PHYSICAL_CPU_MAX: 442 + case _HW_LOGICAL_CPU: 443 + case _HW_LOGICAL_CPU_MAX: 444 + case HW_PAGESIZE: 445 + case _HW_CPUTYPE: 446 + case _HW_CPUSUBTYPE: 447 + case _HW_CPUTHREADTYPE: 448 + settype(CTLTYPE_INT, "I"); 449 + return 0; 450 + case HW_MEMSIZE: 451 + case HW_PHYSMEM: 452 + case HW_USERMEM: 453 + settype(CTLTYPE_QUAD, "QU"); 454 + return 0; 455 + } 456 + break; 457 + case CTL_KERN: 458 + if (nlen < 2) 459 + { 460 + settype(CTLTYPE_NODE, ""); 461 + return 0; 462 + } 463 + 464 + switch (oid[1]) 465 + { 466 + case _KERN_MSGBUF: 467 + case KERN_PROCARGS2: 468 + case KERN_OSTYPE: 469 + case KERN_HOSTNAME: 470 + case KERN_OSRELEASE: 471 + case KERN_VERSION: 472 + case KERN_DOMAINNAME: 473 + settype(CTLTYPE_STRING, ""); 474 + return 0; 475 + case KERN_PROC: 476 + settype(CTLTYPE_STRUCT, ""); 477 + return 0; 478 + case KERN_BOOTTIME: 479 + { 480 + settype(CTLTYPE_STRUCT, "S,timeval"); 481 + return 0; 482 + } 483 + case KERN_ARGMAX: 484 + settype(CTLTYPE_INT, "L"); 485 + return 0; 486 + } 487 + break; 488 + case CTL_MACHDEP: 489 + if (nlen < 2) 490 + { 491 + settype(CTLTYPE_NODE, ""); 492 + return 0; 493 + } 494 + 495 + switch (oid[1]) 496 + { 497 + case _CPU_BRAND_STRING: 498 + settype(CTLTYPE_STRING, ""); 499 + return 0; 500 + } 501 + } 502 + return -ENOENT; 503 + } 504 + 505 + #define outstring(str) \ 506 + strncpy(name, str, *outlen - 1); \ 507 + name[*outlen - 1] = '\0'; \ 508 + if (*outlen > sizeof(str)-1) \ 509 + *outlen = sizeof(str)-1; 510 + 511 + static long sysctl_oid_to_name(const int* oid, int nlen, char* name, unsigned long* outlen) 512 + { 513 + if (nlen == 1) 514 + { 515 + switch (oid[0]) 516 + { 517 + case CTL_HW: 518 + outstring("hw"); 519 + return 0; 520 + case CTL_KERN: 521 + outstring("kern"); 522 + return 0; 523 + } 524 + } 525 + else if (nlen == 2) 526 + { 527 + switch (oid[0]) 528 + { 529 + case CTL_HW: 530 + switch (oid[1]) 531 + { 532 + case HW_AVAILCPU: 533 + outstring("hw.activecpu"); 534 + return 0; 535 + case HW_NCPU: 536 + outstring("hw.ncpu"); 537 + return 0; 538 + case _HW_PHYSICAL_CPU: 539 + outstring("hw.physicalcpu"); 540 + return 0; 541 + case _HW_PHYSICAL_CPU_MAX: 542 + outstring("hw.physicalcpu_max"); 543 + return 0; 544 + case _HW_LOGICAL_CPU: 545 + outstring("hw.logicalcpu"); 546 + return 0; 547 + case _HW_LOGICAL_CPU_MAX: 548 + outstring("hw.logicalcpu_max"); 549 + return 0; 550 + case HW_MEMSIZE: 551 + outstring("hw.memsize"); 552 + return 0; 553 + case HW_PAGESIZE: 554 + outstring("hw.pagesize"); 555 + return 0; 556 + case _HW_CPUTYPE: 557 + outstring("hw.cputype"); 558 + return 0; 559 + case _HW_CPUSUBTYPE: 560 + outstring("hw.cpusubtype"); 561 + return 0; 562 + case _HW_CPUTHREADTYPE: 563 + outstring("hw.cputhreadtype"); 564 + return 0; 565 + } 566 + break; 567 + case CTL_KERN: 568 + switch (oid[1]) 569 + { 570 + case _KERN_MSGBUF: 571 + outstring("kern.msgbuf"); 572 + return 0; 573 + case KERN_BOOTTIME: 574 + outstring("kern.boottime"); 575 + return 0; 576 + case KERN_OSTYPE: 577 + outstring("kern.ostype"); 578 + return 0; 579 + case KERN_VERSION: 580 + outstring("kern.version"); 581 + return 0; 582 + case KERN_OSRELEASE: 583 + outstring("kern.osrelease"); 584 + return 0; 585 + case KERN_HOSTNAME: 586 + outstring("kern.hostname"); 587 + return 0; 588 + case KERN_DOMAINNAME: 589 + outstring("kern.domainname"); 590 + return 0; 591 + } 592 + break; 593 + case CTL_MACHDEP: 594 + switch (oid[1]) 595 + { 596 + case _CPU_BRAND_STRING: 597 + outstring("machdep.cpu.brand_string"); 598 + return 0; 599 + } 600 + } 601 + } 602 + 603 + return -ENOENT; 604 + } 605 + 606 + #ifndef __cpuid 607 + #define __cpuid(level, a, b, c, d) \ 608 + __asm__ ("cpuid\n\t" \ 609 + : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ 610 + : "0" (level)) 611 + #endif 612 + 613 + void get_cpu_brand(char* brand) 614 + { 615 + unsigned int level = 0; 616 + unsigned int eax = 0; 617 + union 618 + { 619 + struct 620 + { 621 + unsigned int ebx; 622 + unsigned int edx; 623 + unsigned int ecx; 624 + }; 625 + char name[12]; 626 + } v; 627 + 628 + __cpuid(level, eax, v.ebx, v.ecx, v.edx); 629 + 630 + strncpy(brand, v.name, 12); 631 + brand[12] = 0; 632 + } 633 +