This commit is contained in:
Your Name 2023-10-17 19:45:31 +03:00
parent 4876e55da1
commit 90d49dd3cf

View File

@ -22,10 +22,24 @@ char *make_path(const char *src, const char *dst) {
}
int write_buffer(int ifd, int ofd) {
char buf[4096];
size_t bytes = 0;
while ((bytes = read(ifd, buf, sizeof(buf))) > 0)
if (write(ofd, buf, bytes) != bytes)
off_t len = lseek(ifd, 0, SEEK_END);
if (len <= 0)
return 1;
if (ftruncate(ofd, len) < 0)
return 1;
void *buf_in = mmap(NULL, len, PROT_READ, MAP_SHARED, ifd, 0);
if (buf_in == MAP_FAILED)
return 1;
void *buf_out = mmap(NULL, len, PROT_WRITE, MAP_SHARED, ofd, 0);
if (buf_out == MAP_FAILED)
return 1;
memcpy(buf_out, buf_in, len);
if (munmap(buf_in, len) || munmap(buf_out, len))
return 1;
return 0;
@ -37,7 +51,7 @@ int copy(const char *src, const char *dst) {
if (ifd < 0)
return 1;
int ofd = open(dst, O_CREAT | O_TRUNC | O_WRONLY, 0666);
int ofd = open(dst, O_CREAT | O_TRUNC | O_RDWR, 0644);
if (ofd < 0) {
close(ifd);
return 1;
@ -62,7 +76,8 @@ int get_stat(const char *path, struct stat *stat_path) {
int cptree(const char *src, const char *dst) {
struct stat stat_path;
get_stat(src, &stat_path);
if (get_stat(src, &stat_path))
return 1;
if (S_ISDIR(stat_path.st_mode) == 0) {
if (copy(src, dst)) {
@ -73,9 +88,8 @@ int cptree(const char *src, const char *dst) {
return 0;
}
else if (mkdir(dst, 0777) < 0) {
else if (mkdir(dst, 0777) < 0)
fprintf(stderr, "cp: %s\n", strerror(errno));
}
DIR *dir = opendir(src);
if (dir == NULL) {
@ -107,10 +121,34 @@ int cptree(const char *src, const char *dst) {
}
int main(const int argc, const char **argv) {
if (argc < 2 || !strcmp(argv[1], "-h")) {
int i;
for (i = 1; i < argc; i++) {
if (argv[i][0] != '-')
break;
else if (!strcmp(argv[i], "-h")) {
printf("cp [Src] [Dst]\n");
return 0;
}
return cptree(argv[1], argv[2]);
}
int ret = 0;
if (argc - i == 2)
ret = cptree(argv[i], argv[argc - 1]);
else {
for (; i < argc - 1; i++) {
char *new_path = make_path(argv[argc - 1], basename(argv[i]));
if (new_path == NULL)
return 1;
if (copy(argv[i], new_path))
ret = 1;
free(new_path);
}
}
return ret;
}