From bfef6cd5f2ff1720543839dea9bcc7ec340ba8f5 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 8 Oct 2014 13:48:12 +0200 Subject: fs: store pointer to fsdev instead of dev in struct filep The struct device_d * in struct filep is never of interest, instead it is always converted to a struct fs_device_d *, so simplify the code by storing the struct fs_device_d * directly. Signed-off-by: Sascha Hauer --- include/fs.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include') diff --git a/include/fs.h b/include/fs.h index b2541a4ee5..c3ce81ae98 100644 --- a/include/fs.h +++ b/include/fs.h @@ -23,7 +23,7 @@ typedef struct dir { } DIR; typedef struct filep { - struct device_d *dev; /* The device this FILE belongs to */ + struct fs_device_d *fsdev; /* The device this FILE belongs to */ loff_t pos; /* current position in stream */ #define FILE_SIZE_STREAM ((loff_t) -1) loff_t size; /* The size of this inode */ @@ -82,7 +82,6 @@ struct fs_driver_d { unsigned long flags; }; -#define dev_to_fs_driver(d) container_of(d->driver, struct fs_driver_d, drv) #define dev_to_fs_device(d) container_of(d, struct fs_device_d, dev) extern struct list_head fs_device_list; -- cgit v1.2.3 From 4f7a18cdb58aaef1c265e0359608a465355d9863 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 8 Oct 2014 14:01:37 +0200 Subject: fs: Store the path in struct filep Signed-off-by: Sascha Hauer --- fs/fs.c | 5 +++++ include/fs.h | 1 + 2 files changed, 6 insertions(+) (limited to 'include') diff --git a/fs/fs.c b/fs/fs.c index 04b6408802..436f5cb751 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -251,6 +251,8 @@ static FILE *get_file(void) static void put_file(FILE *f) { + free(f->path); + f->path = NULL; f->in_use = 0; } @@ -670,6 +672,9 @@ int open(const char *pathname, int flags, ...) if (ret) goto out; } + + f->path = xstrdup(path); + ret = fsdrv->open(&fsdev->dev, f, path); if (ret) goto out; diff --git a/include/fs.h b/include/fs.h index c3ce81ae98..6eddb2312f 100644 --- a/include/fs.h +++ b/include/fs.h @@ -24,6 +24,7 @@ typedef struct dir { typedef struct filep { struct fs_device_d *fsdev; /* The device this FILE belongs to */ + char *path; loff_t pos; /* current position in stream */ #define FILE_SIZE_STREAM ((loff_t) -1) loff_t size; /* The size of this inode */ -- cgit v1.2.3 From a3993a38da55fc1074b5e176354d86fe7742cef3 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 8 Oct 2014 14:02:23 +0200 Subject: fs: implement fstat fstat is useful to get information about an already opened file. Add it to barebox. Signed-off-by: Sascha Hauer --- fs/fs.c | 16 ++++++++++++++++ include/fs.h | 1 + 2 files changed, 17 insertions(+) (limited to 'include') diff --git a/fs/fs.c b/fs/fs.c index 436f5cb751..ffdfa2c0ff 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -1472,6 +1472,22 @@ out: } EXPORT_SYMBOL(lstat); +int fstat(int fd, struct stat *s) +{ + FILE *f; + struct fs_device_d *fsdev; + + if (check_fd(fd)) + return -errno; + + f = &files[fd]; + + fsdev = f->fsdev; + + return fsdev->driver->stat(&fsdev->dev, f->path, s); +} +EXPORT_SYMBOL(fstat); + int mkdir (const char *pathname, mode_t mode) { struct fs_driver_d *fsdrv; diff --git a/include/fs.h b/include/fs.h index 6eddb2312f..63e35ca815 100644 --- a/include/fs.h +++ b/include/fs.h @@ -114,6 +114,7 @@ int close(int fd); int flush(int fd); int lstat(const char *filename, struct stat *s); int stat(const char *filename, struct stat *s); +int fstat(int fd, struct stat *s); ssize_t read(int fd, void *buf, size_t count); ssize_t pread(int fd, void *buf, size_t count, loff_t offset); int ioctl(int fd, int request, void *buf); -- cgit v1.2.3 From 6cf5b986d98a19a8c05f6813b8944a4f5f784dd0 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 8 Oct 2014 14:11:55 +0200 Subject: libfile: add compare_file function Signed-off-by: Sascha Hauer --- include/libfile.h | 2 ++ lib/libfile.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) (limited to 'include') diff --git a/include/libfile.h b/include/libfile.h index 4a25a9153c..6c48ce0b68 100644 --- a/include/libfile.h +++ b/include/libfile.h @@ -15,4 +15,6 @@ int write_file(const char *filename, void *buf, size_t size); int copy_file(const char *src, const char *dst, int verbose); +int compare_file(const char *f1, const char *f2); + #endif /* __LIBFILE_H */ diff --git a/lib/libfile.c b/lib/libfile.c index c626e2f4a0..7ed4b93672 100644 --- a/lib/libfile.c +++ b/lib/libfile.c @@ -331,3 +331,74 @@ out: return ret; } EXPORT_SYMBOL(copy_file); + +/** + * compare_file - Compare two files + * @f1: The first file + * @f2: The second file + * + * Return: 0 if both files are identical, 1 if they differ, + * a negative error code if some error occured + */ +int compare_file(const char *f1, const char *f2) +{ + int fd1, fd2, ret; + struct stat s1, s2; + void *buf1, *buf2; + loff_t left; + + fd1 = open(f1, O_RDONLY); + if (fd1 < 0) + return -errno; + + fd2 = open(f2, O_RDONLY); + if (fd2 < 0) { + ret = -errno; + goto err_out1; + } + + ret = fstat(fd1, &s1); + if (ret) + goto err_out2; + + ret = fstat(fd2, &s2); + if (ret) + goto err_out2; + + if (s1.st_size != s2.st_size) + return 1; + + buf1 = xmalloc(RW_BUF_SIZE); + buf2 = xmalloc(RW_BUF_SIZE); + + left = s1.st_size; + while (left) { + loff_t now = min(left, (loff_t)RW_BUF_SIZE); + + ret = read_full(fd1, buf1, now); + if (ret < 0) + goto err_out3; + + ret = read_full(fd2, buf2, now); + if (ret < 0) + goto err_out3; + + if (memcmp(buf1, buf2, now)) { + ret = 1; + goto err_out3; + } + + left -= now; + } + + ret = 0; + +err_out3: + free(buf1); + free(buf2); +err_out2: + close(fd2); +err_out1: + close(fd1); + return ret; +} -- cgit v1.2.3