librazor/atomic-none.c
author J. Ali Harlow <ali@juiblex.co.uk>
Sat Aug 23 11:13:48 2014 +0100 (2014-08-23)
changeset 440 48204dea0b9f
parent 416 d0aa9e0a6d04
child 441 cf499fd51df7
permissions -rw-r--r--
Remove INTLLIBS from librazor_la_LIBADD.

This partially reverts 611c84a3f4b4538a65d186050608c17adbf17770.
It's not clear what motivated the initial inclusion of INTLLIBS
here since the net effect is only seen in librazor.la and not
in razor.pc and librazor.la is not normally packaged. Certainly
neither the static nor the dynamic versions of librazor currently
use libintl. At best this would cause the linker to search a
static libintl for undefined symbols without finding any; at worse
it causes a static build of plover using librazor.la to fail if
no static version of libintl is installed.
ali@416
     1
/*
ali@416
     2
 * Copyright (C) 2011-2012  J. Ali Harlow <ali@juiblex.co.uk>
ali@416
     3
 *
ali@416
     4
 * This program is free software; you can redistribute it and/or modify
ali@416
     5
 * it under the terms of the GNU General Public License as published by
ali@416
     6
 * the Free Software Foundation; either version 2 of the License, or
ali@416
     7
 * (at your option) any later version.
ali@416
     8
 *
ali@416
     9
 * This program is distributed in the hope that it will be useful,
ali@416
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ali@416
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
ali@416
    12
 * GNU General Public License for more details.
ali@416
    13
 *
ali@416
    14
 * You should have received a copy of the GNU General Public License along
ali@416
    15
 * with this program; if not, write to the Free Software Foundation, Inc.,
ali@416
    16
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
ali@416
    17
 */
ali@416
    18
ali@416
    19
#include "config.h"
ali@416
    20
ali@416
    21
#if !ENABLE_ATOMIC
ali@416
    22
ali@416
    23
#include <stdlib.h>
ali@416
    24
#ifdef MSWIN_API
ali@416
    25
#include <windows.h>
ali@416
    26
#endif
ali@416
    27
#include <stdio.h>
ali@416
    28
#include <limits.h>
ali@416
    29
#include <errno.h>
ali@416
    30
#include <unistd.h>
ali@416
    31
#include <fcntl.h>
ali@416
    32
#include <sys/stat.h>
ali@416
    33
#include <string.h>
ali@416
    34
#include <assert.h>
ali@416
    35
ali@416
    36
#include "razor.h"
ali@416
    37
#include "razor-internal.h"
ali@416
    38
ali@416
    39
#ifndef O_BINARY
ali@416
    40
#define O_BINARY	0
ali@416
    41
#endif
ali@416
    42
ali@416
    43
RAZOR_EXPORT struct razor_atomic *
ali@416
    44
razor_atomic_open(const char *description)
ali@416
    45
{
ali@416
    46
	struct razor_atomic *atomic;
ali@416
    47
ali@416
    48
	atomic = zalloc(sizeof *atomic);
ali@416
    49
ali@416
    50
	return atomic;
ali@416
    51
}
ali@416
    52
ali@416
    53
RAZOR_EXPORT int
ali@416
    54
razor_atomic_commit(struct razor_atomic *atomic)
ali@416
    55
{
ali@416
    56
	return razor_atomic_in_error_state(atomic);
ali@416
    57
}
ali@416
    58
ali@416
    59
RAZOR_EXPORT void
ali@416
    60
razor_atomic_destroy(struct razor_atomic *atomic)
ali@416
    61
{
ali@423
    62
	if (atomic->error)
ali@423
    63
		razor_error_free(atomic->error);
ali@423
    64
ali@416
    65
	free(atomic);
ali@416
    66
}
ali@416
    67
ali@416
    68
RAZOR_EXPORT int
ali@416
    69
razor_atomic_make_dirs(struct razor_atomic *atomic, const char *root,
ali@416
    70
		       const char *path)
