시스템 소프트웨어

파일과 디렉토리 (File and Directory)

masimelo 2023. 2. 5. 19:18

파일의 정보

  • UFS
    • UNIX 계열의 운영체제에서 사용되는 파일 시스템
  • UFS는 4가지 유형의 파일이 있음
    • ordinary file
      • 일반 파일 : 텍스트 파일, 이진 파일 등
    • directory
      • 디렉토리
    • special file
      • 특수 파일 : 소켓, 디바이스 등
    • named
      • 지명 파이프 (Name pipe, FIFO)
  • UNIX 계열의 운영체제는 파일의 정보와 관련된 구조체, 함수 등을 제공함

struct stat{}

struct stat{
    dev_t st_dev; //device
    ino_t st_ino; //inode number
    mode_t st_mode; //protection
    nlink_t st_nlink; //number of hard link
    uid_t st_uid; //user id
    gid_t st_gid; //group id
    dev_t st_rdev; //devive type
    size_t st_size; //total size, bytes
    size_t st_blksize; //blocksize
    blkcnt_t st_blocks; //number of blocks allocated
    time_t st_atime; //time of last access
    time_t st_mtime; //time of last modification
    time_t st_ctime; //time of last change
}

stat() 함수

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

int stat(const char * pathname, struct stat * buf);
  • 설명
    • 유효한 파일인 경우에 파일의 정보를 읽고, 이를 메모리 공간에 저장함
    • 파일이 심볼릭 링크인 경우에, 링크가 가리키는 원본 파일의 정보를 읽음
  • 인자
    • pathname : 파일의 이름 또는 경로
    • buf : 파일의 정보를 저장할 메모리 공간에 대한 포인터
  • 반환
    • 성공 시 0
    • 오류시 -1

lstat() 함수

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

int lstat(const char * pathname, struct stat * buf);
  • 설명
    • 유효한 파일인 경우에 파일의 정보를 읽고, 이를 메모리 공간에 저장함
    • 파일이 심볼릭 링크인 경우에, 링크가 가리키는 원본 파일의 정보를 읽음
  • 인자
    • pathname : 파일의 이름 또는 경로
    • buf : 파일의 정보를 저장할 메모리 공간에 대한 포인터
  • 반환
    • 성공 시 0
    • 오류시 -1

fstat() 함수

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

int fstat(int fd, struct stat * buf);
  • 설명
    • 유효한 파일인 경우에 파일의 정보를 읽고, 이를 메모리 공간에 저장함
    • 파일이 심볼릭 링크인 경우에, 링크가 가리키는 원본 파일의 정보를 읽음
  • 인자
    • fd : 파일 지시자
      • open()을 이용하여 파일에 먼저 접근하고, 반환된 파일지시자 이용
    • buf : 파일의 정보를 저장할 메모리 공간에 대한 포인터
  • 반환
    • 성공시 0
    • 오류시 -1

링크

  • 파일 또는 디렉토리를 직접 복사하지 않고, 파일 또는 디렉토리를 가리키는 것을 의미
  • 하드 링크
    • 원본 파일과 동일한 inode를 가지는 링크
    • 원본파일이 사라지더라도, 하드링크를 통해 접근이 가능
  • 심볼릭 링크
    • 원본파일을 가리키는 포인터
    • 원본파일과 다른 inode를 가짐
    • 원본 파일이 사라지면, 심볼릭 링크를 통해 접근이 불가능함

stat()와 lstat() 함수 예시

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main(void) {
    int r = 0;
    char *pathname = "/usr/bin/vi";

    struct stat buf1;
    struct stat buf2;

    r = stat(pathname, &buf1);
    if (r == -1) {
        perror("stat() error");
        exit(-1);
    }
    r = lstat(pathname, &buf2);
    if (r == -1) {
        perror("lstat() error");
        exit(-1);
    }
    printf("Original file size : %ld\\n", buf1.st_size);
    printf("Symbolic link file size : %ld\\n", buf2.st_size);
}

