gethostbyname() 함수

 

도메인(문자열) 정보로 ip, 별칭 등 host에 대한 정보를 구하는 함수.

 

#include <netdb.h>

struct hostent *gethostbyname(const char *name);

 

서버 이름 또는 도메인(예. www.it-note.kr)으로부터 주소정보(IP Address)를 얻습니다. 주소 정보는 local computer의 /etc/hosts 파일 또는 DNS 서버로 부터 주소 정보를 얻습니다.

 

 

struct hostent 구조체

struct hostent {
    char  *h_name;            /* official name of host */
    char **h_aliases;         /* alias list */
    int    h_addrtype;        /* host address type : AF_INET 또는 AF_INET6 */
    int    h_length;          /* length of address */
    char **h_addr_list;       /* list of addresses */
}

#define h_addr h_addr_list[0] /* for backward compatibility */ 

 

파라미터

name
    - IP 주소를 얻으려는 서버 이름 또는 서버에 대한 도메인명

 

RETURN

NULL
    - 오류가 발생하였습니다.

NULL 아님
    - struct hostent *를 return하며, 주소는 h_addr 멤버 변수에 저장되며, 
      그 주소의 길이는 h_length에 저장됩니다.
    - h_addr의 format은 network byte order의 주소이며, 
      인터넷 표준 점표기법으로 표시하려면 inet_ntoa( )로 변환이  필요합니다.

 


활용 예제

 

Sample

#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#define SERVER_PORT   6905
#define SERVER_NAME   "www.it-note.kr"

......

int main(int argc, char **argv)
{
    struct hostent *he;
    struct sockaddr_in server_addr;
    int  sock;

    ......

    if((he = gethostbyname(SERVER_NAME)) == NULL) {
        fprintf(stderr, "%s는 등록되지 않은 서버명입니다.\n", SERVER_NAME);
        return -1;
    }

    memset(&server_addr, 0x00, sizeof(struct sockaddr_in));
    server_addr.sin_samily = AF_INET;
    memcpy(server_addr.sin.sin_addr, he->h_addr, he->h_length);
    server_addr.sin_port   = htons(SERVER_PORT);

    if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        fprintf(stderr, "Socket 생성 오류: %s\n", strerror(errno));
        return -1;
    }

    if(connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in)) == -1) {
        fprintf(stderr, "Connection Error: %s\n", strerror(errno));
        close(sock);
        return -1;
    }

    ......
}

 

 

참고 :
https://www.it-note.kr/22

setresuid( )함수 setresgid( )함수

 

setresuid( )함수 : 각각의 인자가 real UID, effective UID, saved set-user-ID를 변경함

setresgid( )함수 : 각각의 인자가 real GID, effective GID, saved set-group-ID를 변경함

 

setresuid/setresgid : SET R(eal), E(ffective), S(aved) UID/GID
: 현재 동작 중인 프로세스의 권한을 변경한다.

 

예제

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>

int main(int argc, char **argv, char **envp)
{
	gid_t gid;
	uid_t uid;
	gid = getegid();
	uid = geteuid();
	
	setresgid(gid, gid, gid);
	setresuid(uid, uid, uid);
	
	system("/usr/bin/env echo and now what?");
}

 


□ RUID(Real User ID)

  ○ 프로세스의 실제 소유자 

  ○ 시그널 전송 시 사용됨. unprivileged 프로세스는 본인의 RUID, EUID가 상대방의 RUID, SUID와 동일할 때 시그널

      전송 가능



□ EUID(Effective User ID)

  ○ 일반적으로 RUID와 EUID는 동일

  ○ EUID는 SetUID 권한이 설정된 실행 파일에 의해 변경됨

  ○ EUID는 일시적으로 다른 계정의 UID를 저장

  ○ EUID에 저장된 UID에 따라 프로세스의 권한이 결정됨



