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.
     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 */