fs.cpp revision e6b4e5b20ac8a3b01f1a99dd877a98c92036ce5e
1#include "fs.h" 2#include "files.h" 3#include <unistd.h> 4#include <sys/types.h> 5#include <dirent.h> 6#include <string> 7#include <vector> 8#include <stdio.h> 9#include <string.h> 10#include <errno.h> 11#include <sys/stat.h> 12#include <unistd.h> 13#include <string.h> 14#include <host/CopyFile.h> 15 16using namespace std; 17 18static bool 19is_dir(const string& path) 20{ 21 int err; 22 struct stat st; 23 err = stat(path.c_str(), &st); 24 return err != 0 || S_ISDIR(st.st_mode); 25} 26 27static int 28remove_file(const string& path) 29{ 30 int err = unlink(path.c_str()); 31 if (err != 0) { 32 fprintf(stderr, "error deleting file %s (%s)\n", path.c_str(), 33 strerror(errno)); 34 return errno; 35 } 36 return 0; 37} 38 39int 40remove_recursively(const string& path) 41{ 42 int err; 43 44 if (is_dir(path)) { 45 DIR *d = opendir(path.c_str()); 46 if (d == NULL) { 47 fprintf(stderr, "error getting directory contents %s (%s)\n", 48 path.c_str(), strerror(errno)); 49 return errno; 50 } 51 52 vector<string> files; 53 vector<string> dirs; 54 55 struct dirent *ent; 56 while (NULL != (ent = readdir(d))) { 57 if (0 == strcmp(".", ent->d_name) 58 || 0 == strcmp("..", ent->d_name)) { 59 continue; 60 } 61 string full = path; 62 full += '/'; 63 full += ent->d_name; 64#ifdef HAVE_DIRENT_D_TYPE 65 bool is_directory = (ent->d_type == DT_DIR); 66#else 67 // If dirent.d_type is missing, then use stat instead 68 struct stat stat_buf; 69 stat(full.c_str(), &stat_buf); 70 bool is_directory = S_ISDIR(stat_buf.st_mode); 71#endif 72 if (is_directory) { 73 dirs.push_back(full); 74 } else { 75 files.push_back(full); 76 } 77 } 78 closedir(d); 79 80 for (vector<string>::iterator it=files.begin(); it!=files.end(); it++) { 81 err = remove_file(*it); 82 if (err != 0) { 83 return err; 84 } 85 } 86 87 for (vector<string>::iterator it=dirs.begin(); it!=dirs.end(); it++) { 88 err = remove_recursively(*it); 89 if (err != 0) { 90 return err; 91 } 92 } 93 94 err = rmdir(path.c_str()); 95 if (err != 0) { 96 fprintf(stderr, "error deleting directory %s (%s)\n", path.c_str(), 97 strerror(errno)); 98 return errno; 99 } 100 return 0; 101 } else { 102 return remove_file(path); 103 } 104} 105 106int 107mkdir_recursively(const string& path) 108{ 109 int err; 110 size_t pos = 0; 111 while (true) { 112 pos = path.find('/', pos); 113 string p = path.substr(0, pos); 114 struct stat st; 115 err = stat(p.c_str(), &st); 116 if (err != 0) { 117 err = mkdir(p.c_str(), 0770); 118 if (err != 0) { 119 fprintf(stderr, "can't create directory %s (%s)\n", 120 path.c_str(), strerror(errno)); 121 return errno; 122 } 123 } 124 else if (!S_ISDIR(st.st_mode)) { 125 fprintf(stderr, "can't create directory %s because %s is a file.\n", 126 path.c_str(), p.c_str()); 127 return 1; 128 } 129 pos++; 130 if (p == path) { 131 return 0; 132 } 133 } 134} 135 136int 137copy_file(const string& src, const string& dst) 138{ 139 int err; 140 141 err = copyFile(src.c_str(), dst.c_str(), 142 COPY_NO_DEREFERENCE | COPY_FORCE | COPY_PERMISSIONS); 143 return err; 144} 145