]> granicus.if.org Git - vim/commitdiff
patch 9.0.0803: readblob() cannot read from character device v9.0.0803
authorK.Takata <kentkt@csc.jp>
Thu, 20 Oct 2022 12:28:51 +0000 (13:28 +0100)
committerBram Moolenaar <Bram@vim.org>
Thu, 20 Oct 2022 12:28:51 +0000 (13:28 +0100)
Problem:    readblob() cannot read from character device.
Solution:   Use S_ISCHR() to not check the size. (Ken Takata, closes #11407)

runtime/doc/builtin.txt
src/blob.c
src/proto/blob.pro
src/testdir/test_blob.vim
src/version.c

index 9b46d251784ed9c2ebb13f569e98386b574e089e..5b383fdfcfa4751175a5b11293a0865e15cdd14d 100644 (file)
@@ -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.
index 92efb67ab5ccda3fb5965c08e6c155a108e3e215..a94316c13f56fc5b91a5cbe25eb6ebf7ebb819a6 100644 (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
     // 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)
index 176f43e87fe063a94d3c4bd24edca362facfc56d..7c8b5ac8158b1f16b62e7bda99b3da654cc7677e 100644 (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_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);
index a54cede9e88022c6e3bc2c79118bd165a3708bff..47315ab84fbfcbac1c8ad5ef024c416d3bb95d29 100644 (file)
@@ -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?
 
index 34ff382d1f7c5bf807196efd884ede0e4366e8e1..0de044e3ceaab4714136fc80fbc31738ea9fc89f 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    803,
 /**/
     802,
 /**/