leebaek

[UNIX프로그래밍] 3강 - File 다루기 본문

수업 정리/UNIX 프로그래밍

[UNIX프로그래밍] 3강 - File 다루기

leebaek 2024. 10. 12. 18:35

  • 파일 정보의 획득
  • access permission
  • permission 확인
  • 그 밖의 permission
  • 사용자와 소유권
  • access 시스템 호출
  • chmod 시스템 호출
  • link 시스템 호출
  • symbolic link

■ 파일 정보의 획득 시스템 호출 ( 파일 관련 각종 정보를 불러오기 )

□ stat  / fstat ( return 값 0 : 성공 | -1 : 실패 )

- stat 파일 경로를 기준 / fstat 이미 열린 파일 디스크립터 기준

 

> 헤더 파일

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *pathname, struct stat *buf);
int fstat(int fileds, struct stat *buf);

struct stat fileStat;
int fd = open("/usr/ben/abc", O_RDONLY);

// stat 사용 예시: 파일 경로를 사용해 파일 정보 얻기
stat("/usr/ben/abc", &fileStat)

// fstat 사용 예시: 열린 파일 디스크립터를 사용해 파일 정보 얻기
fstat(fd, &fileStat)

> stat 구조체

struct stat {
    dev_t     st_dev;     // 파일이 있는 장치의 ID
    ino_t     st_ino;     // 파일의 inode 번호
    mode_t    st_mode;    // 파일 모드 (파일 타입 및 접근 권한)
    nlink_t   st_nlink;   // 하드 링크의 개수
    uid_t     st_uid;     // 소유자의 사용자 ID
    gid_t     st_gid;     // 소유자의 그룹 ID
    dev_t     st_rdev;    // 장치 ID (특수 파일의 경우)
    off_t     st_size;    // 파일 크기 (바이트 단위)
    blksize_t st_blksize; // 파일 시스템 I/O의 블록 크기
    blkcnt_t  st_blocks;  // 할당된 512바이트 블록 수
    time_t    st_atime;   // 마지막 접근 시간
    time_t    st_mtime;   // 마지막 수정 시간
    time_t    st_ctime;   // 마지막 상태 변경 시간
};

■ access permission

□ file mode

read(4) + write(2) + execution(1)

owner : group : others

 

ex. 0755의 경우

owner : 읽기, 쓰기, 실행 = 7

group : 읽기, 실행 = 5

others : 읽기, 실행 = 5

 

□ 상징형 모드

 

  • 소유자 권한 (User - U):
    • S_IRUSR (읽기 권한) = 0400
    • S_IWUSR (쓰기 권한) = 0200
    • S_IXUSR (실행 권한) = 0100
    • S_IRWXU (읽기, 쓰기, 실행 권한) = 0700
  • 그룹 권한 (Group - G):
    • S_IRGRP (읽기 권한) = 0040
    • S_IWGRP (쓰기 권한) = 0020
    • S_IXGRP (실행 권한) = 0010
  • 기타 사용자 권한 (Other - O):
    • S_IROTH (읽기 권한) = 0004
    • S_IWOTH (쓰기 권한) = 0002
    • S_IXOTH (실행 권한) = 0001

 


■  permission 확인

struct stat s;

if (s.st_mode & S_IRUSR) { 3-7
    printf("소유자 읽기 권한 설정!!!\n");
}

if (S_ISREG(s.st_mode)) { // 3-5
    printf("일반 파일!!!\n");
}

 


■  그 밖의 permission

04000 S_ISUID : 실행이 시작되면, 실행한 사용자의 euid가 그 파일의 소유자 uid로 설정

02000 S_ISGID: 실행이 시작되면, 실행한 사용자의 egid가 그 파일의 소유자 gid로 설정

if (s.st_mode & S_ISGID) {
    printf("Setgid 비트가 설정되었습니다. 실행 시 소유 그룹의 GID가 egid가 됩니다.\n");
}

■  사용자와 소유권

소유권자 : 파일을 생성한 사람, user-id인 uid(, gid)로 구분

사용자 : 파일을 사용하는 사람, effective uer-id인 euid(, egid) 로 구분


■ access 시스템 호출 ( 특정 파일에 대한 읽기/쓰기/실행 가능한지 확인 )

