반응형
copy_file( )
int copy_file(const char *src_file, const char *dest_file, int overwrite, int copy_attr);
일반적으로 파일을 복사하는 함수를 구현할 때에, 파일의 내용만 복사하고 맙니다. 또한, 이미 파일이 있는 경우에 체크하지 않는 경우도 있습니다. file_copy( ) 함수는 파일의 내용 뿐만 아니라 속성(파일의 접근 권한, 파일에 대한 최종 access 시간, 파일의 최종 변경시간 등)을 함께 복제할 것인지도 선택할 수 있습니다. 또한 파일의 이미 있는 경우는 덮어쓰기를 할 것인지 아니면 보존할 것인지도 선택할 수 있습니다. 그리고 파일을 복사 중에 signal이 발생하여 오류가 발생하더라도 retry를 하여 안정적으로 파일을 복사하도록 구현하였습니다.
파라미터
src_file
- 원본 파일에 대한 상대 Path 또는 절대 Path
dest_file
- 복사될 파일에 대한 상대 Path 또는 절대 Path
overwrite
-복사될 파일이 이미 있는 경우 파일을 덮어쓰기(overwrite)를 할 지
아니면 오류를 발생시키고 중단할 지를 설정합니다.
0 : 이미 파일이 있으면 복사하지 말고 오류 발생
그 외: 이미 파일이 있어도 파일을 overwrite함
copy_attr
- 원본파일의 속성들을 함께 복사할 지 여부를 설정합니다.
0 : 속성은 복사하지 않고 파일의 시간은 복사시점의 시간으로 설정함
그 외: 원본 파일의 접근권한 및 파일 시간 정보도 dest_file에 동기화 함
RETURN
0
- 정상적으로 파일이 복제되었습니다.
-1
- 오류가 발생하였습니다. 상세한 오류 내용은 errno 전역 변수에 설정됩니다.
Source 구현
copy_file 소스 구현
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <utime.h>
#include <errno.h>
#include <fcntl.h>
int copy_file(const char *src_file, const char *dest_file, int overwrite, int copy_attr)
{
int src_fd;
int dest_fd;
struct stat sts;
char data_buf[4096];
int tmp_errno;
int size;
struct utimbuf attr;
if((src_fd = open(src_file, O_RDONLY)) == -1) {
return -1;
}
/* 원본 file의 속성을 읽습니다. */
fstat(src_fd, &sts);
if(overwrite) { /* 이미 파일이 있으면 overwrite를 하겠다면... */
dest_fd = open(dest_file, O_WRONLY | O_CREAT | O_TRUNC, sts.st_mode);
} else { /* 파일이 있으면, 생성하지 말라고 설정한 경우 */
dest_fd = open(dest_file, O_WRONLY | O_CREAT | O_EXCL, sts.st_mode);
}
if(dest_fd == -1) {
tmp_errno = errno;
close(src_fd);
errno = tmp_errno; // close가 초기화한 errno를 복구함
return -1;
}
while(size = read(src_fd, data_buf, 4096)) {
if(size == -1) {
if(errno == EINTR) {
continue;
}
tmp_errno = errno;
close(src_fd);
close(dest_fd);
errno = tmp_errno; // close가 초기화한 errno를 복구함
return -1;
}
while(write(dest_fd, data_buf, size) == -1) {
if(errno == EINTR) {
/* signal이 발생한 경우에는 재작업 */
continue;
} else {
/* disk가 full났거나 무슨 일이 있음. */
tmp_errno = errno;
close(src_fd);
close(dest_fd);
errno = tmp_errno; // close가 초기화한 errno를 복구함
}
}
}
close(src_fd);
close(dest_fd);
/* 원본 파일의 속성을 복원해야 한다면... */
if(copy_attr) {
/* last access 시간, last modify 시간 복구 */
attr.actime = sts.st_atime;
attr.modtime = sts.st_mtime;
utime(dest_file, &attr);
/* 원본 파일의 파일 권한을 복원하기
* open시에 파일권한을 설정하였지만,
* 이미 존재했던 파일은 파일권한이 기존 파일의 권한이므로
* 파일의 권한도 복구합니다.
*/
chmod(dest_file, sts.st_mode);
}
return 0;
}
사용 예제
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void help(const char *command)
{
fprintf(stderr, "%s [-fp] src_file dest_file\n", command);
}
int main(int argc, char *argv[])
{
int overwrite = 0;
int attr = 0;
int idx = 0;
if(argc < 3) {
help(argv[0]);
return 1;
}
if(argc == 4) {
if(argv[1][0] == '-') {
for(idx = 1; idx < strlen(argv[1]); idx++) {
if(argv[1][idx] == 'f') {
overwrite = 1;
} else if(argv[1][idx] == 'p') {
attr = 1;
}
}
} else {
help(argv[0]);
return -1;
}
}
if(copy_file(argv[1], argv[2], overwrite, attr) == -1) {
fprintf(stderr, "FILE COPY ERROR: %s\n", strerror(errno));
return 1;
}
return 0;
}
source download :
반응형
'C언어 응용 > 활용' 카테고리의 다른 글
strcat(3) - 대체 함수 구현 (0) | 2019.10.04 |
---|---|
log 생성 API 구현 (0) | 2019.10.04 |
strncpy시에 한글 반잘림 오류 방지 (0) | 2019.10.04 |
rmdirs( ) - 디렉토리 아래의 모든 파일 및 디렉토리 삭제 (0) | 2019.10.04 |
mkdirs( ) - 계층구조 디렉토리 한번에 만들기 (0) | 2019.10.04 |