librazor/atomic.c
author J. Ali Harlow <ali@juiblex.co.uk>
Fri Apr 15 16:57:55 2016 +0100 (2016-04-15)
changeset 468 45e2bb06c88d
parent 439 f28bb31024b4
child 475 008c75a5e08d
permissions -rw-r--r--
Support expat v2.1
     1 /*
     2  * Copyright (C) 2011-2012  J. Ali Harlow <ali@juiblex.co.uk>
     3  *
     4  * This program is free software; you can redistribute it and/or modify
     5  * it under the terms of the GNU General Public License as published by
     6  * the Free Software Foundation; either version 2 of the License, or
     7  * (at your option) any later version.
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License along
    15  * with this program; if not, write to the Free Software Foundation, Inc.,
    16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
    17  */
    18 
    19 #include "config.h"
    20 
    21 #include <stdlib.h>
    22 #include <stdio.h>
    23 #include <limits.h>
    24 #include <errno.h>
    25 #include <unistd.h>
    26 #include <sys/types.h>
    27 #include <sys/stat.h>
    28 #include <fcntl.h>
    29 #include <string.h>
    30 #include <assert.h>
    31 
    32 #include "razor.h"
    33 #include "razor-internal.h"
    34 
    35 /*
    36  * Atomic transactions
    37  */
    38 
    39 static int allow_all_root_names = 0;
    40 
    41 /*
    42  * Primarily intended for testing named roots under UNIX platforms.
    43  */
    44 RAZOR_EXPORT void
    45 razor_disable_root_name_checks(int disable)
    46 {
    47 	allow_all_root_names = disable;
    48 }
    49 
    50 int
    51 razor_allow_all_root_names(void)
    52 {
    53 	return allow_all_root_names;
    54 }
    55 
    56 RAZOR_EXPORT struct razor_error *
    57 razor_atomic_get_error(struct razor_atomic *atomic)
    58 {
    59 	return atomic->error;
    60 }
    61 
    62 RAZOR_EXPORT const char *
    63 razor_atomic_get_error_msg(struct razor_atomic *atomic)
    64 {
    65 	if (atomic->error)
    66 		return razor_error_get_msg(atomic->error);
    67 	else
    68 		return NULL;
    69 }
    70 
    71 RAZOR_EXPORT void
    72 razor_atomic_abort(struct razor_atomic *atomic, int domain, int code,
    73 		   const char *error_msg)
    74 {
    75 	if (!atomic->error)
    76 		atomic->error = razor_error_new_str(domain, code, NULL,
    77 						    error_msg);
    78 }
    79 
    80 RAZOR_EXPORT void
    81 razor_atomic_propagate_error(struct razor_atomic *atomic,
    82 			     struct razor_error *error, const char *summary)
    83 {
    84 	if (!atomic->error)
    85 		atomic->error = razor_error_dup(error, summary);
    86 }
    87 
    88 RAZOR_EXPORT int
    89 razor_atomic_in_error_state(struct razor_atomic *atomic)
    90 {
    91 	return atomic->error && !atomic->in_undo;
    92 }
    93 
    94 #if !HAVE_WINDOWS_KTM
    95 
    96 /*
    97  * Common code with atomic-none and atomic-emulate
    98  */
    99 
   100 #define RAZOR_ASCII_ISALPHA(c)	\
   101 			((c) >= 'A' && (c) <= 'Z' || (c) >= 'a' && (c) <= 'z')
   102 
   103 int
   104 razor_valid_root_name(const char *name)
   105 {
   106 	if (razor_allow_all_root_names()) {
   107 #ifdef MSWIN_API
   108 		return !strpbrk(name, "/\\");
   109 #else
   110 		return !strchr(name, '/');
   111 #endif
   112 	}
   113 
   114 #ifdef MSWIN_API
   115 	return RAZOR_ASCII_ISALPHA(name[0]) && name[1] == ':' &&
   116 	       name[2] == '\0';
   117 #else
   118 	return name[0] == '\0';
   119 #endif
   120 }
   121 
   122 RAZOR_EXPORT int
   123 razor_atomic_write(struct razor_atomic *atomic, int fd, const void *data,
   124 		   size_t size)
   125 {
   126 	int written;
   127 
   128 	if (razor_atomic_in_error_state(atomic))
   129 		return -1;
   130 
   131 	while(size) {
   132 		written = write(fd, data, size);
   133 		if (written < 0) {
   134 			atomic->error = razor_error_new_posix(NULL);
   135 
   136 			(void)close(fd);
   137 
   138 			return -1;
   139 		}
   140 
   141 		data += written;
   142 		size -= written;
   143 	}
   144 
   145 	return 0;
   146 }
   147 
   148 RAZOR_EXPORT int
   149 razor_atomic_sync(struct razor_atomic *atomic, int handle)
   150 {
   151 	if (razor_atomic_in_error_state(atomic))
   152 		return -1;
   153 
   154 	if (fsync(handle) < 0) {
   155 		atomic->error = razor_error_new_posix(NULL);
   156 		return -1;
   157 	}
   158 
   159 	return 0;
   160 }
   161 
   162 RAZOR_EXPORT int
   163 razor_atomic_close(struct razor_atomic *atomic, int fd)
   164 {
   165 	if (razor_atomic_in_error_state(atomic))
   166 		return -1;
   167 
   168 	if (close(fd) < 0) {
   169 		atomic->error = razor_error_new_posix(NULL);
   170 		return -1;
   171 	}
   172 
   173 	return 0;
   174 }
   175 
   176 #endif	/* !HAVE_WINDOWS_KTM */