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