Mercurial > vim
changeset 30938:84f6f91ca02a v9.0.0803
patch 9.0.0803: readblob() cannot read from character device
Commit: https://github.com/vim/vim/commit/43625762a9751cc6e6e4d8f54fbc8b82d98fb20d
Author: K.Takata <kentkt@csc.jp>
Date: Thu Oct 20 13:28:51 2022 +0100
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 https://github.com/vim/vim/issues/11407)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 20 Oct 2022 14:30:13 +0200 |
parents | d192688c8bab |
children | 0c6fe9b4ecd1 |
files | runtime/doc/builtin.txt src/blob.c src/proto/blob.pro src/testdir/test_blob.vim src/version.c |
diffstat | 5 files changed, 20 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -6859,7 +6859,12 @@ readblob({fname} [, {offset} [, {size}]] readblob('file.bin', 0, 100) < If {size} is -1 or omitted, the whole data starting from {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|. When trying to read bytes beyond the end of the file the result is an empty blob.
--- a/src/blob.c +++ b/src/blob.c @@ -212,9 +212,13 @@ read_blob(FILE *fd, typval_T *rettv, off } // Trying to read bytes that aren't there results in an empty blob, not an // error. - if (size < 0 || size > st.st_size) + if (size <= 0 || ( +#ifdef S_ISCHR + !S_ISCHR(st.st_mode) && +#endif + size > st.st_size)) return OK; - if (vim_fseek(fd, offset, whence) != 0) + if (offset != 0 && vim_fseek(fd, offset, whence) != 0) return OK; if (ga_grow(&blob->bv_ga, (int)size) == FAIL)
--- a/src/proto/blob.pro +++ b/src/proto/blob.pro @@ -10,7 +10,7 @@ int blob_get(blob_T *b, int idx); void blob_set(blob_T *blob, int idx, int byte); void blob_set_append(blob_T *blob, int idx, int byte); int blob_equal(blob_T *b1, blob_T *b2); -int read_blob(FILE *fd, typval_T *rettv, off_T offset, off_T size); +int read_blob(FILE *fd, typval_T *rettv, off_T offset, off_T size_arg); int write_blob(FILE *fd, blob_T *blob); char_u *blob2string(blob_T *blob, char_u **tofree, char_u *numbuf); blob_T *string2blob(char_u *str);
--- a/src/testdir/test_blob.vim +++ b/src/testdir/test_blob.vim @@ -508,6 +508,11 @@ func Test_blob_read_write() END call v9.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:') " TODO: How do we test for the E485 error?