1
0
forked from aniani/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 #11407)
This commit is contained in:
K.Takata
2022-10-20 13:28:51 +01:00
committed by Bram Moolenaar
parent 4c36678ffd
commit 43625762a9
5 changed files with 20 additions and 4 deletions

View File

@@ -6859,7 +6859,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

@@ -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 // Trying to read bytes that aren't there results in an empty blob, not an
// error. // 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; return OK;
if (vim_fseek(fd, offset, whence) != 0) if (offset != 0 && vim_fseek(fd, offset, whence) != 0)
return OK; return OK;
if (ga_grow(&blob->bv_ga, (int)size) == FAIL) if (ga_grow(&blob->bv_ga, (int)size) == FAIL)

View File

@@ -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(blob_T *blob, int idx, int byte);
void blob_set_append(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 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); int write_blob(FILE *fd, blob_T *blob);
char_u *blob2string(blob_T *blob, char_u **tofree, char_u *numbuf); char_u *blob2string(blob_T *blob, char_u **tofree, char_u *numbuf);
blob_T *string2blob(char_u *str); blob_T *string2blob(char_u *str);

View File

@@ -508,6 +508,11 @@ func Test_blob_read_write()
END END
call v9.CheckLegacyAndVim9Success(lines) 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:') 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?

View File

@@ -695,6 +695,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
803,
/**/ /**/
802, 802,
/**/ /**/