Home [SP] Linux File
Post
Cancel

[SP] Linux File

2강-1. 파일 개요 & 기본 명령어

File

  • 보조 기억 장치에 저장된 연관된 정보들의 집합
    • 보조 기억 장치 할당의 최소 단위
    • Sequnce of bytes (물리적 정의)
  • File operations
    • Create, Write, Read, Reposition, Delete, …
  • OS는 file operation들에 대한 system call을 제공해야 함

Types of files in Unix/Linux

  • Regular file (일반 파일)
    • Text or Binary data file
  • Directory
    • Unix/Linux에서는 디렉토리도 하나의 파일
  • Special file (특수파일)
    • 파일 형태로 표현된 커널 내 객체
      • 자원에 대한 시스템 내부적 표현
    • 데이터 전송, 장치 접근 시 사용하는 파일
      • device files, pipes, socket, …

Basic commands for file

  • ls (list)
    • 현재 디렉토리 내 파일 목록 출력
    • -l: 상세 파일 정보 출력
    • -a: 모든 파일(숨겨진 파일 포함) 목록 출력
  • touch
    • 빈 파일 생성 or 변경된 날짜 수정
  • rm
    • 파일 삭제
    • -r: 디렉토리 삭제
  • cat (concatenate)
    • 파일 내용 출력
  • cp (copy)
    • 파일 복사
    • cp 원본 복사본
    • -r: 디렉토리 복사
  • mv (move)
    • 파일 이동 or 이름 변경
    • mv 원본 이동본

File access permission

  • 소유자(Owner), 그룹(Group), 기타(others) 사용자에 따라
  • 읽기(r), 쓰기(w), 실행(x) 권한을 가짐

  • chmod (change mode)
    • 파일 권한 변경
    • chmod 권한 대상
    • chmod u+r 대상: 소유자에게만 읽기 권한을 줌

2강-2. File open & close

Low-level vs High-level file IO

Low-Level File IO (System call)

  • System call을 이용해서 파일 입출력 수행
  • File descripor 사용
  • Byte 단위로 디스크에 입출력
  • 특수 파일에 대한 입출력 가능

    High-Level File IO (Buffered IO)

  • C Std Lib를 사용해서 파일 입출력 수행
  • File pointer 사용
  • 버퍼(block) 단위로 디스크에 입출력 (여러 형식의 입출력 지원)

Opening Files - open(2)

1
2
3
4
5
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int open(const char *pathname, int flags [, mode_t model]);
  • pathname: 열려는 파일의 경로 (파일 이름 포함)
  • flags (file state flags): 파일을 여는 방법(access mode) 설정
  • mode (file access permission): 파일을 새로 생성(O_CREATE)할 때만 유효
  • return: file descriptor (int)

File descriptor

  • 열려 있는 파일을 구분하는 정수값
    • 특수 파일 등 대부분의 파일을 지칭 가능
    • Process별로 kernel이 관리
  • 파일을 열 때 순차적으로 할당 됨
    • Process 당 최대 fd 수 = 1024(default, 변경가능)
  • Default fds (수정 가능)
    • 0: stdin
    • 1: stdout
    • 2: stderr
  • flags (|로 여러 플래그 조합해서 사용 가능)
    • O_RDONLY: 파일을 읽기 전용으로 열기
    • O_WRONLY: 파일을 쓰기 전용으로 열기
    • O_RDWR: 파일을 읽기와 쓰기가 가능하게 열기
    • O_CREAT: 파일이 없으면 파일을 생성
    • O_EXCL: O_CREAT 옵션과 함께 사용할 경우 기존에 없는 파일이면 파일을 생성하지만, 있는 경우 생성하지 않고 오류 출력
    • O_APPEND: 파일 맨 끝에 내용 추가
    • O_TRUNC: 파일을 생성할 때, 이미 존재하는 파일이고 쓰기 옵션으로 열린 경우 기존 내용을 모두 지움
    • O_SYNC / O_DSYNC: 저장장치에 쓰기가 끝나야 스기 동작을 완료

