Linux/UNIX Programming APUE (Files & Directories) 문양세 강원대학교 IT대학 컴퓨터과학전공
강의 목표 및 내용 강의 목표 강의 내용 파일의 상태 및 구조를 이해한다. 파일 시스템 구현을 이해한다. APUE (Files & Directories) 강의 목표 파일의 상태 및 구조를 이해한다. 파일 시스템 구현을 이해한다. 디렉토리 구조 및 구현을 이해한다. 강의 내용 파일 상태 파일 접근 허가권 파일 시스템 구현 링크 (link) 디렉토리
stat() – 파일 상태 확인 역할: 주어진 파일에 대한 정보를 stat 구조체에 얻어 온다. APUE (Files & Directories) #include <sys/types.h> #include <sys/stat.h> int stat (const char *pathname, struct stat *buf ); int fstat (int filedes, struct stat *buf ); int lstat (const char *pathname, struct stat *buf ); 역할: 주어진 파일에 대한 정보를 stat 구조체에 얻어 온다. buf: stat 구조체에 대한 포인터 (정보를 가져올 장소) lstat()은 Symbolic Link가 가리키는 파일이 아닌 Symbolic Link 자체에 대한 정보를 얻는다. 리턴 값: 성공하면 0, 실패하면 -1
stat 구조체 (1/3) <sys/stat.h>에 정의 struct stat { APUE (Files & Directories) <sys/stat.h>에 정의 struct stat { mode_t st_mode; /* file type & mode (permissions) */ ino_t st_ino; /* i-node number (serial number) */ dev_t st_dev; /* device number (filesystem) */ dev_t st_rdev; /* device number for special files */ nlink_t st_nlink; /* number of links */ uid_t st_uid; /* user ID of owner */ gid_t st_gid; /* group ID of owner */ off_t st_size; /* size in bytes, for regular files */ time_t st_atime; /* time of last access */ time_t st_mtime; /* time of last modification */ time_t st_ctime; /* time of last file status change */ long st_blksize;/* best I/O block size */ long st_blocks; /* number of 512-byte blocks allocated */ };
UNIX/Linux 종류 및 버전에 따라 stat 구조체는 다를 수 있음! APUE (Files & Directories) stat 구조체의 예 UNIX/Linux 종류 및 버전에 따라 stat 구조체는 다를 수 있음!
stat 구조체 (3/3) st_atime: 마지막으로 파일의 데이터를 읽은 시각 APUE (Files & Directories) st_atime: 마지막으로 파일의 데이터를 읽은 시각 st_mtime: 마지막으로 파일의 데이터를 수정한 시각 st_ctime: 파일의 내용이 아니고 이름/권한 같은 상태를 변경한 시각 st_blksize: 가장 효율적인 I/O 블럭 크기 (예: 8192 bytes) st_blocks: 파일이 차지하고 있는 공간의 크기 (512 byte의 블록 수)
파일 타입 (1/3) 보통 파일 (Regular File) 디렉토리 파일 (Directory File) APUE (Files & Directories) 보통 파일 (Regular File) 데이터를 포함하고 있는 텍스트 또는 이진 파일 디렉토리 파일 (Directory File) 파일의 이름들과 파일 정보에 대한 포인터들을 포함 문자 특수 파일 (Character Special File) 시스템에 장착된 어떠 장치를 가리키는 파일 문자 단위로 데이터를 전송하는 장치 (c---------) 블록 특수 파일 (Block Special File) 시스템에 장착된 어떤 장치를 가리키는 파일 블럭 단위로 데이터를 전송하는 장치 (b---------)
파일 타입 (2/3) APUE (Files & Directories) 특수 파일 예제
파일 타입 (3/3) FIFO 소켓 (socket) 심볼릭 링크 (Symbolic link) APUE (Files & Directories) FIFO 프로세스 간 통신에 사용되는 파일 (IPC Programming에서 사용됨) Named Pipe라고도 부름 소켓 (socket) 네트워크를 통한 프로세스 간 통신에 사용되는 파일 Network Programming에서 사용하는 보편적인 방법 심볼릭 링크 (Symbolic link) 다른 파일을 가리키는 포인터 역할을 하는 파일 (Windows의 “바로가기”에 해당)
파일 타입 검사 (1/2) 파일 타입을 검사하는 매크로 함수 st_mode 해당 종류의 파일이면 1, 아니면 0을 리턴 APUE (Files & Directories) 파일 타입을 검사하는 매크로 함수 stat.h 파일(/usr/include/sys/stat.h)에 정의되어 있음 S_ISREG() : 정규 파일 S_ISDIR() : 디렉토리 파일 S_ISCHR() : 문자 특수 파일 S_ISBLK() : 블록 특수 파일 S_ISFIFO() : pipe 또는 FIFO S_ISLNK() : 심볼릭 링크 S_ISSOCK() : 소켓 해당 종류의 파일이면 1, 아니면 0을 리턴 stat 구조체의 st_mode 값을 검사함 st_mode type special permission 4 bits 3 bits 9 bits
파일 타입 검사 (2/2) 파일 타입 상수 S_ISxxx() 매크로 함수는 S_IFxxx 상수 값의 설정 여부를 판단 APUE (Files & Directories) 파일 타입 상수 stat.h 파일(/usr/include/sys/stat.h)에 정의되어 있음 S_IFREG : 정규 파일 S_IFDIR : 디렉토리 파일 S_IFCHR : 문자 특수 파일 S_IFBLK : 블록 특수 파일 S_IFFIFO : pipe 또는 FIFO S_IFLNK : 심볼릭 링크 S_IFSOCK : 소켓 S_ISxxx() 매크로 함수는 S_IFxxx 상수 값의 설정 여부를 판단
예제: stat.c (1/2) APUE (Files & Directories)
예제: stat.c (2/2) APUE (Files & Directories) 실행 결과 Symbolic Link 자체의 정보를 얻기 위해서는 stat() 대신 lstat()을 사용
파일 허가권 (File Permissions) (1/2) APUE (Files & Directories) File access permission bits (stat 구조체의 st_mode 값) st_mode st_mode mask Meaning Octal Code S_IRUSR user-read 0400 S_IWUSR user-write 0200 S_IXUSR user-execute 0100 S_IRGRP group-read 0040 S_IWGRP group-write 0020 S_IXGRP group-execute 0010 S_IROTH other-read 0004 S_IWOTH other-write 0002 S_IXOTH other-execute 0001 type special permission 4 bits 3 bits 9 bits
파일 허가권 (File Permissions) (2/2) APUE (Files & Directories) 실제 stat.h에 정의된 예제
관련 명령어 UNIX 명령어 chmod UNIX 명령어 chown (root만 사용 가능) APUE (Files & Directories) UNIX 명령어 chmod File Access Permission 설정 stat 구조체의 st_mode 값을 변경 UNIX 명령어 chown (root만 사용 가능) File 소유 User ID 설정 stat 구조체의 st_uid 값을 변경 UNIX 명령어 chgrp (root만 사용 가능) File 소유 Group ID 설정 stat 구조체의 st_gid
허가권 (Permissions) (1/3) Read 권한이 있어야 (open() 함수에서) APUE (Files & Directories) Read 권한이 있어야 (open() 함수에서) O_RDONLY, O_RDWR를 사용하여 파일을 열 수 있다. Write 권한이 있어야 (open() 함수에서) O_WRONLY, O_RDWR, O_TRUNC를 사용하여 파일을 열 수 있다. 디렉토리에 write 권한과 execute 권한이 있어야 해당 디렉토리에 파일을 생성할 수 있고, 그 디렉토리의 파일을 삭제할 수 있다
허가권 (Permissions) (2/3) APUE (Files & Directories)
허가권 (Permissions) (3/3) APUE (Files & Directories) 파일이 포함된 모든 상위 디렉토리에 대해 execute 권한이 있어야 그 파일을 열 수 있다. 디렉토리에 대한 read 권한이 있어야 디렉토리 안에 들어 있는 파일 이름 목록을 읽을 수 있다. 디렉토리에 대한 write 권한이 있어야 디렉토리에 파일을 생성 삭제 할 수 있다. 디렉토리에 대한 execute 권한이 있어야 그 디렉토리나 그 하위 디렉토리에 있는 파일을 열 수 있다.
Effective User ID Real User ID와 Real Group ID APUE (Files & Directories) Real User ID와 Real Group ID 실제 사용자 ID와 그 사용자가 속한 그룹 ID 로그인한 사용자 ID 일반적으로, Shell 상에서 작업을 수행할 때의 User 및 Group ID로 이해할 수 있음 Effective User ID와 Effective Group ID 프로세스의 속성 일반적으로, 프로그램이 수행될 때의 User ID 및 Group ID로 이해할 수 있음 대부분의 경우 Real User ID 와 Real Group ID 가 사용되나, 다음에 설명하는 S_ISUID와 S_ISGID 비트가 Set된 경우에는 다르게 동작함
S_ISUID와 S_ISGID (1/3) stat 구조체의 st_mode의 비트로 표현됨 st_mode APUE (Files & Directories) stat 구조체의 st_mode의 비트로 표현됨 S_ISUID : set-user-ID S_ISGID : set-group-ID st_mode의 S_ISUID 비트가 설정된 실행 파일을 실행한 경우 그 실행 파일이 실행된 프로세스의 Effective User ID는 Real User ID가 아니고, 그 실행 파일 소유자의 User ID가 된다. st_mode의 S_ISGID 비트가 설정된 실행 파일을 실행한 경우 그 실행 파일이 실행된 프로세스의 Effective Group ID는 Real Group ID가 아니고, 그 실행 파일 소유자의 group ID가 된다. st_mode type special permission 4 bits 3 bits 9 bits
S_ISUID와 S_ISGID (2/3) S_ISUID, S_ISGID 모두가 설정된 실행 파일을 실행하는 경우 APUE (Files & Directories) S_ISUID, S_ISGID 모두가 설정된 실행 파일을 실행하는 경우 Real User ID, Real Group ID 의 권한이 아니고, 그 파일 소유 User ID, Group ID 의 권한으로 실행됨 예제) passwd 명령어: 실행은 아무나 하나, root 권한으로 수행되어야 함
S_ISUID와 S_ISGID (3/3) passwd 명령어가 수행될 때의 effective user ID APUE (Files & Directories) passwd 명령어가 수행될 때의 effective user ID
access() Real User ID와 Real Group ID로 파일의 허가권 검사 리턴 값: 성공하면 0, 실패하면 -1 APUE (Files & Directories) #include <unistd.h> int access ( const char *pathname, int mode ); Real User ID와 Real Group ID로 파일의 허가권 검사 리턴 값: 성공하면 0, 실패하면 -1 mode 값 mode Description R_OK test for read permission W_OK test for write permission X_OK test for execute permission F_OK test for existence of tile
예제: access() (1/2) APUE (Files & Directories)
예제: access() (2/2) APUE (Files & Directories)
chmod(), fchmod() 파일에 대해 Access Permission을 변경한다 리턴 값: 성공하면 0, 실패하면 -1 APUE (Files & Directories) #include <sys/stat.h> #include <sys/types.h> int chmod (const char *pathname, mode_t mode ); int fchmod (int filedes, mode_t mode ); 파일에 대해 Access Permission을 변경한다 stat 구조체의 st_mode 변경 리턴 값: 성공하면 0, 실패하면 -1 mode : bitwise OR S_ISUID, S_ISGID, S_ISVTX S_IRUSR, S_IWUSR, S_IXUSR S_IRGRP, S_IWGRP, S_IXGRP S_IROTH, S_IWOTH, S_IXOTH
예제: chmod() (1/2) APUE (Files & Directories)
예제: chmod() (2/2) APUE (Files & Directories) 실행 결과
chown() 파일의 User ID와 Group ID를 변경한다. 리턴 값: 성공하면 0, 실패하면 -1 APUE (Files & Directories) #include <sys/types.h> #include <unistd.h> int chown (const char *pathname, uid_t owner, gid_t group ); int fchown (int filedes, uid_t owner, gid_t group ); int lchown (const char *pathname, uid_t owner, gid_t group ); 파일의 User ID와 Group ID를 변경한다. stat 구조체의 st_uid, st_gid 변경 리턴 값: 성공하면 0, 실패하면 -1 lchown()은 심볼릭 링크 자체를 변경한다. UNIX 종류 및 버전에 따라 차이가 있을 수 있다. BSD 기반 시스템에서는 super-user만 변환 가능 System V 계열 시스템은 일반 사용자도 변경 가능
truncate(), ftruncate() APUE (Files & Directories) #include <sys/types.h> #include <unistd.h> int truncate (const char *pathname, off_t length ); int ftruncate (int filedes, off_t length ); 파일의 크기를 주어진 length로 줄인다. 리턴 값: 성공하면 0, 실패하면 -1
truncate() 예제 APUE (Files & Directories)
강의 목표 및 내용 강의 목표 강의 내용 파일의 상태 및 구조를 이해한다. 파일 시스템 구현을 이해한다. APUE (Files & Directories) 강의 목표 파일의 상태 및 구조를 이해한다. 파일 시스템 구현을 이해한다. 디렉토리 구조 및 구현을 이해한다. 강의 내용 파일 상태 파일 접근 허가권 파일 시스템 구현 - skip 링크 (link) 디렉토리
Block I/O I/O is always done in terms of blocks. APUE (Files & Directories) I/O is always done in terms of blocks. Sequence of a read() system call
Inode (Index Node) 한 파일은 하나의 i-node를 갖는다. 파일에 대한 정보를 가지고 있다. APUE (Files & Directories) 한 파일은 하나의 i-node를 갖는다. 파일에 대한 정보를 가지고 있다. file size file permissions the owner and group ids the last modification and last access times if it's a regular or directory, the location of data blocks if it's a special file, device numbers if it's a symbolic link, the value of the symbolic link stat 구조체의 필드는 i-node 에서 읽어온다.
The Block Map (1/2) Direct block pointers Indirect block pointer APUE (Files & Directories) Direct block pointers 10 direct block pointers Indirect block pointer an indirect block to address 1024 blocks Double indirect block pointer an double indirect block to contain 1024 indirect block pointers How many blocks can be addressed?
The Block Map (2/2) Inode Disk blocks . . . Direct block pointers APUE (Files & Directories) Inode Disk blocks Direct block pointers to blocks 0 .. 9 . . . To blocks 10 .. 1033 (1024 blocks) Indirect pointers Double indirect pointers Locates up to 1000 indirects To blocks 1034 .. 2057
File System Layout (1/3) Boot Block APUE (Files & Directories) Boot Block Boot code that is used when UNIX is first activated. Super Block (information about the entire file system) the total number of blocks in the file system the number of inodes in the inode free list a bit map of free blocks the size of block in bytes the number of free blocks the number of used blocks
File System Layout (2/3) i-list (다음 페이지 참조) User Blocks Bad Blocks APUE (Files & Directories) i-list (다음 페이지 참조) all the inodes associated with the files on the disk each block in the inode list can hold about 40 inodes User Blocks for storing file blocks Bad Blocks Several block that cannot be used
File System Layout (3/3) Inodes 1..40 Inodes 41..80 . . . Boot block APUE (Files & Directories) . . . Boot block Super block i-list User block User blocks Inodes 1..40 Inodes 41..80 1 2 3 200 201
강의 목표 및 내용 강의 목표 강의 내용 파일의 상태 및 구조를 이해한다. 파일 시스템 구현을 이해한다. APUE (Files & Directories) 강의 목표 파일의 상태 및 구조를 이해한다. 파일 시스템 구현을 이해한다. 디렉토리 구조 및 구현을 이해한다. 강의 내용 파일 상태 파일 접근 허가권 파일 시스템 구현 링크 (link) 디렉토리
unlink() 파일을 삭제하는 역할을 수행함 (엄밀히 말해서, 파일의 link count를 감소시킴) APUE (Files & Directories) #include <unistd.h> int unlink (const char *pathname); 파일을 삭제하는 역할을 수행함 (엄밀히 말해서, 파일의 link count를 감소시킴) stat 구조체의 st_mode 변경 리턴 값: 성공하면 0, 실패하면 -1 파일이 삭제될 경우, inode와 data block이 삭제(free)된다.
예제: unlink() (1/2) APUE (Files & Directories)
예제: unlink() (2/2) APUE (Files & Directories) 실행 결과
symlink() - Symbolic Link – skip APUE (Files & Directories) Symbolic Link는 파일에 대한 간접적인 포인터임 실제 파일에 대한 “경로”를 저장하고 있는 파일임 #include <unistd.h> int symlink (const char *actualpath, const char *sympath ); Symbolic Link를 만든다. Symbolic Link File의 내용은 actualpath에 해당함 Symbolic Link File의 크기는 actualpath 문자열의 길이 (즉, 저장되는 내용이 문자열) 리턴 값: 성공하면 0, 실패하면 -1 파라미터 설명 actualpath: 실제 파일 sympath: 만들 Symbolic Link의 이름
파일 관련 시간 stat 구조체의 st_atime stat 구조체의 st_mtime stat 구조체의 st_ctime APUE (Files & Directories) stat 구조체의 st_atime 파일의 데이터가 마지막으로 읽혔던(read 되었던) 시간 즉, 마지막으로 read()가 호출된 시간 stat 구조체의 st_mtime 파일의 데이터가 마지막으로 변경(write)된 시간 즉, 마지막으로 write()가 호출된 시간 stat 구조체의 st_ctime 파일의 stat 구조체의 내용이 마지막으로 변경된 시간 chmod(), chown() 등이 호출된 시간
utime() 파일의 최종 접근 시간과 최종 변경 시간을 조정한다. times가 NULL 이면, 현재시간으로 설정된다. APUE (Files & Directories) #include <sys/types.h> #include <utime.h> int utime (const char *pathname, const struct utimbuf *times ); 파일의 최종 접근 시간과 최종 변경 시간을 조정한다. times가 NULL 이면, 현재시간으로 설정된다. 리턴 값: 성공하면 0, 실패하면 -1 UNIX 명령어 touch 참고 struct utimbuf { time_t actime; /* access time */ time_t modtime; /* modification time */ } 각 필드는 1970-1-1 00:00 부터 현재까지의 경과 시간을 초로 환산한 값
utime() 예제: utime.c (1/2) APUE (Files & Directories)
utime() 예제: utime.c (2/2) APUE (Files & Directories)
디렉토리 (Directory) 디렉토리 파일 디렉토리 파일의 내용은 구조체 dirent의 배열 형태로 저장됨 APUE (Files & Directories) 디렉토리 파일 일종의 파일이므로 open, read, close 함수 등을 사용할 수 있다. 디렉토리 파일 사용에 편리한 새로운 함수들도 제공된다. 디렉토리 파일의 내용은 구조체 dirent의 배열 형태로 저장됨 file name: 파일 이름, 하위 디렉토리 이름, “.”, “..” i-node number #include <dirent.h> struct dirent { ino_t d_ino; /* i-node number */ char d_name[NAME_MAX + 1]; /* filename */ }
디렉토리 접근 (opendir(), readdir()) APUE (Files & Directories) #include <sys/types.h> #include <dirent.h> DIR *opendir (const char *pathname); struct dirent *readdir(DIR *dp); opendir()로 디렉토리 파일을 열고, readdir()로 디렉토리 파일의 내용을 읽는다. 읽을 때마다 디렉토리 파일의 current file offset은 읽은 구조체 dirent의 크기 만큼 증가한다. 디렉토리의 항목 읽기 위해서는 해당 디렉토리에 대한 읽기 권한이 있어야 한다. 그러나, 쓰기권한이 있어도 write 함수로 직접 쓸 수는 없으며, mkdir(), rmdir() 함수를 사용해야 한다. 리턴 값: 성공하면 구조체 주소, 실패하면 NULL
rewinddir(), closedir() APUE (Files & Directories) #include <sys/types.h> #include <dirent.h> void rewinddir (DIR *dp); int closedir (DIR *dp); rewinddir() 디렉토리 파일의 current file offset을 처음으로 옮긴다. (첫 번째 엔트리로 옮긴다.) closedir() 디렉토리 파일을 닫는다. 리턴 값: 성공하면 0, 실패하면 -1
mkdir() 새로운 디렉토리를 만든다. 리턴 값: 성공하면 0, 실패하면 -1 APUE (Files & Directories) #include <sys/types.h> #include <sys/stat.h> int mkdir (const char *pathname, mode_t mode ); 새로운 디렉토리를 만든다. 리턴 값: 성공하면 0, 실패하면 -1 성공하면, “.”와 “..” 파일은 자동적으로 만들어진다. “.”은 현재 디렉토리 파일의 i-node를, “..”은 부모 디렉토리 파일의 i-node를 각각 가리킨다.
rmdir() 비어있는 디렉토리를 삭제한다. 리턴 값: 성공하면 0, 실패하면 -1 APUE (Files & Directories) #include <unistd.h> int rmdir (const char *pathname ); 비어있는 디렉토리를 삭제한다. 리턴 값: 성공하면 0, 실패하면 -1
가장 자주 사용하는 “ls” 명령어를 만들어 봅시다. 어떻게 만드나? 예제: listfiles.c (1/7) APUE (Files & Directories) 가장 자주 사용하는 “ls” 명령어를 만들어 봅시다. 어떻게 만드나? 디렉토리 관련 함수 opendir(), readdir(), closedir()을 사용 해당 디렉토리의 파일 이름을 알아낸다. 파일 상태함수 lstat()을 사용 파일의 크기, permission, 생성 일자 등을 알아낸다.
예제: listfiles.c (2/7) APUE (Files & Directories)
예제: listfiles.c (3/7) APUE (Files & Directories)
예제: listfiles.c (4/7) APUE (Files & Directories)
예제: listfiles.c (5/7) APUE (Files & Directories)
예제: listfiles.c (6/7) APUE (Files & Directories)
예제: listfiles.c (7/7) APUE (Files & Directories)
chdir(), fchdir() 현재 작업 디렉토리를 변경한다. ($ cd) 반환 값: 성공하면 0, 실패하면 -1 APUE (Files & Directories) #include <unistd.h> int chdir (const char *pathname); int fchdir (int filedes); 현재 작업 디렉토리를 변경한다. ($ cd) 반환 값: 성공하면 0, 실패하면 -1 현재 작업 디렉토리는 프로세스의 속성 (프로세스의 working directory가 변하는 것임)
getcwd() 현재 작업 디렉토리의 경로명을 얻는다. ($ pwd) 반환 값: 성공하면 buf의 주소, 실패하면 NULL APUE (Files & Directories) #include <unistd.h> char *getcwd (char *buf, size_t size ); 현재 작업 디렉토리의 경로명을 얻는다. ($ pwd) 반환 값: 성공하면 buf의 주소, 실패하면 NULL
예제: chdir(), getcwd() (1/2) APUE (Files & Directories)
예제: chdir(), getcwd() (2/2) APUE (Files & Directories) 실행 결과
sync(), fsync() 버퍼에 있는 내용을 디스크에 쓰도록 한다. APUE (Files & Directories) #include <unistd.h> void sync(); int fsync(int filedes); 버퍼에 있는 내용을 디스크에 쓰도록 한다. sync()는 시스템 데몬 프로세스에 의해서 30초마다 호출된다. fsync()는 지정된 파일에 대해서만 I/O 작업을 수행하도록 한다. 참고) O_SYNC 플래그 (모든 write()를 sync mode로 처리함)