different fb back-ends giving the same interface almost impossible.
I've replaced it with bconfig() which is a universal interface for
altering various fb settings. It's somewhat ioctl()-ish, but I hope
it won't hurt.
l -= n;
}
}
+
+int
+bconfig(struct fastbuf *f, uns item, int value)
+{
+ return f->config ? f->config(f, item, value) : -1;
+}
void (*spout)(struct fastbuf *); /* Write buffer data to the file */
void (*seek)(struct fastbuf *, sh_off_t, int); /* Slow path for bseek(), buffer already flushed */
void (*close)(struct fastbuf *); /* Close the stream */
+ int (*config)(struct fastbuf *, uns, int); /* Configure the stream */
};
/* FastIO on standard files */
-struct fb_file {
- struct fastbuf fb;
- int fd; /* File descriptor, -1 if not a real file */
- int is_temp_file; /* 0=normal file, 1=temporary file, delete on close, -1=shared FD */
-};
-#define FB_FILE(f) ((struct fb_file *)(f)->is_fastbuf)
-
struct fastbuf *bopen(byte *name, uns mode, uns buffer);
struct fastbuf *bopen_tmp(uns buffer);
struct fastbuf *bfdopen(int fd, uns buffer);
struct fastbuf *bfdopen_shared(int fd, uns buffer);
-#define FB_IS_TEMP_FILE(f) FB_FILE(f)->is_temp_file
/* FastIO on in-memory streams */
struct fastbuf *fbmem_create(unsigned blocksize); /* Create stream and return its writing fastbuf */
struct fastbuf *fbmem_clone_read(struct fastbuf *); /* Create reading fastbuf */
+/* FastIO on memory mapped files */
+
+struct fastbuf *bopen_mm(byte *name, uns mode);
+
+/* Configuring stream parameters */
+
+int bconfig(struct fastbuf *f, uns type, int data);
+
+#define BCONFIG_IS_TEMP_FILE 0
+
/* Universal functions working on all fastbuf's */
void bclose(struct fastbuf *f);
#include <fcntl.h>
#include <unistd.h>
+struct fb_file {
+ struct fastbuf fb;
+ int fd; /* File descriptor, -1 if not a real file */
+ int is_temp_file; /* 0=normal file, 1=temporary file, delete on close, -1=shared FD */
+};
+#define FB_FILE(f) ((struct fb_file *)(f)->is_fastbuf)
+
static int
bfd_refill(struct fastbuf *f)
{
xfree(f);
}
+static int
+bfd_config(struct fastbuf *f, uns item, int value)
+{
+ switch (item)
+ {
+ case BCONFIG_IS_TEMP_FILE:
+ FB_FILE(f)->is_temp_file = value;
+ return 0;
+ default:
+ return -1;
+ }
+}
+
static struct fastbuf *
bfdopen_internal(int fd, uns buflen, byte *name)
{
f->spout = bfd_spout;
f->seek = bfd_seek;
f->close = bfd_close;
+ f->config = bfd_config;
return f;
}
/*
* FIXME:
- * - problems with temp files
* - O_WRONLY ? (& generally processing of mode bits)
*/
struct fb_mmap {
struct fastbuf fb;
int fd;
- int dummy; /* FIXME: dirty hack for is_temp_file, remove */
+ int is_temp_file;
sh_off_t file_size;
sh_off_t file_extend;
sh_off_t window_pos;
if (F->file_extend > F->file_size &&
sh_ftruncate(F->fd, F->file_size))
die("ftruncate(%s): %m", f->name);
- close(F->fd);
+ switch (F->is_temp_file)
+ {
+ case 1:
+ if (unlink(f->name) < 0)
+ log(L_ERROR, "unlink(%s): %m", f->name);
+ case 0:
+ close(F->fd);
+ }
xfree(f);
}
+static int
+bfmm_config(struct fastbuf *f, uns item, int value)
+{
+ switch (item)
+ {
+ case BCONFIG_IS_TEMP_FILE:
+ FB_MMAP(f)->is_temp_file = value;
+ return 0;
+ default:
+ return -1;
+ }
+}
+
static struct fastbuf *
bfmmopen_internal(int fd, byte *name, uns mode)
{
f->spout = bfmm_spout;
f->seek = bfmm_seek;
f->close = bfmm_close;
+ f->config = bfmm_config;
return f;
}
sprintf(buf, temp_template, (int) getpid(), temp_counter++);
f = bopen(buf, O_RDWR | O_CREAT | O_EXCL, bufsize);
- FB_IS_TEMP_FILE(f) = 1;
+ bconfig(f, BCONFIG_IS_TEMP_FILE, 1);
return f;
}
#endif
#ifdef SORT_DELETE_INPUT
- FB_IS_TEMP_FILE(fb1) = SORT_DELETE_INPUT;
+ bconfig(fb1, BCONFIG_IS_TEMP_FILE, SORT_DELETE_INPUT);
#endif
sorter_pass_counter = 1;
#ifdef SORT_PRESORT
#ifdef SORT_OUTPUT_FB
return fb1;
#else
- FB_IS_TEMP_FILE(fb1) = 0;
+ bconfig(fb1, BCONFIG_IS_TEMP_FILE, 0);
if (rename(fb1->name, outname) < 0)
die("rename(%s,%s): %m", fb1->name, outname);
bclose(fb1);