File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / pimd / libite / fsendfile.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 14 09:12:58 2017 UTC (7 years ago) by misho
Branches: pimd, MAIN
CVS tags: v2_3_2, HEAD
libite

    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>