fstat() 함수 예시

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#define MAX_BUF_SIZE 16
#define PERMS 0644

int main(void) {
    int fd1 = 0;
    char *pathname1 = "./original.txt";
    struct stat fileinfo;
    char *text;

    int fd2 = 0;
    char *pathname2 = "./copy.txt";

    fd1 = open(pathname1, O_RDONLY);
    if (fd1 == -1) {
        perror("open() error");
        exit(-1);
    }
    if (fstat(fd1, &fileinfo) == -1) {
        perror("fstat() error");
        exit(-1);
    }
    text = (char *)malloc(fileinfo.st_size);
    memset(text, 0x00, fileinfo.st_size);
    if (read(fd1, (char *)text, fileinfo.st_size) == -1) {
        perror("read() error");
        exit(-1);
    }
    fd2 = open(pathname2, O_CREAT | O_WRONLY, PERMS);
    if (fd2 == -1) {
        perror("open() error");
        exit(-1);
    }
    if (write(fd2, text, fileinfo.st_size) == -1) {
        perror("write() error");
        exit(-1);
    }
    free(text);
    close(fd1);
    close(fd2);

    return 0;
}

파일 정보 매크로

  • 파일의 정보를 확인하는 매크로
    매크로 설명
    S_ISREG(mode_t mode) 일반 파일
    S_ISDIR(mode_t mode) 디렉토리
    S_ISLNK(mode_t mode) 심볼릭 링크
    S_ISSOCK(mode_t mode) 소켓
    S_ISFIFO(mode_t mode) FIFO
    S_ISCHR(mode_t mode) 문자 장치 파일
    S_ISBLK(mode_t mode) 블록 장치 파일
    S_TYPEISMQ(mode_t mode) 메시지 큐
    S_TYPEISSEM(mode_t mode) 세마포어
    S_TYPEISSHM(mode_t mode) 공유 메모리 객체

struct passwd{}

#include <pwd.h>
#include <sys/types.h>

struct passwd{
        char *pw_name; //user login name
    char *pw_passwd; //encrypted password
    uid_t pw_uid; // user id
    gid_t pw_gid; // group id
    time_t pw_change; //passwd change time
    char *pw_class; // user acess class
    char *pw_gecos; // user full name
    char *pw_dir; // user login dir
    char *pw_shell; // user login shell
    time_t pw_expire; // passwd expiration time
}

getpwuid() 함수

#include <pwd.h>

struct passwd * getpwuid(uid_t uid);
  • 설명
    • UID로 사용자의 정보를 읽고 이를 메모리 공간에 저장하고 반환함
  • 인자
    • uid : 사용자의 ID (UID)
  • 반환
    • 성공 시 사용자의 정보를 저장한 passwd 구조체 포인터
    • 오류시 NULL

stat()과 getpwuid() 함수 예시

#include <fcntl.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#define MAX_BUF_SIZE 16
#define PERMS 0644

void fileType(const struct stat *fileinfo) {
    if (S_ISREG(fileinfo->st_mode)) {
        printf("Regular file");
    } else if (S_ISDIR(fileinfo->st_mode))
        printf("Directory");
    else if (S_ISCHR(fileinfo->st_mode))
        printf("Character device");
    else if (S_ISSOCK(fileinfo->st_mode))
        printf("Socket");
    else if (S_ISFIFO(fileinfo->st_mode))
        printf("FIFO");
    else if (S_ISLNK(fileinfo->st_mode))
        printf("Symbolic link");
    else if (S_ISBLK(fileinfo->st_mode))
        printf("Block device");
    else if (S_TYPEISMQ(fileinfo))
        printf("Message Queue");
    else if (S_TYPEISSHM(fileinfo))
        printf("Shared memory");
    else if (S_TYPEISSEM(fileinfo))
        printf("semaphore");
}
void fileMode(const struct stat *fileinfo) {
    if (S_IRUSR & fileinfo->st_mode) {
        printf("r");
    } else {
        printf("-");
    }
    if (S_IWUSR & fileinfo->st_mode) {
        printf("w");
    } else {
        printf("-");
    }
    if (S_IXUSR & fileinfo->st_mode) {
        printf("x");
    } else {
        printf("-");
    }
    if (S_IRGRP & fileinfo->st_mode) {
        printf("r");
    } else {
        printf("-");
    }
    if (S_IWGRP & fileinfo->st_mode) {
        printf("w");
    } else {
        printf("-");
    }
    if (S_IXGRP & fileinfo->st_mode) {
        printf("x");
    } else {
        printf("-");
    }
    if (S_IROTH & fileinfo->st_mode) {
        printf("r");
    } else {
        printf("-");
    }
    if (S_IWOTH & fileinfo->st_mode) {
        printf("w");
    } else {
        printf("-");
    }
    if (S_IXOTH & fileinfo->st_mode) {
        printf("x");
    } else {
        printf("-");
    }
}

