diff options
Diffstat (limited to 'fs/tftp.c')
-rw-r--r-- | fs/tftp.c | 29 |
1 files changed, 19 insertions, 10 deletions
@@ -93,7 +93,7 @@ struct tftp_priv { IPaddr_t server; }; -static int tftp_truncate(struct device_d *dev, FILE *f, ulong size) +static int tftp_truncate(struct device_d *dev, FILE *f, loff_t size) { return 0; } @@ -573,15 +573,17 @@ static int tftp_read(struct device_d *dev, FILE *f, void *buf, size_t insize) return outsize; } -static loff_t tftp_lseek(struct device_d *dev, FILE *f, loff_t pos) +static int tftp_lseek(struct device_d *dev, FILE *f, loff_t pos) { /* We cannot seek backwards without reloading or caching the file */ - if (pos >= f->pos) { - loff_t ret; + loff_t f_pos = f->pos; + + if (pos >= f_pos) { + int ret = 0; char *buf = xmalloc(1024); - while (pos > f->pos) { - size_t len = min_t(size_t, 1024, pos - f->pos); + while (pos > f_pos) { + size_t len = min_t(size_t, 1024, pos - f_pos); ret = tftp_read(dev, f, buf, len); @@ -591,14 +593,21 @@ static loff_t tftp_lseek(struct device_d *dev, FILE *f, loff_t pos) if (ret < 0) goto out_free; - f->pos += ret; + f_pos += ret; } - ret = pos; - out_free: free(buf); - return ret; + if (ret < 0) { + /* + * Update f->pos even if the overall request + * failed since we can't move backwards + */ + f->pos = f_pos; + return ret; + } + + return 0; } return -ENOSYS; |