2016-08-25 2 views
-2

내 학교 Mac OS의 호스트 이름을 가져 오려고합니다. gethostname()을 사용하지 않고 호스트 이름을 가져 오는 또 다른 방법이 있습니까? 아니요. gethostname()을 사용하지 않고 호스트 이름을 가져 오는 다른 방법이 있습니까? 나는 man 2 sectionlibc 함수 만 사용할 수 있습니다.C에서 Mac OS의 호스트 이름을 얻는 방법

+2

첫 번째 : http://linux.die.net/man/2/gethostname, 두 번째 : 맨 페이지의 어떤 부분이 중요합니까? – KevinDTimm

+1

매뉴얼 페이지의'gethostname()'에 문제가있는 이유는 무엇입니까? (BSD에서 파생 된 시스템에서 섹션 2는 시스템 호출만을 문서화하고 라이브러리 함수는 섹션 3에 있습니다). – dhke

+0

해결 방법 :'f = popen ("hostname")'f를 읽으십시오. –

답변

-1

gethostnamesysctl이고, sysctl은 단지 syscall입니다.
syscalls은 매뉴얼의 섹션 2에 (정의에 따라) 있습니다. (당신은 아무도가없는 경우 또는 otool -tV)

그래서 사람들은 _gethostname_sysctl을 수출하고 일하러 가야하는 알 (: P 또는 소스를 조회)하는 /usr/lib/system에, nm 라이브러리를 좋아하는 디스어셈블러를 잡아. 나는 아래

syscall를 사용하여 sysctl를 사용 gethostnamesysctl을 다시 구현 :

#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 (에서)을 치고 syscall에 모두 넘겨 줘야합니다.

gethostname의 구현을 이해하려면, 당신이 알고 얼마나 sysctl 작품 : 조회 된 값이 저장 될 위치를

  • oldp입니다.
  • newp은 새 값을 읽을 곳입니다. 새로운 값을 설정하지 않으므로 여기에 NULL입니다.
  • name은 실제로는 sysctl에 대한 인수 목록이며 그 내용은 실제로 sysctl이 쿼리되는지 여부에 달려 있습니다.

    CTL_KERN은 커널에서 원하는 것을 나타냅니다.
    KERN_HOSTNAME은 호스트 이름을 검색하고자 함을 나타냅니다.
    KERN_HOSTNAME이 (가) 인수를 취하지 않기 때문에 그게 전부입니다.

    데모 용으로 KERN_PROCARGS이라고 부른 경우 name에는 추가 인수, 즉 인수가 검색되어야하는 프로세스 ID가 필요합니다. 이 경우
    , name는 다음과 같이 보일 것이다 :

    int name[] = { CTL_KERN, KERN_PROCARGS, pid }; 
    

    namelen 이에 따라 3로 설정해야합니다.

지금 위의 구현에 당신이 분명히 할 수 없습니다있어 puts의 사용을했습니다,하지만 난 당신이 strlen를 다시 구현하는 방법을 알아낼 그와 함께 write 콜을 사용할 수 있습니다 신뢰 . ;)

+0

우리는 "할 일이 없다"사이트입니다. 힌트를주는 것은 충분해야합니다. 모든 코드를 게시하면 OP가 자신의 연구 또는 코딩 기술을 향상시키는 데 도움이되지 않습니다. – Olaf

관련 문제