4-3 File IO - 시스템 함수 (과제-1)

do·2022년 4월 6일
0

API

목록 보기
21/42

my_cp 파일 복사 프로그램 (my_cp.c)

#include <stdio.h>
#include <errno.h>
#include <sys/types.h> //open()
#include <sys/stat.h> //open()
#include <fcntl.h> //open()
#include <unistd.h> //close()
#include <string.h> //strcmp() memset()

void Usage()
{
	printf("Usage: c [-f] src_file dest_file\n");
	printf("          -f: dest_file 존재시 src_file 내용으로 바꿈\n");
}

int Close(int i)
{
	if (close(i) != 0) {
		fprintf(stderr, "fd #%d CLOSE errno[%d] : %s\n", i, errno, strerror(errno));
		if (errno == EBADF) {
			return 0;
		}
		else {
			return 0;
		}
	}
    
	printf("fd #%d CLOSE\n", i);
	return 1;
}

int main(int argc, char* argv[])
{
	if (argc != 3 && argc != 4) {
		Usage();
		return 0;
	}

	if (argc == 4 && (strcmp(argv[1], "-f") != 0)) {
		Usage();
		return 0;
	}

	int src = 0;
	int dest = 0;

	int f = 0;
	if (strcmp(argv[1], "-f") == 0) {
		f = 1;
	}
    
	if ((src = open(argv[1 + f], O_RDONLY)) == -1) {
		fprintf(stderr, "SRC OPEN errno[%d]: %s\n", errno, strerror(errno));
		if (errno == ENOENT) {
			return 0;
		}
		else {
			return 0;
		}
	}

	if (f == 0) {
		if ((dest = open(argv[2 + f], O_WRONLY | O_CREAT | O_EXCL)) == -1) {

			fprintf(stderr, "DEST OPEN errno[%d] : %s\n", errno, strerror(errno));

			Close(src);

			if (errno == EISDIR) {
				return 0;
			}
			else if (errno == EEXIST) {
				return 0;
			}
			else {
				return 0;
			}
		}
	}
	else if (f == 1) {
		if ((dest = open(argv[2 + f], O_WRONLY | O_CREAT | O_TRUNC)) == -1) {
			fprintf(stderr, "DEST OPEN errno[%d] : %s\n", errno, strerror(errno));     

			Close(src);

			if (errno == EISDIR) {
				return 0;
			}
			else if (errno == EACCES) {
				return 0;
			}
			else {
				return 0;
			}
		}
	}
    
	char buf[1000];
	
	while(1) {
		memset(buf, 0, sizeof(buf));
		
		int r = read(src, buf, sizeof(buf));
		if (r < 1) {
			fprintf(stderr, "READ errno[%d] : %s\n", errno, strerror(errno));
	
			if (Close(src)) {
				Close(dest);
			}

			if (errno == EISDIR) {
				return 0;
			}
			else {
				return 0;
			}
		}
        
		int w = write(dest, buf, sizeof(buf));
		if (w < 1) {
			fprintf(stderr, "WRITE errno[%d] : %s\n", errno, strerror(errno));

			if (Close(src)) {
				Close(dest);
			}

			if (errno == EBADF) {
				return 0;
			}
			else {
				return 0;
			}
		}
		
	}

	if (Close(src)) {
		Close(dest);
	}          
    
	printf("Copy success!!!\n");
	return 0;
} 

src.dat만 존재한다는 가정

my_cp e.dat ee
SRC OPEN errno[2]: No such file or directory

my_cp src.dat ./
DEST OPEN errno[17]: File exists
fd #3 CLOSE

my_cp src.dat ee/
DEST OPEN errno[21]: Is a directory
fd #3 CLOSE

my_cp ./ ee
READ errno[21]: Is a directory
fd #3 CLOSE
fd #4 CLOSE
(open에서 에러가 걸리지 않은 이유는, src가 O_RDONLY이기 때문. EISDIR 에러는 O_WRONLY 또는 O_RDWR이 세팅 되어야함)

my_cp src.dat dest.dat
fd #3 CLOSE
fd #4 CLOSE
Copy success!!!

my_cp -f src.dat dest.dat
fd #3 CLOSE
fd #4 CLOSE
Copy success!!!

src.dat와 dest.dat도 둘다 존재

my_cp src.dat dest.dat
DEST OPEN errno[17]: File exists
fd #3 CLOSE

my_cp -f src.dat ee/
DEST OPEN errno[21]: Is a directory
fd #3 CLOSE

my_cp -f src.dat dest.dat
fd #3 CLOSE
fd #4 CLOSE
Copy success!!!

my_cp -f src.dat dest.dat
(dest.dat 권한이 0555일 때)
DEST OPEN errno[13]: Permission denied
fd #3 CLOSE

0개의 댓글