mailing list of musl libc
 help / color / mirror / code / Atom feed
fa15be006cf3890f47130a801f7c57d4e015a89d blob 2670 bytes (raw)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
 
#define _GNU_SOURCE
#include "stdio_impl.h"
#include <stdlib.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

struct fcookie {
	void *cookie;
	cookie_io_functions_t iofuncs;
};

static size_t cookieread(FILE *f, unsigned char *buf, size_t len)
{
	struct fcookie *fc = f->cookie;
	size_t ret, remain = len, readlen = 0;

	if (fc->iofuncs.read == NULL) return 0;

	ret = fc->iofuncs.read(fc->cookie, (char *) buf, len - 1);
	if (ret == 0) goto bail_eof;

	readlen += ret;
	remain -= ret;

	f->rpos = f->buf;
	ret = fc->iofuncs.read(fc->cookie, (char *) f->rpos, f->buf_size);
	if (ret == 0) goto bail_eof;
	f->rend = f->rpos + ret;

	if (remain > f->buf_size) remain = f->buf_size;
	memcpy(buf + readlen, f->rpos, remain);
	readlen += remain;
	f->rpos += remain;

	return readlen;

bail_eof:
	f->flags |= F_EOF;
	f->rpos = f->rend = f->buf;
	return readlen;
}

static size_t cookiewrite(FILE *f, const unsigned char *buf, size_t len)
{
	struct fcookie *fc = f->cookie;
	size_t ret;
	size_t len2 = f->wpos - f->wbase;
	if (fc->iofuncs.write == NULL) return 0;
	if (len2) {
		f->wpos = f->wbase;
		if (cookiewrite(f, f->wpos, len2) < len2) return 0;
	}
	return fc->iofuncs.write(fc->cookie, (const char *) buf, len);
}

static off_t cookieseek(FILE *f, off_t off, int whence)
{
	struct fcookie *fc = f->cookie;
	if (fc->iofuncs.seek) return fc->iofuncs.seek(fc->cookie, &off, whence);
	return -1;
}

static int cookieclose(FILE *f)
{
	struct fcookie *fc = f->cookie;
	if (fc->iofuncs.close) return fc->iofuncs.close(fc->cookie);
	return 0;
}

FILE *fopencookie(void *cookie, const char *mode, cookie_io_functions_t iofuncs)
{
	FILE *f;
	struct fcookie *fc;

	/* Check for valid initial mode character */
	if (!strchr("rwa", *mode)) {
		errno = EINVAL;
		return 0;
	}

	/* Allocate FILE+fcookie+buffer or fail */
	if (!(f=malloc(sizeof *f + sizeof *fc + UNGET + BUFSIZ))) return 0;

	/* Zero-fill only the struct, not the buffer */
	memset(f, 0, sizeof *f);

	/* Impose mode restrictions */
	if (!strchr(mode, '+')) f->flags = (*mode == 'r') ? F_NOWR : F_NORD;

	/* Set up our fcookie */
	fc = (void *)(f + 1);
	fc->cookie = cookie;
	fc->iofuncs.read = iofuncs.read;
	fc->iofuncs.write = iofuncs.write;
	fc->iofuncs.seek = iofuncs.seek;
	fc->iofuncs.close = iofuncs.close;

	f->fd = -1;
	f->cookie = fc;
	f->buf = (unsigned char *)f + sizeof *f + sizeof *fc + UNGET;
	f->buf_size = BUFSIZ;
	f->lbf = EOF;
	f->lock = 0;

	/* Initialize op ptrs. No problem if some are unneeded. */
	f->read = cookieread;
	f->write = cookiewrite;
	f->seek = cookieseek;
	f->close = cookieclose;

	/* Add new FILE to open file list */
	return __ofl_add(f);
}
debug log:

solving fa15be00 ...
found fa15be00 in https://inbox.vuxu.org/musl/20171011045254.15544-1-nenolod@dereferenced.org/

applying [1/1] https://inbox.vuxu.org/musl/20171011045254.15544-1-nenolod@dereferenced.org/
diff --git a/src/stdio/fopencookie.c b/src/stdio/fopencookie.c
new file mode 100644
index 00000000..fa15be00

Checking patch src/stdio/fopencookie.c...
Applied patch src/stdio/fopencookie.c cleanly.

index at:
100644 fa15be006cf3890f47130a801f7c57d4e015a89d	src/stdio/fopencookie.c

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).