filetools.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. #include <stdio.h>
  2. #include <sys/file.h>
  3. #include <sys/stat.h>
  4. #include <dirent.h>
  5. #include <unistd.h>
  6. #include <cstring>
  7. #include <iostream>
  8. #include <fstream>
  9. #include "Exception.h"
  10. #include "filetools.h"
  11. std::string concatPathAndFilename(const std::string& path, const std::string& filename)
  12. {
  13. std::string result = path;
  14. if (result[result.length() - 1] != '/')
  15. result += "/";
  16. result += filename;
  17. return result;
  18. }
  19. void fileList(const std::string& fn,
  20. std::vector<std::string>& file, bool recursive)
  21. {
  22. struct stat fstat;
  23. if (stat(fn.c_str(), &fstat) != 0)
  24. return;
  25. if (S_ISREG(fstat.st_mode))
  26. file.push_back(fn);
  27. else if (S_ISDIR(fstat.st_mode))
  28. {
  29. struct dirent* dp;
  30. DIR* dir;
  31. if ((dir = opendir(fn.c_str())) != NULL)
  32. {
  33. /* Loop through directory entries. */
  34. while ((dp = readdir(dir)) != NULL)
  35. {
  36. std::string fname = dp->d_name;
  37. std::string pname = concatPathAndFilename(fn, fname);
  38. if (stat(pname.c_str(), &fstat) == 0)
  39. {
  40. if (S_ISDIR(fstat.st_mode))
  41. {
  42. if (recursive)
  43. if (fname != "." && fname != "..")
  44. fileList(pname, file, true);
  45. }
  46. else if (S_ISREG(fstat.st_mode))
  47. file.push_back(pname);
  48. }
  49. }
  50. closedir(dir);
  51. }
  52. }
  53. }
  54. void dirList(const std::string& fn,
  55. std::vector<std::string>& file, bool recursive)
  56. {
  57. struct stat fstat;
  58. if (stat(fn.c_str(), &fstat) != 0)
  59. return;
  60. if (S_ISREG(fstat.st_mode))
  61. file.push_back(fn);
  62. else if (S_ISDIR(fstat.st_mode))
  63. {
  64. struct dirent* dp;
  65. DIR* dir;
  66. if ((dir = opendir(fn.c_str())) != NULL)
  67. {
  68. /* Loop through directory entries. */
  69. while ((dp = readdir(dir)) != NULL)
  70. {
  71. std::string fname = dp->d_name;
  72. std::string pname = concatPathAndFilename(fn, fname);
  73. if (stat(pname.c_str(), &fstat) == 0)
  74. {
  75. if (S_ISDIR(fstat.st_mode))
  76. {
  77. if (fname != "." && fname != "..")
  78. {
  79. file.push_back(pname);
  80. if (recursive)
  81. dirList(pname, file, true);
  82. }
  83. }
  84. }
  85. }
  86. closedir(dir);
  87. }
  88. }
  89. }
  90. void fileList(int argc, char** argv,
  91. int optind, std::vector<std::string>& file, bool recursive)
  92. {
  93. for (int i = optind; i < argc; i++)
  94. fileList(argv[i], file, recursive);
  95. }
  96. void strings2File(const std::vector<std::string>& s, const std::string& fn)
  97. {
  98. std::ofstream os(fn);
  99. if (!os.good())
  100. throw Exception("strings to file", "Cannot open file " + fn);
  101. for (std::string t : s)
  102. os << t << std::endl;
  103. os.close();
  104. }
  105. void file2Strings(const std::string& fn, std::vector<std::string>& s)
  106. {
  107. std::ifstream is(fn);
  108. if (!is.good())
  109. throw Exception("file to strings", "Cannot open file " + fn);
  110. std::string input;
  111. while (getline(is, input))
  112. s.push_back(input);
  113. }
  114. bool fileExists(const std::string& name)
  115. {
  116. struct stat fstat;
  117. if (stat(name.c_str(), &fstat) != 0)
  118. return false;
  119. if (!S_ISREG(fstat.st_mode))
  120. return false;
  121. return true;
  122. }
  123. bool dirExists(const std::string& name)
  124. {
  125. struct stat fstat;
  126. if (stat(name.c_str(), &fstat) != 0)
  127. return false;
  128. if (!S_ISDIR(fstat.st_mode))
  129. return false;
  130. return true;
  131. }
  132. int lock_fd;
  133. void createLock(const std::string& lockfilename)
  134. {
  135. lock_fd = open(lockfilename.c_str(), O_RDWR | O_CREAT, 0666); // open or create lockfile
  136. //check open success...
  137. int rc = flock(lock_fd, LOCK_EX | LOCK_NB); // grab exclusive lock, fail if can't obtain.
  138. if (rc)
  139. {
  140. std::cerr << "ERROR: cannot get lock at " + lockfilename << std::endl;
  141. exit(1);
  142. // no exception, because at normal end of program lock is
  143. // unlocked and removed
  144. }
  145. }
  146. void removeLock(const std::string& lockfilename)
  147. {
  148. flock(lock_fd, LOCK_UN);
  149. unlink(lockfilename.c_str());
  150. }
  151. #define POPEN_BUFFER_SIZE 2000
  152. Strings myPopen(const std::string& cmd,
  153. int& rc, bool debug, const std::string& logfn)
  154. {
  155. if (debug)
  156. std::cout << "Executing " << cmd << std::endl;
  157. std::ofstream log;
  158. if (!logfn.empty())
  159. log.open(logfn);
  160. if (log.is_open())
  161. {
  162. log << "Executing " << cmd << std::endl;
  163. log << "--------------------------------------------------------" << std::endl;
  164. }
  165. Strings res;
  166. FILE* fd = popen(cmd.c_str(), "r");
  167. if (fd != nullptr)
  168. {
  169. std::string input;
  170. char buffer[POPEN_BUFFER_SIZE];
  171. while (fgets(buffer, POPEN_BUFFER_SIZE - 1, fd))
  172. {
  173. buffer[POPEN_BUFFER_SIZE - 1] = 0; // force string end here
  174. int size = strlen(buffer);
  175. if (buffer[size - 1] == '\n') // substitute linefeed with string end
  176. buffer[size - 1] = 0;
  177. input = buffer;
  178. if (log.is_open())
  179. log << input << std::endl;
  180. res.push_back(input);
  181. if (debug)
  182. std::cout << ">>" << input << "<<" << std::endl;
  183. }
  184. rc = pclose(fd);
  185. if (debug)
  186. std::cout << " result code: " << rc << std::endl;
  187. }
  188. else
  189. {
  190. if (debug)
  191. std::cout << " popen " << cmd << " failed " << std::endl;
  192. rc = 1;
  193. return res;
  194. }
  195. if (log.is_open())
  196. {
  197. log << "--------------------------------------------------------" << std::endl;
  198. log << "result code: " << rc << std::endl;
  199. }
  200. return res;
  201. }