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