Apache Mesos
chown.hpp
Go to the documentation of this file.
1 // Licensed under the Apache License, Version 2.0 (the "License");
2 // you may not use this file except in compliance with the License.
3 // You may obtain a copy of the License at
4 //
5 // http://www.apache.org/licenses/LICENSE-2.0
6 //
7 // Unless required by applicable law or agreed to in writing, software
8 // distributed under the License is distributed on an "AS IS" BASIS,
9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 // See the License for the specific language governing permissions and
11 // limitations under the License.
12 
13 #ifndef __STOUT_OS_POSIX_CHOWN_HPP__
14 #define __STOUT_OS_POSIX_CHOWN_HPP__
15 
16 #include <fts.h>
17 #include <sys/types.h>
18 #include <pwd.h>
19 
20 #include <stout/error.hpp>
21 #include <stout/nothing.hpp>
22 #include <stout/try.hpp>
23 
24 #include <stout/os/stat.hpp>
25 
26 namespace os {
27 
28 // Set the ownership for a path. This function never follows any symlinks.
30  uid_t uid,
31  gid_t gid,
32  const std::string& path,
33  bool recursive)
34 {
35  char* path_[] = {const_cast<char*>(path.c_str()), nullptr};
36 
37  FTS* tree = ::fts_open(
38  path_, FTS_NOCHDIR | FTS_PHYSICAL, nullptr);
39 
40  if (tree == nullptr) {
41  return ErrnoError();
42  }
43 
44  FTSENT *node;
45  while ((node = ::fts_read(tree)) != nullptr) {
46  switch (node->fts_info) {
47  // Preorder directory.
48  case FTS_D:
49  // Regular file.
50  case FTS_F:
51  // Symbolic link.
52  case FTS_SL:
53  // Symbolic link without target.
54  case FTS_SLNONE: {
55  if (::lchown(node->fts_path, uid, gid) < 0) {
57  ::fts_close(tree);
58  return error;
59  }
60 
61  break;
62  }
63 
64  // Unreadable directory.
65  case FTS_DNR:
66  // Error; errno is set.
67  case FTS_ERR:
68  // Directory that causes cycles.
69  case FTS_DC:
70  // `stat(2)` failed.
71  case FTS_NS: {
73  ::fts_close(tree);
74  return error;
75  }
76 
77  default:
78  break;
79  }
80 
81  if (node->fts_level == FTS_ROOTLEVEL && !recursive) {
82  break;
83  }
84  }
85 
86  ::fts_close(tree);
87  return Nothing();
88 }
89 
90 
91 // Changes the specified path's user and group ownership to that of
92 // the specified user.
94  const std::string& user,
95  const std::string& path,
96  bool recursive = true)
97 {
98  passwd* passwd;
99 
100  errno = 0;
101 
102  if ((passwd = ::getpwnam(user.c_str())) == nullptr) {
103  return errno
104  ? ErrnoError("Failed to get user information for '" + user + "'")
105  : Error("No such user '" + user + "'");
106  }
107 
108  return chown(passwd->pw_uid, passwd->pw_gid, path, recursive);
109 }
110 
111 } // namespace os {
112 
113 #endif // __STOUT_OS_POSIX_CHOWN_HPP__
Definition: path.hpp:29
Try< uid_t > uid(const std::string &path, const FollowSymlink follow=FollowSymlink::FOLLOW_SYMLINK)
Definition: stat.hpp:224
Definition: nothing.hpp:16
Definition: errorbase.hpp:36
UINT uid_t
Definition: windows.hpp:183
Definition: check.hpp:33
Result< std::string > user(Option< uid_t > uid=None())
Definition: su.hpp:284
Definition: errorbase.hpp:50
Definition: posix_signalhandler.hpp:23
gid_t pw_gid
Definition: pwd.hpp:30
uid_t pw_uid
Definition: pwd.hpp:29
Definition: pwd.hpp:26
std::string error(const std::string &msg, uint32_t code)
Try< Nothing > chown(uid_t uid, gid_t gid, const std::string &path, bool recursive)
Definition: chown.hpp:29
UINT gid_t
Definition: windows.hpp:184