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