1 #include "util.h" 2 #include <sys/mman.h> 3 4 int mkdir_p(char *path, mode_t mode) 5 { 6 struct stat st; 7 int err; 8 char *d = path; 9 10 if (*d != '/') 11 return -1; 12 13 if (stat(path, &st) == 0) 14 return 0; 15 16 while (*++d == '/'); 17 18 while ((d = strchr(d, '/'))) { 19 *d = '\0'; 20 err = stat(path, &st) && mkdir(path, mode); 21 *d++ = '/'; 22 if (err) 23 return -1; 24 while (*d == '/') 25 ++d; 26 } 27 return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0; 28 } 29 30 static int slow_copyfile(const char *from, const char *to) 31 { 32 int err = 0; 33 char *line = NULL; 34 size_t n; 35 FILE *from_fp = fopen(from, "r"), *to_fp; 36 37 if (from_fp == NULL) 38 goto out; 39 40 to_fp = fopen(to, "w"); 41 if (to_fp == NULL) 42 goto out_fclose_from; 43 44 while (getline(&line, &n, from_fp) > 0) 45 if (fputs(line, to_fp) == EOF) 46 goto out_fclose_to; 47 err = 0; 48 out_fclose_to: 49 fclose(to_fp); 50 free(line); 51 out_fclose_from: 52 fclose(from_fp); 53 out: 54 return err; 55 } 56 57 int copyfile(const char *from, const char *to) 58 { 59 int fromfd, tofd; 60 struct stat st; 61 void *addr; 62 int err = -1; 63 64 if (stat(from, &st)) 65 goto out; 66 67 if (st.st_size == 0) /* /proc? do it slowly... */ 68 return slow_copyfile(from, to); 69 70 fromfd = open(from, O_RDONLY); 71 if (fromfd < 0) 72 goto out; 73 74 tofd = creat(to, 0755); 75 if (tofd < 0) 76 goto out_close_from; 77 78 addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fromfd, 0); 79 if (addr == MAP_FAILED) 80 goto out_close_to; 81 82 if (write(tofd, addr, st.st_size) == st.st_size) 83 err = 0; 84 85 munmap(addr, st.st_size); 86 out_close_to: 87 close(tofd); 88 if (err) 89 unlink(to); 90 out_close_from: 91 close(fromfd); 92 out: 93 return err; 94 } 95 96 unsigned long convert_unit(unsigned long value, char *unit) 97 { 98 *unit = ' '; 99 100 if (value > 1000) { 101 value /= 1000; 102 *unit = 'K'; 103 } 104 105 if (value > 1000) { 106 value /= 1000; 107 *unit = 'M'; 108 } 109 110 if (value > 1000) { 111 value /= 1000; 112 *unit = 'G'; 113 } 114 115 return value; 116 } 117 118 int readn(int fd, void *buf, size_t n) 119 { 120 void *buf_start = buf; 121 122 while (n) { 123 int ret = read(fd, buf, n); 124 125 if (ret <= 0) 126 return ret; 127 128 n -= ret; 129 buf += ret; 130 } 131 132 return buf - buf_start; 133 } 134