c언어/시스템 프로그래밍

시스템프로그래밍 - 4일차

시스템 엔지니어 2023. 4. 8. 18:37

시스템프로그래밍 - 4일차

강의 링크

Duplicating FD - dup(2) / dup2(2)

  • 복사하는 시스템 콜
$ man -s 2 dup

#include <unistd.h>

int dup(int oldfd);
int dup2(int oldfd, int newfd);

oldfd (old file descriptor)

  • 복사하려는 file descriptornewfd (old file descriptor)

newfd (old file descriptor)

  • 새로운 fd 지정
  • dup()의 경우 할당 가능한 fd 중 가장 작은 값 할당

Return: oldfd를 복사한 새로운 fd

  • -1: error

예제

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

int main(void) {
  int fd, fd1;

  fd = open("tmp.aaa", O_CREAT | O_WRONLY | O_TRUNC, 0644);
  if (fd == -1) {
          perror("Create tmp.aaa");
          exit(1);
  }
  close(1);         # stdout을 close

  fd1 = dup(fd);    # tmp.aaa 파일을 파일 디스크립터(1) 과 연결

  printf("DUP FD=%d\n", fd1);
  printf("Standard Output Redirection\n");
  close(fd);

  return 0;
}

실행

$ cat tmp.aaa 
DUP FD=1
Standard Output Redirection

stdout을 close 하고, dup 시스템콜을 이용하여 tmp.aaa를 stdout과 연결했다. 결과는 printf()가 모니터에 출려되지 않고, tmp.aaa에 저장이 되었다. fd를 잘 다루면 이런 것도 가능하다는 것을 알수 있었다.

fcntl

  • file control
  • 파일 디스크립터를 제어한다.
$ man -s 2 fcntl 
#include <unistd.h> 
#include <fcntl.h>
int fcntl(int fd, int cmd, ... /\* arg \*/ );

fd (file descriptor)

  • 대상 file descriptor

cmd (command)

  • 수행할 명령
  • F_GETFL (상태 flag 읽기), F_STEFL (상태 flag 설정) 등

arg (argument)

  • cmd에 필요한 인자들

return: cmd에 따라 다름

fcntl 예제

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

int main(void) {  
int fd, flags;

fd = open("linux.txt", O_RDWR); #linux.txt 생성  
if (fd == -1) {  
perror("open");  
exit(1);  
}

if ((flags = fcntl(fd, F_GETFL)) == -1) {  
perror("fcntl");  
exit(1);  
}

flags |= O_APPEND; // change to append mode #append mode or로 추가

if (fcntl(fd, F_SETFL, flags) == -1) { #fcntl 시스템 콜로 추가  
perror("fcntl");  
exit(1);  
}

if (write(fd, "KOREATECH", 9) != 9) perror("write"); #linux.txt 파일에 KOREATECH 단어 추가  
close(fd);

return 0;  
}

결과

$ cat linux.txt  
Linux system programming

$ ./fcntl.out  
$ cat linux.txt  
Linux system programming  
KOREATECHroot

fcntl 시스템콜을 이용하여 append offset을 추가했다. 실행 결과 맨뒤에 추가한 단어 KOREATECH가 linux.txt에 추가 되는 것을 알 수 있었다.