/* * Copyright (C) 2011-2012 J. Ali Harlow * * 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" #include #include #include #include #include #include #include #include #include #include #include "razor.h" #include "razor-internal.h" /* * Atomic transactions */ static int allow_all_root_names = 0; /* * Primarily intended for testing named roots under UNIX platforms. */ RAZOR_EXPORT void razor_disable_root_name_checks(int disable) { allow_all_root_names = disable; } int razor_allow_all_root_names(void) { return allow_all_root_names; } RAZOR_EXPORT const char * razor_atomic_get_error_msg(struct razor_atomic *atomic) { 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) atomic->error = razor_error_new_str(NULL, error_msg); } RAZOR_EXPORT int razor_atomic_in_error_state(struct razor_atomic *atomic) { return atomic->error && !atomic->in_undo; } #if !HAVE_WINDOWS_KTM /* * Common code with atomic-none and atomic-emulate */ #define RAZOR_ASCII_ISALPHA(c) \ ((c) >= 'A' && (c) <= 'Z' || (c) >= 'a' && (c) <= 'z') int razor_valid_root_name(const char *name) { if (razor_allow_all_root_names()) { #ifdef MSWIN_API return !strpbrk(name, "/\\"); #else return !strchr(name, '/'); #endif } #ifdef MSWIN_API return RAZOR_ASCII_ISALPHA(name[0]) && name[1] == ':' && name[2] == '\0'; #else return name[0] == '\0'; #endif } RAZOR_EXPORT int razor_atomic_write(struct razor_atomic *atomic, int fd, const void *data, size_t size) { int written; if (razor_atomic_in_error_state(atomic)) return -1; while(size) { written = write(fd, data, size); if (written < 0) { atomic->error = razor_error_new_str(NULL, strerror(errno)); (void)close(fd); return -1; } data += written; size -= written; } return 0; } RAZOR_EXPORT int razor_atomic_sync(struct razor_atomic *atomic, int handle) { if (razor_atomic_in_error_state(atomic)) return -1; if (fsync(handle) < 0) { atomic->error = razor_error_new_str(NULL, strerror(errno)); return -1; } return 0; } RAZOR_EXPORT int razor_atomic_close(struct razor_atomic *atomic, int fd) { if (razor_atomic_in_error_state(atomic)) return -1; if (close(fd) < 0) { atomic->error = razor_error_new_str(NULL, strerror(errno)); return -1; } return 0; } #endif /* !HAVE_WINDOWS_KTM */