diff options
Diffstat (limited to 'util/nvmutil/lib/file.c')
| -rw-r--r-- | util/nvmutil/lib/file.c | 159 |
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; |