ali@416
    71
{
ali@416
    72
	char buffer[PATH_MAX], *p;
ali@416
    73
	const char *slash, *next;
ali@416
    74
	struct stat buf;
ali@416
    75
ali@416
    76
	if (razor_atomic_in_error_state(atomic))
ali@416
    77
		return -1;
ali@416
    78
ali@416
    79
	strcpy(buffer, root);
ali@416
    80
	p = buffer + strlen(buffer);
ali@416
    81
	slash = path;
ali@416
    82
	for (slash = path; *slash != '\0'; slash = next) {
ali@416
    83
#ifdef MSWIN_API
ali@416
    84
		next = strpbrk(slash + 1, "/\\");
ali@416
    85
#else
ali@416
    86
		next = strchr(slash + 1, '/');
ali@416
    87
#endif
ali@416
    88
		if (next == NULL)
ali@416
    89
			break;
ali@416
    90
ali@416
    91
		memcpy(p, slash, next - slash);
ali@416
    92
		p += next - slash;
ali@416
    93
		*p = '\0';
ali@416
    94
ali@416
    95
		if (razor_valid_root_name(buffer))
ali@416
    96
			continue;
ali@416
    97
ali@416
    98
		if (stat(buffer, &buf) == 0) {
ali@416
    99
			if (!S_ISDIR(buf.st_mode)) {
ali@423
   100
				atomic->error = razor_error_new_str(buffer,
ali@423
   101
								    "Not a directory");
ali@416
   102
				return -1;
ali@416
   103
			}
ali@416
   104
		} else if (mkdir(buffer, 0777) < 0) {
ali@423
   105
			atomic->error = razor_error_new_str(buffer,
ali@423
   106
							    strerror(errno));
ali@416
   107
			return -1;
ali@416
   108
		}
ali@416
   109
	}
ali@416
   110
ali@416
   111
	return 0;
ali@416
   112
}
ali@416
   113
ali@416
   114
RAZOR_EXPORT int
ali@416
   115
razor_atomic_remove(struct razor_atomic *atomic, const char *path)
ali@416
   116
{
ali@416
   117
#ifdef MSWIN_API
ali@416
   118
	wchar_t *buf;
ali@416
   119
	DWORD err;
ali@416
   120
#endif
ali@416
   121
ali@416
   122
	if (razor_atomic_in_error_state(atomic))
ali@416
   123
		return -1;
ali@416
   124
ali@416
   125
#ifdef MSWIN_API
ali@416
   126
	buf = razor_utf8_to_utf16(path, -1);
ali@416
   127
ali@416
   128
	if (!DeleteFileW(buf)) {
ali@416
   129
		err = GetLastError();
ali@416
   130
		if (err != ERROR_FILE_NOT_FOUND &&
ali@416
   131
		    err != ERROR_PATH_NOT_FOUND &&
ali@416
   132
		    !(SetFileAttributesW(buf, FILE_ATTRIBUTE_NORMAL) &&
ali@416
   133
		      DeleteFileW(buf)) &&
ali@416
   134
		    !RemoveDirectoryW(buf) &&
ali@416
   135
		    GetLastError() != ERROR_DIR_NOT_EMPTY)
ali@423
   136
			atomic->error = razor_error_new_mswin(buf, err);
ali@416
   137
	}
ali@416
   138
ali@416
   139
	free(buf);
ali@416
   140
#else
ali@416
   141
	if (remove(path))
ali@423
   142
		atomic->error = razor_error_new_str(path, strerror(errno));
ali@416
   143
#endif
ali@416
   144
ali@423
   145
	return razor_atomic_in_error_state(atomic);
ali@416
   146
}
ali@416
   147
ali@416
   148
RAZOR_EXPORT int
ali@416
   149
razor_atomic_rename_file(struct razor_atomic *atomic, const char *oldpath,
ali@416
   150
			 const char *newpath)
