]> git.tdb.fi Git - libs/core.git/blob - source/fs/unix/stat.cpp
1404fede5c030b462fa410c38adb9de0dd0cb568
[libs/core.git] / source / fs / unix / stat.cpp
1 #define _FILE_OFFSET_BITS 64
2 #include <cerrno>
3 #include <unistd.h>
4 #include <sys/stat.h>
5 #include <grp.h>
6 #include <pwd.h>
7 #include <msp/core/systemerror.h>
8 #include <msp/strings/format.h>
9 #include "stat.h"
10 #include "stat_private.h"
11
12 namespace Msp {
13 namespace FS {
14
15 Stat::Private::Private(const Private &other):
16         owner_id(other.owner_id),
17         group_id(other.group_id)
18 { }
19
20 Stat::Private::~Private()
21 { }
22
23 Stat Stat::Private::from_struct_stat(const struct stat &st)
24 {
25         Stat result;
26         result.exists = true;
27         if(S_ISREG(st.st_mode))
28                 result.type = REGULAR;
29         else if(S_ISDIR(st.st_mode))
30                 result.type = DIRECTORY;
31         else if(S_ISLNK(st.st_mode))
32                 result.type = SYMLINK;
33         else
34                 result.type = UNKNOWN;
35         result.size = st.st_size;
36         result.alloc_size = st.st_blocks*512;
37         result.mtime = Time::TimeStamp::from_unixtime(st.st_mtime);
38
39         result.priv = new Private;
40         result.priv->owner_id = st.st_uid;
41         result.priv->group_id = st.st_gid;
42
43         return result;
44 }
45
46 void Stat::Private::fill_owner_info(Stat::OwnerInfo &result)
47 {
48         char buf[1024];
49
50         struct passwd pw;
51         struct passwd *owner;
52         if(!getpwuid_r(owner_id, &pw, buf, sizeof(buf), &owner) && owner)
53                 result.owner = owner->pw_name;
54         else
55                 result.owner = format("%d", owner_id);
56
57         struct group gr;
58         struct group *group;
59         if(!getgrgid_r(group_id, &gr, buf, sizeof(buf), &group) && group)
60                 result.group = group->gr_name;
61         else
62                 result.group = format("%d", group_id);
63 }
64
65
66 Stat Stat::stat(const Path &path)
67 {
68         struct stat st;
69         int ret = ::stat(path.str().c_str(), &st);
70         if(ret==-1)
71         {
72                 if(errno==ENOENT)
73                         return Stat();
74                 else
75                         throw system_error("stat");
76         }
77
78         return Private::from_struct_stat(st);
79 }
80
81 Stat Stat::lstat(const Path &path)
82 {
83         struct stat st;
84         int ret = ::lstat(path.str().c_str(), &st);
85         if(ret==-1)
86         {
87                 if(errno==ENOENT)
88                         return Stat();
89                 else
90                         throw system_error("lstat");
91         }
92
93         return Private::from_struct_stat(st);
94 }
95
96 bool exists(const Path &path)
97 {
98         return access(path.str().c_str(), F_OK)==0;
99 }
100
101 } // namespace FS
102 } // namespace Msp