ls 함수처럼 현재 디렉토리에 있는 파일(숨겨진 디렉토리 포함)들의 이름을 출력하고 어떤 타입의 파일인지도 출력하는 함수를 만들어보자
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
32
33
34
35 |
#include <fcntl.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
int main(int argc,char *argv[])
{
struct stat sbuf;
DIR *dirp;
struct dirent *dp;
if(argc != 2){
fprintf(stderr,"usage: myls dirname\n");
exit(0);
}
dirp = opendir(argv[1]);
if(dirp == NULL){
perror("opendir");
exit(0);
}
else{
while(dp = readdir(dirp)){
printf("%s -> ",dp->d_name);
stat(dp->d_name,&sbuf);
switch(sbuf.st_mode & S_IFMT){
case S_IFREG: printf("Regular file\n"); break;
case S_IFDIR: printf("Directory file\n"); break;
case S_IFLNK: printf("Link file\n"); break;
default: printf("unknown file\n"); break;
}
}
}
closedir(dirp);
} |
cs |
- struct stat buf를 선언 : i-node의 정보를 저장하기 위함
- DIR *dirp : 디렉토리파일을 열 때 사용
- struct dirent *dp : open한 디렉토리파일을 읽을 때 사용 -> 다 읽으면 NULL출력
- argument값 검사
- opendir로 입력한 디렉토리를 엶 -> dirp
- dirp가 없다면 에러메시지 출력 후 프로그램 종료
- 있다면 dp에 모든 정보를 읽을 때 까지(NULL) 반복
- printf로 d_name을 출력 -> 디렉토리 내부의 파일, 디렉토리 등의 이름을 가지고 있음
- stat함수로 sbuf에 각 d_name의 경로 정보를 저장
- sbuf의 내용들 중 st_mode의 값(어떤 타입의 파일인지)과 S_IFMT(파일 속성값이 있는지 확인)를 &연산자로 비교하여 나온값이
- S_IFREG이면 regular file이라고 출력
- S_IFDIR이면 directory file이라고 출력
- S_IFLNK이면 Link file이라고 출력
- 위 세가지중 아무것도 아니라면 unknown file이라고 출력
- dirp를 닫음
Implementing cp
- 이전에 만들어 보았던 mycp라는 함수는 단순히 파일의 내용만을 복사하는 파일이었다면
- 이번에 만들어볼 mycp2라는 함수는 파일의 내용 뿐만아니라 모드까지 동일하게 세팅됨
- 참조 함수 : chmod/fchmod
- chmod : pathname의 파일에 지정된 mode를 허가
- fchmod : 파일 설명자 fd를 사용한다는 점을 제외하고 chmod와 동일
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
32
33
34
35
36
37
38
39
40 |
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <dirent.h>
#define SZ_BUF 1024
int main(int argc,char *argv[]){
int fd_in;
int fd_out;
struct stat sbuf;
if(argc != 3){
printf("mycp source_file dest_file\n");
}
fd_in = open(argv[1],O_RDONLY);
fd_out = open(argv[2],O_RDWR|O_CREAT,0666);
if(fd_in == -1 || fd_out == -1){
perror("open");
exit(0);
}
else{
char *buffer[SZ_BUF];
int nb;
fstat(fd_in,&sbuf);
fchmod(fd_out,sbuf.st_mode);
while(nb = read(fd_in, buffer, SZ_BUF)){
write(fd_out, buffer ,nb);
}
printf("success\n");
close(fd_in);
close(fd_out);
exit(0);
}
} |
cs |
- Buf size를 1024byte로 정의
- fd_in 복사 당할 파일 -> 읽기 전용으로만 open
- fd_out 복사하여 붙여넣을 파일 -> 읽기,쓰기전용/ 파일이 없으면 만들고 유저, 그룹, 다른 사용자까지 접근 허용
- fd_in이나 fd_out이 에러가 나서 -1이 반환된 경우 에러메시지 출력 후 프로그램 종료
- 만약 4번 상황이 아니라면 fstat함수로 sbuf에 fd_in의 mode를 저장
- fcmod로 fd_out에 fd_in의 mode를 동일하게 설정
- read한 값이 없을 때(0)까지 반복하여 fd_out에 write
- 모두 끝나면 success라는 메시지를 출력하고 모든 파일을 닫은 후 프로그램 종료
'LINUX 실습' 카테고리의 다른 글
Signal 시스템 콜 실습 (0) | 2018.11.29 |
---|---|
[함수 만들기]프로세스 시스템 콜 (0) | 2018.11.26 |
[File I/O]시스템 콜을 이용하여 함수 만들기 (0) | 2018.11.12 |
[System call 실습]System call의 기본 개념 (0) | 2018.11.02 |
[Git실습]Git사용법 부터 간단한 작성,수정,저장 (0) | 2018.10.17 |