如何在C中获取mac os的主机名

时间:2016-08-25 13:31:44

标签: c

我正在尝试获取学校mac os的主机名。我不能在学校macs的手册页的第3部分中使用gethostname(),而不是第2部分。是否有另一种获取主机名的方法,而不使用gethostname()?我只允许在libc中使用man 2 section个功能。

1 个答案:

答案 0 :(得分:-1)

gethostname只是sysctl,而sysctl只是syscall。 并且系统调用(根据定义)在手册的第2部分中。

抓住你最喜欢的反汇编程序(或otool -tV,如果没有),nm /usr/lib/system中的库,找出哪些导出_gethostname和{{1} },并开始工作(或查找源:P)。

下面我使用_sysctlgethostname使用sysctl重新实施sysctl

syscall

#include <sys/syscall.h> // SYS_sysctl #include <sys/sysctl.h> // CTL_KERN, KERN_HOSTNAME #include <unistd.h> // syscall int sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { return syscall(SYS_sysctl, name, namelen, oldp, oldlenp, newp, newlen); } int gethostname(char *buf, size_t buflen) { int name[] = { CTL_KERN, KERN_HOSTNAME }; size_t namelen = 2; return sysctl(name, namelen, buf, &buflen, NULL, 0); } int puts(const char *s) { // left as an exercise to the reader ;) } int main(void) { #define BUFSIZE 256 char buf[BUFSIZE]; size_t buflen = BUFSIZE; if(gethostname(buf, buflen) == 0) { puts(buf); } return 0; } 的实施并不复杂;你真的只是在其他参数前面拍了sysctl(来自SYS_sysctl)并将它们全部传递给sys/syscall.h

要了解syscall的实施情况,您必须了解gethostname的工作原理:

  • sysctl是查询值的存储位置。
  • oldp是从中读取新值的位置。由于我们未设置任何新值,因此此处为newp
  • NULL或多或少是name的实际参数列表,其内容取决于所查询的实际sysctl

    sysctl表示我们需要来自内核的东西 CTL_KERN表示我们要检索主机名 由于KERN_HOSTNAME没有提出任何论据,所以它就是全部。

    仅仅为了演示,如果您调用了KERN_HOSTNAMEKERN_PROCARGS将需要一个额外的参数,即应该检索参数的进程ID。
    在这种情况下,name将如下所示:

    name

    并且int name[] = { CTL_KERN, KERN_PROCARGS, pid }; 必须相应地设置为namelen

现在在上面的实现中,我已经使用了3,你显然不允许这样做,但我相信你可以弄清楚如何重新实现{{1}并使用puts系统调用。 ;)