int main(int argc, char const *argv[]) {
    struct stat fileinfo;
    struct passwd *userinfo;

    if (argc != 2) {
        printf("Usage : %s [pathname]\\n", argv[0]);
        exit(-1);
    }

    printf("File name or path : %s\\n", argv[1]);
    if (stat(argv[1], &fileinfo) == -1) {
        perror("stat() error");
        exit(-1);
    }
    printf("File type : ");
    fileType(&fileinfo);
    printf("File permission : ");
    fileMode(&fileinfo);

    printf("\\nFile size: %ld\\n", fileinfo.st_size);

    userinfo = getpwuid(fileinfo.st_uid);
    printf("Owner name : %s\\n", userinfo->pw_name);

    return 0;
}

 

디렉토리

  • UNIX 계열의 운영체제에서 디렉토리는 파일의 한 종류임
  • 디릭토리는 파일의 목록을 저장하는 파일
    • 파일을 포함하여 하위 디렉토리 또한 포함할 수 있음
  • 디렉토리는 creat() 또는 open() 함수를 이용하여 생성이 불가능함
  • 구조적으로 디렉토리는 일련의 디렉토리 엔트리로 구성됨
    • 각 엔트리는 디렉토리에 포함되어 있는 파일 또는 디렉토리임
    • 각 엔트리는 파일의 inode번호와 파일의 읾을 저장하는 문자 필드로 구성됨

struct dirent{}

#include <dirent.h>

struct dirent{
    ino_t d_ino; //inode number of entry
    unsigned int d_reclen; //length of this record
    unsigned int d_type; // file type
    unsigned int d_namlen; //length if string in d_name
    char d_name{MAXNAMLEN +1]; //file name
}

chdir() 함수

#include <unistd.h>

int chdir(const char *pathname);
  • 설명
    • 작업 디렉토리를 변경함
  • 인자
    • pathname : 디렉토리의 이름 또는 경로
  • 반환
    • 성공시 0
    • 오류시 -1

getcwd() 함수

#include <unistd.h>

char * getcwd(char * buf, size_t size);
  • 설명
    • 현재 작업 디렉토리의 경로를 얻고, 이를 메모리 공간에 저장함
  • 인자
    • buf : 현재 작업 디렉토리의 경로를 저장할 메모리 공간에 대한 포인터
    • size : 저장할 경로의 길이
  • 반환
    • 오류시 NULL

chdir()과 getcwd() 함수 예제

#include <fcntl.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#define MAX_PATH_LEN 1024

int main(int argc, char const *argv[]) {
    char cwd[MAX_PATH_LEN + 1] = {
        '\\0',
    };
    if (getcwd(cwd, MAX_PATH_LEN) == NULL) {
        perror("getcwd() error");
        exit(-1);
    }
    printf("Current work directory : %s\\n", cwd);
    if (chdir("..") == -1) {
        perror("chdir() error");
        exit(-1);
    }
    puts("Move to ..");
    if (getcwd(cwd, MAX_PATH_LEN) == NULL) {
        perror("getcwd() error");
        exit(-1);
    }
    printf("Current work directory : %s\\n", cwd);

    return 0;
}

