본문 바로가기
전공/유닉스

3장. 파일과 디렉토리

by 임 낭 만 2023. 11. 1.

파일 정보의 획득

  • 파일 관련 각종 정보를 알아볼 수 있는 system call
  • 사용법 :
    • fstat는 open된 file에 대한 정보를 획득
    • buf엔 file 정보가 저장
#include<fcntl.h>
#include<sys/types.h> 
#include<sys/stat.h>

int stat (const char *pathname, struct stat *buf);
int fstat (int filedes, struct stat *buf);
//stat : 파일을 open하지 않은채로 정보 얻음.
//fstat : 파일을 open해놓고 파일 정보 얻음. 따라서 첫번째 인수 fd
//두 번째 인자 : 정보를 저장해야 될 공간의 주소
  • buf 에 채워진 내용은?
    • st_dev, st_ino : identifier (논리적 장치번호와 inode 번호)
    • st_mode : permission mode
    • st_nlink : link의 수 (파일에 붙어있는 이름의 개수)
    • st_uid, st_gid : user의 uid와 gid (만든 사람의 user id, 어떤 그룹에 속해있는지 group id)
    • st_rdev : file이 장치인 경우만 사용
    • st_size : 논리적 크기
    • st_atime, st_mtime, st_ctime : file의 최근 access time, update time, stat 구조의 update time
    • st_blksize : I/O block 크기
    • st_blocks : 파일에 할당된 block의 수
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>	//ctime함수 사용하기 위해
int main(void) {
	struct stat buf;	//정보 저장할 공간

	stat("p1.c", &buf);
	printf("%o, %ld\n", buf.st_mode & 0777, buf.st_size);
    printf("%s", ctime(&buf.st_mtime));	//주소를 넣어줘야함

	return 0;
}
//mode랑 시간을 제외하고는 대부분 정수 %d or %ld

access permission

  • file mode : 0764=0400+0200+0100+0040+0020+0004
    • owner:group:others:
    • read(4)+write(2)+execution(1)
  • 상징형 모드 : page 136, 표 3.9
    • 0764 = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IROTH

permission 확인

if (s.st_mode&S_IRUSR)
	printf(“소유자 읽기 권한 설정!!!”);
//비트 연산자를 통해 설정된 권한을 알 수 있음
  • 파일 접근 권한 확인 상수 : page 136, 표3-9
if (S_ISREG(s.st_mode))
	printf(“일반 파일!!!”);
//이 값이 1이면 디렉토리가 아닌 일반 파일
  • 파일 종류 확인 상수 : page 132, 표3-6
  • 파일 종류 검색 매크로 : page 134, 표3-7

그 밖의 permission

  • 04000 S_ISUID : 실행이 시작되면, 소유자의 uid가 euid 가 된다.
  • 02000 S_ISGID : 실행이 시작되면, 소유자의 gid가 egid 가 된다.

사용자와 소유권

  • 소유권자 : 파일을 생성한 사람, user-id인 uid로 구분 (gid)
  • 사용자 : 파일을 사용하는 사람, effective user-id인 euid 로 구분 (egid)

access 시스템 호출

  • 특정 파일에 대한 읽기/쓰기/실행이 가능한지 확인하는 system call
  • 사용법 :
#include <unistd.h> 

int access(const char *pathname, int amode);
//amode 파일 존재하는지 : F_OK
  • 인수 사용법 :
    • amode : R_OK , W_OK, X_OK, 또는 F_OK
    • return 값 : 0 or -1
    • euid가 아니라 uid에 근거하여 process가 file에 접근 가능한지를 표현
int main(void) {
	
	printf("%d\n", access("test1.c", F_OK));
	printf("%d\n", access("test2.c", F_OK | R_OK | W_OK));
	chmod("test2.c", 0400);
	printf("%d\n", access("test2.c", F_OK | R_OK | W_OK));

	return 0;
}
// | : or 표시가 아니라 and 개념임

 

chmod 시스템 호출

  • 특정 파일의 access permission을 변경하는 system call
  • 사용법 :
#include <sys/types.h> 
#include <sys/stat.h>

int chmod(const char *pathname, mode_t mode); 
int fchmod(int fd, mode_t mode);
//fchmod는 파일을 오픈하고 오픈한 파일에 대해서 변경
  • 소유자만 사용 가능

link 시스템 호출

  • 기존 파일에 새로운 이름을 부여하는 system call
    • 한 파일에 하나 이상의 이름 : 각 이름을 "hard link" 라 부름
    • link count : link의 수
  • 사용법:
    • return값 : 0 or -1 (new_path가 이미 존재하면.)
#include <unistd.h> 

int link (const char *orginal_path, const char *new_path);
//첫 번째 인수 : 원래 파일 이름
//두 번째 인수 : 새로 붙이려고 하는 파일 이름
//실패 경우 : 파일 없는 경우, 이미 존재하는 파일의 이름인 경우
  • unlink의 재검토 : unlink("a.out");
    • 실은 link를 제거 → link_count--
    • 만약, link_count가 0이 되면 실제로 제거 (free block으로)
int main(void) {
	
	link("test1", "test2");
	link("test1", "A/B/C/test3");	//A 밑 B 밑 C 디렉토리 밑에 test3

	return 0;
}
//세 파일은 모두 같은 파일. 이름만 다르게 붙어있는 것임 (바로가기랑 비슷)
//어느 하나의 파일 내용을 바꾸면 모두 바뀜
//같이 작업을 할 때 유용하게 사용 가능

 