□ SUID(Saved set-user-ID)

  ○ SUID는 프로세스의 권한을 낮게 변경했다가 원래대로 복구할 때 사용됨

  ○ 프로세스의 권한이 낮게 변경될 때, 변경 전의 EUID는 SUID에 저장됨

  ○ 이후, 낮은 권한이 원래 권한으로 복구될 때, SUID는 EUID에 저장됨

참고 :

https://blog.naver.com/starjhjh/222286475230

'Programming Language > C Language' 카테고리의 다른 글

gethostname() 함수  (0) 2021.07.06
C언어) getuid() 함수  (0) 2021.06.16
C언어) getgid() 함수  (0) 2021.06.16
C언어) 파일 디스크립터(FD, File Descriptor)  (0) 2021.06.15
C언어) read() 함수  (0) 2021.06.15

C함수 실제 사용자 ID 구하기

getuid() 함수

 

실제 사용자 ID를 구합니다.

  • 헤더: unistd.h
  • 형태: uid_t getuid(void)
  • 인수: -
  • 반환: uid_t getuid()는 항상 성공하며, 사용자 ID를 반환

 

예제

#include <stdio.h>
#include <unistd.h>

int main()
{
   printf( "%d\n", getuid());
   return 0;
}

 

실행 결과

$ ./a.out
500
$

 

 

참고 :

https://badayak.com/4383

C함수 실제 그룹 ID 구하기

getgid() 함수

 

실제 그룹 ID를 구합니다.

  • 헤더: unistd.h
  • 형태: uid_t getgid(void)
  • 인수: -
  • 반환: uid_t getgid()는 항상 성공하며 사용자 ID를 반환
  •  

예제

#include <stdio.h>
#include <unistd.h>

int main()
{
   printf( "%d\n", getgid());
   return 0;
}

 

실행 결과

$ ./a.out
500
$

 

 

참고 :

https://badayak.com/4385

파일 디스크립터 (FD, File Descriptor)란,

 

Unix OS에서 네트워크 소켓과 같은 파일이나 기타 입력/출력 리소스에 액세스하는 데 사용되는 추상표현이다.

 

즉, 시스템으로 부터 할당받은 파일이나 소켓을 대표하는 정수다.

파일 디스크립터는 음이 아닌 정수(Non-negative Integer)로, 일반적으로 형식 int로 C 프로그래밍 언어로 표현된다(음수 값은 "무값" 또는 오류 조건을 나타내기 위해 예약된다).
(Window에서는 file handle이라고 부르고 값은 랜덤하게 할당된다.)

 

FD의 0번에서 2번까지는 고정되어 있다. (unistd.h 헤더파일에 명시)

각 Unix 프로세스는 세 가지 standard streams에 해당하는 고정된 standard POSIX file descriptors를 가진다.

표준입력 및 표준출력도 파일 디스크립터로 표현이 되는데 이들은 프로그램이 시작되면 기본적으로 열리고, 종료 시 자동으로 닫힌다.

표 출처 위키피디아 https://en.wikipedia.org/wiki/File_descriptor

 

  • 표준 입력(Standard Input) : File Descriptor 0
  • 표준 출력(Standard Output) : File Descriptor 1
  • 표준 에러 출력(Standard Error) : File Descriptor 2

 

파일 디스크립터가 단순히 숫자인 이유는 프로세스가 유지하고 있는 file descriptors 테이블의 인덱스이기 때문이다. 

일 오픈 or 소켓생성 시 부여되는 파일 디스크립터는 3부터 시작한다.

프로세스가 실행 중에 파일을 Open 하면 커널은 해당 프로세스의 파일 디스크립터 숫자 중에 사용하지 않는 가장 작은 값을 할당해 준다.

그 다음 프로세스가 열려있는 파일에 시스템 콜을 이용해서 접근할 때, 파일 디스크립터 값을 이용해 파일을 지칭할 수 있다. 

사진 출처 https://dev-ahn.tistory.com/96

