|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
From 061843340fbf2493bb615e20e66f60c5d1ef0455 Mon Sep 17 00:00:00 2001
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
From: William Pitcock <nenolod@dereferenced.org>
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
Date: Tue, 5 Dec 2017 16:04:43 -0500
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
Subject: implement the fopencookie extension to stdio
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
notes added by maintainer:
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
this function is a GNU extension. it was chosen over the similar BSD
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
function funopen because the latter depends on fpos_t being an
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
arithmetic type as part of its public API, conflicting with our
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
definition of fpos_t and with the intent that it be an opaque type. it
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
was accepted for inclusion because, despite not being widely used, it
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
is usually very difficult to extricate software using it from the
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
dependency on it.
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
calling pattern for the read and write callbacks is not likely to
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
match glibc or other implementations, but should work with any
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
reasonable callbacks. in particular the read function is never called
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
without at least one byte being needed to satisfy its caller, so that
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
spurious blocking is not introduced.
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
contracts for what callbacks called from inside libc/stdio can do are
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
always complicated, and at some point still need to be specified
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
explicitly. at the very least, the callbacks must return or block
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
indefinitely (they cannot perform nonlocal exits) and they should not
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
make calls to stdio using their own FILE as an argument.
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
---
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
include/stdio.h | 14 +++++
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
src/stdio/fopencookie.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++++
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
2 files changed, 152 insertions(+)
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
create mode 100644 src/stdio/fopencookie.c
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
diff --git a/include/stdio.h b/include/stdio.h
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
index 884d2e6..2932c76 100644
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
--- a/include/stdio.h
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+++ b/include/stdio.h
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
@@ -182,6 +182,20 @@ int vasprintf(char **, const char *, __isoc_va_list);
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
#ifdef _GNU_SOURCE
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
char *fgets_unlocked(char *, int, FILE *);
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
int fputs_unlocked(const char *, FILE *);
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+typedef ssize_t (cookie_read_function_t)(void *, char *, size_t);
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+typedef ssize_t (cookie_write_function_t)(void *, const char *, size_t);
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+typedef int (cookie_seek_function_t)(void *, off_t *, int);
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+typedef int (cookie_close_function_t)(void *);
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+typedef struct {
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ cookie_read_function_t *read;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ cookie_write_function_t *write;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ cookie_seek_function_t *seek;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ cookie_close_function_t *close;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+} cookie_io_functions_t;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+FILE *fopencookie(void *, const char *, cookie_io_functions_t);
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
#endif
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
diff --git a/src/stdio/fopencookie.c b/src/stdio/fopencookie.c
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
new file mode 100644
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
index 0000000..2f46dd5
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
--- /dev/null
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+++ b/src/stdio/fopencookie.c
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
@@ -0,0 +1,138 @@
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+#define _GNU_SOURCE
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+#include "stdio_impl.h"
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+#include <stdlib.h>
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+#include <sys/ioctl.h>
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+#include <fcntl.h>
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+#include <errno.h>
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+#include <string.h>
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+struct fcookie {
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ void *cookie;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ cookie_io_functions_t iofuncs;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+};
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+struct cookie_FILE {
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ FILE f;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ struct fcookie fc;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ unsigned char buf[UNGET+BUFSIZ];
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+};
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+static size_t cookieread(FILE *f, unsigned char *buf, size_t len)
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+{
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ struct fcookie *fc = f->cookie;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ ssize_t ret = -1;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ size_t remain = len, readlen = 0;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ size_t len2 = len - !!f->buf_size;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ if (!fc->iofuncs.read) goto bail;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ if (len2) {
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ ret = fc->iofuncs.read(fc->cookie, (char *) buf, len2);
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ if (ret <= 0) goto bail;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ readlen += ret;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ remain -= ret;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ }
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ if (!f->buf_size || remain > !!f->buf_size) return readlen;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ f->rpos = f->buf;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ ret = fc->iofuncs.read(fc->cookie, (char *) f->rpos, f->buf_size);
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ if (ret <= 0) goto bail;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ f->rend = f->rpos + ret;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ buf[readlen++] = *f->rpos++;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ return readlen;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+bail:
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ f->flags |= ret == 0 ? F_EOF : F_ERR;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ f->rpos = f->rend = f->buf;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ return readlen;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+}
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+static size_t cookiewrite(FILE *f, const unsigned char *buf, size_t len)
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+{
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ struct fcookie *fc = f->cookie;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ ssize_t ret;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ size_t len2 = f->wpos - f->wbase;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ if (!fc->iofuncs.write) return len;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ if (len2) {
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ f->wpos = f->wbase;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ if (cookiewrite(f, f->wpos, len2) < len2) return 0;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ }
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ ret = fc->iofuncs.write(fc->cookie, (const char *) buf, len);
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ if (ret < 0) {
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ f->wpos = f->wbase = f->wend = 0;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ f->flags |= F_ERR;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ return 0;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ }
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ return ret;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+}
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+static off_t cookieseek(FILE *f, off_t off, int whence)
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+{
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ struct fcookie *fc = f->cookie;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ int res;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ if (whence > 2U) {
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ errno = EINVAL;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ return -1;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ }
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ if (!fc->iofuncs.seek) {
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ errno = ENOTSUP;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ return -1;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ }
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ res = fc->iofuncs.seek(fc->cookie, &off, whence);
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ if (res < 0)
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ return res;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ return off;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+}
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+static int cookieclose(FILE *f)
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+{
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ struct fcookie *fc = f->cookie;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ if (fc->iofuncs.close) return fc->iofuncs.close(fc->cookie);
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ return 0;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+}
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+FILE *fopencookie(void *cookie, const char *mode, cookie_io_functions_t iofuncs)
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+{
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ struct cookie_FILE *f;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ /* Check for valid initial mode character */
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ if (!strchr("rwa", *mode)) {
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ errno = EINVAL;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ return 0;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ }
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ /* Allocate FILE+fcookie+buffer or fail */
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ if (!(f=malloc(sizeof *f))) return 0;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ /* Zero-fill only the struct, not the buffer */
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ memset(&f->f, 0, sizeof f->f);
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ /* Impose mode restrictions */
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ if (!strchr(mode, '+')) f->f.flags = (*mode == 'r') ? F_NOWR : F_NORD;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ /* Set up our fcookie */
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ f->fc.cookie = cookie;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ f->fc.iofuncs.read = iofuncs.read;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ f->fc.iofuncs.write = iofuncs.write;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ f->fc.iofuncs.seek = iofuncs.seek;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ f->fc.iofuncs.close = iofuncs.close;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ f->f.fd = -1;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ f->f.cookie = &f->fc;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ f->f.buf = f->buf + UNGET;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ f->f.buf_size = BUFSIZ;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ f->f.lbf = EOF;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ /* Initialize op ptrs. No problem if some are unneeded. */
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ f->f.read = cookieread;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ f->f.write = cookiewrite;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ f->f.seek = cookieseek;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ f->f.close = cookieclose;
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ /* Add new FILE to open file list */
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+ return __ofl_add(&f->f);
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
+}
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
--
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
cgit v0.11.2
|
|
Lucio Andrés Illanes Albornoz (arab, vxp) |
ff26b5 |
|