상세 컨텐츠

본문 제목

UNIX - 파일 조작하기

개발/UNIX

by 2021. 10. 14. 19:13

본문

반응형

System Call (시스템 호출)

‘프로그램’과 ‘커널’ 사이를 연결하는 API

프로그램 만으로는 불가능한 기능을, 커널의 기능을 빌려서 수행

Windows에도 ‘시스템 호출’이 있다

WIN16 API, WIN32 API, WIN64 API

프로그램의 하위 호환성을 제공

Win 2.0의 프로그램이 Win 7에서도 수행

Unix 시스템의 구조

kernel에 어셈블리 코드가 포함되어있지만, 직접 접근할 수 없으므로 system calls이 중간 인터페이스의 역할을 한다.

unistd.h

Unix Standard Header

Unix 시스템 호출 전반을 담당하는 헤더 파일

  • 사용자 ID 획득
  • 그룹 ID 획득
  • 파일 및 장치 읽기/쓰기
  • 프로세스 복제
  • 파이프
  • 그 외 다수의 시스템 호출

fcntl.h

File Control Header

Unix 시스템 중 파일을 담당하는 헤더 파일

  • 파일 생성
  • 파일 속성 변경

사용자 및 그룹 확인

  • getuid() : 사용자의 ‘실제’ ID 출력
  • geteuid () : 사용자의 ‘유효’ ID 출력
  • getgid () : 사용자의 ‘실제’ 그룹 ID 출력
  • getegid () : 사용자의 ‘유효’ 그룹 ID 출력
#include <stdio.h>
#include <unistd.h>
int main() {
	print£("UID : $d, EVID : Sd\n",getuid(), geteuid());
	print£("GID : $d, EGID : $d\n",getgid(), getegid());
	return 0;
}

실제 ID유효 ID

  • 실제 ID : 프로그램의 ‘실행을 명령’하는 ID
  • 유효 ID : 프로그램을 ‘실제로 수행’하는 ID
  • chmod +s 로 유효 ID 우회가 가능
    사용자를 바꿔도 프로그램의 유효ID EUID를 프로그램 owner로 고정시킬 수 있음

파일 열기 및 생성

C언어 : fopen() (stdio.h)

Unix 호출 : open() (fcntl.h)

사용법 : open(파일명, 모드, 권한)

  • 파일명 : 읽거나 쓸 파일 이름
  • 모드 : 읽거나 쓸 때의 모드 지정
  • 권한 : 파일을 새로 만들 때에만 권한 지정
  • 권한 생략 시 754로 지정(rwxr-xr--)

C언어 : FILE* fp = fopen(“input.txt”, “w+”);

  • 반환되는 값은 포인터로 표현된 파일 포인터

Unix : int fd = open(“input.txt”, O_RDWR);

  • 반환되는 값은 정수로 표현된 파일 서술자

파일 서술자(File Descriptor)?

  • 파일에 접근하기 위한 추상적인 정수 키
  • 키의 관리는 커널에서 수행

미리 정의된 파일 서술자

0 : stdin (표준 입력, 파일로부터 읽기만 가능)

1 : stdout (표준 일반 출력, 파일에 쓰기만 가능)

2 : stderr (표준 오류 출력, 파일에 쓰기만 가능)

 

파일 서술자 추가 시, 할당되지 않은 서술자 중 가장 작은 번호로 자동 할당한다

 

파일 열기 옵션

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: a.txt → fd2: a.txt)
  • fd1과 fd2는 같은 파일을 가리킴
  • fd2의 키는 자동으로 지정

dup2(fd1, fd2);

  • int fd2 = dup(fd1) 와 같은 기능을 수행
  • fd2가 이미 열려있다면 파일을 닫은 후 복제
  • fd2의 키를 수동으로 지정할 수 있음

example

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

int main()
{
	int fd = open(TEST,O_RDWR|O_CREAT, 0644);
	printf("Before dup2()\n");
	dup2(fd,1);
	printf ("After dup2()\n");
	close(fd);
	return 0;
}

result 

unix@unixsystem:~$ cc -o dup dup.c
unix@unixsystem:~$ ./dup
Before dup2()
unix@unixsystem:~$ cat test.txt
After dup2()
unix@unixsystem:~$ _

dup2() 이후 test.txt 파일에 출력되었다. (표준 입출력 자체에도 영향을 끼칠 수 있다.)

파일에서 읽기

int result = read(fd, buffer, bytes)

  • fd : 읽을 파일의 서술자
  • buffer : 결과를 저장할 버퍼(포인터 형식)
  • bytes : 파일에서 읽을 바이트 수
  • result : 실제로 읽은 바이트 수
    > 0 : 버퍼에 실제 내용이 들어감
    = 0 : 파일의 끝(EOF)
    < 0 : 오류 발생

파일로 쓰기

int result = write(fd, buffer, bytes)

  • fd : 쓸 파일의 서술자
  • buffer : 내용이 저장되어 있는 버퍼(포인터 형식)
  • bytes : 파일에서 쓸 바이트 수
  • result : 실제로 쓴 바이트 수
    > 0 : 파일에 실제 내용이 쓰였음
    = 0 : 쓴 내용 없음
    < 0 : 오류 발생

example

#incluage <unistd.h>
#include <fcntl.h>
int main()
{	
	int bytes;
	char buffer[256];
	do
	{
		bytes = read(0,buffer,255);
		if(bytes <= 0) break;
		write(1,buffer,bytes);
	}
	while(1);
	return 0;
}

result

unix@unixsystem:~$ cc -o read read.c
unix@unixsystem:~$ ./read
Unix System Programming
Unix System Programming
Text read from stdin
Text read from stdin
and written to stdout
and written to stdout
Press Ctrl+D to terminate current input
Press Ctrl+D to terminate current input


Ctrl+D also breaks out if nothing was read.
Ctrl+D also breaks out if nothing was read.
unix@unixsystem:~$ _

Command line 매개변수 

#include <stdio.h>
int main(int argc, char* argv[]){

}

int main(int argc, char** argv){

}

argc : 매개변수의 개수 (파일 실행 명령어 포함)

argv : 각각의 매개변수

example

#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 ;
}

파일 접근 Primitive

lseek()

  • 특정 파일의 파일포인터 위치를 변경해주는 함수
  • off_t  lseek(filedes, offset, flag)
  • 매개변수
    filedes파일 descriptor
    offset : 시작 위치로부터의 추가 offset (음수 가능)
    flag : offset 시작 위치
     - SEEK_SET  파일의 처음부터 시작
     - SEEK_CUR  파일 포인터의 현재 위치부터 시작
     - SEEK_END  파일의 끝부터 시작
  • 반환값
    성공 : offset
    실패 : 음수
반응형

관련글 더보기