mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-02-15 04:32:24 +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
6
NEWS
6
NEWS
|
@ -3,6 +3,12 @@ For full details, see the git log at: https://github.com/ksh93/ksh/tree/1.0
|
|||
|
||||
Any uppercase BUG_* names are modernish shell bug IDs.
|
||||
|
||||
2022-06-28:
|
||||
|
||||
- Fixed a bug that caused the <#((num)) or >#((num)) arithmetic seek
|
||||
redirection operator to fail if used with file descriptor 0, 1 or 2
|
||||
connected to a block device.
|
||||
|
||||
2022-06-22:
|
||||
|
||||
- Fixed: 'echo' failed when used inside a command substitution that
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -87,9 +87,8 @@ Sfoff_t sfseek(Sfio_t* f, /* seek to a new location in this stream */
|
|||
}
|
||||
|
||||
if(f->extent < 0)
|
||||
{ /* let system call set errno */
|
||||
(void)SFSK(f,(Sfoff_t)0,SEEK_CUR,f->disc);
|
||||
return (Sfoff_t)(-1);
|
||||
{ /* not seekable with sfio: let the system call either set errno or succeed */
|
||||
return SFSK(f,p,type,f->disc);
|
||||
}
|
||||
|
||||
/* throw away ungetc data */
|
||||
|
|
Loading…
Reference in a new issue