관리 메뉴

너와 나의 스토리

[CH.5] 파일 조작 - System call 본문

Unix/실습

[CH.5] 파일 조작 - System call

노는게제일좋아! 2019. 10. 9. 18:01
반응형

System call

  • 프로그램과 커널 사이를 연결하는 API
  • windows에도 system call이 있다.

 

 

unistd.h & fcntl.h

  • unistd.h
    • Unix Standard Header
    • Unix 시스템 호출 전반을 담당하는 헤더 파일
      • 사용자,그룹 ID 획득
      • 파일 및 장치 읽기/쓰기
      • 프로세스 복제
      • 파이프
      • 그 외 다수의 시스템 호출
  • fcntl.h
    • File Control Header
    • Unix 시스템 중 파일을 담당하는 헤더 파일
      • 파일 생성
      • 파일 속성 변경

 

 

파일 열기 및 생성

  • C 언어: fopen() <stdio.h>
    • FILE* fp=fopen("input.txt","w+");
    • 반환되는 값: 파일 포인터
  • Unix 호출: open() <fcntl.h>
    • int fd = open("input.txt",O_RDWR);
    • 반환되는 값: 정수로 표현된 파일 디스크립터 <- 정수 키의 관리는 커널에서 수행
  • 사용법: open(파일명, 모드, 권한)
    • 파일명: 읽거나 쓸 파일 이름
    • 모드: 읽거나 쓸 때의 모드 지정
    • 권한: 파일을 새로 만들 때에만 권한 지정
      • 권한 생략 시 default는 754 (rwxr-xr--)

 

파일 열기 옵션

  • O_RDONLY : 읽기 전용으로 열기
  • O_WRONLY : 쓰기 전용으로 열기
  • O_RDWR : 읽기/쓰기 겸용으로 열기
  • O_APPEND : 파일의 끝에서부터 추가
    • 이 옵션이 없으면 파일의 처음부터 시작
  • O_CREAT : 파일이 없으면 새로 생성
    • 이 옵션이 없으면 파일 없을 때 오류 발생
  • O_TRUNC : 파일이 이미 있으면 내용을 삭제
    • 이 옵션이 없으면 내용을 삭제하지 않고 덮어 씀
  • O_EXCL : 파일이 이미 있으면 오류 발생

 

 

파일 생성

  • int fd=creat(파일명, 권한);
    • 파일을 쓰기 전용으로 새로 생성
    • O_WRONLY | O_CREAT | O_TRUNC와 동일
    • 이미 존재하던 파일이면 초기화 후 덮어씀
    • 권한은 open()의 권한과 동일

 

파일 닫기

  • close(fd);
    • 열려 있는 파일을 닫음 (파일 서술자를 매개변수로 받음)

 

파일 서술자 복제

  • int fd2=dup(fd1);
    • fd1의 파일을 fd2로 복제
    • fd1과 fd2는 같은 파일을 가리킴
    • fd2의 키는 자동으로 지정
  • dup2(fd1,fd2);
    • int fd2=dup(fd1)로 같은 기능을 수행
    • fd2가 이미 열려있다면 파일을 닫은 후 복제
    • fd2의 키를 수동으로 지정할 수 있음
// dup.c

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#define TEST "test.txt"

int main()
{
	int fd=open("test.txt", O_RDWR|O_CREAT,0644);
    printf("Before dup2()\n");
    dup2(fd,1);  // 파일 디스크립터 1: 표준 일반 출력
    printf("After dup2()\n");
    close(fd);
    return 0;
}

"After dup2()"는 출력되지 않는다.

 

왜냐하면, dup2(fd,1)를 통해 표준 일반 출력(1)이 fd가 가리키는 파일을 가리키게 되므로, 화면에 출력되는 것이 아니라 fd가 가리키는 파일에 출력이 되는 것이다.

<- cat 명령어로 test.txt 파일 내용을 불러온 결과

 

 

* 컴파일 하는 법: cc -o file file.c

 

파일에서 읽기

  • int result =read(fd, buffer, bytes)
    • fd: 읽을 파일의 디스크립터
    • buffer: 결과(읽어 온 데이터)를 저장할 버퍼(포인터 형식)
    • bytes: 파일에서 읽을 바이트 수
    • result: 실제로 읽은 바이트 수
      • result>0: 버퍼에 실제 내용이 그대로 들어감
      • result=0: 파일의 끝(EOF), 더 이상 읽을 것이 없음
      • result<0: 오류

 

파일에 쓰기

  • int result=write(fd, buffer,bytes)
    • fd: 쓸 파일의 디스크립터
    • buffer: 파일에 쓸 바이트 수
    • result: 파일에 실제로 쓴 바이트 수
      • result>0: 파일에 실제 내용이 그대로 쓰임
      • result=0: 쓴 내용이 없음
      • result<0: 오류
#include <unistd.h>
#include <fcntl.h>
int main()
{
	int bytes;
    char buffer[256];
    do{
    	bytes=read(0,buffer,255);  // 표준입력(0)으로 읽는다
        if(bytes<=0) break;
        write(1,buffer,bytest);    // 표준출력(1)로 쓴다
    }
    while(1);
    return 0;
}

첫 줄: 내가 쓴 것  -> 표준 입력

두 번째 줄: 출력된 것  -> 표준 출력

 

 

 

'<' 명령을 통해 test.txt에서 읽어온 것을

'<' 명령을 통해 test2.txt에 적음

 

 

  • <: 표준 입력을 파일로 재지정
  • >: 표준 일반 출력을 파일에 덮어씀
  • 2>: 표준 오류 출력을 파일로 덮어씀
  • >>: 표준 입력 출력을 파일에 추가
  • 2>>: 표준 오류 출력을 파일에 추가
  • &>: 모든 출력을 파일로 재지정
  • 2>&1: 표준 오류 출력을 표준 일반 출력으로

 

Command line 매개변수 사용법

#include <stdio.h>

int main(int argc, char* argv[]){
	int count;
    printf("argc: %d\n", argc);
    printf("--------arguments list--------\n);
    for(count=0;count<argc;count++){
    	printf("argv[%d]: %s\n", count, argv[count]);
    }
    return 0;
}

./commandline도 하나의 파라미터로 생각해서 

총 4개의 파라미터가 들어온 것으로 생각

 

 

 

 

 

파일 접근 Primitive

  • lseek()
    • 특정 파일의 파일 포인터 위치를 변경해주는 함수
    • off_t lseek(fd, offset, flag);
      • fd: 파일 디스크립터
      • offset: (flag)시작 위치로부터의 추가 offset (음수 가능)
      • flag: offset 시작 위치
        • SEEK_SET: 파일의 처음부터 시작
        • SEEK_CUR: 파일 포인터의 현재 위치부터 시작
        • SEEK_END: 파일의 끝부터 시작
      • 반환:
        • 성공: offset
        • 실패: 음수 

 

 

 

 

 

 

반응형
Comments