vim-patch:9.0.0803: readblob() cannot read from character device

Problem:    readblob() cannot read from character device.
Solution:   Use S_ISCHR() to not check the size. (Ken Takata, closes vim/vim#11407)

43625762a9

S_ISCHR is always defined in Nvim.

Co-authored-by: K.Takata <kentkt@csc.jp>
This commit is contained in:
zeertzjq 2023-02-28 19:23:28 +08:00
parent bfa0bc7df0
commit 4bd0611d7b
3 changed files with 14 additions and 3 deletions

View File

@ -6164,7 +6164,12 @@ readblob({fname} [, {offset} [, {size}]]) *readblob()*
readblob('file.bin', 0, 100) readblob('file.bin', 0, 100)
< If {size} is -1 or omitted, the whole data starting from < If {size} is -1 or omitted, the whole data starting from
{offset} will be read. {offset} will be read.
When the file can't be opened an error message is given and This can be also used to read the data from a character device
on Unix when {size} is explicitly set. Only if the device
supports seeking {offset} can be used. Otherwise it should be
zero. E.g. to read 10 bytes from a serial console: >
readblob('/dev/ttyS0', 0, 10)
< When the file can't be opened an error message is given and
the result is an empty |Blob|. the result is an empty |Blob|.
When trying to read bytes beyond the end of the file the When trying to read bytes beyond the end of the file the
result is an empty blob. result is an empty blob.

View File

@ -5893,10 +5893,11 @@ int read_blob(FILE *const fd, typval_T *rettv, off_T offset, off_T size_arg)
} }
// Trying to read bytes that aren't there results in an empty blob, not an // Trying to read bytes that aren't there results in an empty blob, not an
// error. // error.
if (size < 0 || size > (off_T)os_fileinfo_size(&file_info)) { if (size < 0 || (!S_ISCHR(file_info.stat.st_mode)
&& size > (off_T)os_fileinfo_size(&file_info))) {
return OK; return OK;
} }
if (vim_fseek(fd, offset, whence) != 0) { if (offset != 0 && vim_fseek(fd, offset, whence) != 0) {
return OK; return OK;
} }

View File

@ -459,6 +459,11 @@ func Test_blob_read_write()
END END
call CheckLegacyAndVim9Success(lines) call CheckLegacyAndVim9Success(lines)
if filereadable('/dev/random')
let b = readblob('/dev/random', 0, 10)
call assert_equal(10, len(b))
endif
call assert_fails("call readblob('notexist')", 'E484:') call assert_fails("call readblob('notexist')", 'E484:')
" TODO: How do we test for the E485 error? " TODO: How do we test for the E485 error?