* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
+
+#include <config.h>
+
#include <glib.h>
#include <stdio.h>
-#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif
#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
+
+static gpointer error_quark = "FileError";
+
+gpointer
+g_file_error_quark (void)
+{
+ return error_quark;
+}
GFileError
g_file_error_from_errno (gint err_no)
}
}
-#ifndef O_LARGEFILE
-#define OPEN_FLAGS (O_RDONLY)
+#ifdef G_OS_WIN32
+#define TMP_FILE_FORMAT "%.*s%s.tmp"
#else
-#define OPEN_FLAGS (O_RDONLY | O_LARGEFILE)
+#define TMP_FILE_FORMAT "%.*s.%s~"
#endif
+
gboolean
-g_file_get_contents (const gchar *filename, gchar **contents, gsize *length, GError **error)
+g_file_set_contents (const gchar *filename, const gchar *contents, gssize length, GError **err)
{
- gchar *str;
- int fd;
- struct stat st;
- long offset;
- int nread;
-
- g_return_val_if_fail (filename != NULL, FALSE);
- g_return_val_if_fail (contents != NULL, FALSE);
- g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-
- *contents = NULL;
- if (length)
- *length = 0;
-
- fd = open (filename, OPEN_FLAGS);
- if (fd == -1) {
- if (error != NULL) {
- int err = errno;
- *error = g_error_new (G_LOG_DOMAIN, g_file_error_from_errno (err), "Error opening file");
- }
+ const char *name;
+ char *path;
+ FILE *fp;
+
+ if (!(name = strrchr (filename, G_DIR_SEPARATOR)))
+ name = filename;
+ else
+ name++;
+
+ path = g_strdup_printf (TMP_FILE_FORMAT, name - filename, filename, name);
+ if (!(fp = fopen (path, "wb"))) {
+ g_set_error (err, G_FILE_ERROR, g_file_error_from_errno (errno), "%s", g_strerror (errno));
+ g_free (path);
return FALSE;
}
-
- if (fstat (fd, &st) != 0) {
- if (error != NULL) {
- int err = errno;
- *error = g_error_new (G_LOG_DOMAIN, g_file_error_from_errno (err), "Error in fstat()");
- }
- close (fd);
+
+ if (length < 0)
+ length = strlen (contents);
+
+ if (fwrite (contents, 1, length, fp) < length) {
+ g_set_error (err, G_FILE_ERROR, g_file_error_from_errno (ferror (fp)), "%s", g_strerror (ferror (fp)));
+ g_unlink (path);
+ g_free (path);
+ fclose (fp);
+
return FALSE;
}
-
- str = g_malloc (st.st_size + 1);
- offset = 0;
- do {
- nread = read (fd, str + offset, st.st_size - offset);
- if (nread > 0) {
- offset += nread;
- }
- } while ((nread > 0 && offset < st.st_size) || (nread == -1 && errno == EINTR));
-
- close (fd);
- str [st.st_size] = '\0';
- if (length) {
- *length = st.st_size;
- }
- *contents = str;
- return TRUE;
-}
-
-gint
-g_file_open_tmp (const gchar *tmpl, gchar **name_used, GError **error)
-{
- const static gchar *default_tmpl = ".XXXXXX";
- gchar *t;
- gint fd;
- gint len;
-
- g_return_val_if_fail (error == NULL || *error == NULL, -1);
-
- if (tmpl == NULL)
- tmpl = default_tmpl;
-
- if (strchr (tmpl, G_DIR_SEPARATOR) != NULL) {
- if (error) {
- *error = g_error_new (G_LOG_DOMAIN, 24, "Template should not have any " G_DIR_SEPARATOR_S);
- }
- return -1;
- }
-
- len = strlen (tmpl);
- if (len < 6 || strcmp (tmpl + len - 6, "XXXXXX")) {
- if (error) {
- *error = g_error_new (G_LOG_DOMAIN, 24, "Template should end with XXXXXX");
- }
- return -1;
- }
-
- t = g_build_filename (g_get_tmp_dir (), tmpl, NULL);
- fd = mkstemp (t);
- if (fd == -1) {
- if (error) {
- int err = errno;
- *error = g_error_new (G_LOG_DOMAIN, g_file_error_from_errno (err), "Error in mkstemp()");
- }
- g_free (t);
- return -1;
- }
-
- if (name_used) {
- *name_used = t;
- } else {
- g_free (t);
- }
- return fd;
-}
-
-gboolean
-g_file_test (const gchar *filename, GFileTest test)
-{
- struct stat st;
- gboolean have_stat;
-
- if (filename == NULL || test == 0)
+
+ fclose (fp);
+
+ if (g_rename (path, filename) != 0) {
+ g_set_error (err, G_FILE_ERROR, g_file_error_from_errno (errno), "%s", g_strerror (errno));
+ g_unlink (path);
+ g_free (path);
return FALSE;
-
- have_stat = FALSE;
-#ifdef G_OS_WIN32
-#else
- if ((test & G_FILE_TEST_EXISTS) != 0) {
- if (access (filename, F_OK) == 0)
- return TRUE;
- }
-
- if ((test & G_FILE_TEST_IS_EXECUTABLE) != 0) {
- if (access (filename, X_OK) == 0)
- return TRUE;
- }
- if ((test & G_FILE_TEST_IS_SYMLINK) != 0) {
- have_stat = (lstat (filename, &st) == 0);
- if (have_stat && S_ISLNK (st.st_mode))
- return TRUE;
}
-#endif
-
- if ((test & G_FILE_TEST_IS_REGULAR) != 0) {
- if (!have_stat)
- have_stat = (stat (filename, &st) == 0);
- if (have_stat && S_ISREG (st.st_mode))
- return TRUE;
- }
- if ((test & G_FILE_TEST_IS_DIR) != 0) {
- if (!have_stat)
- have_stat = (stat (filename, &st) == 0);
- if (have_stat && S_ISDIR (st.st_mode))
- return TRUE;
- }
- return FALSE;
+
+ g_free (path);
+
+ return TRUE;
}
-