d71d555b4d1b1c6f97f121d507356c06d35808b8
[mono.git] / support / sys-stat.c
1 /*
2  * <sys/stat.h> wrapper functions.
3  *
4  * Authors:
5  *   Jonathan Pryor (jonpryor@vt.edu)
6  *
7  * Copyright (C) 2004-2006 Jonathan Pryor
8  */
9
10 #ifndef _GNU_SOURCE
11 #define _GNU_SOURCE
12 #endif /* ndef _GNU_SOURCE */
13
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <unistd.h>
17 #include <fcntl.h>
18 #include <errno.h>
19
20 #include "map.h"
21 #include "mph.h"
22
23 G_BEGIN_DECLS
24
25 int
26 Mono_Posix_FromStat (struct Mono_Posix_Stat *from, void *_to)
27 {
28         struct stat *to = _to;
29         memset (to, 0, sizeof(*to));
30
31         to->st_dev         = from->st_dev;
32         to->st_ino         = from->st_ino;
33
34         unsigned int to_st_mode;
35         if (Mono_Posix_FromFilePermissions (from->st_mode, &to_st_mode) != 0) {
36                 return -1;
37         }
38
39         to->st_mode        = to_st_mode;
40         to->st_nlink       = from->st_nlink;
41         to->st_uid         = from->st_uid;
42         to->st_gid         = from->st_gid;
43         to->st_rdev        = from->st_rdev;
44         to->st_size        = from->st_size;
45         to->st_blksize     = from->st_blksize;
46         to->st_blocks      = from->st_blocks;
47         to->st_atime       = from->st_atime_;
48         to->st_mtime       = from->st_mtime_;
49         to->st_ctime       = from->st_ctime_;
50 #ifdef HAVE_STRUCT_STAT_ST_ATIM
51         to->st_atim.tv_nsec = from->st_atime_nsec;
52 #endif
53 #ifdef HAVE_STRUCT_STAT_ST_MTIM
54         to->st_mtim.tv_nsec = from->st_mtime_nsec;
55 #endif
56 #ifdef HAVE_STRUCT_STAT_ST_CTIM
57         to->st_ctim.tv_nsec = from->st_ctime_nsec;
58 #endif
59
60         return 0;
61 }
62
63 int
64 Mono_Posix_ToStat (void *_from, struct Mono_Posix_Stat *to)
65 {
66         struct stat *from = _from;
67         memset (to, 0, sizeof(*to));
68
69         to->st_dev        = from->st_dev;
70         to->st_ino        = from->st_ino;
71         if (Mono_Posix_ToFilePermissions (from->st_mode, &to->st_mode) != 0) {
72                 return -1;
73         }
74         to->st_nlink      = from->st_nlink;
75         to->st_uid        = from->st_uid;
76         to->st_gid        = from->st_gid;
77         to->st_rdev       = from->st_rdev;
78         to->st_size       = from->st_size;
79         to->st_blksize    = from->st_blksize;
80         to->st_blocks     = from->st_blocks;
81         to->st_atime_     = from->st_atime;
82         to->st_mtime_     = from->st_mtime;
83         to->st_ctime_     = from->st_ctime;
84 #ifdef HAVE_STRUCT_STAT_ST_ATIM
85         to->st_atime_nsec = from->st_atim.tv_nsec;
86 #endif
87 #ifdef HAVE_STRUCT_STAT_ST_MTIM
88         to->st_mtime_nsec = from->st_mtim.tv_nsec;
89 #endif
90 #ifdef HAVE_STRUCT_STAT_ST_CTIM
91         to->st_ctime_nsec = from->st_ctim.tv_nsec;
92 #endif
93
94         return 0;
95 }
96
97 gint32
98 Mono_Posix_Syscall_stat (const char *file_name, struct Mono_Posix_Stat *buf)
99 {
100         int r;
101         struct stat _buf;
102
103         if (buf == NULL) {
104                 errno = EFAULT;
105                 return -1;
106         }
107         r = stat (file_name, &_buf);
108         if (r != -1 && Mono_Posix_ToStat (&_buf, buf) == -1)
109                 r = -1;
110         return r;
111 }
112
113 gint32
114 Mono_Posix_Syscall_fstat (int filedes, struct Mono_Posix_Stat *buf)
115 {
116         int r;
117         struct stat _buf;
118
119         if (buf == NULL) {
120                 errno = EFAULT;
121                 return -1;
122         }
123         r = fstat (filedes, &_buf);
124         if (r != -1 && Mono_Posix_ToStat (&_buf, buf) == -1)
125                 r = -1;
126         return r;
127 }
128
129 gint32
130 Mono_Posix_Syscall_lstat (const char *file_name, struct Mono_Posix_Stat *buf)
131 {
132         int r;
133         struct stat _buf;
134
135         if (buf == NULL) {
136                 errno = EFAULT;
137                 return -1;
138         }
139         r = lstat (file_name, &_buf);
140         if (r != -1 && Mono_Posix_ToStat (&_buf, buf) == -1)
141                 r = -1;
142         return r;
143 }
144
145 #ifdef HAVE_FSTATAT
146 gint32
147 Mono_Posix_Syscall_fstatat (gint32 dirfd, const char *file_name, struct Mono_Posix_Stat *buf, gint32 flags)
148 {
149         int r;
150         struct stat _buf;
151
152         if (Mono_Posix_FromAtFlags (flags, &flags) == -1)
153                 return -1;
154
155         if (buf == NULL) {
156                 errno = EFAULT;
157                 return -1;
158         }
159         r = fstatat (dirfd, file_name, &_buf, flags);
160         if (r != -1 && Mono_Posix_ToStat (&_buf, buf) == -1)
161                 r = -1;
162         return r;
163 }
164 #endif
165
166 gint32
167 Mono_Posix_Syscall_mknod (const char *pathname, guint32 mode, mph_dev_t dev)
168 {
169         if (Mono_Posix_FromFilePermissions (mode, &mode) == -1)
170                 return -1;
171         return mknod (pathname, mode, dev);
172 }
173
174 #ifdef HAVE_MKNODAT
175 gint32
176 Mono_Posix_Syscall_mknodat (int dirfd, const char *pathname, guint32 mode, mph_dev_t dev)
177 {
178         if (Mono_Posix_FromFilePermissions (mode, &mode) == -1)
179                 return -1;
180         return mknodat (dirfd, pathname, mode, dev);
181 }
182 #endif
183
184 G_END_DECLS
185
186 gint64
187 Mono_Posix_Syscall_get_utime_now ()
188 {
189 #ifdef UTIME_NOW
190         return UTIME_NOW;
191 #else
192         return -1;
193 #endif
194 }
195
196 gint64
197 Mono_Posix_Syscall_get_utime_omit ()
198 {
199 #ifdef UTIME_OMIT
200         return UTIME_OMIT;
201 #else
202         return -1;
203 #endif
204 }
205
206 static inline struct timespec*
207 copy_utimens (struct timespec* to, struct Mono_Posix_Timespec *from)
208 {
209         if (from) {
210                 to[0].tv_sec  = from[0].tv_sec;
211                 to[0].tv_nsec = from[0].tv_nsec;
212                 to[1].tv_sec  = from[1].tv_sec;
213                 to[1].tv_nsec = from[1].tv_nsec;
214                 return to;
215         }
216
217         return NULL;
218 }
219
220 #ifdef HAVE_FUTIMENS
221 gint32
222 Mono_Posix_Syscall_futimens(int fd, struct Mono_Posix_Timespec *tv)
223 {
224         struct timespec _tv[2];
225         struct timespec *ptv;
226
227         ptv = copy_utimens (_tv, tv);
228
229         return futimens (fd, ptv);
230 }
231 #endif /* def HAVE_FUTIMENS */
232
233 #ifdef HAVE_UTIMENSAT
234 gint32
235 Mono_Posix_Syscall_utimensat(int dirfd, const char *pathname, struct Mono_Posix_Timespec *tv, int flags)
236 {
237         struct timespec _tv[2];
238         struct timespec *ptv;
239
240         ptv = copy_utimens (_tv, tv);
241
242         return utimensat (dirfd, pathname, ptv, flags);
243 }
244 #endif /* def HAVE_UTIMENSAT */
245
246
247 /*
248  * vim: noexpandtab
249  */