diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2008-10-21 21:35:16 +0200 |
---|---|---|
committer | Sebastian Andrzej Siewior <sebastian@breakpoint.cc> | 2010-03-07 09:58:49 +0100 |
commit | 3d06b10be52b2a5ddcd4328bc2da11c3cc25f809 (patch) | |
tree | a60a88084ecc06b9e65dc716b3cfd5bca0b26bba /kexec/kexec.c | |
parent | 5996651eccbffb7c195c2911f37fda2f2258e48d (diff) |
slurpfile: use lseek() on character nodes instead of fstat() for file size
fstat() is used to determine the filesize before read() and
it requires a filesystem. That means that it can not be used
on character nodes. This makes it impossible to obtains the
kernel from a char node like mtd or more likely ubi.
We can't use this in every case because files in /proc don't
support lseek(). This is required by the powerpc part to read
some device-tree entries.
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Diffstat (limited to 'kexec/kexec.c')
-rw-r--r-- | kexec/kexec.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/kexec/kexec.c b/kexec/kexec.c index d282ade..fe29fb5 100644 --- a/kexec/kexec.c +++ b/kexec/kexec.c @@ -475,7 +475,7 @@ char *slurp_file(const char *filename, off_t *r_size) { int fd; char *buf; - off_t size, progress; + off_t size, progress, err; ssize_t result; struct stat stats; @@ -494,7 +494,26 @@ char *slurp_file(const char *filename, off_t *r_size) die("Cannot stat: %s: %s\n", filename, strerror(errno)); } - size = stats.st_size; + /* + * Seek in case the kernel is a character node like /dev/ubi0_0. + * This does not work on regular files which live in /proc and + * we need this for some /proc/device-tree entries + */ + if (S_ISCHR(stats.st_mode)) { + + size = lseek(fd, 0, SEEK_END); + if (size < 0) + die("Can not seek file %s: %s\n", filename, + strerror(errno)); + + err = lseek(fd, 0, SEEK_SET); + if (err < 0) + die("Can not seek to the begin of file %s: %s\n", + filename, strerror(errno)); + } else { + size = stats.st_size; + } + *r_size = size; buf = xmalloc(size); progress = 0; |