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