librazor/atomic.c
author J. Ali Harlow <ali@juiblex.co.uk>
Sat Oct 04 18:12:58 2014 +0100 (2014-10-04)
changeset 454 56ff755c268c
parent 439 f28bb31024b4
child 475 008c75a5e08d
permissions -rw-r--r--
Only export symbols starting with razor_ in dynamic library.

Apart from being good practice to avoid clashes with higher-level
libraries and the application, this also fixes an obscure bug: The
gnulib library is used both by librazor (the dynamic library) and
by razor (the executable). In doing so, we want to have two separate
copies of the library despite the code duplication this involves.
Without the explicit limit to export only razor_ symbols, the razor
executable under mingw64 was picking up the getopt_long function
from librazor and the optind variable from libgnu which meant that
it did not see optind changing. Hiding librazor's copy of getopt
causes the linker to find libgnu's copy and everything works.

Note that under mingw librazor-#.dll still contains undocumented
(private) razor_ symbols but these will do no harm as long as nobody
tries to use them.
ali@403
     1
/*
ali@416
     2
 * Copyright (C) 2011-2012  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@416
    26
#include <sys/types.h>
ali@416
    27
#include <sys/stat.h>
ali@403
    28
#include <fcntl.h>
ali@403
    29
#include <string.h>
ali@403
    30
#include <assert.h>
ali@403
    31
ali@403
    32
#include "razor.h"
ali@403
    33
#include "razor-internal.h"
ali@403
    34
ali@403
    35
/*
ali@403
    36
 * Atomic transactions
ali@403
    37
 */
ali@403
    38
ali@403
    39
static int allow_all_root_names = 0;
ali@403
    40
ali@403
    41
/*
ali@403
    42
 * Primarily intended for testing named roots under UNIX platforms.
ali@403
    43
 */
ali@403
    44
RAZOR_EXPORT void
ali@403
    45
razor_disable_root_name_checks(int disable)
ali@403
    46
{
ali@403
    47
	allow_all_root_names = disable;
ali@403
    48
}
ali@403
    49
ali@416
    50
int
ali@416
    51
razor_allow_all_root_names(void)
ali@403
    52
{
ali@416
    53
	return allow_all_root_names;
ali@403
    54
}
ali@403
    55
ali@439
    56
RAZOR_EXPORT struct razor_error *
ali@439
    57
razor_atomic_get_error(struct razor_atomic *atomic)
ali@439
    58
{
ali@439
    59
	return atomic->error;
ali@439
    60
}
ali@439
    61
ali@403
    62
RAZOR_EXPORT const char *
ali@403
    63
razor_atomic_get_error_msg(struct razor_atomic *atomic)
ali@403
    64
{
ali@423
    65
	if (atomic->error)
ali@423
    66
		return razor_error_get_msg(atomic->error);
ali@423
    67
	else
ali@423
    68
		return NULL;
ali@403
    69
}
ali@403
    70
ali@403
    71
RAZOR_EXPORT void
ali@447
    72
razor_atomic_abort(struct razor_atomic *atomic, int domain, int code,
ali@447
    73
		   const char *error_msg)
ali@403
    74
{
ali@423
    75
	if (!atomic->error)
ali@447
    76
		atomic->error = razor_error_new_str(domain, code, NULL,
ali@447
    77
						    error_msg);
ali@447
    78
}
ali@447
    79
ali@447
    80
RAZOR_EXPORT void
ali@447
    81
razor_atomic_propagate_error(struct razor_atomic *atomic,
ali@447
    82
			     struct razor_error *error, const char *summary)
ali@447
    83
{
ali@447
    84
	if (!atomic->error)
ali@447
    85
		atomic->error = razor_error_dup(error, summary);
ali@403
    86
}
ali@403
    87
ali@403
    88
RAZOR_EXPORT int
ali@403
    89
razor_atomic_in_error_state(struct razor_atomic *atomic)
ali@403
    90
{
ali@423
    91
	return atomic->error && !atomic->in_undo;
ali@403
    92
}
ali@416
    93
ali@416
    94
#if !HAVE_WINDOWS_KTM
ali@416
    95
ali@416
    96
/*
ali@416
    97
 * Common code with atomic-none and atomic-emulate
ali@416
    98
 */
ali@416
    99
ali@416
   100
#define RAZOR_ASCII_ISALPHA(c)	\
ali@416
   101
			((c) >= 'A' && (c) <= 'Z' || (c) >= 'a' && (c) <= 'z')
ali@416
   102
ali@416
   103
int
ali@416
   104
razor_valid_root_name(const char *name)
ali@416
   105
{
ali@416
   106
	if (razor_allow_all_root_names()) {
ali@416
   107
#ifdef MSWIN_API
ali@416
   108
		return !strpbrk(name, "/\\");
ali@416
   109
#else
ali@416
   110
		return !strchr(name, '/');
ali@416
   111
#endif
ali@416
   112
	}
ali@416
   113
ali@416
   114
#ifdef MSWIN_API
ali@416
   115
	return RAZOR_ASCII_ISALPHA(name[0]) && name[1] == ':' &&
ali@416
   116
	       name[2] == '\0';
ali@416
   117
#else
ali@416
   118
	return name[0] == '\0';
ali@416
   119
#endif
ali@416
   120
}
ali@416
   121
ali@416
   122
RAZOR_EXPORT int
ali@416
   123
razor_atomic_write(struct razor_atomic *atomic, int fd, const void *data,
ali@416
   124
		   size_t size)
ali@416
   125
{
ali@416
   126
	int written;
ali@416
   127
ali@416
   128
	if (razor_atomic_in_error_state(atomic))
ali@416
   129
		return -1;
ali@416
   130
ali@416
   131
	while(size) {
ali@416
   132
		written = write(fd, data, size);
ali@416
   133
		if (written < 0) {
ali@447
   134
			atomic->error = razor_error_new_posix(NULL);
ali@416
   135
ali@416
   136
			(void)close(fd);
ali@416
   137
ali@416
   138
			return -1;
ali@416
   139
		}
ali@416
   140
ali@416
   141
		data += written;
ali@416
   142
		size -= written;
ali@416
   143
	}
ali@416
   144
ali@416
   145
	return 0;
ali@416
   146
}
ali@416
   147
ali@416
   148
RAZOR_EXPORT int
ali@416
   149
razor_atomic_sync(struct razor_atomic *atomic, int handle)
ali@416
   150
{
ali@416
   151
	if (razor_atomic_in_error_state(atomic))
ali@416
   152
		return -1;
ali@416
   153
ali@416
   154
	if (fsync(handle) < 0) {
ali@447
   155
		atomic->error = razor_error_new_posix(NULL);
ali@416
   156
		return -1;
ali@416
   157
	}
ali@416
   158
ali@416
   159
	return 0;
ali@416
   160
}
ali@416
   161
ali@416
   162
RAZOR_EXPORT int
ali@416
   163
razor_atomic_close(struct razor_atomic *atomic, int fd)
ali@416
   164
{
ali@416
   165
	if (razor_atomic_in_error_state(atomic))
ali@416
   166
		return -1;
ali@416
   167
ali@416
   168
	if (close(fd) < 0) {
ali@447
   169
		atomic->error = razor_error_new_posix(NULL);
ali@416
   170
		return -1;
ali@416
   171
	}
ali@416
   172
ali@416
   173
	return 0;
ali@416
   174
}
ali@416
   175
ali@416
   176
#endif	/* !HAVE_WINDOWS_KTM */