File Tabel

  • 열린 파일을 관리하는 표
    • kernel이 process별로 유지
    • 열린 파일에 대한 각종 정보 관리
    • (Access mode, file offset, pointer to files)
  • [fd array] - [file table] - [filesystem]

mode

  • 파일 권한 설정 값 사용
  • 정의 된 플래그 사용
    • 조합하여 사용 가능 (| OR bit operation)
    • 비트에 대한 해석으로 옵션을 유추할 수 있음
S_IRWXU0700소유자 읽기/쓰기/실행 권한
S_IRUSR0400소유자 읽기 권한
S_IWUSR0200소유자 쓰기 권한
S_IXUSR0100소유자 실행 권한
S_IRWXG0070그룹 읽기/쓰기/실행 권한
S_IRGRP0040그룹 읽기 권한
S_IWGRP0020그룹 쓰기 권한
S_IXGRP0010그룹 실행 권한
S_IRWXO0007기타 사용자 읽기/쓰기/실행 권한
S_IROTH0004기타 사용자 읽기 권한
S_IWOTH0002기타 사용자 쓰기 권한
S_IXOTH0001기타 사용자 실행 권한

Closing Files - close (2)

1
2
3
#include <unistd.h>

int close (int fd);
  • fd (file descriptor)
  • return
    • 0: success
    • -1: error

[EX] Open & Close a file

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
28
29
30
31
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

// ex1
int main(void){
  int fd;
  mode_t mode;

  mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; // 644

  fd = open("hello.txt", O_CREAT, mode);
  if (fd==-1){ perror("CREAT"); exit(1); }

  close(fd);
  return 0;
}

// ex2
int main(void){
  int fd;
  
  fd = open("hello.txt", O_CREAT|O_EXCL, 644);
  if (fd==-1){ perror("EXCL"); exit(1); }

  close(fd);
  return 0;
}

Error handling for system call

  • System call은 실패 시 -1을 반환
  • Error code는 errno에 저장 됨
    • error.h에 선언되어 있음 (special variable)
    • extern으로 직접 접근 가능 (extern 다른 파일에 정의된 변수에 접근)
  • perror
    • Error message를 출력해주는 함수
1
2
3
#include <stdio.h>

void perror(const char *str)

[EX] Allocating file desciptor

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
28
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int openFile(void){
  int fd = open("hello.txt", O_RDWR);
  if (fd==-1){ perror("File Open"); exit(1); }
  return fd;
}

int main(void){
  int fd = 0;
  
  fd = openFile();
  printf("fd = %d\n", fd);
  close(fd);

  close(0); // stdin 수정

  fd = openFile();
  printf("fd = %d\n", fd);
  close(fd);

  return 0;
}

2강-3. File read & write

Reading to a file - read (2)

1
2
3
#include <unistd.h>

ssize_t read(int fd, void *buf, size_t count);
  • fd (file descriptor): 읽으려는 파일의 file desciptor
  • buff (buffer): 읽은 내용을 저장할 buffer의 시작 주소
  • count: 읽을 byte의 수
  • return: 실제로 읽은 byte의 수
    • 0: EOF
    • -1: 에러

Writing to a file - write (2)

1
2
3
#include <unistd.h>

ssize_t write(int fd, const void *buf, size_t count);
  • fd (file descriptor): 기록하려는 파일의 file descriptor
  • buf (buffer): 기록할 내용이 저장된 buffer의 시작 주소 (수정 방지를 위해 const)
  • count: 기록할 byte의 수
  • return: 실제로 기록한 byte의 수
    • -1: 에러

File offset (File position)

  • File operation (e.g., read/write)을 적용할 위치
  • 파일의 시작점부터 현재 위치까지의 byte 수
  • Read(2)/Write(2) 수행 시, 읽은/기록한 byte 수 만큼 순차적으로 이동

[EX] File Read & Write

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 <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int main(void){
  int rfd, wfd, n;
  char buf[10] = 0; // 버퍼 초기화
  
  // 읽기용
  rfd = open("hello.txt", O_RDONLY);
  if (rfd==-1){ perror("Open hello.txt"); exit(1); }

  // 쓰기용
  wfd = open("hello.bak", O_CREAT | O_WRONLY | O_TRUNC, 0644);
  if (wfd==-1){ perror("Open hello.bak"); exit(1); }

  // 복사
  while ((n=read(rfd, buf, 6))>0) {
    if (write(wfd, buf, n)!=n) { perror("Write"); }
  }
  if (n==-1) { perror("Read"); }

  close(rfd);
  close(wfd);
  return 0;
}

