[PATCH 1/6] move file helper functions to separate file
Sascha Hauer
s.hauer at pengutronix.de
Thu Jul 31 05:27:32 PDT 2014
We have our file helper functions in several places. Move them
all to lib/libfile.c.
With this we no longer have file helpers in fs/fs.c which contains
the core fs functions and no functions in lib/libbb.c which are
not from busybox.
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
arch/arm/lib/bootm.c | 1 +
arch/arm/mach-at91/boot_test_cmd.c | 1 +
arch/arm/mach-omap/omap_generic.c | 1 +
arch/arm/mach-omap/xload.c | 1 +
arch/blackfin/boards/ipe337/cmd_alternate.c | 1 +
arch/mips/lib/bootm.c | 1 +
commands/barebox-update.c | 1 +
commands/cp.c | 1 +
commands/crc.c | 1 +
commands/edit.c | 1 +
commands/exec.c | 1 +
commands/insmod.c | 1 +
commands/linux16.c | 1 +
commands/of_dump.c | 1 +
commands/oftree.c | 1 +
commands/readf.c | 1 +
commands/tftp.c | 1 +
commands/uimage.c | 1 +
common/blspec.c | 1 +
common/bootm.c | 1 +
common/hush.c | 1 +
common/menutree.c | 1 +
common/uimage.c | 1 +
drivers/usb/gadget/dfu.c | 1 +
fs/fs.c | 72 -------
fs/uimagefs.c | 1 +
include/fs.h | 14 --
include/libbb.h | 7 -
include/libfile.h | 15 ++
lib/Makefile | 2 +-
lib/copy_file.c | 86 ---------
lib/gui/image_renderer.c | 1 +
lib/libbb.c | 93 ---------
lib/libfile.c | 288 ++++++++++++++++++++++++++++
34 files changed, 330 insertions(+), 273 deletions(-)
create mode 100644 include/libfile.h
delete mode 100644 lib/copy_file.c
create mode 100644 lib/libfile.c
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
index d9b9111..9dce2cb 100644
--- a/arch/arm/lib/bootm.c
+++ b/arch/arm/lib/bootm.c
@@ -6,6 +6,7 @@
#include <image.h>
#include <init.h>
#include <fs.h>
+#include <libfile.h>
#include <linux/list.h>
#include <xfuncs.h>
#include <malloc.h>
diff --git a/arch/arm/mach-at91/boot_test_cmd.c b/arch/arm/mach-at91/boot_test_cmd.c
index 66c598b..4fd1998 100644
--- a/arch/arm/mach-at91/boot_test_cmd.c
+++ b/arch/arm/mach-at91/boot_test_cmd.c
@@ -7,6 +7,7 @@
#include <common.h>
#include <command.h>
#include <libbb.h>
+#include <libfile.h>
#include <getopt.h>
#include <fs.h>
#include <fcntl.h>
diff --git a/arch/arm/mach-omap/omap_generic.c b/arch/arm/mach-omap/omap_generic.c
index 060c592..334cf8d 100644
--- a/arch/arm/mach-omap/omap_generic.c
+++ b/arch/arm/mach-omap/omap_generic.c
@@ -20,6 +20,7 @@
#include <io.h>
#include <fs.h>
#include <malloc.h>
+#include <libfile.h>
#include <linux/stat.h>
#include <mach/gpmc.h>
#include <mach/generic.h>
diff --git a/arch/arm/mach-omap/xload.c b/arch/arm/mach-omap/xload.c
index a309450..e9d7bbb 100644
--- a/arch/arm/mach-omap/xload.c
+++ b/arch/arm/mach-omap/xload.c
@@ -5,6 +5,7 @@
#include <init.h>
#include <driver.h>
#include <linux/mtd/mtd.h>
+#include <libfile.h>
#include <fs.h>
#include <fcntl.h>
#include <sizes.h>
diff --git a/arch/blackfin/boards/ipe337/cmd_alternate.c b/arch/blackfin/boards/ipe337/cmd_alternate.c
index 992d274..b332cfb 100644
--- a/arch/blackfin/boards/ipe337/cmd_alternate.c
+++ b/arch/blackfin/boards/ipe337/cmd_alternate.c
@@ -1,5 +1,6 @@
#include <common.h>
#include <command.h>
+#include <libfile.h>
#include <linux/stat.h>
#include <malloc.h>
#include <fs.h>
diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c
index 3d6a4ce..0e03aa9 100644
--- a/arch/mips/lib/bootm.c
+++ b/arch/mips/lib/bootm.c
@@ -1,5 +1,6 @@
#include <boot.h>
#include <common.h>
+#include <libfile.h>
#include <init.h>
#include <fs.h>
#include <errno.h>
diff --git a/commands/barebox-update.c b/commands/barebox-update.c
index a24dc3e..92e0efa 100644
--- a/commands/barebox-update.c
+++ b/commands/barebox-update.c
@@ -17,6 +17,7 @@
*/
#include <common.h>
#include <command.h>
+#include <libfile.h>
#include <getopt.h>
#include <malloc.h>
#include <errno.h>
diff --git a/commands/cp.c b/commands/cp.c
index 1a56754..af7a3d4 100644
--- a/commands/cp.c
+++ b/commands/cp.c
@@ -26,6 +26,7 @@
#include <malloc.h>
#include <libgen.h>
#include <getopt.h>
+#include <libfile.h>
/**
* @param[in] argc Argument count from command line
diff --git a/commands/crc.c b/commands/crc.c
index 7c2936c..9b6a3e2 100644
--- a/commands/crc.c
+++ b/commands/crc.c
@@ -22,6 +22,7 @@
#include <fs.h>
#include <getopt.h>
#include <malloc.h>
+#include <libfile.h>
#include <environment.h>
static int crc_from_file(const char* file, ulong *crc)
diff --git a/commands/edit.c b/commands/edit.c
index 5a2da7d..97c2a81 100644
--- a/commands/edit.c
+++ b/commands/edit.c
@@ -21,6 +21,7 @@
#include <fs.h>
#include <linux/ctype.h>
#include <fcntl.h>
+#include <libfile.h>
#include <readkey.h>
#include <errno.h>
#include <xfuncs.h>
diff --git a/commands/exec.c b/commands/exec.c
index 635f65e..7c8934f 100644
--- a/commands/exec.c
+++ b/commands/exec.c
@@ -23,6 +23,7 @@
#include <fcntl.h>
#include <linux/stat.h>
#include <errno.h>
+#include <libfile.h>
#include <malloc.h>
#include <xfuncs.h>
diff --git a/commands/insmod.c b/commands/insmod.c
index 176437e..735dde0 100644
--- a/commands/insmod.c
+++ b/commands/insmod.c
@@ -3,6 +3,7 @@
#include <module.h>
#include <errno.h>
#include <fs.h>
+#include <libfile.h>
#include <malloc.h>
static int do_insmod(int argc, char *argv[])
diff --git a/commands/linux16.c b/commands/linux16.c
index 594efc7..bb678bd 100644
--- a/commands/linux16.c
+++ b/commands/linux16.c
@@ -24,6 +24,7 @@
#include <environment.h>
#include <fs.h>
#include <errno.h>
+#include <libfile.h>
#include <getopt.h>
#include <malloc.h>
#include <boot.h>
diff --git a/commands/of_dump.c b/commands/of_dump.c
index cafde07..315dbba 100644
--- a/commands/of_dump.c
+++ b/commands/of_dump.c
@@ -18,6 +18,7 @@
*/
#include <common.h>
+#include <libfile.h>
#include <fdt.h>
#include <of.h>
#include <command.h>
diff --git a/commands/oftree.c b/commands/oftree.c
index 983a0a5..ad622de 100644
--- a/commands/oftree.c
+++ b/commands/oftree.c
@@ -26,6 +26,7 @@
#include <common.h>
#include <environment.h>
#include <fdt.h>
+#include <libfile.h>
#include <of.h>
#include <command.h>
#include <fs.h>
diff --git a/commands/readf.c b/commands/readf.c
index c8cc574..8dd5a2b 100644
--- a/commands/readf.c
+++ b/commands/readf.c
@@ -1,6 +1,7 @@
#include <common.h>
#include <command.h>
#include <fs.h>
+#include <libfile.h>
#include <malloc.h>
#include <linux/stat.h>
#include <linux/ctype.h>
diff --git a/commands/tftp.c b/commands/tftp.c
index 62b9424..8a3b541 100644
--- a/commands/tftp.c
+++ b/commands/tftp.c
@@ -24,6 +24,7 @@
#include <fs.h>
#include <net.h>
#include <libbb.h>
+#include <libfile.h>
#define TFTP_MOUNT_PATH "/.tftp_tmp_path"
diff --git a/commands/uimage.c b/commands/uimage.c
index 33523d7..7c2dca4 100644
--- a/commands/uimage.c
+++ b/commands/uimage.c
@@ -7,6 +7,7 @@
#include <malloc.h>
#include <errno.h>
#include <getopt.h>
+#include <libfile.h>
static int uimage_fd;
diff --git a/common/blspec.c b/common/blspec.c
index 9314eea..a4adc48 100644
--- a/common/blspec.c
+++ b/common/blspec.c
@@ -21,6 +21,7 @@
#include <malloc.h>
#include <block.h>
#include <fcntl.h>
+#include <libfile.h>
#include <libbb.h>
#include <init.h>
#include <boot.h>
diff --git a/common/bootm.c b/common/bootm.c
index 71390cb..447c9b6 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -16,6 +16,7 @@
#include <fs.h>
#include <malloc.h>
#include <memory.h>
+#include <libfile.h>
#include <globalvar.h>
#include <init.h>
diff --git a/common/hush.c b/common/hush.c
index 6be43cf..09d9326 100644
--- a/common/hush.c
+++ b/common/hush.c
@@ -118,6 +118,7 @@
#include <libbb.h>
#include <glob.h>
#include <getopt.h>
+#include <libfile.h>
#include <libbb.h>
#include <magicvar.h>
#include <linux/list.h>
diff --git a/common/menutree.c b/common/menutree.c
index 814512d..97e628d 100644
--- a/common/menutree.c
+++ b/common/menutree.c
@@ -15,6 +15,7 @@
#include <glob.h>
#include <menu.h>
#include <fs.h>
+#include <libfile.h>
#include <linux/stat.h>
diff --git a/common/uimage.c b/common/uimage.c
index 4ef0968..a7011a7 100644
--- a/common/uimage.c
+++ b/common/uimage.c
@@ -22,6 +22,7 @@
#include <malloc.h>
#include <errno.h>
#include <libbb.h>
+#include <libfile.h>
#include <uncompress.h>
#include <fcntl.h>
#include <fs.h>
diff --git a/drivers/usb/gadget/dfu.c b/drivers/usb/gadget/dfu.c
index d0f2155..bc5ee9c 100644
--- a/drivers/usb/gadget/dfu.c
+++ b/drivers/usb/gadget/dfu.c
@@ -43,6 +43,7 @@
#include <linux/list.h>
#include <usb/gadget.h>
#include <linux/stat.h>
+#include <libfile.h>
#include <usb/ch9.h>
#include <usb/dfu.h>
#include <config.h>
diff --git a/fs/fs.c b/fs/fs.c
index dd410b7..fd3d353 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -34,78 +34,6 @@
#include <libgen.h>
#include <block.h>
-void *read_file(const char *filename, size_t *size)
-{
- int fd;
- struct stat s;
- void *buf = NULL;
- const char *tmpfile = "/.read_file_tmp";
- int ret;
-
-again:
- if (stat(filename, &s))
- return NULL;
-
- if (s.st_size == FILESIZE_MAX) {
- ret = copy_file(filename, tmpfile, 0);
- if (ret)
- return NULL;
- filename = tmpfile;
- goto again;
- }
-
- buf = xzalloc(s.st_size + 1);
-
- fd = open(filename, O_RDONLY);
- if (fd < 0)
- goto err_out;
-
- ret = read_full(fd, buf, s.st_size);
- if (ret < 0)
- goto err_out1;
-
- close(fd);
-
- if (size)
- *size = s.st_size;
-
- if (filename == tmpfile)
- unlink(tmpfile);
-
- return buf;
-
-err_out1:
- close(fd);
-err_out:
- free(buf);
-
- if (filename == tmpfile)
- unlink(tmpfile);
-
- return NULL;
-}
-
-EXPORT_SYMBOL(read_file);
-
-int write_file(const char *filename, void *buf, size_t size)
-{
- int fd, ret;
-
- fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT);
- if (fd < 0)
- return fd;
-
- ret = write_full(fd, buf, size);
-
- close(fd);
-
- if (ret < 0)
- return ret;
-
- return 0;
-}
-EXPORT_SYMBOL(write_file);
-
char *mkmodestr(unsigned long mode, char *str)
{
static const char *l = "xwr";
diff --git a/fs/uimagefs.c b/fs/uimagefs.c
index 6547b7c..63931c2 100644
--- a/fs/uimagefs.c
+++ b/fs/uimagefs.c
@@ -17,6 +17,7 @@
#include <uimagefs.h>
#include <libbb.h>
#include <rtc.h>
+#include <libfile.h>
static bool uimagefs_is_data_file(struct uimagefs_handle_data *d)
{
diff --git a/include/fs.h b/include/fs.h
index 073641c..b2541a4 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -164,20 +164,6 @@ int ls(const char *path, ulong flags);
char *mkmodestr(unsigned long mode, char *str);
/*
- * Read a file into memory. Memory is allocated with malloc and must
- * be freed with free() afterwards. This function allocates one
- * byte more than actually needed and sets this to zero, so that
- * it can be used for text files.
- * If size is nonzero it s set to the file size.
- */
-void *read_file(const char *filename, size_t *size);
-
-/*
- * Write a buffer to a file. This file is newly created.
- */
-int write_file(const char *filename, void *buf, size_t size);
-
-/*
* This function turns 'path' into an absolute path and removes all occurrences
* of "..", "." and double slashes. The returned string must be freed wit free().
*/
diff --git a/include/libbb.h b/include/libbb.h
index 2fe710c..a362bd3 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -26,15 +26,8 @@ int recursive_action(const char *fileName, unsigned flags,
char * safe_strncpy(char *dst, const char *src, size_t size);
-int copy_file(const char *src, const char *dst, int verbose);
-
int process_escape_sequence(const char *source, char *dest, int destlen);
char *simple_itoa(unsigned int i);
-int write_full(int fd, void *buf, size_t size);
-int read_full(int fd, void *buf, size_t size);
-
-char *read_file_line(const char *fmt, ...);
-
#endif /* __LIBBB_H */
diff --git a/include/libfile.h b/include/libfile.h
new file mode 100644
index 0000000..d47a111
--- /dev/null
+++ b/include/libfile.h
@@ -0,0 +1,15 @@
+#ifndef __LIBFILE_H
+#define __LIBFILE_H
+
+int write_full(int fd, void *buf, size_t size);
+int read_full(int fd, void *buf, size_t size);
+
+char *read_file_line(const char *fmt, ...);
+
+void *read_file(const char *filename, size_t *size);
+
+int write_file(const char *filename, void *buf, size_t size);
+
+int copy_file(const char *src, const char *dst, int verbose);
+
+#endif /* __LIBFILE_H */
diff --git a/lib/Makefile b/lib/Makefile
index e8769a9..dfd3aae 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -25,7 +25,6 @@ obj-$(CONFIG_GLOB) += fnmatch.o
obj-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o
obj-y += glob.o
obj-y += notifier.o
-obj-y += copy_file.o
obj-y += random.o
obj-y += lzo/
obj-$(CONFIG_LZ4_DECOMPRESS) += lz4/
@@ -44,3 +43,4 @@ obj-y += gui/
obj-$(CONFIG_XYMODEM) += xymodem.o
obj-y += unlink-recursive.o
obj-$(CONFIG_STMP_DEVICE) += stmp-device.o
+obj-y += libfile.o
diff --git a/lib/copy_file.c b/lib/copy_file.c
deleted file mode 100644
index fdd0cac..0000000
--- a/lib/copy_file.c
+++ /dev/null
@@ -1,86 +0,0 @@
-#include <common.h>
-#include <fs.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <malloc.h>
-#include <libbb.h>
-#include <progress.h>
-
-/**
- * @param[in] src FIXME
- * @param[out] dst FIXME
- * @param[in] verbose FIXME
- */
-int copy_file(const char *src, const char *dst, int verbose)
-{
- char *rw_buf = NULL;
- int srcfd = 0, dstfd = 0;
- int r, w;
- int ret = 1;
- void *buf;
- int total = 0;
- struct stat statbuf;
-
- rw_buf = xmalloc(RW_BUF_SIZE);
-
- srcfd = open(src, O_RDONLY);
- if (srcfd < 0) {
- printf("could not open %s: %s\n", src, errno_str());
- goto out;
- }
-
- dstfd = open(dst, O_WRONLY | O_CREAT | O_TRUNC);
- if (dstfd < 0) {
- printf("could not open %s: %s\n", dst, errno_str());
- goto out;
- }
-
- if (verbose) {
- if (stat(src, &statbuf) < 0)
- statbuf.st_size = 0;
-
- init_progression_bar(statbuf.st_size);
- }
-
- while(1) {
- r = read(srcfd, rw_buf, RW_BUF_SIZE);
- if (r < 0) {
- perror("read");
- goto out;
- }
- if (!r)
- break;
-
- buf = rw_buf;
- while (r) {
- w = write(dstfd, buf, r);
- if (w < 0) {
- perror("write");
- goto out;
- }
- buf += w;
- r -= w;
- total += w;
- }
-
- if (verbose) {
- if (statbuf.st_size && statbuf.st_size != FILESIZE_MAX)
- show_progress(total);
- else
- show_progress(total / 16384);
- }
- }
-
- ret = 0;
-out:
- if (verbose)
- putchar('\n');
-
- free(rw_buf);
- if (srcfd > 0)
- close(srcfd);
- if (dstfd > 0)
- close(dstfd);
-
- return ret;
-}
diff --git a/lib/gui/image_renderer.c b/lib/gui/image_renderer.c
index 8047961..dd29389 100644
--- a/lib/gui/image_renderer.c
+++ b/lib/gui/image_renderer.c
@@ -10,6 +10,7 @@
#include <errno.h>
#include <fs.h>
#include <malloc.h>
+#include <libfile.h>
static LIST_HEAD(image_renderers);
diff --git a/lib/libbb.c b/lib/libbb.c
index dd42e66..239611c 100644
--- a/lib/libbb.c
+++ b/lib/libbb.c
@@ -126,96 +126,3 @@ char *simple_itoa(unsigned int i)
return p + 1;
}
EXPORT_SYMBOL(simple_itoa);
-
-/*
- * write_full - write to filedescriptor
- *
- * Like write, but guarantees to write the full buffer out, else
- * it returns with an error.
- */
-int write_full(int fd, void *buf, size_t size)
-{
- size_t insize = size;
- int now;
-
- while (size) {
- now = write(fd, buf, size);
- if (now <= 0)
- return now;
- size -= now;
- buf += now;
- }
-
- return insize;
-}
-EXPORT_SYMBOL(write_full);
-
-/*
- * read_full - read from filedescriptor
- *
- * Like read, but this function only returns less bytes than
- * requested when the end of file is reached.
- */
-int read_full(int fd, void *buf, size_t size)
-{
- size_t insize = size;
- int now;
- int total = 0;
-
- while (size) {
- now = read(fd, buf, size);
- if (now == 0)
- return total;
- if (now < 0)
- return now;
- total += now;
- size -= now;
- buf += now;
- }
-
- return insize;
-}
-EXPORT_SYMBOL(read_full);
-
-/*
- * read_file_line - read a line from a file
- *
- * Used to compose a filename from a printf format and to read a line from this
- * file. All leading and trailing whitespaces (including line endings) are
- * removed. The returned buffer must be freed with free(). This function is
- * supposed for reading variable like content into a buffer, so files > 1024
- * bytes are ignored.
- */
-char *read_file_line(const char *fmt, ...)
-{
- va_list args;
- char *filename;
- char *buf, *line = NULL;
- size_t size;
- int ret;
- struct stat s;
-
- va_start(args, fmt);
- filename = vasprintf(fmt, args);
- va_end(args);
-
- ret = stat(filename, &s);
- if (ret)
- goto out;
-
- if (s.st_size > 1024)
- goto out;
-
- buf = read_file(filename, &size);
- if (!buf)
- goto out;
-
- line = strim(buf);
-
- line = xstrdup(line);
- free(buf);
-out:
- free(filename);
- return line;
-}
-EXPORT_SYMBOL_GPL(read_file_line);
diff --git a/lib/libfile.c b/lib/libfile.c
new file mode 100644
index 0000000..b36537f
--- /dev/null
+++ b/lib/libfile.c
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2014 Sascha Hauer <s.hauer at pengutronix.de>, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <common.h>
+#include <fs.h>
+#include <fcntl.h>
+#include <malloc.h>
+#include <libfile.h>
+#include <progress.h>
+#include <linux/stat.h>
+
+/*
+ * write_full - write to filedescriptor
+ *
+ * Like write, but guarantees to write the full buffer out, else
+ * it returns with an error.
+ */
+int write_full(int fd, void *buf, size_t size)
+{
+ size_t insize = size;
+ int now;
+
+ while (size) {
+ now = write(fd, buf, size);
+ if (now <= 0)
+ return now;
+ size -= now;
+ buf += now;
+ }
+
+ return insize;
+}
+EXPORT_SYMBOL(write_full);
+
+/*
+ * read_full - read from filedescriptor
+ *
+ * Like read, but this function only returns less bytes than
+ * requested when the end of file is reached.
+ */
+int read_full(int fd, void *buf, size_t size)
+{
+ size_t insize = size;
+ int now;
+ int total = 0;
+
+ while (size) {
+ now = read(fd, buf, size);
+ if (now == 0)
+ return total;
+ if (now < 0)
+ return now;
+ total += now;
+ size -= now;
+ buf += now;
+ }
+
+ return insize;
+}
+EXPORT_SYMBOL(read_full);
+
+/*
+ * read_file_line - read a line from a file
+ *
+ * Used to compose a filename from a printf format and to read a line from this
+ * file. All leading and trailing whitespaces (including line endings) are
+ * removed. The returned buffer must be freed with free(). This function is
+ * supposed for reading variable like content into a buffer, so files > 1024
+ * bytes are ignored.
+ */
+char *read_file_line(const char *fmt, ...)
+{
+ va_list args;
+ char *filename;
+ char *buf, *line = NULL;
+ size_t size;
+ int ret;
+ struct stat s;
+
+ va_start(args, fmt);
+ filename = vasprintf(fmt, args);
+ va_end(args);
+
+ ret = stat(filename, &s);
+ if (ret)
+ goto out;
+
+ if (s.st_size > 1024)
+ goto out;
+
+ buf = read_file(filename, &size);
+ if (!buf)
+ goto out;
+
+ line = strim(buf);
+
+ line = xstrdup(line);
+ free(buf);
+out:
+ free(filename);
+ return line;
+}
+EXPORT_SYMBOL_GPL(read_file_line);
+
+/**
+ * read_file - read a file to an allocated buffer
+ * @filename: The filename to read
+ * @size: After successful return contains the size of the file
+ *
+ * This function reads a file to an allocated buffer.
+ * Some TFTP servers do not transfer the size of a file. In this case
+ * a the file is first read to a temporary file.
+ *
+ * Return: The buffer conataining the file or NULL on failure
+ */
+void *read_file(const char *filename, size_t *size)
+{
+ int fd;
+ struct stat s;
+ void *buf = NULL;
+ const char *tmpfile = "/.read_file_tmp";
+ int ret;
+
+again:
+ if (stat(filename, &s))
+ return NULL;
+
+ if (s.st_size == FILESIZE_MAX) {
+ ret = copy_file(filename, tmpfile, 0);
+ if (ret)
+ return NULL;
+ filename = tmpfile;
+ goto again;
+ }
+
+ buf = xzalloc(s.st_size + 1);
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0)
+ goto err_out;
+
+ ret = read_full(fd, buf, s.st_size);
+ if (ret < 0)
+ goto err_out1;
+
+ close(fd);
+
+ if (size)
+ *size = s.st_size;
+
+ if (filename == tmpfile)
+ unlink(tmpfile);
+
+ return buf;
+
+err_out1:
+ close(fd);
+err_out:
+ free(buf);
+
+ if (filename == tmpfile)
+ unlink(tmpfile);
+
+ return NULL;
+}
+EXPORT_SYMBOL(read_file);
+
+/**
+ * write_file - write a buffer to a file
+ * @filename: The filename to write
+ * @size: The size of the buffer
+ *
+ * Return: 0 for success or negative error value
+ */
+int write_file(const char *filename, void *buf, size_t size)
+{
+ int fd, ret;
+
+ fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT);
+ if (fd < 0)
+ return fd;
+
+ ret = write_full(fd, buf, size);
+
+ close(fd);
+
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+EXPORT_SYMBOL(write_file);
+
+/**
+ * copy_file - Copy a file
+ * @src: The source filename
+ * @dst: The destination filename
+ * @verbose: if true, show a progression bar
+ *
+ * Return: 0 for success or negative error code
+ */
+int copy_file(const char *src, const char *dst, int verbose)
+{
+ char *rw_buf = NULL;
+ int srcfd = 0, dstfd = 0;
+ int r, w;
+ int ret = 1;
+ void *buf;
+ int total = 0;
+ struct stat statbuf;
+
+ rw_buf = xmalloc(RW_BUF_SIZE);
+
+ srcfd = open(src, O_RDONLY);
+ if (srcfd < 0) {
+ printf("could not open %s: %s\n", src, errno_str());
+ goto out;
+ }
+
+ dstfd = open(dst, O_WRONLY | O_CREAT | O_TRUNC);
+ if (dstfd < 0) {
+ printf("could not open %s: %s\n", dst, errno_str());
+ goto out;
+ }
+
+ if (verbose) {
+ if (stat(src, &statbuf) < 0)
+ statbuf.st_size = 0;
+
+ init_progression_bar(statbuf.st_size);
+ }
+
+ while (1) {
+ r = read(srcfd, rw_buf, RW_BUF_SIZE);
+ if (r < 0) {
+ perror("read");
+ goto out;
+ }
+ if (!r)
+ break;
+
+ buf = rw_buf;
+ while (r) {
+ w = write(dstfd, buf, r);
+ if (w < 0) {
+ perror("write");
+ goto out;
+ }
+ buf += w;
+ r -= w;
+ total += w;
+ }
+
+ if (verbose) {
+ if (statbuf.st_size && statbuf.st_size != FILESIZE_MAX)
+ show_progress(total);
+ else
+ show_progress(total / 16384);
+ }
+ }
+
+ ret = 0;
+out:
+ if (verbose)
+ putchar('\n');
+
+ free(rw_buf);
+ if (srcfd > 0)
+ close(srcfd);
+ if (dstfd > 0)
+ close(dstfd);
+
+ return ret;
+}
+EXPORT_SYMBOL(copy_file);
--
2.0.1
More information about the barebox
mailing list