/* * util_file_open -- open a memory pool file */ int util_file_open(const char *path, size_t *size, size_t minsize, int flags) { LOG(3, "path \"%s\" size %p minsize %zu flags %d", path, size, minsize, flags); int oerrno; int fd; #ifdef _WIN32 flags |= O_BINARY; #endif if ((fd = os_open(path, flags)) < 0) { ERR("!open \"%s\"", path); return -1; } if (os_flock(fd, OS_LOCK_EX | OS_LOCK_NB) < 0) { ERR("!flock \"%s\"", path); (void) os_close(fd); return -1; } if (size || minsize) { if (size) ASSERTeq(*size, 0); ssize_t actual_size = util_file_get_size(path); if (actual_size < 0) { ERR("stat \"%s\": negative size", path); errno = EINVAL; goto err; } if ((size_t)actual_size < minsize) { ERR("size %zu smaller than %zu", (size_t)actual_size, minsize); errno = EINVAL; goto err; } if (size) { *size = (size_t)actual_size; LOG(4, "actual file size %zu", *size); } } return fd; err: oerrno = errno; if (os_flock(fd, OS_LOCK_UN)) ERR("!flock unlock"); (void) os_close(fd); errno = oerrno; return -1; }
/* * util_file_create -- create a new memory pool file */ int util_file_create(const char *path, size_t size, size_t minsize) { LOG(3, "path \"%s\" size %zu minsize %zu", path, size, minsize); ASSERTne(size, 0); if (size < minsize) { ERR("size %zu smaller than %zu", size, minsize); errno = EINVAL; return -1; } if (((os_off_t)size) < 0) { ERR("invalid size (%zu) for os_off_t", size); errno = EFBIG; return -1; } int fd; int mode; int flags = O_RDWR | O_CREAT | O_EXCL; #ifndef _WIN32 mode = 0; #else mode = S_IWRITE | S_IREAD; flags |= O_BINARY; #endif /* * Create file without any permission. It will be granted once * initialization completes. */ if ((fd = os_open(path, flags, mode)) < 0) { ERR("!open \"%s\"", path); return -1; } if ((errno = os_posix_fallocate(fd, 0, (os_off_t)size)) != 0) { ERR("!posix_fallocate \"%s\", %zu", path, size); goto err; } /* for windows we can't flock until after we fallocate */ if (os_flock(fd, OS_LOCK_EX | OS_LOCK_NB) < 0) { ERR("!flock \"%s\"", path); goto err; } return fd; err: LOG(4, "error clean up"); int oerrno = errno; if (fd != -1) (void) os_close(fd); os_unlink(path); errno = oerrno; return -1; }
/* * ut_flock -- a flock that cannot return -1 */ int ut_flock(const char *file, int line, const char *func, int fd, int op) { int retval = os_flock(fd, op); if (retval != 0) ut_fatal(file, line, func, "!flock: %d", fd); return retval; }