Linux

File Input & Output System calls

joonojoono 2023. 3. 24. 23:31
반응형

본 자료는 상명대학교 신동하 교수님의 수업을 정리한 것임을 밝힙니다.

File input/output System Calls

flags란?

<fcntl.h>에 정의돼있다.

flags는 파일을 어떤 용도로 open할 지를 지정한다.

O_RDONLYread only
O_WRONLYwrite only
O_RDWRread, write
O_APPENDappend
O_CREAT새 파일 생성, 추가 인수 필요
O_EXCLO_CREAT와 같이 사용 되면 존재하는 파일을 또 생성할 때 error가 생성 (같이 사용된다는 것은 bitwise or 하는 것 “|”)
O_TRUNC파일 크기가 0이 됨
O_SYNCwrite시 physical I/O가 완료될 때까지 wait한다.

mode란?

<sys/stat.h>에 정의돼있다.

creat할 file의 mode=(user/group/other) 각각의 read/write/execute를 OR한 값을 지정한다.

bitwise OR 로 합칠 수 있다.

00400octa O, value
S_IRUSRuser read(00400)
S_IWUSRuser write (00200)
S_XUSRuser execute (00100)
S_IRGRPgroup read (00040)
S_IWGRPgroup write (00020)
S_IXGRPgroup execute (00010)
S_IROTHother read (00004)
S_IWOTHother write (00002)
S_IXOTHother execute(00001)

open: 주어진 pathname으로 file을 열거나 생성하고 file descriptor를 넘겨준다.

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
int creat(const char *pathname, mode_t mode);

=========================================================

return value: 성공 시 새 (file descriptor), 오류 시 (-1)

creat: 주어진 pathname으로 file을 생성하고 file descriptor를 넘겨준다.

creat와 open 비교

// 아래 두 함수는 기능이 같다.
creat(pathname, mode)
open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode)

함수 creat은 open을 사용하여 프로그래밍이 가능하기 때문에 실제 필요없다.

read: 주어진 file descriptor에 해당하는 file로 부터 데이터를 읽는다.

#include <unistd.h>

// fd: file descriptor, buf: data를 읽을 mem의 시작
// count: 읽을 char의 갯수
ssize_t read(int fd, void *buf, size_t count);

file로부터 data를 읽는 함수

read가 성공적으로 완료되면 해당 파일의 읽기/쓰기 위치인 file offset이 read한 byte 수 만큼 증가한다.

return value: 성공 시 read한 byte 수. file의 끝에 도달시, 0 오류시 -1

write: 주어진 file descriptor에 해당하는 파일에 데이터를 쓴다.

#include <unistd.h>

// buf: write할 data가 저장된 시작 주소 
ssize_t write(int fd, const void *buf, size_t count);

write는 주어진 파일에 데이터를 쓰는 함수

write가 성공적으로 완료되면 해당 파일의 읽기/쓰기 위치인 file offsetwrite한 byte 수 만큼 증가한다.

return value: 성공시 write한 byte 수, 오류 시 -1

Example

device I/O도 read, write함수를 사용하여 이용할 수 있다.

// copy.c

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

// Linux의 ext4 파일 시스템에서 disk의 block size는 4K임
#define BUFFSIZE 4096 
// 실제 system call read, write는 unbufered I/O라 버퍼링이 없다.
// 아래 버퍼는 데이터를 저장할 용도로 사용하는 것이다.
char buf[BUFFSIZE];

int main() {
	int n;

	// STDIN, STDOUT은 프로그램 시작, 종료 시 open, close되므로
	// open, close를 할 필요가 없음
	while((n = read(STDIN_FILENO, buf, BUFFSIZE) > 0) {
		// n만큼 읽었는데 n만큼 출력하지 않으면 오류
		if(write(STDOUT_FILENO, buf, n) != n) {
			perror("write");
			exit(1);
		}
		// n이 음수를 return하면 오류
		if(n < 0) {
			perror("read");
			exit(1);
		}
	}

	return 0;
}

close: 주어진 file descriptor에 해당하는 file을 닫는다.

#include <unistd.h>

int close(int fd);

함수 close는 open한 파일을 더 이상 사용하지 않을 경우 부른다.

return value: 성공 시 0, 오류 시 -1

lseek: 주어진 file descriptor에 해당하는 file의 입출력 위치를 변경한다. (offset)

whence

offset의 상대적 시작 위치를 지정한다.

SEEK_SET파일의 시작 지점에서부터 offset.
SEEK_CUR현재 file offset에서부터 offset
SEEK_END파일의 끝 지점에서부터 offset
#include <sys/types.h>
#include <unistd.h>

off_t lseek(int file_descriptor, off_t offset, int whence);

lseek은 주어진 file의 입출력 위치인 file offset을 변경하는 함수다.

return value: 성공시 new file offset, 오류 시 -1


Uploaded by N2T

반응형