File access methods

  • Sequential access (순차 접근)
    • File을 record(or bytes) 단위로 순서대로 접근
  • Directed access (직접 접근)
    • 원하는 Block(위치)을 직접 접근
  • Indexed access
    • Index를 참조하여, 원하는 block을 찾은 후 데이터에 접근

Moving the file offset = lseek (2)

1
2
3
4
5
#include <sys/types.h>
#include <unistd.h>

// Dicrected access
off_t lseek(int fd, off_t offset, int whence)
  • fd (file descriptor): 대상 file descriptor
  • offset: 이동 시킬 byte 수 (양수 or 음수)
  • whence: 기준 위치
    • SEEK_SET: 파일의 시작
    • SEEK_CUR: 현재 위치
    • SEEK_END: 파일의 끝
  • return: 이동 후 file offset, -1 에러
  • cur_offset = lseek(fd, 0, SEEK_CUR)

[EX] Moving the file offset

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
28
29
30
31
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int main(void){
  int fd, n;
  off_t start, cur;
  char buf[256];

  fd = open("linux.txt", O_RDONLY);
  if (fd==-1) { perror("Open linux.txt"); exit(1); }

  start = lseek(fd, 0, SEEK_CUR);
  n = read(fd, buf, 255);
  buf[n] = '\0'; // 문자열의 끝
  printf("Offset start=%d, Read Str=%s, n=%d", (int)start, buf, n);

  cur = lseek(fd, 0, SEEK_CUR); // cur == n
  printf("Offset cur=%d\n", (int)cur);

  start = lseek(fd, 6, SEEK_SET);
  n = read(fd, buf, 255);
  buf[n] = '\0';
  printf("Offset start=%d, Read Str=%s", (int)start, buf);

  close(fd);

  return 0;
}

Page Cache & Write-Back

  • Page cache
    • In-memory sotre of recently accessed data from an on-disk filesystem
    • Disk 접근 시간 절약을 위해 kernel 내부적 기법
  • Page write-back
    • Page cache에 변경 된 내용을 disk에 반영하는 것
    • 반영 시기는 kernel이 결정

Synchronizing with disks - fsync (2)

1
2
3
#include <unistd.h>

int fsync(int fd);
  • Page write-back을 강제로 수행
  • fd (file descriptor): 대상 file descriptor
  • return
    • 0: success
    • -1: error

2강-4. File descriptor 다루기

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

1
2
3
4
#include <unistd.h>

int dup(int oldfd);
int dup2(int oldfd, int newfd);
  • oldfd (old file descriptor): 복사하려는 file descriptor
  • newfd (new file descriptor)
    • 새로운 fd 지정
    • dup()의 경우 할당 가능한 fd 중 가장 작은 값 할당
  • return: oldfd를 복사한 새로운 fd, -1 error

[EX] IO redirection

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int main(void){
  int fd, fd1;

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

  fd1 = dup(fd);

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

  return 0;
}

Manipulating FD - fcntl (2)

1
2
3
4
#include <unistd.h>
#include <fcntl.h>

int fcntl(int fd, int cmd, /* arg */ ...);
  • fd (file descriptor): 대상 file descriptor
  • cmd (command): 수행할 명령
    • F_GETFL: 상태 flag 읽기
    • F_SETFL: 상태 flag 설정 등
  • arg (argument): cmd에 필요한 인자들
  • return: cmd에 따라 다름

[EX] Changing FD flag

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
28
29
30
#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);
  if (fd==-1){ perror("open"); exit(1); }

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

  flags |= O_APPEND;

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

  if (write(fd, "KOREATECH", 9)!=9) perror("write");

  close(fd);

  return 0;
}
This post is licensed under CC BY 4.0 by the author.

23년 3월 3주차 주간 회고

[DSP] Section 3: 오디오 데이터 특징

Comments powered by Disqus.