Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/pkg
Path: blob/main/compat/funopen.c
2065 views
1
/* Copyright (c) 2014, Vsevolod Stakhov
2
* All rights reserved.
3
*
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions are met:
6
* * Redistributions of source code must retain the above copyright
7
* notice, this list of conditions and the following disclaimer.
8
* * Redistributions in binary form must reproduce the above copyright
9
* notice, this list of conditions and the following disclaimer in the
10
* documentation and/or other materials provided with the distribution.
11
*
12
* THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY
13
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15
* DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
16
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22
*/
23
#ifndef _GNU_SOURCE
24
# define _GNU_SOURCE
25
#endif
26
#include <sys/types.h>
27
#include <stdint.h>
28
#include <stdio.h>
29
#include <stdlib.h>
30
31
#include "bsd_compat.h"
32
#include "pkg_config.h"
33
#include <xmalloc.h>
34
35
#ifndef HAVE_FUNOPEN
36
37
typedef struct {
38
int (*readfn)(void *, char *, int);
39
int (*writefn)(void *, const char *, int);
40
off_t (*seekfn)(void *, off_t, int);
41
int (*closefn)(void *);
42
void *cookie;
43
} bsd_cookie_funcs_t;
44
45
static ssize_t
46
cookie_read(void *cookie, char *buf, size_t size)
47
{
48
bsd_cookie_funcs_t *funcs = cookie;
49
return (ssize_t)funcs->readfn(funcs->cookie, buf, (int)size);
50
}
51
52
static ssize_t
53
cookie_write(void *cookie, const char *buf, size_t size)
54
{
55
bsd_cookie_funcs_t *funcs = cookie;
56
return (ssize_t)funcs->writefn(funcs->cookie, buf, (int)size);
57
}
58
59
#ifndef off64_t
60
#define off64_t off_t
61
#endif
62
63
static int
64
cookie_seek(void *cookie, off64_t *offset, int whence)
65
{
66
bsd_cookie_funcs_t *funcs = cookie;
67
off_t v = funcs->seekfn(funcs->cookie, (off_t)*offset, whence);
68
if (v < 0)
69
return -1;
70
*offset = (off64_t)v;
71
return 0;
72
}
73
74
static int
75
cookie_close(void *cookie)
76
{
77
int ret = 0;
78
bsd_cookie_funcs_t *funcs = cookie;
79
if (funcs->closefn)
80
ret = funcs->closefn(funcs->cookie);
81
free(cookie);
82
return ret;
83
}
84
85
FILE *
86
funopen(const void *cookie, int (*readfn)(void *, char *, int),
87
int (*writefn)(void *, const char *, int),
88
off_t (*seekfn)(void *, off_t, int), int (*closefn)(void *))
89
{
90
bsd_cookie_funcs_t *cf = xmalloc(sizeof(bsd_cookie_funcs_t));
91
cf->readfn = readfn;
92
cf->writefn = writefn;
93
cf->seekfn = seekfn;
94
cf->closefn = closefn;
95
cf->cookie = __DECONST(void *, cookie);
96
97
cookie_io_functions_t c;
98
if (readfn) c.read = cookie_read;
99
if (writefn) c.write = cookie_write;
100
if (seekfn) c.seek = cookie_seek;
101
c.close = cookie_close;
102
103
return fopencookie(cf, "a+", c);
104
}
105
106
#endif
107
108