[runtime] Move eglib into mono/eglib so it becomes a convenience library similar...
[mono.git] / mono / eglib / gfile.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
29 #include <config.h>
30
31 #include <glib.h>
32 #include <stdio.h>
33 #include <string.h>
34 #ifdef HAVE_UNISTD_H
35 #include <unistd.h>
36 #endif
37 #include <errno.h>
38
39 static gpointer error_quark = "FileError";
40
41 gpointer
42 g_file_error_quark (void)
43 {
44         return error_quark;
45 }
46
47 GFileError
48 g_file_error_from_errno (gint err_no)
49 {
50         switch (err_no) {
51         case EEXIST:
52                 return G_FILE_ERROR_EXIST;
53         case EISDIR:
54                 return G_FILE_ERROR_ISDIR;
55         case EACCES:
56                 return G_FILE_ERROR_ACCES;
57         case ENAMETOOLONG:
58                 return G_FILE_ERROR_NAMETOOLONG;
59         case ENOENT:
60                 return G_FILE_ERROR_NOENT;
61         case ENOTDIR:
62                 return G_FILE_ERROR_NOTDIR;
63         case ENXIO:
64                 return G_FILE_ERROR_NXIO;
65         case ENODEV:
66                 return G_FILE_ERROR_NODEV;
67         case EROFS:
68                 return G_FILE_ERROR_ROFS;
69 #ifdef ETXTBSY
70         case ETXTBSY:
71                 return G_FILE_ERROR_TXTBSY;
72 #endif
73         case EFAULT:
74                 return G_FILE_ERROR_FAULT;
75 #ifdef ELOOP
76         case ELOOP:
77                 return G_FILE_ERROR_LOOP;
78 #endif
79         case ENOSPC:
80                 return G_FILE_ERROR_NOSPC;
81         case ENOMEM:
82                 return G_FILE_ERROR_NOMEM;
83         case EMFILE:
84                 return G_FILE_ERROR_MFILE;
85         case ENFILE:
86                 return G_FILE_ERROR_NFILE;
87         case EBADF:
88                 return G_FILE_ERROR_BADF;
89         case EINVAL:
90                 return G_FILE_ERROR_INVAL;
91         case EPIPE:
92                 return G_FILE_ERROR_PIPE;
93         case EAGAIN:
94                 return G_FILE_ERROR_AGAIN;
95         case EINTR:
96                 return G_FILE_ERROR_INTR;
97         case EIO:
98                 return G_FILE_ERROR_IO;
99         case EPERM:
100                 return G_FILE_ERROR_PERM;
101         case ENOSYS:
102                 return G_FILE_ERROR_NOSYS;
103         default:
104                 return G_FILE_ERROR_FAILED;
105         }
106 }
107
108 #ifdef G_OS_WIN32
109 #define TMP_FILE_FORMAT "%.*s%s.tmp"
110 #else
111 #define TMP_FILE_FORMAT "%.*s.%s~"
112 #endif
113
114 gboolean
115 g_file_set_contents (const gchar *filename, const gchar *contents, gssize length, GError **err)
116 {
117         const char *name;
118         char *path;
119         FILE *fp;
120         
121         if (!(name = strrchr (filename, G_DIR_SEPARATOR)))
122                 name = filename;
123         else
124                 name++;
125         
126         path = g_strdup_printf (TMP_FILE_FORMAT, name - filename, filename, name);
127         if (!(fp = fopen (path, "wb"))) {
128                 g_set_error (err, G_FILE_ERROR, g_file_error_from_errno (errno), "%s", g_strerror (errno));
129                 g_free (path);
130                 return FALSE;
131         }
132         
133         if (length < 0)
134                 length = strlen (contents);
135         
136         if (fwrite (contents, 1, length, fp) < length) {
137                 g_set_error (err, G_FILE_ERROR, g_file_error_from_errno (ferror (fp)), "%s", g_strerror (ferror (fp)));
138                 g_unlink (path);
139                 g_free (path);
140                 fclose (fp);
141                 
142                 return FALSE;
143         }
144         
145         fclose (fp);
146         
147         if (g_rename (path, filename) != 0) {
148                 g_set_error (err, G_FILE_ERROR, g_file_error_from_errno (errno), "%s", g_strerror (errno));
149                 g_unlink (path);
150                 g_free (path);
151                 return FALSE;
152         }
153         
154         g_free (path);
155         
156         return TRUE;
157 }