licornea_tools
filesystem.posix.cc
Go to the documentation of this file.
1 #include "os.h"
2 #if defined(LICORNEA_OS_LINUX) || defined(LICORNEA_OS_DARWIN)
3 #include "filesystem.h"
4 #include "assert.h"
5 #include <sys/stat.h>
6 #include <sys/types.h>
7 #include <unistd.h>
8 #include <errno.h>
9 #include <stdexcept>
10 #include <limits.h>
11 #include <iostream>
12 #include <deque>
13 #include <system_error>
14 
15 namespace tlz {
16 
17 namespace {
18  constexpr std::size_t path_max_length = 1024;
19 }
20 
21 std::string filename_parent(const std::string& path_) {
22  std::string path(path_);
23  if(path.back() == '/') path = path.substr(0, path.length() - 1);
24  auto pos = path.find_last_of('/');
25  if(pos != std::string::npos) return path.substr(0, pos + 1);
26  else if(path != "." && path != ".." && path != "") return ".";
27  else throw std::invalid_argument("cannot get parent path of " + path);
28 }
29 
30 std::string filename_append(const std::string& a, const std::string& b) {
31  if(a.back() == '/') return a + b;
32  else return a + "/" + b;
33 }
34 
35 std::string get_current_directory() {
36  char buffer[path_max_length];
37  char* path = getcwd(buffer, path_max_length);
38  if(path != nullptr) return std::string(path);
39  else throw std::system_error(errno, std::system_category(), "getcwd() failed");
40 }
41 
42 bool file_exists(const std::string& filename) {
43  struct stat sb;
44  return (stat(filename.c_str(), &sb) == 0);
45 }
46 
47 bool is_directory(const std::string& filename) {
48  struct stat sb;
49  int result = stat(filename.c_str(), &sb);
50  if(result == 0) return S_ISDIR(sb.st_mode);
51  else throw std::system_error(errno, std::system_category(), "stat() failed");
52 }
53 
54 bool is_file(const std::string& filename) {
55  struct stat sb;
56  int result = stat(filename.c_str(), &sb);
57  if(result == 0) return S_ISREG(sb.st_mode);
58  else throw std::system_error(errno, std::system_category(), "stat() failed");
59 }
60 
61 std::size_t file_size(const std::string& filename) {
62  struct stat sb;
63  int result = stat(filename.c_str(), &sb);
64  if(result == 0) return sb.st_size;
65  else throw std::system_error(errno, std::system_category(), "stat() failed");
66 }
67 
68 void make_directory(const std::string& dirname) {
69  // don't fail if *directory* already exists at dirname
70 
71  int result = mkdir(dirname.c_str(), S_IRWXU | S_IRWXG);
72  if(result == 0 || (result == -1 && errno == EEXIST && is_directory(dirname))) return;
73  else throw std::system_error(errno, std::system_category(), "mkdir() failed");
74 }
75 
76 void make_parent_directories(const std::string& filename) {
77  std::deque<std::string> new_dirs;
78 
79  std::string dir = filename_parent(filename);
80  while(! file_exists(dir) && dir != "/") {
81  new_dirs.push_front(dir);
82  dir = filename_parent(dir);
83  }
84  for(const std::string& dir : new_dirs) {
85  make_directory(dir);
86  }
87 }
88 
89 void delete_file(const std::string& filename) {
90  int result = unlink(filename.c_str());
91  if(result != 0) throw std::system_error(errno, std::system_category(), "unlink() failed");
92 }
93 
94 }
95 
96 #endif
std::string filename_append(const std::string &a, const std::string &b)
bool file_exists(const std::string &filename)
bool is_file(const std::string &filename)
bool is_directory(const std::string &filename)
std::size_t file_size(const std::string &filename)
std::string get_current_directory()
void delete_file(const std::string &filename)
std::string filename_parent(const std::string &filename)
void make_directory(const std::string &dirname)
void make_parent_directories(const std::string &filename)