Skip to content

Commit 4362576

Browse files
k-takatabrammool
authored andcommitted
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 #11407)
1 parent 4c36678 commit 4362576

File tree

5 files changed

+20
-4
lines changed

5 files changed

+20
-4
lines changed

runtime/doc/builtin.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6859,7 +6859,12 @@ readblob({fname} [, {offset} [, {size}]]) *readblob()*
68596859
readblob('file.bin', 0, 100)
68606860
< If {size} is -1 or omitted, the whole data starting from
68616861
{offset} will be read.
6862-
When the file can't be opened an error message is given and
6862+
This can be also used to read the data from a character device
6863+
on Unix when {size} is explicitly set. Only if the device
6864+
supports seeking {offset} can be used. Otherwise it should be
6865+
zero. E.g. to read 10 bytes from a serial console: >
6866+
readblob('/dev/ttyS0', 0, 10)
6867+
< When the file can't be opened an error message is given and
68636868
the result is an empty |Blob|.
68646869
When trying to read bytes beyond the end of the file the
68656870
result is an empty blob.

src/blob.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,9 +212,13 @@ read_blob(FILE *fd, typval_T *rettv, off_T offset, off_T size_arg)
212212
}
213213
// Trying to read bytes that aren't there results in an empty blob, not an
214214
// error.
215-
if (size < 0 || size > st.st_size)
215+
if (size <= 0 || (
216+
#ifdef S_ISCHR
217+
!S_ISCHR(st.st_mode) &&
218+
#endif
219+
size > st.st_size))
216220
return OK;
217-
if (vim_fseek(fd, offset, whence) != 0)
221+
if (offset != 0 && vim_fseek(fd, offset, whence) != 0)
218222
return OK;
219223

220224
if (ga_grow(&blob->bv_ga, (int)size) == FAIL)

src/proto/blob.pro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ int blob_get(blob_T *b, int idx);
1010
void blob_set(blob_T *blob, int idx, int byte);
1111
void blob_set_append(blob_T *blob, int idx, int byte);
1212
int blob_equal(blob_T *b1, blob_T *b2);
13-
int read_blob(FILE *fd, typval_T *rettv, off_T offset, off_T size);
13+
int read_blob(FILE *fd, typval_T *rettv, off_T offset, off_T size_arg);
1414
int write_blob(FILE *fd, blob_T *blob);
1515
char_u *blob2string(blob_T *blob, char_u **tofree, char_u *numbuf);
1616
blob_T *string2blob(char_u *str);

src/testdir/test_blob.vim

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,11 @@ func Test_blob_read_write()
508508
END
509509
call v9.CheckLegacyAndVim9Success(lines)
510510

511+
if filereadable('/dev/random')
512+
let b = readblob('/dev/random', 0, 10)
513+
call assert_equal(10, len(b))
514+
endif
515+
511516
call assert_fails("call readblob('notexist')", 'E484:')
512517
" TODO: How do we test for the E485 error?
513518

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,8 @@ static char *(features[]) =
695695

696696
static int included_patches[] =
697697
{ /* Add new patch number below this line */
698+
/**/
699+
803,
698700
/**/
699701
802,
700702
/**/

0 commit comments

Comments
 (0)