이것은 한낱 대학생이 교수의 수업을 듣고 작성한 개인저장용 복습 문서입니다.
그렇지만, 물론 지적과 수정은 환영합니다.
Opening
#include
#include <sys/stat.h>
int open(const char *path, int flag);
int open(const char *path, int flag, mode_t mode);
-file offset : 입력 위치
-*path : 경로 / flag : 읽기or쓰기or읽기&쓰기 / mode : 파일을 새로만들시 해당 파일의 permission
-open의 리턴값인 파일의 정보는 file descriptor라고 한다.
-flag : 액세스 모드 3가지 중 하나를 고르고, '|'를 사용해서 추가 옵션을 줄 수 있다.
ex) open("test.txt", O_RDWR | O_APPEND)
• 액세스 모드
– O_RDONLY: read only
– O_WRONLY: write only
– O_RDWR: read and write
• 추가 옵션
– O_APPEND: file_offset이 전에 썼던 끝부분으로 이동한다.
– O_TRUNC: 기존 파일의 내용을 초기화한다.
– O_CREAT: 새로 파일을 만들어서 그 파일을 열어주되, 파일이름이 겹치면 그냥 그 파일을 열어준다.
– O_EXCL: O_CREAT와 함께 사용, 파일이름이 겹칠 때 에러리턴해서 잘못된 파일 여는 것 방지.
– O_NOCTTY: prevents an opened device from becoming a controlling terminal
-현재 있는 파일의 덮어 쓸 위험을 피하려면? O_CREAT | O_EXCL 사용
Permission mask
user / group / else의 권한은 각각
read(r) write(w) execute(x)로 구성된다. 이에 대한 경우의 수는 총 2^3 = 8가지이다.
따라서 각 권한을 0~7로 표현할 수 있다.
0~7 / 0~7 / 0~7 로 표현가능. ex) 332, 755 등
O_CREAT 옵션 사용시 사용 (mode_t mode에)
POSIX 에서는 권한을 다른 방식으로 표기한다
이를 이용해
int fd;
mode_t fdmode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if ((fd = open(“info.dat”, O_RDWR | O_CREAT, fdmode)) == -1)
perror(“failed to open info.dat”);
와 같이 mode_t mode 값을 초기화한다.
copyfilemain.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#define READ_FLAGS O_RDONLY
#define WRITE_FLAGS (O_WRONLY | O_CREAT | O_EXCL)
#define WRITE_PERMS (S_IRUSR | S_IWUSR)
int main(int argc, char *argv[]) {
int bytes;
int fromfd, tofd;
if (argc != 3) {
fprintf(stderr, "Usage: %s from_fileto_file\n", argv[0]);
return 1;
}
if ((fromfd = open(argv[1], READ_FLAGS)) == -1) {
perror("Failed to open input file");
return 1;
}
if ((tofd = open(argv[2], WRITE_FLAGS, WRITE_PERMS)) == -1){
perror("Failed to create output file");
return 1;
}
bytes = copyfile(fromfd, tofd);
printf("%d bytes copied from %s to %s\n", bytes, argv[1],argv[2]);
return 0; /* the return closes the files*/
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
|
-인자가 3개가 아니면 오류 메세지 출력 (명령어 대상파일 목적파일)
-대상파일을 읽기전용로 열고, 목적파일을 새로만들고 덮어씌움방지를 하여 쓰기전용으로 연다.
-목적파일의 permission은 user에게 읽기와 쓰기권한만 준다.
-그리고 각 대상파일과 목적파일을 copyfile에 넣어준다.
Closing
#include
int close(int filedes);
사용이 끝난 open된 파일은 반드시 close해주어야한다.
프로세스가 아예 끝나면 프로세스에서 열린 파일은 자동으로 close된다.
r_close() : 시그널에 의한 에러 발생을 방지한 close함수
#include
#include
int r_close(int fd) {
int retval;
while (retval = close(fd), retval == -1 && errno == EINTR) ;
return retval;
}
LSEEK
파일 offset의 위치를 임의로 이동시킨다.
#include<sys/types.h>
#include
off_t lseek(int filedes,off_t offset,int start_flag);
-offset : off의 이동방향,크기 (-면 왼쪽, +면 오른쪽)
-flag : SEEK_SET 처음 / SEEK_CUR 현재 / SEEK_END 끝
File representation
File descriptors vs. pointers
• 파일은 file pointer혹은 file descriptor로 디자인된다.
• File pointers
– ISO C의 표준 I/O 라이브러리 함수에서 사용된다. (fopen, fscanf, fprintf, fread, fwrite, fclose..)
– stdin, stdout, stderr (defined in stdio.h)
• File descriptors
– UNIX I/O 함수에서 사용된다. (open, read, write, close, ioctl..)
– STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO (defined in unistd.h)
File descriptor
-파일 하나를 열면, 프로세스에 특정된 File descriptor table의 한 부분을 차지한다.
-동시에 System file table, In-memory inode table도 한 부분씩 차지한다.
-System file table에는 오픈된 파일에 대한 정보가 들어있다 : file offset, access mode, count
-cf. count : 해당 위치를 지정하는 File descriptor table의 수
-즉, 하나의 System file table에 여러개의 File descriptor table이 지정될 수 있다.
-In-memory inode table은 System file table이 가르킨다.
-System의 실제 파일에 대한 정보를 담고 있다 : meta info, status info의 레퍼런스
-즉, 파일의 inode를 가르킨다.
-만약 close를 통해 myfd를 닫으면, file descriptor talbe의 엔트리는 바로 삭제된다.
-하지만 system file table이나 in-memory inode talbe의 엔트리는 count값을 줄여준다.
-count값이 0이되면 해당 엔트리들도 삭제가 된다.
-만약 두개의 프로세스가 같은 파일을 시작해서 write를 한다면? 서로가 서로의 값을 덮어씌울 확률이 높다.
-만약 file offset이 inode table에서 관리된다면? 덮어씌울일없이 서로 공유하여 하나씩 입력이 가능하다.
File Pointers
-FILE 이라는 data structure를 가르키는 포인터
-FILE : buffer + file descriptor value
-fprintf , fwrite? 바로 읽거나 쓰지 않고, buffer에 쓰여지다가 buffer가 가득차면 읽고 쓴다.
-만약 buffer가 딜레이되면 fflush를 통해 버퍼를 강제로 비워서 사용할 수 있다.
-terminal환경에서는 line-buffered, 즉 라인이 차면 출력을 실행한다.
-단, STD-ER은 제외. 에러메세지와 같이 우선순위가 높은 것은 STD-ER로 바로 출력된다.
-open 후 fork 시 부모의 file descriptor 정보가 상속되기 때문에 같은 System file table을 가리키게 된다. (a, b)
-하지만 fork 후 open 시 각각 다른 file descriptor 정보를 가지고 있어 다른 System file talbe을 가리키게 된다. (a, a)
-개행 문자 \n이 없는 경우 buffer를 물려주어, "This is my output.This is my output." 두 번 출력. file offset도 그 뒤에
-개행 문자 \n이 있는 경우 buffer를 물려주지않아, "This is my output." 한번 출력. file offset 한라인 아래에
'💻 CS > 시스템프로그래밍' 카테고리의 다른 글
[시스템프로그래밍] UNIX Special Files (0) | 2019.12.01 |
---|---|
[시스템프로그래밍] Files and Directories (0) | 2019.11.26 |
[시스템프로그래밍] UNIX I/O - 1 (2) | 2019.11.04 |
[시스템프로그래밍] 중간고사 대비 (0) | 2019.10.22 |
[시스템프로그래밍] Processes in UNIX (1) | 2019.10.12 |