mkdir() 함수

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

int mkdir(const char * pathname, mode_t mode);
  • 설명
    • 디렉토리를 지정한 접근권한으로 생성함
  • 인자
    • pathname : 디렉토리의 이름 또는 경로
    • mode : 파일의 접근 권한
  • 반환
    • 성공 시 0
    • 오류시 -1

mkdir() 함수 예시

#include <fcntl.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#define PERMS 0755
#define MAX_PATH_LEN 1024

int main(int argc, char const *argv[]) {
    if (argc != 2) {
        printf("Usage : %s [pathname]\\n", argv[0]);
        exit(-1);
    }
    if (mkdir(argv[1], PERMS) == -1) {
        perror("mkdir() error");
        exit(-1);
    }

    return 0;
}

rmdir() 함수

#include <unistd.h>

int rmdir(const char*pathname);
  • 설명
    • 비어있는 디렉토리를 삭제함
  • 인자
    • pathname : 디렉토리의 이름 또는 경로
  • 반환
    • 성공시 0
    • 오류시 -1

opendir() 함수

#include <dirent.h>

DIR * opendir(const char* pathname);
  • 설명
    • 유효한 디렉토리인 경우 디렉토리의 정보를 읽고, 디렉토리 스트림 핸들을 반환함
  • 인자
    • pathname : 디렉토리의 이름 또는 경로
  • 반환
    • 성공 시, 디렉토리 스트림에 대한 DIR * 핸들 (반환된 핸들은 첫번째 항목을 가리킴)
      • 디렉토리 스트림 : 특정 디렉토리 내의 모든 항목들에 대한 정보
    • 오류시 NULL

closedir() 함수

#include <dirent.h>

int closedir(DIR * dirp);
  • 설명
    • 유효한 디렉토리 스트림인 경우에, 디렉토리 스트림을 닫음
  • 인자
    • dirp : 디렉토리 스트림 핸들
  • 반환
    • 성공시 0
    • 오류시 -1

readdir() 함수

#include <dirent.h>

struct dirent * readdir(DIR * dirp);
  • 설명
    • 유효한 디렉토리 스트림인 경우에 디렉토리의 항목을 읽고, 이에 대한 정보를 반환함
  • 인자
    • dirp : 디렉토리 스트림 핸든
  • 반환
    • 성공시 디렉토리 항목을 저장한 struct dirent의 포인터
    • 오류시 NULL
    • 디렉토리를 끝까지 읽은 경우에 NULL

readdir() 함수 예시

#include <dirent.h>
#include <fcntl.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#define PERMS 0755
#define MAX_PATH_LEN 1024

int main(int argc, char const *argv[]) {
    struct stat fileinfo;

    DIR *dirp;
    struct dirent *dirinfo;

    if (argc != 2) {
        printf("Usage : %s [pathname}\\n", argv[0]);
        exit(-1);
    }
    if (stat(argv[1], &fileinfo) == -1) {
        perror("stat() error");
        exit(-1);
    }
    if (!S_ISDIR(fileinfo.st_mode)) {
        fprintf(stderr, "%s is not directory\\n", argv[1]);
        exit(-1);
    }
    dirp = opendir(argv[1]);
    while ((dirinfo = readdir(dirp)) != NULL) {
        printf("inode number : %ld, Name : %s\\n", dirinfo->d_ino,
               dirinfo->d_name);
    }
    closedir(dirp);
    return 0;
}

'시스템 소프트웨어' 카테고리의 다른 글

연결 리스트 (Linked list)  (0) 2023.03.08
배열과 문자열 (Array and String)  (0) 2023.03.07
시그널 (Signal)  (0) 2023.03.07
프로세스 (Process)  (0) 2023.02.05
파일 입출력 (File Input Output)  (0) 2023.02.04