symbolic link

  • symbol형 link
    • link의 제한점 :
      • directory에 대한 link 생성은 불가
      • 다른 file system에 있는 file에 대해서는 link 생성 불가
    • → symbolic link (자체가 file; 그 안에 다른 file에 대한 경로 수록; )
  • 사용법 :
    • return 값 : 0 or -1 (symname이 이미 존재 하면)
#include <unistd.h>

int symlink (const char *realname, const char *symname);
//디렉토리에 link 가능
int main(void) {
	
	symlink("A/B/C/test3", "test4");

	return 0;
}
//test4는 속성 l로 시작 (link). 완전히 별개의 파일
//test4가 가리키는 파일을 오픈하는 것임
  • open system call에 의해 open 가능; 어떤 파일이 open 되는지? realname? or symname?
  • readlink의 사용 : symname안에 있는 내용을 보고 싶으면.
#include <unistd.h>

int readlink (const char *sympath, char *buffer, size_t buffsize);
//파일을 오픈하지 않고 사용
int main(void) {
	char ch[100] = { 0 };

	readlink("test4", ch, 100);
	printf("%s\n", ch);

	return 0;
}
  • 사용법 :
#include <sys/types.h>
#include<sys/stat.h> 
int lstat (const char *linkname, struct stat *buf);
//symbolic link에 대한 stat명령
  • symbolic link가 가리키는 파일이 아닌 symbolic link 자체의 파일 정보를 전달
int main(void) {
	struct stat buf;

	stat("test4", &buf);	//test4가 가리키고 있는 파일에 대한 정보
	printf("%o, %ld\n", buf.st_mode & 0777, buf.st_size);
	printf("%s\n", ctime(&buf.st_mtime));

	lstat("test4", &buf);	//test4에 대한 정보
	printf("%o, %ld\n", buf.st_mode & 0777, buf.st_size);
	printf("%s\n", ctime(&buf.st_mtime));

	return 0;
}

directory 생성 및 제거 

  • directory 생성: directory file에 .과 ..을 넣어서 생성
#include <sys/types.h> 
#include <sys/stat.h> 
int mkdir(const char *pathname, mode_t mode);
  • directory 제거: directory가 비어 있을 경우에만 성공
#include <unistd.h> 
int rmdir(const char *pathname);

 

rename 시스템 호출

  • 사용법 :
    • file과 directory 둘 다 rename 가능
    • newpathname이 존재해도 -1이 아님. 기존 file을 제거하고 새 이름 부여
#include <stdio.h> 
int rename (const char *oldpathname, const char *newpathname);

 

getcwd 시스템 호출

  • 사용법 :
    • return 값 : current working directory의 경로 이름
    • size는 실제 길이 보다 +1이 커야 한다.
    • 성공 시 directory의 경로 이름이 name에 copy; 실패 시 null pointer return;
#include <unistd.h> 
char *getcwd(char *name, size_t size);

chdir 시스템 호출

  • 사용법 :
#include <unistd.h> 
int chdir(const char *path);
//디렉토리 바꾸는 명령
//current working directory가 바뀜
  • 예 :
fd1=open(“/usr/ben/abc”, O_RDONLY);
fd2=open(“/usr/ben/xyz”, O_RDWR);

//->
chdir(“/usr/ben”);
fd1=open(“abc”, O_RDONLY);
fd2=open(“xyz”, O_RDWR);
int main(void) {
	char ch[100] = { 0 };

	mkdir("T1", 0700);
	chdir("T1");
	mkdir("T2", 0700);
	chdir("T2");
	mkdir("T3", 0700);
	chdir("T3");

	getcwd(ch, 99);
	printf("%s\n", ch);

	return 0;
}
//실행 프로그램 안에서 디렉토리를 바꾼 것이므로 실행 프로그램 종료 후 다시 원래로 돌아옴
//쉘에는 영향을 주지 않음
//쉘 프로그램이 직접 실행한 것이 아니라 다른 프로세스에서 실행한 것임

 

directory 열기 및 닫기

  • directory 열기:
#include <sys/types.h> 
#include <dirent.h> 
DIR *opendir(const char *dirname);

→ DIR형의 data structure에 대한 pointer를 return; 실패 시 null pointer return;

  • directory 닫기:
#include <dirent.h> 
int closedir(DIR *dirptr);

directory 읽기

  • 사용법:
#include <sys/types.h> 
#include <dirent.h> 
struct dirent *readdir (DIR *dirptr);
  • return 값: dirptr이 가리키는 DIR 구조내의 한 항;
struct dirent : ino_t d_ino; 
		char d_name[];
  • pointer dirptr은 read 후 다음 항을 가리킨다.
  • directory의 끝에 도달하면 null pointer를 return;
int main(void) {
	DIR* dp;
	struct dirent* d;

	dp = opendir(".");
	d = readdir(dp);
	while (d != NULL) {
		printf("%ld: %s\n", d->d_ino, d->d_name);
		d = readdir(dp);
	}

	return 0;
}

 

directory file pointer 이동

  • 사용법 :
#include <sys/types.h> 
#include <dirent.h> 
void rewinddir(DIR *dirptr);

'전공 > 유닉스' 카테고리의 다른 글

6장. 프로세스 생성과 실행  (1) 2023.11.01
5장. 프로세스 정보  (0) 2023.11.01
4장. 시스템 정보  (0) 2023.11.01
2장. 파일 입출력 (2)  (1) 2023.10.23
2장. 파일 입출력 (1)  (1) 2023.10.05

댓글