NSH dd command test with block devices
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@1242 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
parent
b2a511f7dc
commit
5baf279692
|
@ -754,14 +754,50 @@ dd if=<infile> of=<outfile> [bs=<sectsize>] [count=<sectors
|
||||||
</pre></ul>
|
</pre></ul>
|
||||||
<p>
|
<p>
|
||||||
<b>Synopsis</b>.
|
<b>Synopsis</b>.
|
||||||
Copy blocks from <infile> to <outfile>. As an example:
|
Copy blocks from <infile> to <outfile>.
|
||||||
|
<infile> or <outfile> may be the path to a standard file, a character device, or a block device.
|
||||||
|
Examples follow:
|
||||||
|
</p>
|
||||||
|
<ol>
|
||||||
|
<li>
|
||||||
|
Read from character device, write to regular file.
|
||||||
|
This will create a new file of the specified size filled with zero.
|
||||||
<ul><pre>
|
<ul><pre>
|
||||||
|
nsh> ls -l /dev
|
||||||
|
/dev:
|
||||||
|
crw-rw-rw- 0 zero
|
||||||
nsh> dd if=/dev/zero of=/tmp/zeros bs=64 count=16
|
nsh> dd if=/dev/zero of=/tmp/zeros bs=64 count=16
|
||||||
nsh> ls -l /tmp
|
nsh> ls -l /tmp
|
||||||
/tmp:
|
/tmp:
|
||||||
-rw-rw-rw- 1024 ZEROS
|
-rw-rw-rw- 1024 ZEROS
|
||||||
</pre></ul>
|
</pre></ul>
|
||||||
</p>
|
</li>
|
||||||
|
<li>
|
||||||
|
Read from character device, write to block device.
|
||||||
|
This will fill the entire block device with zeros.
|
||||||
|
</li>
|
||||||
|
<ul><pre>
|
||||||
|
nsh> ls -l /dev
|
||||||
|
/dev:
|
||||||
|
brw-rw-rw- 0 ram0
|
||||||
|
crw-rw-rw- 0 zero
|
||||||
|
nsh> dd if=/dev/zero of=/dev/ram0
|
||||||
|
</pre></ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Read from a block devic, write to a character device. This
|
||||||
|
will read the entire block device and dump the contents in
|
||||||
|
the bit bucket.
|
||||||
|
</li>
|
||||||
|
<ul><pre>
|
||||||
|
nsh> ls -l /dev
|
||||||
|
/dev:
|
||||||
|
crw-rw-rw- 0 null
|
||||||
|
brw-rw-rw- 0 ram0
|
||||||
|
nsh> dd if=/dev/ram0 of=/dev/null
|
||||||
|
</pre></ul>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
<table width ="100%">
|
<table width ="100%">
|
||||||
<tr bgcolor="#e4e4e4">
|
<tr bgcolor="#e4e4e4">
|
||||||
|
|
|
@ -85,7 +85,7 @@
|
||||||
|
|
||||||
ssize_t bchlib_read(FAR void *handle, FAR char *buffer, size_t offset, size_t len)
|
ssize_t bchlib_read(FAR void *handle, FAR char *buffer, size_t offset, size_t len)
|
||||||
{
|
{
|
||||||
FAR struct bchlib_s *bch;
|
FAR struct bchlib_s *bch = (FAR struct bchlib_s *)handle;
|
||||||
size_t nsectors;
|
size_t nsectors;
|
||||||
size_t sector;
|
size_t sector;
|
||||||
uint16 sectoffset;
|
uint16 sectoffset;
|
||||||
|
@ -202,135 +202,3 @@ ssize_t bchlib_read(FAR void *handle, FAR char *buffer, size_t offset, size_t le
|
||||||
|
|
||||||
return bytesread;
|
return bytesread;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: bchlib_write
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Write to the block device set-up by bchlib_setup as if it were a character
|
|
||||||
* device.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
ssize_t bchlib_write(FAR void *handle, FAR const char *buffer, size_t offset, size_t len)
|
|
||||||
{
|
|
||||||
FAR struct bchlib_s *bch;
|
|
||||||
size_t nsectors;
|
|
||||||
size_t sector;
|
|
||||||
uint16 sectoffset;
|
|
||||||
size_t nbytes;
|
|
||||||
size_t byteswritten;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* Get rid of this special case right away */
|
|
||||||
|
|
||||||
if (len < 1)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert the file position into a sector number an offset. */
|
|
||||||
|
|
||||||
sector = offset / bch->sectsize;
|
|
||||||
sectoffset = offset - sector * bch->sectsize;
|
|
||||||
|
|
||||||
if (sector >= bch->nsectors)
|
|
||||||
{
|
|
||||||
return -EFBIG;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write the initial partial sector */
|
|
||||||
|
|
||||||
byteswritten = 0;
|
|
||||||
if (sectoffset > 0)
|
|
||||||
{
|
|
||||||
/* Read the full sector into the sector buffer */
|
|
||||||
|
|
||||||
bchlib_readsector(bch, sector);
|
|
||||||
|
|
||||||
/* Copy the tail end of the sector from the user buffer */
|
|
||||||
|
|
||||||
if (sectoffset + len > bch->sectsize)
|
|
||||||
{
|
|
||||||
nbytes = bch->sectsize - sectoffset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nbytes = len;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(&bch->buffer[sectoffset], buffer, nbytes);
|
|
||||||
bch->dirty = TRUE;
|
|
||||||
|
|
||||||
/* Adjust pointers and counts */
|
|
||||||
|
|
||||||
sectoffset = 0;
|
|
||||||
sector++;
|
|
||||||
|
|
||||||
if (sector >= bch->nsectors)
|
|
||||||
{
|
|
||||||
return nbytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
byteswritten = nbytes;
|
|
||||||
buffer += nbytes;
|
|
||||||
len -= nbytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Then write all of the full sectors following the partial sector */
|
|
||||||
|
|
||||||
if (len >= bch->sectsize )
|
|
||||||
{
|
|
||||||
nsectors = len / bch->sectsize;
|
|
||||||
if (sector + nsectors > bch->nsectors)
|
|
||||||
{
|
|
||||||
nsectors = bch->nsectors - sector;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write the contiguous sectors */
|
|
||||||
|
|
||||||
ret = bch->inode->u.i_bops->write(bch->inode, bch->buffer, sector, nsectors);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
fdbg("Write failed: %d\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Adjust pointers and counts */
|
|
||||||
|
|
||||||
sectoffset = 0;
|
|
||||||
sector += nsectors;
|
|
||||||
|
|
||||||
nbytes = nsectors * bch->sectsize;
|
|
||||||
byteswritten += nbytes;
|
|
||||||
|
|
||||||
if (sector >= bch->nsectors)
|
|
||||||
{
|
|
||||||
return byteswritten;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer += nbytes;
|
|
||||||
len -= nbytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Then write any partial final sector */
|
|
||||||
|
|
||||||
if (len > 0)
|
|
||||||
{
|
|
||||||
/* Read the sector into the sector buffer */
|
|
||||||
|
|
||||||
bchlib_readsector(bch, sector);
|
|
||||||
|
|
||||||
/* Copy the head end of the sector from the user buffer */
|
|
||||||
|
|
||||||
memcpy(bch->buffer, buffer, len);
|
|
||||||
bch->dirty = TRUE;
|
|
||||||
|
|
||||||
/* Adjust counts */
|
|
||||||
|
|
||||||
byteswritten += len;
|
|
||||||
}
|
|
||||||
|
|
||||||
return byteswritten;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@
|
||||||
|
|
||||||
ssize_t bchlib_write(FAR void *handle, FAR const char *buffer, size_t offset, size_t len)
|
ssize_t bchlib_write(FAR void *handle, FAR const char *buffer, size_t offset, size_t len)
|
||||||
{
|
{
|
||||||
FAR struct bchlib_s *bch;
|
FAR struct bchlib_s *bch = (FAR struct bchlib_s *)handle;
|
||||||
size_t nsectors;
|
size_t nsectors;
|
||||||
size_t sector;
|
size_t sector;
|
||||||
uint16 sectoffset;
|
uint16 sectoffset;
|
||||||
|
|
|
@ -252,15 +252,38 @@ o cp <source-path> <dest-path>
|
||||||
|
|
||||||
o dd if=<infile> of=<outfile> [bs=<sectsize>] [count=<sectors>] [skip=<sectors>]
|
o dd if=<infile> of=<outfile> [bs=<sectsize>] [count=<sectors>] [skip=<sectors>]
|
||||||
|
|
||||||
Copy blocks from <infile> to <outfile>.
|
Copy blocks from <infile> to <outfile>. <nfile> or <outfile> may
|
||||||
|
be the path to a standard file, a character device, or a block device.
|
||||||
|
|
||||||
Example:
|
Examples:
|
||||||
|
|
||||||
|
1. Read from character device, write to regular file. This will
|
||||||
|
create a new file of the specified size filled with zero.
|
||||||
|
|
||||||
nsh> dd if=/dev/zero of=/tmp/zeros bs=64 count=16
|
nsh> dd if=/dev/zero of=/tmp/zeros bs=64 count=16
|
||||||
nsh> ls -l /tmp
|
nsh> ls -l /tmp
|
||||||
/tmp:
|
/tmp:
|
||||||
-rw-rw-rw- 1024 ZEROS
|
-rw-rw-rw- 1024 ZEROS
|
||||||
|
|
||||||
|
2. Read from character device, write to block device. This will
|
||||||
|
fill the entire block device with zeros.
|
||||||
|
|
||||||
|
nsh> ls -l /dev
|
||||||
|
/dev:
|
||||||
|
brw-rw-rw- 0 ram0
|
||||||
|
crw-rw-rw- 0 zero
|
||||||
|
nsh> dd if=/dev/zero of=/dev/ram0
|
||||||
|
|
||||||
|
3. Read from a block devic, write to a character device. This
|
||||||
|
will read the entire block device and dump the contents in
|
||||||
|
the bit bucket.
|
||||||
|
|
||||||
|
nsh> ls -l /dev
|
||||||
|
/dev:
|
||||||
|
crw-rw-rw- 0 null
|
||||||
|
brw-rw-rw- 0 ram0
|
||||||
|
nsh> dd if=/dev/ram0 of=/dev/null
|
||||||
|
|
||||||
o echo [<string|$name> [<string|$name>...]]
|
o echo [<string|$name> [<string|$name>...]]
|
||||||
|
|
||||||
Copy the sequence of strings and expanded environment variables to
|
Copy the sequence of strings and expanded environment variables to
|
||||||
|
|
|
@ -209,12 +209,25 @@ static int dd_writeblk(struct dd_s *dd)
|
||||||
ssize_t nbytes;
|
ssize_t nbytes;
|
||||||
off_t offset = (dd->sector - dd->skip) * dd->sectsize;
|
off_t offset = (dd->sector - dd->skip) * dd->sectsize;
|
||||||
|
|
||||||
|
/* Write the sector at the specified offset */
|
||||||
|
|
||||||
nbytes = bchlib_write(DD_OUTHANDLE, (char*)dd->buffer, offset, dd->sectsize);
|
nbytes = bchlib_write(DD_OUTHANDLE, (char*)dd->buffer, offset, dd->sectsize);
|
||||||
if (nbytes < 0)
|
if (nbytes < 0)
|
||||||
{
|
{
|
||||||
nsh_output(dd->vtbl, g_fmtcmdfailed, g_dd, "bshlib_write", NSH_ERRNO);
|
/* bchlib_write return -EFBIG on attempts to write past the end of
|
||||||
|
* the device.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (nbytes == -EFBIG)
|
||||||
|
{
|
||||||
|
dd->eof = TRUE; /* Set end-of-file */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nsh_output(dd->vtbl, g_fmtcmdfailed, g_dd, "bshlib_write", NSH_ERRNO_OF(-nbytes));
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
@ -238,7 +251,7 @@ static int dd_writech(struct dd_s *dd)
|
||||||
nbytes = write(DD_OUTFD, buffer, dd->sectsize - written);
|
nbytes = write(DD_OUTFD, buffer, dd->sectsize - written);
|
||||||
if (nbytes < 0)
|
if (nbytes < 0)
|
||||||
{
|
{
|
||||||
nsh_output(dd->vtbl, g_fmtcmdfailed, g_dd, "write", NSH_ERRNO);
|
nsh_output(dd->vtbl, g_fmtcmdfailed, g_dd, "write", NSH_ERRNO_OF(-nbytes));
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,11 +276,14 @@ static int dd_readblk(struct dd_s *dd)
|
||||||
nbytes = bchlib_read(DD_INHANDLE, (char*)dd->buffer, offset, dd->sectsize);
|
nbytes = bchlib_read(DD_INHANDLE, (char*)dd->buffer, offset, dd->sectsize);
|
||||||
if (nbytes < 0)
|
if (nbytes < 0)
|
||||||
{
|
{
|
||||||
nsh_output(dd->vtbl, g_fmtcmdfailed, g_dd, "bshlib_read", NSH_ERRNO);
|
nsh_output(dd->vtbl, g_fmtcmdfailed, g_dd, "bshlib_read", NSH_ERRNO_OF(-nbytes));
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* bchlib_read return 0 on attempts to write past the end of the device. */
|
||||||
|
|
||||||
dd->nbytes = nbytes;
|
dd->nbytes = nbytes;
|
||||||
|
dd->eof = (nbytes == 0);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -287,7 +303,7 @@ static int dd_readch(struct dd_s *dd)
|
||||||
nbytes = read(DD_INFD, buffer, dd->sectsize - dd->nbytes);
|
nbytes = read(DD_INFD, buffer, dd->sectsize - dd->nbytes);
|
||||||
if (nbytes < 0)
|
if (nbytes < 0)
|
||||||
{
|
{
|
||||||
nsh_output(dd->vtbl, g_fmtcmdfailed, g_dd, "read", NSH_ERRNO);
|
nsh_output(dd->vtbl, g_fmtcmdfailed, g_dd, "read", NSH_ERRNO_OF(-nbytes));
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,7 +353,7 @@ static inline int dd_infopen(const char *name, struct dd_s *dd)
|
||||||
type = dd_filetype(name);
|
type = dd_filetype(name);
|
||||||
if (type < 0)
|
if (type < 0)
|
||||||
{
|
{
|
||||||
nsh_output(dd->vtbl, g_fmtcmdfailed, g_dd, "stat", NSH_ERRNO);
|
nsh_output(dd->vtbl, g_fmtcmdfailed, g_dd, "stat", NSH_ERRNO_OF(-type));
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,9 +465,9 @@ static inline int dd_outfopen(const char *name, struct dd_s *dd)
|
||||||
int cmd_dd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
int cmd_dd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct dd_s dd;
|
struct dd_s dd;
|
||||||
const char *infile = NULL;
|
char *infile = NULL;
|
||||||
const char *outfile = NULL;
|
char *outfile = NULL;
|
||||||
int ret;
|
int ret = ERROR;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Initialize the dd structure */
|
/* Initialize the dd structure */
|
||||||
|
@ -490,11 +506,11 @@ int cmd_dd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
||||||
{
|
{
|
||||||
if (strncmp(argv[i], "if=", 3) == 0)
|
if (strncmp(argv[i], "if=", 3) == 0)
|
||||||
{
|
{
|
||||||
infile = &argv[i][3];
|
infile = nsh_getfullpath(vtbl, &argv[i][3]);
|
||||||
}
|
}
|
||||||
else if (strncmp(argv[i], "of=", 3) == 0)
|
else if (strncmp(argv[i], "of=", 3) == 0)
|
||||||
{
|
{
|
||||||
outfile = &argv[i][3];
|
outfile = nsh_getfullpath(vtbl, &argv[i][3]);
|
||||||
}
|
}
|
||||||
else if (strncmp(argv[i], "bs=", 3) == 0)
|
else if (strncmp(argv[i], "bs=", 3) == 0)
|
||||||
{
|
{
|
||||||
|
@ -514,14 +530,14 @@ int cmd_dd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
||||||
if (!infile || !outfile)
|
if (!infile || !outfile)
|
||||||
{
|
{
|
||||||
nsh_output(vtbl, g_fmtargrequired, g_dd);
|
nsh_output(vtbl, g_fmtargrequired, g_dd);
|
||||||
return ERROR;
|
goto errout_with_paths;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (dd.skip < 0 || dd.skip > dd.nsectors)
|
if (dd.skip < 0 || dd.skip > dd.nsectors)
|
||||||
{
|
{
|
||||||
nsh_output(vtbl, g_fmtarginvalid, g_dd);
|
nsh_output(vtbl, g_fmtarginvalid, g_dd);
|
||||||
return ERROR;
|
goto errout_with_paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate the I/O buffer */
|
/* Allocate the I/O buffer */
|
||||||
|
@ -530,7 +546,7 @@ int cmd_dd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
||||||
if (!dd.buffer)
|
if (!dd.buffer)
|
||||||
{
|
{
|
||||||
nsh_output(vtbl, g_fmtcmdoutofmemory, g_dd);
|
nsh_output(vtbl, g_fmtcmdoutofmemory, g_dd);
|
||||||
return ERROR;
|
goto errout_with_paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open the input file */
|
/* Open the input file */
|
||||||
|
@ -538,7 +554,7 @@ int cmd_dd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
||||||
ret = dd_infopen(infile, &dd);
|
ret = dd_infopen(infile, &dd);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
return ret;
|
goto errout_with_paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open the output file */
|
/* Open the output file */
|
||||||
|
@ -562,6 +578,10 @@ int cmd_dd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
||||||
goto errout_with_outf;
|
goto errout_with_outf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Has the incoming data stream ended? */
|
||||||
|
|
||||||
|
if (!dd.eof)
|
||||||
|
{
|
||||||
/* Pad with zero if necessary (at the end of file only) */
|
/* Pad with zero if necessary (at the end of file only) */
|
||||||
|
|
||||||
for (i = dd.nbytes; i < dd.sectsize; i++)
|
for (i = dd.nbytes; i < dd.sectsize; i++)
|
||||||
|
@ -588,12 +608,23 @@ int cmd_dd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
||||||
|
|
||||||
dd.sector++;
|
dd.sector++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
ret = OK;
|
||||||
|
|
||||||
errout_with_outf:
|
errout_with_outf:
|
||||||
DD_INCLOSE(&dd);
|
DD_INCLOSE(&dd);
|
||||||
errout_with_inf:
|
errout_with_inf:
|
||||||
DD_OUTCLOSE(&dd);
|
DD_OUTCLOSE(&dd);
|
||||||
free(dd.buffer);
|
free(dd.buffer);
|
||||||
|
errout_with_paths:
|
||||||
|
if (infile)
|
||||||
|
{
|
||||||
|
free(infile);
|
||||||
|
}
|
||||||
|
if (outfile)
|
||||||
|
{
|
||||||
|
free(outfile);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -370,9 +370,10 @@ EXTERN int lib_flushall(FAR struct streamlist *list);
|
||||||
* subdirectory
|
* subdirectory
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Register /dev/null */
|
/* Register /dev/null and /dev/zero */
|
||||||
|
|
||||||
EXTERN void devnull_register(void);
|
EXTERN void devnull_register(void);
|
||||||
|
EXTERN void devzero_register(void);
|
||||||
|
|
||||||
/* Setup the loop device so that it exports the file referenced by 'filename'
|
/* Setup the loop device so that it exports the file referenced by 'filename'
|
||||||
* as a block device.
|
* as a block device.
|
||||||
|
@ -384,10 +385,15 @@ EXTERN int loteardown(const char *devname);
|
||||||
|
|
||||||
/* Setup so that the block driver referenced by 'blkdev' can be accessed
|
/* Setup so that the block driver referenced by 'blkdev' can be accessed
|
||||||
* similar to a character device.
|
* similar to a character device.
|
||||||
|
*
|
||||||
|
* Access via a character device:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
EXTERN int bchdev_register(const char *blkdev, const char *chardev, boolean readonly);
|
EXTERN int bchdev_register(const char *blkdev, const char *chardev, boolean readonly);
|
||||||
EXTERN int bchdev_unregister(const char *chardev);
|
EXTERN int bchdev_unregister(const char *chardev);
|
||||||
|
|
||||||
|
/* Low level, direct access: */
|
||||||
|
|
||||||
EXTERN int bchlib_setup(const char *blkdev, boolean readonly, FAR void **handle);
|
EXTERN int bchlib_setup(const char *blkdev, boolean readonly, FAR void **handle);
|
||||||
EXTERN int bchlib_teardown(FAR void *handle);
|
EXTERN int bchlib_teardown(FAR void *handle);
|
||||||
EXTERN ssize_t bchlib_read(FAR void *handle, FAR char *buffer, size_t offset, size_t len);
|
EXTERN ssize_t bchlib_read(FAR void *handle, FAR char *buffer, size_t offset, size_t len);
|
||||||
|
|
Loading…
Reference in New Issue