mirror of
https://github.com/troglobit/libite.git
synced 2026-10-01 13:32:42 +07:00
Factor out fsendfile() to reduce overall size when linking.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com> Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
committed by
Joachim Nilsson
parent
c48ce14739
commit
1423edc044
@@ -55,8 +55,8 @@ endif
|
||||
|
||||
DISTFILES = README LICENSE
|
||||
HEADERS = lite.h
|
||||
OBJS := chomp.o copyfile.o dir.o fexist.o fisdir.o fmode.o rsync.o
|
||||
OBJS += strlcpy.o strlcat.o strtonum.o tempfile.o
|
||||
OBJS := chomp.o copyfile.o dir.o fexist.o fisdir.o fmode.o fsendfile.o
|
||||
OBJS += rsync.o strlcpy.o strlcat.o strtonum.o tempfile.o
|
||||
DEPS := $(OBJS:.o=.d)
|
||||
JUNK = *~ *.bak *.map .*.d *.d DEADJOE semantic.cache *.gdb *.elf core core.*
|
||||
|
||||
|
||||
-45
@@ -234,51 +234,6 @@ exit:
|
||||
return errno = result;
|
||||
}
|
||||
|
||||
/**
|
||||
* fsendfile - copy data between file streams
|
||||
* @out: Destination stream
|
||||
* @in: Source stream
|
||||
* @sz: Size in bytes to copy.
|
||||
*
|
||||
* @out may be NULL, in which case @sz bytes are read and discarded
|
||||
* from @in. This is useful for streams where seeks are not
|
||||
* permitted. Additionally @sz may be the special value zero (0) in
|
||||
* which case fsendfile will copy until EOF is seen on @src.
|
||||
*
|
||||
* Returns:
|
||||
* The number of bytes copied. If there was an error, -1 is returned
|
||||
* and errno will be set accordingly.
|
||||
*/
|
||||
size_t fsendfile (FILE *out, FILE *in, size_t sz)
|
||||
{
|
||||
char *buf;
|
||||
size_t blk = BUFSIZ, num = 0, tot = 0;
|
||||
|
||||
buf = (char *)malloc(BUFSIZ);
|
||||
if (!buf)
|
||||
return -1;
|
||||
|
||||
while (!sz || tot < sz) {
|
||||
if (sz && ((sz - tot) < BUFSIZ))
|
||||
blk = sz - tot;
|
||||
|
||||
num = fread(buf, 1, blk, in);
|
||||
if (num == 0)
|
||||
break;
|
||||
|
||||
if (out && (fwrite(buf, num, 1, out) != 1)) {
|
||||
num = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
tot += num;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
|
||||
return (num == (size_t)-1) ? (size_t)-1 : tot;
|
||||
}
|
||||
|
||||
/* Tests if dst is a directory, if so, reallocates dst and appends src filename returning 1 */
|
||||
static int adjust_target(char *src, char **dst)
|
||||
{
|
||||
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
/* Copy data between file streams
|
||||
*
|
||||
* Copyright (c) 2013 Tobias Waldekranz <tobias@waldekranz.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
/**
|
||||
* fsendfile - copy data between file streams
|
||||
* @dst: Destination stream
|
||||
* @src: Source stream
|
||||
* @len: Number of bytes to copy
|
||||
*
|
||||
* @dst may be %NULL, in which case @len bytes are read and discarded
|
||||
* from @src. This can be useful for streams where seeking is not
|
||||
* permitted. Additionally, @len may be the special value zero (0), in
|
||||
* which case fsendfile() will copy until %EOF is seen on @src.
|
||||
*
|
||||
* Returns:
|
||||
* The number of bytes copied. If an error is detected -1 is returned
|
||||
* and @errno will be set accordingly.
|
||||
*/
|
||||
size_t fsendfile(FILE *dst, FILE *src, size_t len)
|
||||
{
|
||||
char *buf;
|
||||
size_t blk = BUFSIZ, num = 0, tot = 0;
|
||||
|
||||
if (!src) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf = (char *)malloc(BUFSIZ);
|
||||
if (!buf)
|
||||
return -1;
|
||||
|
||||
while (!len || tot < len) {
|
||||
if (len && ((len - tot) < BUFSIZ))
|
||||
blk = len - tot;
|
||||
|
||||
num = fread(buf, 1, blk, src);
|
||||
if (num == 0)
|
||||
break;
|
||||
|
||||
if (dst && (fwrite(buf, num, 1, dst) != 1)) {
|
||||
num = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
tot += num;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
|
||||
return (num == (size_t)-1) ? (size_t)-1 : tot;
|
||||
}
|
||||
|
||||
#ifdef UNITTEST
|
||||
#include <unistd.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int i = 0;
|
||||
char *files[] = {
|
||||
"/etc/passwd", "/tmp/tok",
|
||||
"/etc/passwd", "/tmp/passwd",
|
||||
"/etc/passwd", "/tmp/passwd",
|
||||
NULL
|
||||
};
|
||||
FILE *src, *dst;
|
||||
|
||||
while (files[i]) {
|
||||
src = fopen(files[i], "r");
|
||||
dst = fopen(files[i + 1], "w");
|
||||
fprintf(stderr, "fsendfile(%s, %s, 512)\t", files[i], files[i + 1]);
|
||||
if (-1 == fsendfile(dst, src, 512))
|
||||
perror("Failed");
|
||||
|
||||
if (!access(files[i + 1], F_OK))
|
||||
fprintf(stderr, "OK => %s\n", files[i + 1]);
|
||||
|
||||
remove(files[i + 1]);
|
||||
i += 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* UNITTEST */
|
||||
|
||||
/**
|
||||
* Local Variables:
|
||||
* compile-command: "gcc -g -o sendy -DUNITTEST fsendfile.c && ./sendy"
|
||||
* version-control: t
|
||||
* indent-tabs-mode: t
|
||||
* c-file-style: "linux"
|
||||
* End:
|
||||
*/
|
||||
Reference in New Issue
Block a user