fix build
[mono.git] / eglib / src / gfile-posix.c
1 /*
2  * File utility functions.
3  *
4  * Author:
5  *   Gonzalo Paniagua Javier (gonzalo@novell.com)
6  *
7  * (C) 2006 Novell, Inc.
8  *
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:
16  *
17  * The above copyright notice and this permission notice shall be
18  * included in all copies or substantial portions of the Software.
19  *
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.
27  */
28 #include <config.h>
29 #include <glib.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <errno.h>
33 #include <fcntl.h>
34 #include <sys/stat.h>
35 #include <sys/types.h>
36
37 #ifdef _MSC_VER
38 int mkstemp (char *tmp_template);
39 #endif
40
41 #ifndef O_LARGEFILE
42 #define OPEN_FLAGS (O_RDONLY)
43 #else
44 #define OPEN_FLAGS (O_RDONLY | O_LARGEFILE)
45 #endif
46 gboolean
47 g_file_get_contents (const gchar *filename, gchar **contents, gsize *length, GError **error)
48 {
49         gchar *str;
50         int fd;
51         struct stat st;
52         long offset;
53         int nread;
54
55         g_return_val_if_fail (filename != NULL, FALSE);
56         g_return_val_if_fail (contents != NULL, FALSE);
57         g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
58
59         *contents = NULL;
60         if (length)
61                 *length = 0;
62
63         fd = open (filename, OPEN_FLAGS);
64         if (fd == -1) {
65                 if (error != NULL) {
66                         int err = errno;
67                         *error = g_error_new (G_LOG_DOMAIN, g_file_error_from_errno (err), "Error opening file");
68                 }
69                 return FALSE;
70         }
71
72         if (fstat (fd, &st) != 0) {
73                 if (error != NULL) {
74                         int err = errno;
75                         *error = g_error_new (G_LOG_DOMAIN, g_file_error_from_errno (err), "Error in fstat()");
76                 }
77                 close (fd);
78                 return FALSE;
79         }
80
81         str = g_malloc (st.st_size + 1);
82         offset = 0;
83         do {
84                 nread = read (fd, str + offset, st.st_size - offset);
85                 if (nread > 0) {
86                         offset += nread;
87                 }
88         } while ((nread > 0 && offset < st.st_size) || (nread == -1 && errno == EINTR));
89
90         close (fd);
91         str [st.st_size] = '\0';
92         if (length) {
93                 *length = st.st_size;
94         }
95         *contents = str;
96         return TRUE;
97 }
98
99 gint
100 g_file_open_tmp (const gchar *tmpl, gchar **name_used, GError **error)
101 {
102         const static gchar *default_tmpl = ".XXXXXX";
103         gchar *t;
104         gint fd;
105         size_t len;
106
107         g_return_val_if_fail (error == NULL || *error == NULL, -1);
108
109         if (tmpl == NULL)
110                 tmpl = default_tmpl;
111
112         if (strchr (tmpl, G_DIR_SEPARATOR) != NULL) {
113                 if (error) {
114                         *error = g_error_new (G_LOG_DOMAIN, 24, "Template should not have any " G_DIR_SEPARATOR_S);
115                 }
116                 return -1;
117         }
118
119         len = strlen (tmpl);
120         if (len < 6 || strcmp (tmpl + len - 6, "XXXXXX")) {
121                 if (error) {
122                         *error = g_error_new (G_LOG_DOMAIN, 24, "Template should end with XXXXXX");
123                 }
124                 return -1;
125         }
126
127         t = g_build_filename (g_get_tmp_dir (), tmpl, NULL);
128
129         fd = mkstemp (t);
130
131         if (fd == -1) {
132                 if (error) {
133                         int err = errno;
134                         *error = g_error_new (G_LOG_DOMAIN, g_file_error_from_errno (err), "Error in mkstemp()");
135                 }
136                 g_free (t);
137                 return -1;
138         }
139
140         if (name_used) {
141                 *name_used = t;
142         } else {
143                 g_free (t);
144         }
145         return fd;
146 }