file descriptors 테이블의 각 항목은 FD 플래그 파일 테이블로의 포인터를 가지고 있다.

이 포인터를 이용하여 FD 를 통해 시스템의 파일을 참조 할 수 있는 것이다.

프로세스는 이런 FD 테이블과 파일 테이블의 정보를 직접 고칠 수 없으며, 반드시 커널을 통해서 수정을 해야 한다.

 

 

FD의 최대값은 OPEN_MAX라는 값이다.

즉, 하나의 프로세스 당 최대 OPEN_MAX개의 파일을 열 수 있다. OPEN_MAX 값은 플랫폼에 따라 다르다.

최대 파일 갯수는 다음의 방법을 사용하여 알아볼 수 있다. 내 mac에서는 2560개의 값이 나왔다.

 

OPEN_MAX는 단일 프로그램에 허용되는 최대 열린 파일 수를 정의하는 상수다.

Unix 시스템에서 C언어의 OPEN_MAX는 limits.h에 정의돼있다.

OPEN_MAX와 FOPEN_MAX와 _SC_OPEN_MAX는 조금씩 다르다고 한다. (출처)

 

방법 1) 터미널에서 getconf 명령어로 확인

getconf OPEN_MAX


/* 결과값 */
2560

 

방법 2) <unistd.h>의 sysconf() 함수로 확인

#include <unistd.h>
#include <stdio.h>

int	main(void){
	int	max;

	max = sysconf(_SC_OPEN_MAX);
	printf("%d\n", max);
	return(0);
}


/* 컴파일 후 결과값 */
2560

 

 


스토리 비유하기

(출처 : mintnlatte.tistory.com/266)
전화 한 통만 하면 필요한 논문을 복사해 주는 곳이 있다. 그리고 그곳의 단골손님 영수가 있다. 그런데 이 녀석은 매번 똑같은 논문의 일부분을 복사해 달라고 한다. “아저씨~ ‘고도의 정보화 사회가 되어 가면서, 인간의 삶의 질과 관계된 문제들이 점점 더 그 중요성이 더해짐에 따라 감각, 지각, 사고, 성격, 지능, 적성 등의 인간적 특징들이 고려됐을 때의 인간의 원리에 대한 연구’ 라는 논문 26쪽부터 30쪽까지 복사해 주세요” 이 녀석은 보통 이런 식으로 하루에도 여러 번 주문을 한다. 설상가상으로 말하는 속도도 느린 편이다. 그래서 아저씨가 말씀하시길 “그 논문은 이제부터 너의 18번이다! 그냥 저의 18번 논문 26쪽부터 30쪽까지 복사해 주세요 라고 해라!”영수는 그 이후로도 최소 50자가 넘는 제목의 논문만 복사 주문을 한다. 그 때 마다 아저씨는 논문에 새로운 번호를 할당해 준다(중복되지 않는). 그래야 영수와의 대화 속에서 스트레스를 덜 받을 수 있기 때문이다.

여기서 아저씨는 시스템이고, 영수는 개발자를 의미한다.

그리고 숫자는 파일 디스크립터이고, 논문은 소켓이나 파일을 의미한다.

파일(혹은 소켓)을 생성할 때마다 시스템은 그러한 숫자를 생성해서 건네줄 것이다. 그것이 시스템과 개발자가 편하게 대화하는 방법이 된다.

결국 파일 디스크립터란 시스템이 만들어 놓은 것을 가리키기 좋게 하기 위해 시스템이 우리들에게 건네주는 숫자에 지나지 않는다.

 

 


출처

파일 디스크립터

위키피디아 en.wikipedia.org/wiki/File_descriptor

mint&latte, mintnlatte.tistory.com/266

dev-ahn, dev-ahn.tistory.com/96

 

파일 디스크립터의 OPEN_MAX

네이버블로그 우동 blog.naver.com/PostView.nhn?blogId=s2kiess&logNo=220119492474&proxyReferer=https:%2F%2Fwww.google.com%2F