ali@416
   151
{
ali@416
   152
#ifdef MSWIN_API
ali@416
   153
	wchar_t *oldbuf, *newbuf;
ali@416
   154
	const DWORD flags = MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING;
ali@416
   155
#endif
ali@416
   156
ali@416
   157
	if (razor_atomic_in_error_state(atomic))
ali@416
   158
		return -1;
ali@416
   159
ali@416
   160
#ifdef MSWIN_API
ali@416
   161
	newbuf = razor_utf8_to_utf16(newpath, -1);
ali@416
   162
	oldbuf = razor_utf8_to_utf16(oldpath, -1);
ali@416
   163
ali@416
   164
	/*
ali@416
   165
	 * Passing MOVEFILE_REPLACE_EXISTING to MoveFileEx() will
ali@416
   166
	 * cover every case we care about _except_ replacing an empty
ali@416
   167
	 * directory with a file. Calling RemoveDirectory() will deal
ali@416
   168
	 * with this case while having no effect in all other cases.
ali@416
   169
	 */
ali@416
   170
	(void)RemoveDirectoryW(newbuf);
ali@416
   171
ali@416
   172
	if (!MoveFileExW(oldbuf, newbuf, flags))
ali@423
   173
		atomic->error = razor_error_new_mswin(newbuf, GetLastError());
ali@416
   174
ali@416
   175
	free(newbuf);
ali@416
   176
	free(oldbuf);
ali@416
   177
#else
ali@416
   178
	if (rename(oldpath, newpath))
ali@423
   179
		atomic->error = razor_error_new_str(newpath, strerror(errno));
ali@416
   180
#endif
ali@416
   181
ali@423
   182
	return razor_atomic_in_error_state(atomic);
ali@416
   183
}
ali@416
   184
ali@416
   185
RAZOR_EXPORT int
ali@416
   186
razor_atomic_create_dir(struct razor_atomic *atomic, const char *dirname,
ali@416
   187
			mode_t mode)
ali@416
   188
{
ali@416
   189
	if (razor_atomic_in_error_state(atomic))
ali@416
   190
		return -1;
ali@416
   191
ali@416
   192
	if (!mkdir(dirname, mode & (S_IRWXU | S_IRWXG | S_IRWXO)))
ali@416
   193
		return 0;
ali@416
   194
ali@416
   195
	if (errno != EEXIST) {
ali@423
   196
		atomic->error = razor_error_new_str(dirname, strerror(errno));
ali@416
   197
		return -1;
ali@416
   198
	}
ali@416
   199
ali@416
   200
	if (chmod(dirname, mode & (S_IRWXU | S_IRWXG | S_IRWXO)) < 0) {
ali@423
   201
		atomic->error = razor_error_new_str(dirname, strerror(errno));
ali@416
   202
		return -1;
ali@416
   203
	}
ali@416
   204
ali@416
   205
	return 0;
ali@416
   206
}
ali@416
   207
ali@416
   208
RAZOR_EXPORT int
ali@416
   209
razor_atomic_create_symlink(struct razor_atomic *atomic, const char *target,
ali@416
   210
			    const char *path)
ali@416
   211
{
ali@416
   212
	if (razor_atomic_in_error_state(atomic))
ali@416
   213
		return -1;
ali@416
   214
ali@416
   215
#if HAVE_SYMLINK
ali@416
   216
	if (symlink(target, path) < 0) {
ali@423
   217
		atomic->error = razor_error_new_str(path, strerror(errno));
ali@416
   218
		return -1;
ali@416
   219
	}
ali@416
   220
ali@416
   221
	return 0;
ali@416
   222
#else
ali@423
   223
	atomic->error = razor_error_new_str(NULL,
ali@423
   224
					    "Symbolic links not supported "
ali@423
   225
					    "on this platform");
ali@416
   226
ali@416
   227
	return -1;
ali@416
   228
#endif
ali@416
   229
}
ali@416
   230
ali@416
   231
RAZOR_EXPORT int
ali@416
   232
razor_atomic_create_file(struct razor_atomic *atomic, const char *filename,
ali@416
   233
			 mode_t mode)
ali@416
   234
{
ali@416
   235
	int fd;
ali@416
   236
ali@416
   237
	if (razor_atomic_in_error_state(atomic))
ali@416
   238
		return -1;
ali@416
   239
ali@423
   240
	fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
ali@416
   241
		  mode & (S_IRWXU | S_IRWXG | S_IRWXO));
ali@416
   242
ali@416
   243
	if (fd == -1)
ali@423
   244
		atomic->error = razor_error_new_str(filename, strerror(errno));
ali@416
   245
ali@416
   246
	return fd;
ali@416
   247
}
ali@416
   248
ali@416
   249
#endif	/* !ENABLE_ATOMIC */