Annotation of embedaddon/pimd/libite/fsendfile.c, revision 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>