summaryrefslogtreecommitdiff
path: root/util/nvmutil/lib/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/nvmutil/lib/file.c')
-rw-r--r--util/nvmutil/lib/file.c159
1 files changed, 54 insertions, 105 deletions
diff --git a/util/nvmutil/lib/file.c b/util/nvmutil/lib/file.c
index 92d7ee7c..f90ecdba 100644
--- a/util/nvmutil/lib/file.c
+++ b/util/nvmutil/lib/file.c
@@ -5,21 +5,14 @@
* Safe file handling.
*/
-#ifdef __OpenBSD__
-#include <sys/param.h>
-#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <time.h>
#include <unistd.h>
#include "../include/common.h"
@@ -74,7 +67,7 @@ xopen(int *fd_ptr, const char *path, int flags, struct stat *st)
err(errno, "%s: file not seekable", path);
}
-/* Ensure x_i_rename() is durable by syncing the
+/* Ensure rename() is durable by syncing the
* directory containing the target file.
*/
@@ -120,8 +113,8 @@ fsync_dir(const char *path)
if (dirbuf == NULL)
goto err_fsync_dir;
- x_v_memcpy(dirbuf, path, pathlen + 1);
- slash = x_c_strrchr(dirbuf, '/');
+ memcpy(dirbuf, path, pathlen + 1);
+ slash = strrchr(dirbuf, '/');
if (slash != NULL) {
*slash = '\0';
@@ -154,10 +147,10 @@ fsync_dir(const char *path)
}
/* sync file on disk */
- if (x_i_fsync(dirfd) == -1)
+ if (fsync_on_eintr(dirfd) == -1)
goto err_fsync_dir;
- if (x_i_close(dirfd) == -1)
+ if (close_on_eintr(dirfd) == -1)
goto err_fsync_dir;
if (dirbuf != NULL)
@@ -177,7 +170,7 @@ err_fsync_dir:
free(dirbuf);
if (dirfd > -1)
- x_i_close(dirfd);
+ close_on_eintr(dirfd);
errno = saved_errno;
@@ -219,7 +212,7 @@ new_tmpfile(int *fd, int local, const char *path)
*/
char tmp_none[] = "";
char tmp_default[] = "/tmp";
- char default_tmpname[] = "tmpXXXXXX";
+ char default_tmpname[] = "tmpXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
char *tmpname;
char *base = NULL;
@@ -302,22 +295,22 @@ new_tmpfile(int *fd, int local, const char *path)
*dest = '.'; /* hidden file */
- x_v_memcpy(dest + (unsigned long)1, tmpname, tmpname_len);
+ memcpy(dest + (unsigned long)1, tmpname, tmpname_len);
- x_v_memcpy(dest + (unsigned long)1 + tmpname_len,
+ memcpy(dest + (unsigned long)1 + tmpname_len,
default_tmpname, tmpdir_len);
} else {
- x_v_memcpy(dest, base, tmpdir_len);
+ memcpy(dest, base, tmpdir_len);
dest[tmpdir_len] = '/';
- x_v_memcpy(dest + tmpdir_len + 1, tmpname, tmpname_len);
+ memcpy(dest + tmpdir_len + 1, tmpname, tmpname_len);
}
dest[tmppath_len] = '\0';
- fd_tmp = x_i_mkstemp(dest);
+ fd_tmp = mkstemp_n(dest);
if (fd_tmp == -1)
goto err_new_tmpfile;
@@ -374,7 +367,7 @@ err_new_tmpfile:
free(dest);
if (fd_tmp > -1)
- x_i_close(fd_tmp);
+ close_on_eintr(fd_tmp);
return NULL;
}
@@ -428,36 +421,56 @@ x_c_tmpdir(void)
*/
int
-x_i_mkstemp(char *template)
+mkstemp_n(char *template)
{
int fd;
- int i, j;
+ unsigned long i, j;
unsigned long len;
char *p;
- char ch[] =
+ unsigned long xc = 0;
+
+ static char ch[] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
unsigned long r;
+ unsigned long max_len =
+#ifndef PATH_LEN
+ 4096;
+#else
+ (PATH_LEN);
+#endif
- len = xstrxlen(template, PATH_LEN);
+ len = xstrxlen(template, max_len);
- /* find trailing XXXXXX */
- if (len < 6)
+ if (len < 6) {
+ errno = EINVAL;
return -1;
+ }
- p = template + len - 6;
+ p = template + len;
- for (i = 0; i < 100; i++) {
+ while (p > template && p[-1] == 'X') {
+ --p;
+ ++xc;
+ }
+
+ if (xc < 6) {
+ errno = EINVAL;
+ return -1;
+ }
- for (j = 0; j < 6; j++) {
+ for (i = 0; i < 200; i++) {
+
+ for (j = 0; j < xc; j++) {
r = rlong();
p[j] = ch[(unsigned long)(r >> 1) % (sizeof(ch) - 1)];
}
- fd = open(template, O_RDWR | O_CREAT | O_EXCL, 0600);
+ fd = open(template,
+ O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW | O_CLOEXEC, 0600);
if (fd >= 0)
return fd;
@@ -613,12 +626,6 @@ prw(int fd, void *mem, unsigned long nrw,
int loop_eagain, int loop_eintr,
int off_reset)
{
-#ifndef MAX_EAGAIN_RETRIES
- unsigned long retries = 100000;
-#else
- unsigned long retries = MAX_EAGAIN_RETRIES;
-#endif
-
long r;
int positional_rw;
struct stat st;
@@ -686,14 +693,14 @@ real_pread_pwrite:
HAVE_REAL_PREAD_PWRITE > 0
goto real_pread_pwrite;
#else
- if ((off_orig = lseek_loop(fd, (off_t)0, SEEK_CUR,
+ if ((off_orig = lseek_on_eintr(fd, (off_t)0, SEEK_CUR,
loop_eagain, loop_eintr)) == (off_t)-1) {
r = -1;
- } else if (lseek_loop(fd, off, SEEK_SET,
+ } else if (lseek_on_eintr(fd, off, SEEK_SET,
loop_eagain, loop_eintr) == (off_t)-1) {
r = -1;
} else {
- verified = lseek_loop(fd, (off_t)0, SEEK_CUR,
+ verified = lseek_on_eintr(fd, (off_t)0, SEEK_CUR,
loop_eagain, loop_eintr);
/*
@@ -708,7 +715,7 @@ real_pread_pwrite:
* that nothing is touching it now.
*/
if (off_reset && off != verified)
- lseek_loop(fd, off, SEEK_SET,
+ lseek_on_eintr(fd, off, SEEK_SET,
loop_eagain, loop_eintr);
do {
@@ -729,7 +736,7 @@ real_pread_pwrite:
* will cause an exit, including
* per EINTR/EAGAIN re-spin.
*/
- verified = lseek_loop(fd, (off_t)0, SEEK_CUR,
+ verified = lseek_on_eintr(fd, (off_t)0, SEEK_CUR,
loop_eagain, loop_eintr);
if (off != verified)
@@ -747,13 +754,12 @@ real_pread_pwrite:
} while (r == -1 &&
(errno == try_err(loop_eintr, EINTR) ||
- errno == try_err(loop_eagain, EAGAIN)) &&
- retries++ < MAX_EAGAIN_RETRIES);
+ errno == try_err(loop_eagain, EAGAIN)));
}
saved_errno = errno;
- off_last = lseek_loop(fd, off_orig, SEEK_SET,
+ off_last = lseek_on_eintr(fd, off_orig, SEEK_SET,
loop_eagain, loop_eintr);
if (off_last != off_orig) {
@@ -883,12 +889,12 @@ err_rw_over_nrw:
#if !defined(HAVE_REAL_PREAD_PWRITE) || \
HAVE_REAL_PREAD_PWRITE < 1
/*
- * lseek_loop() does lseek() but optionally
+ * lseek_on_eintr() does lseek() but optionally
* on an EINTR/EAGAIN wait loop. Used by prw()
* for setting offsets for positional I/O.
*/
off_t
-lseek_loop(int fd, off_t off, int whence,
+lseek_on_eintr(int fd, off_t off, int whence,
int loop_eagain, int loop_eintr)
{
off_t old;
@@ -914,65 +920,8 @@ try_err(int loop_err, int errval)
return -1;
}
-/* portable rename(). WARNING:
- * not powercut-safe. do this to
- * use system rename:
- * #define SYS_RENAME 1
- *
- * written academically, but in reality,
- * nearly all unix systems have rename()
- */
-
-int
-x_i_rename(const char *src, const char *dst)
-{
-#if defined(SYS_RENAME) &&\
- SYS_RENAME > 0
- return rename(src, dst);
-#else
- int sfd, dirfd;
- ssize_t r;
- char buf[8192];
-
- sfd = open(src, O_RDONLY);
- if (sfd < 0)
- return -1;
-
- dirfd = open(dst, O_WRONLY | O_CREAT | O_TRUNC, 0600);
- if (dirfd < 0) {
- x_i_close(sfd);
- return -1;
- }
-
- while ((r = read(sfd, buf, sizeof(buf))) > 0) {
- ssize_t w = write(dirfd, buf, r);
- if (w != r) {
- x_i_close(sfd);
- x_i_close(dirfd);
- return -1;
- }
- }
-
- if (r < 0) {
- x_i_close(sfd);
- x_i_close(dirfd);
- return -1;
- }
-
- x_i_fsync(dirfd);
-
- x_i_close(sfd);
- x_i_close(dirfd);
-
- if (unlink(src) < 0)
- return -1;
-
- return 0;
-#endif
-}
-
int
-x_i_close(int fd)
+close_on_eintr(int fd)
{
int r;
int saved_errno = errno;
@@ -988,7 +937,7 @@ x_i_close(int fd)
}
int
-x_i_fsync(int fd)
+fsync_on_eintr(int fd)
{
int r;