fs-posix.c revision 30605b7bd82acb92cca47b080636757bf9d02a73
/* Copyright (c) 2010-2015 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "buffer.h"
#include "str.h"
#include "guid.h"
#include "istream.h"
#include "ostream.h"
#include "safe-mkstemp.h"
#include "mkdir-parents.h"
#include "write-full.h"
#include "file-lock.h"
#include "file-dotlock.h"
#include "fs-api-private.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
#define MAX_MKDIR_RETRY_COUNT 5
#define FS_DEFAULT_MODE 0600
enum fs_posix_lock_method {
};
struct posix_fs {
};
struct posix_fs_file {
int fd;
enum fs_open_mode open_mode;
enum fs_open_flags open_flags;
bool seek_to_beginning;
bool success;
};
struct posix_fs_lock {
};
struct posix_fs_iter {
char *path;
int err;
};
static struct fs *fs_posix_alloc(void)
{
}
static int
{
const char *const *tmp;
else
return -1;
}
} else {
return -1;
}
}
return 0;
}
{
}
{
/* FS_PROPERTY_DIRECTORIES not returned because fs_delete()
automatically rmdir()s parents. This could be changed later though,
but SIS code at least would need to be changed to support it. */
}
{
return 1;
return 0;
return 1;
else {
return -1;
}
}
{
const char *p;
return 0;
break;
/* success, continue to parent */
/* there are other entries in this directory */
break;
/* some other not-unexpected error */
break;
} else {
return -1;
}
}
return 0;
}
{
const char *slash;
unsigned int try_count = 0;
int fd;
return -1;
try_count++;
}
if (fd == -1) {
return -1;
}
return fd;
}
{
case FS_OPEN_MODE_READONLY:
break;
case FS_OPEN_MODE_APPEND:
break;
case FS_OPEN_MODE_CREATE:
case FS_OPEN_MODE_REPLACE:
T_BEGIN {
} T_END;
break;
}
return -1;
return 0;
}
static struct fs_file *
{
struct posix_fs_file *file;
if (mode != FS_OPEN_MODE_CREATE_UNIQUE_128)
else {
}
}
{
}
}
}
{
case FS_OPEN_MODE_READONLY:
case FS_OPEN_MODE_APPEND:
break;
case FS_OPEN_MODE_CREATE:
case FS_OPEN_MODE_REPLACE:
break;
}
break;
}
}
{
if (fs_posix_open(file) < 0)
return -1;
}
return 0;
}
{
if (fs_posix_open_for_read(file) < 0)
return TRUE;
/* HAVE_POSIX_FADVISE alone isn't enough for CentOS 4.9 */
#if defined(HAVE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
return TRUE;
}
#endif
return FALSE;
}
{
if (fs_posix_open_for_read(file) < 0)
return -1;
if (file->seek_to_beginning) {
return -1;
}
}
if (ret < 0)
return ret;
}
static struct istream *
{
if (fs_posix_open_for_read(file) < 0)
else {
/* the stream could live even after the fs_file */
}
return input;
}
{
int ret;
return -1;
}
}
case FS_OPEN_MODE_CREATE:
}
}
if (ret < 0) {
return -1;
}
break;
case FS_OPEN_MODE_REPLACE:
return -1;
}
break;
default:
i_unreached();
}
/* allow opening the file after writing to it */
return 0;
}
{
if (fs_posix_open(file) < 0)
return -1;
}
return -1;
}
return fs_posix_write_finish(file);
}
/* atomic append - it should either succeed or fail */
if (ret < 0) {
return -1;
}
return -1;
}
return 0;
}
{
} else {
}
}
{
case FS_OPEN_MODE_APPEND:
if (ret == 0) {
}
break;
case FS_OPEN_MODE_CREATE:
case FS_OPEN_MODE_REPLACE:
if (ret == 0)
break;
case FS_OPEN_MODE_READONLY:
i_unreached();
}
}
static int
{
struct dotlock_settings dotlock_set;
int ret = -1;
switch (fs->lock_method) {
#ifndef HAVE_FLOCK
#else
if (secs == 0) {
} else {
}
if (ret < 0) {
}
#endif
break;
secs == 0 ? 0 :
if (ret < 0) {
"file_dotlock_create(%s) failed: %m",
}
break;
}
if (ret <= 0)
return ret;
return 1;
}
{
}
{
return -1;
}
return 0;
}
return 1;
}
{
return -1;
}
} else {
return -1;
}
}
return 0;
}
{
unsigned int try_count = 0;
int ret;
/* destination file already exists - replace it */
}
return -1;
try_count++;
}
if (ret < 0) {
return -1;
}
return 0;
}
{
unsigned int try_count = 0;
int ret;
return -1;
try_count++;
}
if (ret < 0) {
return -1;
}
return 0;
}
{
if (!UNLINK_EISDIR(errno)) {
return -1;
}
/* attempting to delete a directory. convert it to rmdir()
automatically. */
return -1;
}
}
return 0;
}
static struct fs_iter *
{
struct posix_fs_iter *iter;
}
}
}
{
bool ret;
T_BEGIN {
else
} T_END;
return ret;
}
{
struct dirent *d;
return NULL;
errno = 0;
continue;
#ifdef HAVE_DIRENT_D_TYPE
switch (d->d_type) {
case DT_UNKNOWN:
break;
/* fall through */
case DT_REG:
case DT_LNK:
return d->d_name;
break;
case DT_DIR:
return d->d_name;
break;
default:
break;
}
#else
return d->d_name;
#endif
}
if (errno != 0) {
}
return NULL;
}
{
int ret = 0;
}
ret = -1;
}
return ret;
}
const struct fs fs_class_posix = {
.name = "posix",
.v = {
NULL,
}
};