#
# See http://sources.redhat.com/autobook/autobook/autobook_91.html#SEC91 for details
#
-LT_CURRENT=3
+LT_CURRENT=4
LT_REVISION=0
-LT_AGE=1
+LT_AGE=2
AC_SUBST(LT_CURRENT)
AC_SUBST(LT_REVISION)
AC_SUBST(LT_AGE)
iterator.c \
importer.c \
merger.c \
+ error.c \
atomic.c \
atomic-ktm.c \
atomic-none.c \
return 0;
if (errno != EEXIST || chmod(action->args.path, mode) < 0) {
- if (!atomic->error_str)
- razor_atomic_set_error_str(atomic, action->args.path,
- strerror(errno));
+ if (!atomic->error)
+ atomic->error = razor_error_new_str(action->args.path,
+ strerror(errno));
atomic_action_free(action);
return NULL;
}
}
if (rmdir(action->args.path) < 0) {
- if (!atomic->error_str)
- razor_atomic_set_error_str(atomic, action->args.path,
- strerror(errno));
+ if (!atomic->error)
+ atomic->error = razor_error_new_str(action->args.path,
+ strerror(errno));
atomic_action_free(action);
return NULL;
} else
r = symlink(action->args.u.create_symlink.target, action->args.path);
if (r < 0) {
- if (!atomic->error_str)
- razor_atomic_set_error_str(atomic, NULL,
- strerror(errno));
+ if (!atomic->error)
+ atomic->error = razor_error_new_str(action->args.path,
+ strerror(errno));
atomic_action_free(action);
return NULL;
}
}
if (unlink(action->args.path) < 0) {
- if (!atomic->error_str)
- razor_atomic_set_error_str(atomic, NULL,
- strerror(errno));
+ if (!atomic->error)
+ atomic->error = razor_error_new_str(action->args.path,
+ strerror(errno));
atomic_action_free(action);
return NULL;
}
(void)RemoveDirectoryW(newbuf);
if (!MoveFileExW(oldbuf, newbuf, flags)) {
- if (!atomic->error_str)
- razor_atomic_set_error_mswin(atomic, newbuf,
- GetLastError());
+ if (!atomic->error)
+ atomic->error = razor_error_new_mswin(newbuf,
+ GetLastError());
return -1;
}
free(oldbuf);
#else
if (rename(path, dest)) {
- if (!atomic->error_str)
- razor_atomic_set_error_str(atomic, dest,
- strerror(errno));
+ if (!atomic->error)
+ atomic->error = razor_error_new_str(dest,
+ strerror(errno));
return -1;
}
#endif
#if ENABLE_ATOMIC && !HAVE_WINDOWS_KTM
#include <stdlib.h>
+#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
atomic->toplevel = NULL;
}
- return !!atomic->error_str;
+ return razor_atomic_in_error_state(atomic);
}
RAZOR_EXPORT void razor_atomic_destroy(struct razor_atomic *atomic)
atomic->toplevel = NULL;
}
- free(atomic->error_path);
- free(atomic->error_str);
- free(atomic->error_msg);
+ if (atomic->error)
+ razor_error_free(atomic->error);
+
free(atomic);
}
return 0;
#else
- razor_atomic_set_error_str(atomic, NULL, "Symbolic links not supported "
- "on this platform");
+ atomic->error = razor_error_new_str(NULL,
+ "Symbolic links not supported "
+ "on this platform");
return -1;
#endif
if (razor_atomic_in_error_state(atomic))
return -1;
- atomic->error_path = strdup(filename);
tmpnam = atomic_action_attic_tmpnam(atomic);
fd = open(tmpnam, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
mode & (S_IRWXU | S_IRWXG | S_IRWXO));
if (fd == -1)
- razor_atomic_set_error_str(atomic, NULL, strerror(errno));
+ atomic->error = razor_error_new_str(filename, strerror(errno));
else {
a = atomic_action_new(ACTION_MOVE);
a->args.path = tmpnam;
return atomic;
}
-void
-razor_atomic_set_error_str(struct razor_atomic *atomic, const wchar_t *path,
- const char *str)
-{
- assert(!atomic->error_str);
-
- free(atomic->error_path);
-
- if (path)
- atomic->error_path = razor_utf16_to_utf8(path, -1);
- else
- atomic->error_path = NULL;
-
- atomic->error_str = strdup(str);
-}
-
-static void
-razor_atomic_set_error(struct razor_atomic *atomic, const wchar_t *path,
- DWORD error)
-{
- wchar_t *buf;
-
- assert(!atomic->error_str);
-
- free(atomic->error_path);
-
- if (path)
- atomic->error_path = razor_utf16_to_utf8(path, -1);
- else
- atomic->error_path = NULL;
-
- FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER|
- FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, error, MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
- (LPWSTR)&buf, 0, NULL);
- atomic->error_str = razor_utf16_to_utf8(buf, -1);
- LocalFree(buf);
-}
-
RAZOR_EXPORT int
razor_atomic_commit(struct razor_atomic *atomic)
{
retval = !CommitTransaction(atomic->transaction);
if (retval) {
- razor_atomic_set_error(atomic, NULL, GetLastError());
+ atomic->error = razor_error_new_mswin(NULL, GetLastError());
RollbackTransaction(atomic->transaction);
}
RollbackTransaction(atomic->transaction);
CloseHandle(atomic->transaction);
}
- free(atomic->error_path);
- free(atomic->error_str);
- free(atomic->error_msg);
+ if (atomic->error)
+ razor_error_free(atomic->error);
free(atomic);
}
if (err == ERROR_FILE_NOT_FOUND) {
creating = 1;
} else {
- razor_atomic_set_error(atomic,
- buffer->str,
- err);
+ atomic->error = razor_error_new_mswin(buffer->str,
+ err);
razor_wstr_destroy(buffer);
return -1;
}
} else if (!(fa.dwFileAttributes&
FILE_ATTRIBUTE_DIRECTORY)) {
- razor_atomic_set_error_str(atomic, buffer->str,
- "Not a directory");
+ atomic->error = razor_error_new_str(buffer->str,
+ "Not a directory");
razor_wstr_destroy(buffer);
return -1;
}
if (creating) {
if (!CreateDirectoryTransactedW(NULL, buffer->str, NULL,
atomic->transaction)) {
- razor_atomic_set_error(atomic, buffer->str,
- GetLastError());
+ atomic->error = razor_error_new_mswin(buffer->str,
+ GetLastError());
razor_wstr_destroy(buffer);
return -1;
}
* same path, this is likely to cause more problems than it solves.
*/
- razor_atomic_set_error(atomic, buf, err);
+ atomic->error = razor_error_new_mswin(buf, err);
free(buf);
return -1;
}
if (!MoveFileTransactedW(oldbuf, newbuf, NULL, NULL, flags,
atomic->transaction))
- razor_atomic_set_error(atomic, newbuf, GetLastError());
+ atomic->error = razor_error_new_mswin(newbuf, GetLastError());
free(newbuf);
free(oldbuf);
- return !!atomic->error_str;
+ return razor_atomic_in_error_state(atomic);
}
RAZOR_EXPORT int
err = GetLastError();
if (err != ERROR_FILE_EXISTS && err != ERROR_ALREADY_EXISTS) {
abort:
- razor_atomic_set_error(atomic, buf, err);
+ atomic->error = razor_error_new_mswin(buf, err);
free(buf);
return -1;
}
* and we don't always know that at the time when the
* link is created, so it's a convienent lie for now.
*/
- razor_atomic_set_error_str(atomic, NULL, "Symbolic links not supported "
- "on this platform");
+ atomic->error = razor_error_new_str(NULL,
+ "Symbolic links not supported "
+ "on this platform");
return -1;
}
files = realloc(atomic->files,
(atomic->n_files+1) * sizeof(struct razor_atomic_file));
if (!files) {
- razor_atomic_set_error_str(atomic, NULL, "Not enough memory");
+ atomic->error = razor_error_new_str(NULL, "Not enough memory");
return -1;
}
atomic->n_files++;
NULL);
if (files[i].h == INVALID_HANDLE_VALUE) {
- razor_atomic_set_error(atomic, files[i].path, GetLastError());
+ atomic->error = razor_error_new_mswin(files[i].path,
+ GetLastError());
free(files[i].path);
atomic->n_files--;
return -1;
while(size) {
if (!WriteFile(atomic->files[handle].h, data, size, &written,
NULL)) {
- razor_atomic_set_error(atomic,
- atomic->files[handle].path,
- GetLastError());
+ atomic->error = razor_error_new_mswin(atomic->files[handle].path,
+ GetLastError());
(void)CloseHandle(atomic->files[handle].h);
free(atomic->files[handle].path);
assert(atomic->files[handle].h != INVALID_HANDLE_VALUE);
if (!CloseHandle(atomic->files[handle].h)) {
- razor_atomic_set_error(atomic, atomic->files[handle].path,
- GetLastError());
+ atomic->error = razor_error_new_mswin(atomic->files[handle].path,
+ GetLastError());
free(atomic->files[handle].path);
atomic->files[handle].path = NULL;
atomic->files[handle].h = INVALID_HANDLE_VALUE;
atomic->files[handle].h = h;
if (atomic->files[handle].h == INVALID_HANDLE_VALUE) {
- razor_atomic_set_error(atomic, atomic->files[handle].path,
- GetLastError());
+ atomic->error = razor_error_new_mswin(atomic->files[handle].path,
+ GetLastError());
free(atomic->files[handle].path);
atomic->files[handle].path = NULL;
return -1;
}
- return !!atomic->error_str;
+ return razor_atomic_in_error_state(atomic);
}
RAZOR_EXPORT int
assert(atomic->files[handle].h != INVALID_HANDLE_VALUE);
if (!CloseHandle(atomic->files[handle].h))
- razor_atomic_set_error(atomic, atomic->files[handle].path,
- GetLastError());
+ atomic->error = razor_error_new_mswin(atomic->files[handle].path,
+ GetLastError());
free(atomic->files[handle].path);
atomic->files[handle].path = NULL;
atomic->files[atomic->n_files-1].h == INVALID_HANDLE_VALUE)
atomic->n_files--;
- return !!atomic->error_str;
+ return razor_atomic_in_error_state(atomic);
}
#endif /* HAVE_WINDOWS_KTM */
RAZOR_EXPORT void
razor_atomic_destroy(struct razor_atomic *atomic)
{
- free(atomic->error_path);
- free(atomic->error_str);
- free(atomic->error_msg);
+ if (atomic->error)
+ razor_error_free(atomic->error);
+
free(atomic);
}
if (stat(buffer, &buf) == 0) {
if (!S_ISDIR(buf.st_mode)) {
- razor_atomic_set_error_str(atomic, buffer,
- "Not a directory");
+ atomic->error = razor_error_new_str(buffer,
+ "Not a directory");
return -1;
}
} else if (mkdir(buffer, 0777) < 0) {
- razor_atomic_set_error_str(atomic, buffer,
- strerror(errno));
+ atomic->error = razor_error_new_str(buffer,
+ strerror(errno));
return -1;
}
}
DeleteFileW(buf)) &&
!RemoveDirectoryW(buf) &&
GetLastError() != ERROR_DIR_NOT_EMPTY)
- razor_atomic_set_error_mswin(atomic, buf, err);
+ atomic->error = razor_error_new_mswin(buf, err);
}
free(buf);
#else
if (remove(path))
- razor_atomic_set_error_str(atomic, path, strerror(errno));
+ atomic->error = razor_error_new_str(path, strerror(errno));
#endif
- return !!atomic->error_str;
+ return razor_atomic_in_error_state(atomic);
}
RAZOR_EXPORT int
(void)RemoveDirectoryW(newbuf);
if (!MoveFileExW(oldbuf, newbuf, flags))
- razor_atomic_set_error_mswin(atomic, newbuf, GetLastError());
+ atomic->error = razor_error_new_mswin(newbuf, GetLastError());
free(newbuf);
free(oldbuf);
#else
if (rename(oldpath, newpath))
- razor_atomic_set_error_str(atomic, newpath, strerror(errno));
+ atomic->error = razor_error_new_str(newpath, strerror(errno));
#endif
- return !!atomic->error_str;
+ return razor_atomic_in_error_state(atomic);
}
RAZOR_EXPORT int
return 0;
if (errno != EEXIST) {
- razor_atomic_set_error_str(atomic, dirname, strerror(errno));
+ atomic->error = razor_error_new_str(dirname, strerror(errno));
return -1;
}
if (chmod(dirname, mode & (S_IRWXU | S_IRWXG | S_IRWXO)) < 0) {
- razor_atomic_set_error_str(atomic, dirname, strerror(errno));
+ atomic->error = razor_error_new_str(dirname, strerror(errno));
return -1;
}
#if HAVE_SYMLINK
if (symlink(target, path) < 0) {
- razor_atomic_set_error_str(atomic, NULL, strerror(errno));
+ atomic->error = razor_error_new_str(path, strerror(errno));
return -1;
}
return 0;
#else
- razor_atomic_set_error_str(atomic, NULL, "Symbolic links not supported "
- "on this platform");
+ atomic->error = razor_error_new_str(NULL,
+ "Symbolic links not supported "
+ "on this platform");
return -1;
#endif
if (razor_atomic_in_error_state(atomic))
return -1;
- atomic->error_path = strdup(filename);
- fd = open(atomic->error_path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
+ fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
mode & (S_IRWXU | S_IRWXG | S_IRWXO));
if (fd == -1)
- razor_atomic_set_error_str(atomic, NULL, strerror(errno));
+ atomic->error = razor_error_new_str(filename, strerror(errno));
return fd;
}
RAZOR_EXPORT const char *
razor_atomic_get_error_msg(struct razor_atomic *atomic)
{
- if (!atomic->error_msg) {
- if (atomic->error_path)
- atomic->error_msg = razor_concat(atomic->error_path,
- ": ",
- atomic->error_str,
- NULL);
- else
- atomic->error_msg = strdup(atomic->error_str);
- }
-
- return atomic->error_msg;
+ if (atomic->error)
+ return razor_error_get_msg(atomic->error);
+ else
+ return NULL;
}
RAZOR_EXPORT void
razor_atomic_abort(struct razor_atomic *atomic, const char *error_msg)
{
- if (!atomic->error_str)
- razor_atomic_set_error_str(atomic, NULL, error_msg);
+ if (!atomic->error)
+ atomic->error = razor_error_new_str(NULL, error_msg);
}
RAZOR_EXPORT int
razor_atomic_in_error_state(struct razor_atomic *atomic)
{
- return atomic->error_str && !atomic->in_undo;
+ return atomic->error && !atomic->in_undo;
}
#if !HAVE_WINDOWS_KTM
#endif
}
-#ifdef MSWIN_API
-void
-razor_atomic_set_error_mswin(struct razor_atomic *atomic, const wchar_t *path,
- DWORD error)
-{
- wchar_t *buf;
-
- assert(!atomic->error_str);
-
- free(atomic->error_path);
-
- if (path)
- atomic->error_path = razor_utf16_to_utf8(path, -1);
- else
- atomic->error_path = NULL;
-
- FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER|
- FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, error, MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
- (LPWSTR)&buf, 0, NULL);
- atomic->error_str = razor_utf16_to_utf8(buf, -1);
- LocalFree(buf);
-}
-#endif
-
-void
-razor_atomic_set_error_str(struct razor_atomic *atomic, const char *path,
- const char *str)
-{
- assert(!atomic->error_str);
-
- atomic->error_path = path ? strdup(path) : NULL;
- atomic->error_str = strdup(str);
-}
-
RAZOR_EXPORT int
razor_atomic_write(struct razor_atomic *atomic, int fd, const void *data,
size_t size)
while(size) {
written = write(fd, data, size);
if (written < 0) {
- razor_atomic_set_error_str(atomic, NULL,
- strerror(errno));
+ atomic->error = razor_error_new_str(NULL,
+ strerror(errno));
(void)close(fd);
return -1;
if (fsync(handle) < 0) {
- razor_atomic_set_error_str(atomic, NULL, strerror(errno));
+ atomic->error = razor_error_new_str(NULL, strerror(errno));
return -1;
}
- free(atomic->error_path);
- atomic->error_path = NULL;
-
return 0;
}
return -1;
if (close(fd) < 0) {
- razor_atomic_set_error_str(atomic, NULL, strerror(errno));
+ atomic->error = razor_error_new_str(NULL, strerror(errno));
return -1;
}
- free(atomic->error_path);
- atomic->error_path = NULL;
-
return 0;
}
--- /dev/null
+/*
+ * Copyright (C) 2011-2012 J. Ali Harlow <ali@juiblex.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#ifdef MSWIN_API
+#include <windows.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#include "razor.h"
+#include "razor-internal.h"
+
+RAZOR_EXPORT const char *
+razor_error_get_msg(struct razor_error *error)
+{
+ if (!error->msg) {
+ if (error->path)
+ error->msg = razor_concat(error->path, ": ", error->str,
+ NULL);
+ else
+ error->msg = strdup(error->str);
+ }
+
+ return error->msg;
+}
+
+#ifdef MSWIN_API
+struct razor_error *
+razor_error_new_mswin(const wchar_t *path, DWORD err)
+{
+ struct razor_error *error;
+ wchar_t *buf;
+
+ error = zalloc(sizeof *error);
+
+ if (path)
+ error->path = razor_utf16_to_utf8(path, -1);
+
+ FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER|
+ FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, err, MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
+ (LPWSTR)&buf, 0, NULL);
+ error->str = razor_utf16_to_utf8(buf, -1);
+ LocalFree(buf);
+
+ return error;
+}
+#endif
+
+#if HAVE_WINDOWS_KTM
+struct razor_error *
+razor_error_new_str(const wchar_t *path, const char *str)
+#else
+struct razor_error *
+razor_error_new_str(const char *path, const char *str)
+#endif
+{
+ struct razor_error *error;
+
+ error = zalloc(sizeof *error);
+
+#if HAVE_WINDOWS_KTM
+ if (path)
+ error->path = razor_utf16_to_utf8(path, -1);
+#else
+ if (path)
+ error->path = strdup(path);
+#endif
+
+ error->str = strdup(str);
+
+ return error;
+}
+
+void razor_error_free(struct razor_error *error)
+{
+ free(error->path);
+ free(error->str);
+ free(error->msg);
+ free(error);
+}
wchar_t *razor_utf8_to_utf16(const char *utf8, int len);
#endif
+/* Error functions */
+struct razor_error {
+ char *path;
+ char *str;
+ char *msg;
+};
+
+#ifdef MSWIN_API
+struct razor_error *razor_error_new_mswin(const wchar_t *path, DWORD error);
+#endif
+
+#if HAVE_WINDOWS_KTM
+struct razor_error *razor_error_new_str(const wchar_t *path, const char *str);
+#else
+struct razor_error *razor_error_new_str(const char *path, const char *str);
+#endif
+
/* Atomic functions */
#if HAVE_WINDOWS_KTM
HANDLE h;
} *files;
int in_undo;
- char *error_path;
- char *error_str;
- char *error_msg;
+ struct razor_error *error;
};
#elif ENABLE_ATOMIC
struct atomic_action {
char *toplevel;
unsigned next_file_tag;
int in_undo;
- char *error_path;
- char *error_str;
- char *error_msg;
+ struct razor_error *error;
};
char *atomic_action_attic_tmpnam(struct razor_atomic *atomic);
#else /* !HAVE_WINDOWS_KTM && !ENABLE_ATOMIC */
struct razor_atomic {
int in_undo;
- char *error_path;
- char *error_str;
- char *error_msg;
+ struct razor_error *error;
};
#endif
int razor_allow_all_root_names(void);
int razor_valid_root_name(const char *name);
-#ifdef MSWIN_API
-void
-razor_atomic_set_error_mswin(struct razor_atomic *atomic, const wchar_t *path,
- DWORD error);
-#endif
-
-#if HAVE_WINDOWS_KTM
-void
-razor_atomic_set_error_str(struct razor_atomic *atomic, const wchar_t *path,
- const char *str);
-#else
-void
-razor_atomic_set_error_str(struct razor_atomic *atomic, const char *path,
- const char *str);
-#endif
-
#endif /* _RAZOR_INTERNAL_H_ */
};
/**
+ * SECTION:error
+ * @title: Error reporting
+ * @short_description: A system for reporting errors.
+ *
+ * This object represents an error condition.
+ */
+struct razor_error;
+
+const char *razor_error_get_msg(struct razor_error *error);
+void razor_error_free(struct razor_error *error);
+
+/**
* SECTION:atomic
* @title: Atomic transactions
* @short_description: File-based transactions that shouldn't half-succeed