□ 접근 ( return 값 0: 성공 | -1 : 실패 )

> 헤더 파일

#include <unistd.h>
int access(const char *pathname, int amode);

const char *filepath = "example.txt";

if (access(filepath, R_OK) == 0) {
        printf("읽기 권한이 있습니다.\n");
}

 

  • amode: 파일에 대한 접근 모드를 지정
    • R_OK: 읽기 권한이 있는지 확인
    • W_OK: 쓰기 권한이 있는지 확인
    • X_OK: 실행 권한이 있는지 확인
    • F_OK: 파일이 존재하는지 확인

파일 존재 확인 ( F_OK ) -> R_OK | W_OK | X_OK 순


■ chmod시스템 호출 ( 특정 파일에 access permission 변경 )

□ access 변경 ( return 값 0: 성공 | -1 : 실패 )

- 소유자만 사용 가능

 

> 헤더 파일

#include <sys/stat.h>
int chmod(const char *pathname, mode_t mode);
int fchmod(int fd, mode_t mode);

const char *filepath = "example.txt";
int fd = open(filepath, O_RDONLY);

// 새로운 권한을 764로 설정
mode_t new_mode = S_IRUSR | S_IWUSR | S_IXUSR |   // 소유자: rwx
                  S_IRGRP | S_IWGRP |           // 그룹: rw-
                  S_IROTH;                      // 기타: r--

chmod(filepath, new_mode);
fchmod(fd, new_mode);

■ link 시스템 호출 ( 기존 파일에 새로운 이름 부여 )

□ 이름 부여 ( return 값 0: 성공 | -1 : 실패 )

- hard link : 한 파일에 하나 이상의 이름

- link count : link의 수

 

> 헤더 파일

#include <unistd.h>
int link(const char *orgianl_path, const char *new_path);

const char *original_file = "example.txt"; // 기존 파일
const char *new_link = "example_link.txt"; // 새 하드 링크

link(original_file, new_link)

□ 이름 삭제 ( return 값 0: 성공 | -1 : 실패 )

- link count-- -> 만약 link_count = 0이 되면 실제로 파일 제거 ( free block으로 바뀜 )

const char *file_to_remove = "example_link.txt";

unlink(file_to_remove)

 

 

▷ link의 제한점 :

  • directory에 대한 link 생성 불가 ( 파일만 가능, 저장소 공유 불가 )
  • 다른 file system에 있는 file에 대해서는 link 생성 불가

-> symbolic link 사용


■ symbolic link 시스템 호출 (  파일  안에 다른 파일 경로 수록 ) 

□ 파일 경로 수록 ( return 값 0: 성공 | -1 ( synname이 이미 존재하면 ) : 실패 )

 

> 헤더 파일

#include <unistd.h>
int symlink(const char *realname, const char *symname);

const char *original_file = "example.txt"; // 원본 파일
const char *symbolic_link = "example_link.txt"; // 심볼릭 링크

symlink(original_file, symbolic_link)

□ symname 안에 있는 내용 읽기 ( return 값 원본 파일의 경로 길이 : 성공 | -1  : 실패 )

- 파일 경로를 저장할 버퍼와 버퍼 크기 지정

 

> 헤더 파일

#include <unistd.h>
int readlink(const char *sympath, char *buffer, size_t buffersize);

const char *symbolic_link = "example_link.txt"; // 심볼릭 링크
char buffer[256]; // 경로를 저장할 버퍼

// 심볼릭 링크의 경로 읽기
ssize_t len = readlink(symbolic_link, buffer, sizeof(buffer) - 1);

□ symbolic link 자체 파일 정보 ( return 값 0 : 성공 | -1  : 실패 )

- 파일 경로를 저장할 버퍼와 버퍼 크기 지정

 

> 헤더 파일

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int lstat(const char *linkname, struct stat *buf);

const char *symbolic_link = "example_link.txt"; // 심볼릭 링크
struct stat buf;

// lstat을 사용하여 심볼릭 링크 정보 얻기
lstat(symbolic_link, &buf);

 

* stat 사용시 symbolic link가 가리키는 파일 정보

* lstat 사용시 symbolic link 자체 파일 정보