File_VMS.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. //
  2. // File_VMS.cpp
  3. //
  4. // $Id: //poco/1.4/Foundation/src/File_VMS.cpp#1 $
  5. //
  6. // Library: Foundation
  7. // Package: Filesystem
  8. // Module: File
  9. //
  10. // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
  11. // and Contributors.
  12. //
  13. // SPDX-License-Identifier: BSL-1.0
  14. //
  15. #include "Poco/File_VMS.h"
  16. #include "Poco/Exception.h"
  17. #include "Poco/Path.h"
  18. #include "Poco/String.h"
  19. #include <stdio.h>
  20. #include <unistd.h>
  21. #include <unixio.h>
  22. #include <file.h>
  23. #include <stat.h>
  24. #include <errno.h>
  25. #include <utime.h>
  26. #include <lib$routines.h>
  27. #include <rmsdef.h>
  28. #include <starlet.h>
  29. #include <lnmdef.h>
  30. #include <ssdef.h>
  31. #include <descrip.h>
  32. namespace Poco {
  33. FileImpl::FileImpl()
  34. {
  35. }
  36. FileImpl::FileImpl(const std::string& path): _path(path)
  37. {
  38. if (!_path.empty())
  39. {
  40. Path p(_path);
  41. p.makeFile();
  42. _path = p.toString();
  43. }
  44. }
  45. FileImpl::~FileImpl()
  46. {
  47. }
  48. void FileImpl::swapImpl(FileImpl& file)
  49. {
  50. std::swap(_path, file._path);
  51. }
  52. void FileImpl::setPathImpl(const std::string& path)
  53. {
  54. _path = path;
  55. }
  56. bool FileImpl::existsImpl() const
  57. {
  58. poco_assert (!_path.empty());
  59. return access(_path.c_str(), F_OK) == 0;
  60. }
  61. bool FileImpl::canReadImpl() const
  62. {
  63. poco_assert (!_path.empty());
  64. struct stat st;
  65. if (stat(_path.c_str(), &st) == 0)
  66. {
  67. if (st.st_uid == geteuid())
  68. return (st.st_mode & S_IRUSR) != 0;
  69. else if (st.st_gid == getegid())
  70. return (st.st_mode & S_IRGRP) != 0;
  71. else
  72. return (st.st_mode & S_IROTH) != 0;
  73. }
  74. else handleLastErrorImpl(_path);
  75. return false;
  76. }
  77. bool FileImpl::canWriteImpl() const
  78. {
  79. poco_assert (!_path.empty());
  80. struct stat st;
  81. if (stat(_path.c_str(), &st) == 0)
  82. {
  83. if (st.st_uid == geteuid())
  84. return (st.st_mode & S_IWUSR) != 0;
  85. else if (st.st_gid == getegid())
  86. return (st.st_mode & S_IWGRP) != 0;
  87. else
  88. return (st.st_mode & S_IWOTH) != 0;
  89. }
  90. else handleLastErrorImpl(_path);
  91. return false;
  92. }
  93. bool FileImpl::canExecuteImpl() const
  94. {
  95. Path p(_path);
  96. return icompare(p.getExtension(), "exe") == 0;
  97. }
  98. bool FileImpl::isFileImpl() const
  99. {
  100. poco_assert (!_path.empty());
  101. struct stat st;
  102. if (stat(_path.c_str(), &st) == 0)
  103. return S_ISREG(st.st_mode);
  104. else
  105. handleLastErrorImpl(_path);
  106. return false;
  107. }
  108. bool FileImpl::isDirectoryImpl() const
  109. {
  110. poco_assert (!_path.empty());
  111. struct stat st;
  112. if (stat(_path.c_str(), &st) == 0)
  113. return S_ISDIR(st.st_mode);
  114. else
  115. handleLastErrorImpl(_path);
  116. return false;
  117. }
  118. bool FileImpl::isLinkImpl() const
  119. {
  120. return false;
  121. }
  122. bool FileImpl::isLinkImpl() const
  123. {
  124. return false;
  125. }
  126. bool FileImpl::isHiddenImpl() const
  127. {
  128. return false;
  129. }
  130. Timestamp FileImpl::createdImpl() const
  131. {
  132. poco_assert (!_path.empty());
  133. struct stat st;
  134. if (stat(_path.c_str(), &st) == 0)
  135. return Timestamp(st.st_ctime);
  136. else
  137. handleLastErrorImpl(_path);
  138. return 0;
  139. }
  140. Timestamp FileImpl::getLastModifiedImpl() const
  141. {
  142. poco_assert (!_path.empty());
  143. struct stat st;
  144. if (stat(_path.c_str(), &st) == 0)
  145. return Timestamp(st.st_mtime);
  146. else
  147. handleLastErrorImpl(_path);
  148. return 0;
  149. }
  150. void FileImpl::setLastModifiedImpl(const Timestamp& ts)
  151. {
  152. poco_assert (!_path.empty());
  153. struct utimbuf tb;
  154. tb.actime = ts.epochTime();
  155. tb.modtime = ts.epochTime();
  156. if (utime(_path.c_str(), &tb) != 0)
  157. handleLastErrorImpl(_path);
  158. }
  159. FileImpl::FileSizeImpl FileImpl::getSizeImpl() const
  160. {
  161. poco_assert (!_path.empty());
  162. struct stat st;
  163. if (stat(_path.c_str(), &st) == 0)
  164. return st.st_size;
  165. else
  166. handleLastErrorImpl(_path);
  167. return 0;
  168. }
  169. void FileImpl::setSizeImpl(FileSizeImpl size)
  170. {
  171. poco_assert (!_path.empty());
  172. if (truncate(_path.c_str(), size) != 0)
  173. handleLastErrorImpl(_path);
  174. }
  175. void FileImpl::setWriteableImpl(bool flag)
  176. {
  177. poco_assert (!_path.empty());
  178. struct stat st;
  179. if (stat(_path.c_str(), &st) != 0)
  180. handleLastErrorImpl(_path);
  181. mode_t mode;
  182. if (flag)
  183. {
  184. mode = st.st_mode | S_IWUSR;
  185. }
  186. else
  187. {
  188. mode_t wmask = S_IWUSR | S_IWGRP | S_IWOTH;
  189. mode = st.st_mode & ~wmask;
  190. }
  191. if (chmod(_path.c_str(), mode) != 0)
  192. handleLastErrorImpl(_path);
  193. }
  194. void FileImpl::setExecutableImpl(bool flag)
  195. {
  196. // not supported
  197. }
  198. void FileImpl::copyToImpl(const std::string& path) const
  199. {
  200. poco_assert (!_path.empty());
  201. // copying a file correctly under OpenVMS is non-trivial,
  202. // so we just invoke the COPY program.
  203. std::string cmd = "COPY ";
  204. cmd.append(_path);
  205. cmd.append(" ");
  206. cmd.append(path);
  207. if (system(cmd.c_str()) != 0)
  208. throw FileException("COPY command failed", _path);
  209. }
  210. void FileImpl::renameToImpl(const std::string& path)
  211. {
  212. poco_assert (!_path.empty());
  213. POCO_DESCRIPTOR_STRING(oldNameDsc, _path);
  214. POCO_DESCRIPTOR_STRING(newNameDsc, path);
  215. int res;
  216. if ((res = lib$rename_file(&oldNameDsc, &newNameDsc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) != 1)
  217. {
  218. switch (res & 0x0FFFFFFF)
  219. {
  220. case RMS$_FNF:
  221. throw FileNotFoundException(_path);
  222. case RMS$_DEV:
  223. case RMS$_DNF:
  224. throw PathNotFoundException(_path);
  225. case RMS$_SYN:
  226. throw PathSyntaxException(path);
  227. case RMS$_RMV:
  228. throw FileAccessDeniedException(_path);
  229. case RMS$_PRV:
  230. throw FileAccessDeniedException("insufficient privileges", _path);
  231. default:
  232. throw FileException(path);
  233. }
  234. }
  235. }
  236. void FileImpl::removeImpl()
  237. {
  238. poco_assert (!_path.empty());
  239. int rc;
  240. if (isDirectoryImpl())
  241. {
  242. setWriteableImpl(true);
  243. rc = rmdir(_path.c_str());
  244. }
  245. else
  246. {
  247. rc = unlink(_path.c_str());
  248. }
  249. if (rc) handleLastErrorImpl(_path);
  250. }
  251. bool FileImpl::createFileImpl()
  252. {
  253. poco_assert (!_path.empty());
  254. int n = open(_path.c_str(), O_WRONLY | O_CREAT | O_EXCL);
  255. if (n != -1)
  256. {
  257. close(n);
  258. return true;
  259. }
  260. if (n == -1 && errno == EEXIST)
  261. return false;
  262. else
  263. handleLastErrorImpl(_path);
  264. return false;
  265. }
  266. bool FileImpl::createDirectoryImpl()
  267. {
  268. poco_assert (!_path.empty());
  269. if (existsImpl() && isDirectoryImpl())
  270. return false;
  271. Path p(_path);
  272. p.makeDirectory();
  273. if (mkdir(p.toString().c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0)
  274. handleLastErrorImpl(_path);
  275. return true;
  276. }
  277. void FileImpl::handleLastErrorImpl(const std::string& path)
  278. {
  279. switch (errno)
  280. {
  281. case EIO:
  282. throw IOException(path);
  283. case EPERM:
  284. throw FileAccessDeniedException("insufficient permissions", path);
  285. case EACCES:
  286. throw FileAccessDeniedException(path);
  287. case ENOENT:
  288. throw FileNotFoundException(path);
  289. case ENOTDIR:
  290. throw OpenFileException("not a directory", path);
  291. case EISDIR:
  292. throw OpenFileException("not a file", path);
  293. case EROFS:
  294. throw FileReadOnlyException(path);
  295. case EEXIST:
  296. throw FileExistsException(path);
  297. case ENOSPC:
  298. throw FileException("no space left on device", path);
  299. case EDQUOT:
  300. throw FileException("disk quota exceeded", path);
  301. case ENOTEMPTY:
  302. throw FileException("directory not empty", path);
  303. case ENAMETOOLONG:
  304. throw PathSyntaxException(path);
  305. default:
  306. throw FileException(strerror(errno), path);
  307. }
  308. }
  309. } // namespace Poco