remove langversion:linq as it is the default now
[mono.git] / eglib / src / gfile.c
blob68201e753fc9bcc7a55347d2f072424fc8467cd3
1 /*
2 * File utility functions.
4 * Author:
5 * Gonzalo Paniagua Javier (gonzalo@novell.com)
7 * (C) 2006 Novell, Inc.
9 * Permission is hereby granted, free of charge, to any person obtaining
10 * a copy of this software and associated documentation files (the
11 * "Software"), to deal in the Software without restriction, including
12 * without limitation the rights to use, copy, modify, merge, publish,
13 * distribute, sublicense, and/or sell copies of the Software, and to
14 * permit persons to whom the Software is furnished to do so, subject to
15 * the following conditions:
17 * The above copyright notice and this permission notice shall be
18 * included in all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 #include <config.h>
29 #include <glib.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <errno.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <fcntl.h>
37 #ifdef G_OS_WIN32
38 #include <io.h>
39 #define open _open
40 #define S_ISREG(x) ((x & _S_IFMT) == _S_IFREG)
41 #define S_ISDIR(x) ((x & _S_IFMT) == _S_IFDIR)
42 #endif
44 #ifdef HAVE_UNISTD_H
45 #include <unistd.h>
46 #endif
48 GFileError
49 g_file_error_from_errno (gint err_no)
51 switch (err_no) {
52 case EEXIST:
53 return G_FILE_ERROR_EXIST;
54 case EISDIR:
55 return G_FILE_ERROR_ISDIR;
56 case EACCES:
57 return G_FILE_ERROR_ACCES;
58 case ENAMETOOLONG:
59 return G_FILE_ERROR_NAMETOOLONG;
60 case ENOENT:
61 return G_FILE_ERROR_NOENT;
62 case ENOTDIR:
63 return G_FILE_ERROR_NOTDIR;
64 case ENXIO:
65 return G_FILE_ERROR_NXIO;
66 case ENODEV:
67 return G_FILE_ERROR_NODEV;
68 case EROFS:
69 return G_FILE_ERROR_ROFS;
70 #ifdef ETXTBSY
71 case ETXTBSY:
72 return G_FILE_ERROR_TXTBSY;
73 #endif
74 case EFAULT:
75 return G_FILE_ERROR_FAULT;
76 #ifdef ELOOP
77 case ELOOP:
78 return G_FILE_ERROR_LOOP;
79 #endif
80 case ENOSPC:
81 return G_FILE_ERROR_NOSPC;
82 case ENOMEM:
83 return G_FILE_ERROR_NOMEM;
84 case EMFILE:
85 return G_FILE_ERROR_MFILE;
86 case ENFILE:
87 return G_FILE_ERROR_NFILE;
88 case EBADF:
89 return G_FILE_ERROR_BADF;
90 case EINVAL:
91 return G_FILE_ERROR_INVAL;
92 case EPIPE:
93 return G_FILE_ERROR_PIPE;
94 case EAGAIN:
95 return G_FILE_ERROR_AGAIN;
96 case EINTR:
97 return G_FILE_ERROR_INTR;
98 case EIO:
99 return G_FILE_ERROR_IO;
100 case EPERM:
101 return G_FILE_ERROR_PERM;
102 case ENOSYS:
103 return G_FILE_ERROR_NOSYS;
104 default:
105 return G_FILE_ERROR_FAILED;
109 #ifndef O_LARGEFILE
110 #define OPEN_FLAGS (O_RDONLY)
111 #else
112 #define OPEN_FLAGS (O_RDONLY | O_LARGEFILE)
113 #endif
114 gboolean
115 g_file_get_contents (const gchar *filename, gchar **contents, gsize *length, GError **error)
117 gchar *str;
118 int fd;
119 struct stat st;
120 long offset;
121 int nread;
123 g_return_val_if_fail (filename != NULL, FALSE);
124 g_return_val_if_fail (contents != NULL, FALSE);
125 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
127 *contents = NULL;
128 if (length)
129 *length = 0;
131 fd = open (filename, OPEN_FLAGS);
132 if (fd == -1) {
133 if (error != NULL) {
134 int err = errno;
135 *error = g_error_new (G_LOG_DOMAIN, g_file_error_from_errno (err), "Error opening file");
137 return FALSE;
140 if (fstat (fd, &st) != 0) {
141 if (error != NULL) {
142 int err = errno;
143 *error = g_error_new (G_LOG_DOMAIN, g_file_error_from_errno (err), "Error in fstat()");
145 close (fd);
146 return FALSE;
149 str = g_malloc (st.st_size + 1);
150 offset = 0;
151 do {
152 nread = read (fd, str + offset, st.st_size - offset);
153 if (nread > 0) {
154 offset += nread;
156 } while ((nread > 0 && offset < st.st_size) || (nread == -1 && errno == EINTR));
158 close (fd);
159 str [st.st_size] = '\0';
160 if (length) {
161 *length = st.st_size;
163 *contents = str;
164 return TRUE;
167 #ifdef _MSC_VER
168 int mkstemp (char *tmp_template)
170 int fd;
171 gunichar2* utf16_template;
173 utf16_template = u8to16 (tmp_template);
175 fd = -1;
176 utf16_template = _wmktemp( utf16_template);
177 if (utf16_template && *utf16_template) {
178 /* FIXME: _O_TEMPORARY causes file to disappear on close causing a test to fail */
179 fd = _wopen( utf16_template, _O_BINARY | _O_CREAT /*| _O_TEMPORARY*/ | _O_EXCL, _S_IREAD | _S_IWRITE);
182 sprintf (tmp_template + strlen (tmp_template) - 6, "%S", utf16_template + wcslen (utf16_template) - 6);
184 g_free (utf16_template);
185 return fd;
187 #endif
189 gint
190 g_file_open_tmp (const gchar *tmpl, gchar **name_used, GError **error)
192 const static gchar *default_tmpl = ".XXXXXX";
193 gchar *t;
194 gint fd;
195 size_t len;
197 g_return_val_if_fail (error == NULL || *error == NULL, -1);
199 if (tmpl == NULL)
200 tmpl = default_tmpl;
202 if (strchr (tmpl, G_DIR_SEPARATOR) != NULL) {
203 if (error) {
204 *error = g_error_new (G_LOG_DOMAIN, 24, "Template should not have any " G_DIR_SEPARATOR_S);
206 return -1;
209 len = strlen (tmpl);
210 if (len < 6 || strcmp (tmpl + len - 6, "XXXXXX")) {
211 if (error) {
212 *error = g_error_new (G_LOG_DOMAIN, 24, "Template should end with XXXXXX");
214 return -1;
217 t = g_build_filename (g_get_tmp_dir (), tmpl, NULL);
219 fd = mkstemp (t);
221 if (fd == -1) {
222 if (error) {
223 int err = errno;
224 *error = g_error_new (G_LOG_DOMAIN, g_file_error_from_errno (err), "Error in mkstemp()");
226 g_free (t);
227 return -1;
230 if (name_used) {
231 *name_used = t;
232 } else {
233 g_free (t);
235 return fd;
238 #ifdef _MSC_VER
239 #pragma warning(disable:4701)
240 #endif
242 gboolean
243 g_file_test (const gchar *filename, GFileTest test)
245 #ifdef G_OS_WIN32
246 struct _stat64 stat;
247 int ret = 0;
248 gunichar2* utf16_filename = NULL;
250 if (filename == NULL || test == 0)
251 return FALSE;
253 utf16_filename = u8to16 (filename);
254 ret = _wstati64 (utf16_filename, &stat);
255 g_free (utf16_filename);
257 if ((test & G_FILE_TEST_EXISTS) != 0) {
258 if (ret == 0)
259 return TRUE;
262 if (ret != 0)
263 return FALSE;
265 if ((test & G_FILE_TEST_IS_EXECUTABLE) != 0) {
266 if (stat.st_mode & _S_IEXEC)
267 return TRUE;
270 if ((test & G_FILE_TEST_IS_REGULAR) != 0) {
271 if (stat.st_mode & _S_IFREG)
272 return TRUE;
275 if ((test & G_FILE_TEST_IS_DIR) != 0) {
276 if (stat.st_mode & _S_IFDIR)
277 return TRUE;
280 /* make this last in case it is OR'd with something else */
281 if ((test & G_FILE_TEST_IS_SYMLINK) != 0) {
282 return FALSE;
285 return FALSE;
286 #else
287 struct stat st;
288 gboolean have_stat;
290 if (filename == NULL || test == 0)
291 return FALSE;
293 have_stat = FALSE;
295 if ((test & G_FILE_TEST_EXISTS) != 0) {
296 if (access (filename, F_OK) == 0)
297 return TRUE;
300 if ((test & G_FILE_TEST_IS_EXECUTABLE) != 0) {
301 if (access (filename, X_OK) == 0)
302 return TRUE;
304 if ((test & G_FILE_TEST_IS_SYMLINK) != 0) {
305 have_stat = (lstat (filename, &st) == 0);
306 if (have_stat && S_ISLNK (st.st_mode))
307 return TRUE;
310 if ((test & G_FILE_TEST_IS_REGULAR) != 0) {
311 if (!have_stat)
312 have_stat = (stat (filename, &st) == 0);
313 if (have_stat && S_ISREG (st.st_mode))
314 return TRUE;
316 if ((test & G_FILE_TEST_IS_DIR) != 0) {
317 if (!have_stat)
318 have_stat = (stat (filename, &st) == 0);
319 if (have_stat && S_ISDIR (st.st_mode))
320 return TRUE;
322 return FALSE;
323 #endif