summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorK.Takata <kentkt@csc.jp>2022-10-20 13:28:51 +0100
committerBram Moolenaar <Bram@vim.org>2022-10-20 13:28:51 +0100
commit43625762a9751cc6e6e4d8f54fbc8b82d98fb20d (patch)
tree0261835c4d3eb079e9013ae8277531b12c1d5db2
parent4c36678ffd1f933a6d4a12415994dea15e4ccec6 (diff)
patch 9.0.0803: readblob() cannot read from character devicev9.0.0803
Problem: readblob() cannot read from character device. Solution: Use S_ISCHR() to not check the size. (Ken Takata, closes #11407)
-rw-r--r--runtime/doc/builtin.txt7
-rw-r--r--src/blob.c8
-rw-r--r--src/proto/blob.pro2
-rw-r--r--src/testdir/test_blob.vim5
-rw-r--r--src/version.c2
5 files changed, 20 insertions, 4 deletions
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index 9b46d25178..5b383fdfcf 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -6859,7 +6859,12 @@ readblob({fname} [, {offset} [, {size}]]) *readblob()*
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.
diff --git a/src/blob.c b/src/blob.c
index 92efb67ab5..a94316c13f 100644
--- a/src/blob.c
+++ b/src/blob.c
@@ -212,9 +212,13 @@ read_blob(FILE *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
// 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)
diff --git a/src/proto/blob.pro b/src/proto/blob.pro
index 176f43e87f..7c8b5ac815 100644
--- 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);
diff --git a/src/testdir/test_blob.vim b/src/testdir/test_blob.vim
index a54cede9e8..47315ab84f 100644
--- 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?
diff --git a/src/version.c b/src/version.c
index 34ff382d1f..0de044e3ce 100644
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 803,
+/**/
802,
/**/
801,