mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Fix seeking on block devices with FD 0, 1 or 2
@stephane-chazelas reports:
> A very weird issue:
>
> To reproduce on GNU/Linux (here as superuser)
>
> # truncate -s10M file
> # export DEV="$(losetup -f --show file)"
> # ksh -c 'exec 3<> "$DEV" 3>#((0))' # fine
> # ksh -c 'exec 1<> file 1>#((0))' # fine
> # ksh -c 'exec 1<> "$DEV" 1>#((0))'
> ksh: 0: invalid seek offset
>
> Any seek offset is considered "invalid" as long as the file is a
> block device and the fd is 0, 1 or 2. It's fine for fds above 2
> and it's fine with any fd for regular files.
Apparently, block devices are not seekable with sfio. In io.c there
is specific code to avoid using sfio's sfseek(3) if there is no
sfio stream in sh.sftable[] for the file descriptor in question:
1398: Sfio_t *sp = sh.sftable[fn];
[...]
1420: if(sp)
1421: {
1422: off=sfseek(sp, off, SEEK_SET);
1423: sfsync(sp);
1424: }
1425: else
1426: off=lseek(fn, off, SEEK_SET);
For file descriptors 0, 1 or 2 (stdin/stdout/stderr), there is a
sh.sftable[] stream by default, and it is marked as not seekable.
This makes it return -1 in these lines in sfseek.c, even if the
system call called via SFSK() succeeds:
89: if(f->extent < 0)
90: { /* let system call set errno */
91: (void)SFSK(f,(Sfoff_t)0,SEEK_CUR,f->disc);
92: return (Sfoff_t)(-1);
93: }
...which explains the strange behaviour.
src/lib/libast/sfio/sfseek.c: sfseek():
- Allow for the possibility that the fallback system call might
succeed: let it handle both errno and the return value.
Resolves: https://github.com/ksh93/ksh/issues/318
This commit is contained in:
parent
cc1689849e
commit
416a412d71
3 changed files with 9 additions and 4 deletions
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
#define SH_RELEASE_FORK "93u+m" /* only change if you develop a new ksh93 fork */
|
||||
#define SH_RELEASE_SVER "1.0.0-beta.2" /* semantic version number: https://semver.org */
|
||||
#define SH_RELEASE_DATE "2022-06-22" /* must be in this format for $((.sh.version)) */
|
||||
#define SH_RELEASE_DATE "2022-06-28" /* must be in this format for $((.sh.version)) */
|
||||
#define SH_RELEASE_CPYR "(c) 2020-2022 Contributors to ksh " SH_RELEASE_FORK
|
||||
|
||||
/* Scripts sometimes field-split ${.sh.version}, so don't change amount of whitespace. */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue