我正在尝试获取学校mac os的主机名。我不能在学校macs的手册页的第3部分中使用gethostname()
,而不是第2部分。是否有另一种获取主机名的方法,而不使用gethostname()
?我只允许在libc
中使用man 2 section
个功能。
答案 0 :(得分:-1)
gethostname
只是sysctl
,而sysctl
只是syscall
。
并且系统调用(根据定义)在手册的第2部分中。
抓住你最喜欢的反汇编程序(或otool -tV
,如果没有),nm
/usr/lib/system
中的库,找出哪些导出_gethostname
和{{1} },并开始工作(或查找源:P)。
下面我使用_sysctl
和gethostname
使用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_HOSTNAME
,KERN_PROCARGS
将需要一个额外的参数,即应该检索参数的进程ID。
在这种情况下,name
将如下所示:
name
并且int name[] = { CTL_KERN, KERN_PROCARGS, pid };
必须相应地设置为namelen
。
现在在上面的实现中,我已经使用了3
,你显然不允许这样做,但我相信你可以弄清楚如何重新实现{{1}并使用puts
系统调用。 ;)