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