Javaer101 www.javaer101.com/article/2890626.html

 

 

 

참고 :

https://code4human.tistory.com/123

'Programming Language > C Language' 카테고리의 다른 글

C언어) getuid() 함수  (0) 2021.06.16
C언어) getgid() 함수  (0) 2021.06.16
C언어) read() 함수  (0) 2021.06.15
C언어) open() 함수  (0) 2021.06.15
C언어) strstr() 함수  (0) 2021.06.15

C함수 파일 읽기

read() 함수

 

open() 함수로 열기를 한 파일의 내용을 읽기를 합니다.

  • 헤더: unistd.h
  • 형태: ssize_t read (int fd, void *buf, size_t nbytes)
  • 인수: int fd 파일 디스크립터
           void *buf 파일을 읽어 들일 버퍼
           size_t nbytes 퍼버의 크기
  • 반환: ssize_t -1 == 실패, 정상적으로 실행되었다면 읽어들인 바이트 수

 

예제

예제에 사용할 test.txt 파일에는 아래와 같이 5바이트씩 문장이 입력되어 있습니다.

12345
ABCDE
abcde
67890

 

표준 출력함수 fgets() 에는 버퍼가 크더라도 파일의 첫 번째 행만 읽어서 반환하지만 read()는 버퍼의 크기만큼 읽을 수 있다면 모두 읽어 들입니다. 그러므로 read()에서 사용할 버퍼의 크기가 파일 보다 크다면 파일의 모든 내용을 읽어 들이게 됩니다.

 

아래는 test.txt의 파일 내용보다 버퍼의 크기가 1024로 크기가 크므로 한번에 읽기를 해서 파일의 모든 내용을 출력하는 예제입니다.

#include <stdio.h>         // puts()
#include <string.h>        // strlen()
#include <fcntl.h>         // O_WRONLY
#include <unistd.h>        // write(), close()

#define  BUFF_SIZE   1024

int main()
{
   char   buff[BUFF_SIZE];
   int    fd;

   if ( 0 < ( fd = open( "./test.txt", O_RDONLY))){
      read( fd, buff, BUFF_SIZE);
      puts( buff);
      close( fd);
   } else {
      printf( "파일 열기에 실패했습니다.\n");
   }
   return 0;
}

 

출력

$ a.out
12345
ABCDE
abcde
67890
$

 

만일 파일 내용보다 버퍼 크기가 작다면 여러번 읽기를 시도할 수 있습니다.

#include <stdio.h>         // puts()
#include <string.h>        // strlen()
#include <fcntl.h>         // O_WRONLY
#include <unistd.h>        // write(), close()

#define  BUFF_SIZE   5     // 버퍼의 크기가 작습니다.

int main()
{
   char     buff[BUFF_SIZE];
   int      fd;
   ssize_t  rd_size;

   if ( 0 < ( fd = open( "./test.txt", O_RDONLY))){
      while( 0 < ( rd_size = read( fd, buff, BUFF_SIZE-1))){  //  4 byte씩 읽씁니다.
         buff[rd_size]  = '\0';      // puts()를 위해 NULL을 대입
         puts( buff);
      }
      close( fd);
   } else {
      printf( "파일 열기에 실패했습니다.\n");
   }
   return 0;
}

 

출력

$ a.out
1234
5
AB
CDE

abcd
e
67
890
$

 

 

참고 :

https://badayak.com/4486?category=887532

'Programming Language > C Language' 카테고리의 다른 글

C언어) getgid() 함수  (0) 2021.06.16
C언어) 파일 디스크립터(FD, File Descriptor)  (0) 2021.06.15
C언어) open() 함수  (0) 2021.06.15
C언어) strstr() 함수  (0) 2021.06.15
C언어) volatile 의 의미(뜻)  (0) 2020.11.20

+ Recent posts