o Common parts of close code moved to bclose_file_helper().
o Compatibility wrappers moved to fb-param.c.
o Everything related to temp files moved to fb-temp.c.
o Several byte -> char conversions.
o Better comments.
o Testing code compiles again.
int can_overwrite_buffer; /* Can the buffer be altered? (see discussion above) 0=never, 1=temporarily, 2=permanently */
};
-/* FastIO on files with run-time parametrization */
+/* FastIO on files with several configurable back-ends */
enum fb_type { /* Which back-end you want to use */
FB_STD, /* Standard buffered I/O */
- FB_DIRECT, /* Direct I/O bypassing system caches (see fb-direct.c for description) */
+ FB_DIRECT, /* Direct I/O bypassing system caches (see fb-direct.c for a description) */
FB_MMAP /* Memory mapped files */
};
struct fb_params {
enum fb_type type;
- uns buffer_size;
- /* FB_STD only */
- uns keep_back_buf;
- /* FB_DIRECT only */
- uns read_ahead;
+ uns buffer_size; /* 0 for default size */
+ uns keep_back_buf; /* FB_STD: optimize for bi-directional access */
+ uns read_ahead; /* FB_DIRECT options */
uns write_back;
struct asio_queue *asio;
};
struct fastbuf *bopen_tmp_file(struct fb_params *params);
struct fastbuf *bopen_fd(int fd, struct fb_params *params);
-/* FastIO on standard files */
+/* FastIO on standard files (shortcuts for FB_STD) */
-struct fastbuf *bfdopen_internal(int fd, const char *name, uns buflen);
struct fastbuf *bopen(const char *name, uns mode, uns buflen);
struct fastbuf *bopen_try(const char *name, uns mode, uns buflen);
struct fastbuf *bopen_tmp(uns buflen);
struct fastbuf *bfdopen_shared(int fd, uns buflen);
void bfilesync(struct fastbuf *b);
+/* Temporary files */
+
#define TEMP_FILE_NAME_LEN 256
void temp_file_name(char *name);
void bfix_tmp_file(struct fastbuf *fb, const char *name);
/* Internal functions of some file back-ends */
+struct fastbuf *bfdopen_internal(int fd, const char *name, uns buflen);
struct fastbuf *bfmmopen_internal(int fd, const char *name, uns mode);
extern uns fbdir_cheat;
struct asio_queue;
struct fastbuf *fbdir_open_fd_internal(int fd, const char *name, struct asio_queue *io_queue, uns buffer_size, uns read_ahead, uns write_back);
+void bclose_file_helper(struct fastbuf *f, int fd, int is_temp_file);
+
/* FastIO on in-memory streams */
struct fastbuf *fbmem_create(uns blocksize); /* Create stream and return its writing fastbuf */
/* Configuring stream parameters */
enum bconfig_type {
- BCONFIG_IS_TEMP_FILE,
- BCONFIG_KEEP_BACK_BUF,
+ BCONFIG_IS_TEMP_FILE, /* 0=normal file, 1=temporary file, -1=shared fd */
+ BCONFIG_KEEP_BACK_BUF, /* Optimize for bi-directional access */
};
int bconfig(struct fastbuf *f, uns type, int data);
void bseek(struct fastbuf *f, sh_off_t pos, int whence);
void bsetpos(struct fastbuf *f, sh_off_t pos);
void brewind(struct fastbuf *f);
-sh_off_t bfilesize(struct fastbuf *f); // -1 if not seekable
+sh_off_t bfilesize(struct fastbuf *f); /* -1 if not seekable */
static inline sh_off_t btell(struct fastbuf *f)
{
/*
* UCW Library -- Fast Buffered I/O on O_DIRECT Files
*
- * (c) 2006 Martin Mares <mj@ucw.cz>
+ * (c) 2006--2007 Martin Mares <mj@ucw.cz>
*
* This software may be freely distributed and used according to the terms
* of the GNU Lesser General Public License.
*
* FIXME: what if the OS doesn't support O_DIRECT?
* FIXME: unaligned seeks and partial writes?
- * FIXME: merge with other file-oriented fastbufs
*/
#undef LOCAL_DEBUG
struct fb_direct {
struct fastbuf fb;
int fd; // File descriptor
- int is_temp_file; // 0=normal file, 1=temporary file, delete on close, -1=shared FD
+ int is_temp_file;
struct asio_queue *io_queue; // I/O queue to use
struct asio_queue *user_queue; // If io_queue was supplied by the user
struct asio_request *pending_read;
if (!F->user_queue)
fbdir_put_io_queue();
- switch (F->is_temp_file)
- {
- case 1:
- if (unlink(f->name) < 0)
- msg(L_ERROR, "unlink(%s): %m", f->name);
- case 0:
- close(F->fd);
- }
-
+ bclose_file_helper(f, F->fd, F->is_temp_file);
xfree(f);
}
int main(int argc, char **argv)
{
+ struct fb_params par = { .type = FB_DIRECT };
struct fastbuf *f, *t;
log_init(NULL);
if (cf_getopt(argc, argv, CF_SHORT_OPTS, CF_NO_LONG_OPTS, NULL) >= 0)
die("Hey, whaddya want?");
- f = (optind < argc) ? fbdir_open(argv[optind++], O_RDONLY, NULL) : fbdir_open_fd(0, NULL);
- t = (optind < argc) ? fbdir_open(argv[optind++], O_RDWR | O_CREAT | O_TRUNC, NULL) : fbdir_open_fd(1, NULL);
+ f = (optind < argc) ? bopen_file(argv[optind++], O_RDONLY, &par) : bopen_fd(0, &par);
+ t = (optind < argc) ? bopen_file(argv[optind++], O_RDWR | O_CREAT | O_TRUNC, &par) : bopen_fd(1, &par);
bbcopy(f, t, ~0U);
ASSERT(btell(f) == btell(t));
/*
* UCW Library -- Fast Buffered I/O on Files
*
- * (c) 1997--2004 Martin Mares <mj@ucw.cz>
+ * (c) 1997--2007 Martin Mares <mj@ucw.cz>
* (c) 2007 Pavel Charvat <pchar@ucw.cz>
*
* This software may be freely distributed and used according to the terms
struct fb_file {
struct fastbuf fb;
int fd; /* File descriptor */
- int is_temp_file; /* 0=normal file, 1=temporary file, delete on close, -1=shared FD */
+ int is_temp_file;
int keep_back_buf; /* Optimize for backwards reading */
sh_off_t wpos; /* Real file position */
uns wlen; /* Window size */
static void
bfd_close(struct fastbuf *f)
{
- switch (FB_FILE(f)->is_temp_file)
- {
- case 1:
- if (unlink(f->name) < 0)
- msg(L_ERROR, "unlink(%s): %m", f->name);
- case 0:
- if (close(FB_FILE(f)->fd))
- die("close(%s): %m", f->name);
- }
+ bclose_file_helper(f, FB_FILE(f)->fd, FB_FILE(f)->is_temp_file);
xfree(f);
}
return f;
}
-struct fastbuf *
-bopen_try(const char *name, uns mode, uns buflen)
-{
- return bopen_file_try(name, mode, &(struct fb_params){ .type = FB_STD, .buffer_size = buflen });
-}
-
-struct fastbuf *
-bopen(const char *name, uns mode, uns buflen)
-{
- return bopen_file(name, mode, &(struct fb_params){ .type = FB_STD, .buffer_size = buflen });
-}
-
-struct fastbuf *
-bfdopen(int fd, uns buflen)
-{
- return bopen_fd(fd, &(struct fb_params){ .type = FB_STD, .buffer_size = buflen });
-}
-
-struct fastbuf *
-bfdopen_shared(int fd, uns buflen)
-{
- struct fastbuf *f = bfdopen(fd, buflen);
- FB_FILE(f)->is_temp_file = -1;
- return f;
-}
-
void
bfilesync(struct fastbuf *b)
{
{
struct fastbuf *f, *t;
f = bopen_tmp(16);
- t = bfdopen(1, 13);
+ t = bfdopen_shared(1, 13);
for (uns i = 0; i < 16; i++)
bwrite(f, "<hello>", 7);
bprintf(t, "%d\n", (int)btell(f));
* of the GNU Lesser General Public License.
*/
+#undef LOCAL_DEBUG
+
#include "lib/lib.h"
#include "lib/fastbuf.h"
#include "lib/lfs.h"
if (F->file_extend > F->file_size &&
sh_ftruncate(F->fd, F->file_size))
die("ftruncate(%s): %m", f->name);
- switch (F->is_temp_file)
- {
- case 1:
- if (unlink(f->name) < 0)
- msg(L_ERROR, "unlink(%s): %m", f->name);
- case 0:
- if (close(F->fd))
- die("close(%s): %m", f->name);
- }
+ bclose_file_helper(f, F->fd, F->is_temp_file);
xfree(f);
}
int main(int argc, char **argv)
{
- struct fastbuf *f = bopen_mm(argv[1], O_RDONLY);
- struct fastbuf *g = bopen_mm(argv[2], O_RDWR | O_CREAT | O_TRUNC);
+ struct fb_params par = { .type = FB_MMAP };
+ struct fastbuf *f = bopen_file(argv[1], O_RDONLY, &par);
+ struct fastbuf *g = bopen_file(argv[2], O_RDWR | O_CREAT | O_TRUNC, &par);
int c;
DBG("Copying");
* UCW Library -- FastIO on files with run-time parametrization
*
* (c) 2007 Pavel Charvat <pchar@ucw.cz>
+ * (c) 2007 Martin Mares <mj@ucw.cz>
*
* This software may be freely distributed and used according to the terms
* of the GNU Lesser General Public License.
}
static struct fastbuf *
-bopen_fd_internal(int fd, struct fb_params *params, uns mode, const byte *name)
+bopen_fd_internal(int fd, struct fb_params *params, uns mode, const char *name)
{
- byte buf[32];
+ char buf[32];
if (!name)
{
sprintf(buf, "fd%d", fd);
}
static struct fastbuf *
-bopen_file_internal(const byte *name, int mode, struct fb_params *params, int try)
+bopen_file_internal(const char *name, int mode, struct fb_params *params, int try)
{
if (!params)
params = &fbpar_def;
return bopen_fd_internal(fd, params ? : &fbpar_def, ~0U, NULL);
}
+/* Function for use by individual file back-ends */
+
+void
+bclose_file_helper(struct fastbuf *f, int fd, int is_temp_file)
+{
+ switch (is_temp_file)
+ {
+ case 1:
+ if (unlink(f->name) < 0)
+ msg(L_ERROR, "unlink(%s): %m", f->name);
+ case 0:
+ if (close(fd))
+ die("close(%s): %m", f->name);
+ }
+}
+
+/* Compatibility wrappers */
+
struct fastbuf *
-bopen_tmp_file(struct fb_params *params)
+bopen_try(const char *name, uns mode, uns buflen)
{
- byte buf[TEMP_FILE_NAME_LEN];
- temp_file_name(buf);
- struct fastbuf *fb = bopen_file_internal(buf, O_RDWR | O_CREAT | O_TRUNC, params, 0);
- bconfig(fb, BCONFIG_IS_TEMP_FILE, 1);
- return fb;
+ return bopen_file_try(name, mode, &(struct fb_params){ .type = FB_STD, .buffer_size = buflen });
}
+
+struct fastbuf *
+bopen(const char *name, uns mode, uns buflen)
+{
+ return bopen_file(name, mode, &(struct fb_params){ .type = FB_STD, .buffer_size = buflen });
+}
+
+struct fastbuf *
+bfdopen(int fd, uns buflen)
+{
+ return bopen_fd(fd, &(struct fb_params){ .type = FB_STD, .buffer_size = buflen });
+}
+
+struct fastbuf *
+bfdopen_shared(int fd, uns buflen)
+{
+ struct fastbuf *f = bfdopen(fd, buflen);
+ bconfig(f, BCONFIG_IS_TEMP_FILE, -1);
+ return f;
+}
+
/*
* UCW Library -- Temporary Fastbufs
*
- * (c) 2002--2006 Martin Mares <mj@ucw.cz>
+ * (c) 2002--2007 Martin Mares <mj@ucw.cz>
*
* This software may be freely distributed and used according to the terms
* of the GNU Lesser General Public License.
}
struct fastbuf *
-bopen_tmp(uns buflen)
+bopen_tmp_file(struct fb_params *params)
{
- char buf[TEMP_FILE_NAME_LEN];
- struct fastbuf *f;
+ char name[TEMP_FILE_NAME_LEN];
+ temp_file_name(name);
+ struct fastbuf *fb = bopen_file(name, O_RDWR | O_CREAT | O_TRUNC, params);
+ bconfig(fb, BCONFIG_IS_TEMP_FILE, 1);
+ return fb;
+}
- // FIXME: This needs cleanup and merging with other bopen functions.
- temp_file_name(buf);
- f = bopen(buf, O_RDWR | O_CREAT | O_TRUNC, buflen);
- bconfig(f, BCONFIG_IS_TEMP_FILE, 1);
- return f;
+struct fastbuf *
+bopen_tmp(uns buflen)
+{
+ return bopen_tmp_file(&(struct fb_params){ .type = FB_STD, .buffer_size = buflen });
}
void bfix_tmp_file(struct fastbuf *fb, const char *name)