Annotation of embedaddon/pimd/libite/fsendfile.c, revision 1.1.1.1
1.1 misho 1: /* Copy data between file streams
2: *
3: * Copyright (c) 2013 Tobias Waldekranz <tobias@waldekranz.com>
4: *
5: * Permission is hereby granted, free of charge, to any person obtaining a copy
6: * of this software and associated documentation files (the "Software"), to deal
7: * in the Software without restriction, including without limitation the rights
8: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9: * copies of the Software, and to permit persons to whom the Software is
10: * furnished to do so, subject to the following conditions:
11: *
12: * The above copyright notice and this permission notice shall be included in
13: * all copies or substantial portions of the Software.
14: *
15: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21: * THE SOFTWARE.
22: */
23:
24: #include <errno.h>
25: #include <stdio.h>
26: #include <stdlib.h>
27:
28:
29: /**
30: * fsendfile - copy data between file streams
31: * @src: Source stream
32: * @dst: Destination stream
33: * @len: Number of bytes to copy
34: *
35: * @dst may be %NULL, in which case @len bytes are read and discarded
36: * from @src. This can be useful for streams where seeking is not
37: * permitted. Additionally, @len may be the special value zero (0), in
38: * which case fsendfile() will copy until %EOF is seen on @src.
39: *
40: * Returns:
41: * The number of bytes copied. If an error is detected -1 is returned
42: * and @errno will be set accordingly.
43: */
44: size_t fsendfile(FILE *src, FILE *dst, size_t len)
45: {
46: char *buf;
47: size_t blk = BUFSIZ, num = 0, tot = 0;
48:
49: if (!src) {
50: errno = EINVAL;
51: return -1;
52: }
53:
54: buf = (char *)malloc(BUFSIZ);
55: if (!buf)
56: return -1;
57:
58: while (!len || tot < len) {
59: if (len && ((len - tot) < BUFSIZ))
60: blk = len - tot;
61:
62: num = fread(buf, 1, blk, src);
63: if (num == 0)
64: break;
65:
66: if (dst && (fwrite(buf, num, 1, dst) != 1)) {
67: num = -1;
68: break;
69: }
70:
71: tot += num;
72: }
73:
74: free(buf);
75:
76: return (num == (size_t)-1) ? (size_t)-1 : tot;
77: }
78:
79: #ifdef UNITTEST
80: #include <err.h>
81: #include <unistd.h>
82:
83: int main(void)
84: {
85: int i = 0;
86: char *files[] = {
87: "/etc/passwd", "/tmp/tok",
88: "/etc/passwd", "/tmp/passwd",
89: "/etc/passwd", "/tmp/passwd",
90: NULL
91: };
92: FILE *src, *dst;
93:
94: while (files[i]) {
95: src = fopen(files[i], "r");
96: dst = fopen(files[i + 1], "w");
97: printf("fsendfile(%s, %s, 512)\t", files[i], files[i + 1]);
98: if (-1 == fsendfile(src, dst, 512))
99: err(1, "Failed fsendfile(%s, %s)", files[i], files[i + 1]);
100:
101: if (!access(files[i + 1], F_OK))
102: printf("OK => %s\n", files[i + 1]);
103:
104: remove(files[i + 1]);
105: i += 2;
106: }
107:
108: return 0;
109: }
110: #endif /* UNITTEST */
111:
112: /**
113: * Local Variables:
114: * compile-command: "make V=1 -f fsendfile.mk"
115: * version-control: t
116: * indent-tabs-mode: t
117: * c-file-style: "linux"
118: * End:
119: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>