nshlib/dd: Add support for reading from/writing to standard input/output

Test
  1. Input from stdin and output to stdout
       Keyboard input: 12345AAAAABBBBB
    nsh> dd bs=5
    1234512345AAAAAAAAAABBBBBBBBBB

  2. Input from file and output to stdout
    nsh> dd if=/etc/init.d/rc.sysinit
    mkrd -m 2 -s 512 1024
    mkfatfs /dev/ram2
    mount -t vfat /dev/ram2 "/tmp"

  3. Input from stdin and output to file
       Keyboard input: QWERT
    dd of=/data/dd_stdout bs=5

    Then, cat the output file in host (based on HostFS):
    $ cat ./dd_stdout
    QWERT

Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
This commit is contained in:
wangjianyu3
2024-10-17 16:32:15 +08:00
committed by Xiang Xiao
parent a799c3e805
commit e5a1bb1796
2 changed files with 31 additions and 25 deletions

View File

@@ -186,7 +186,7 @@ static const struct cmdmap_s g_cmdmap[] =
#endif
#ifndef CONFIG_NSH_DISABLE_DD
CMD_MAP("dd", cmd_dd, 3, 7,
CMD_MAP("dd", cmd_dd, 1, 7,
"if=<infile> of=<outfile> [bs=<sectsize>] [count=<sectors>] "
"[skip=<sectors>] [seek=<sectors>] [verify] [conv=<nocreat,notrunc>]"),
#endif

View File

@@ -54,13 +54,6 @@
*/
#define DEFAULT_SECTSIZE 512
/* At present, piping of input and output are not support, i.e., both of=
* and if= arguments are required.
*/
#undef CAN_PIPE_FROM_STD
#define g_dd "dd"
/****************************************************************************
@@ -258,10 +251,15 @@ static int dd_verify(FAR const char *infile, FAR const char *outfile,
/****************************************************************************
* Name: cmd_dd
*
* At present, redirect of input and output are supported.
* of= and if= arguments are required only when verify enabled.
*
****************************************************************************/
int cmd_dd(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv)
{
FAR struct console_stdio_s *pstate = (FAR struct console_stdio_s *)vtbl;
struct dd_s dd;
FAR char *infile = NULL;
FAR char *outfile = NULL;
@@ -287,17 +285,13 @@ int cmd_dd(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv)
* from stdin.
*/
#ifdef CAN_PIPE_FROM_STD
dd->infd = 0; /* stdin */
#endif
dd.infd = INFD(pstate); /* stdin */
/* If no OF= option is provided on the command line, then write
* to stdout.
*/
#ifdef CAN_PIPE_FROM_STD
dd->outfd = 1; /* stdout */
#endif
dd.outfd = OUTFD(pstate); /* stdout */
/* Parse command line parameters */
@@ -354,13 +348,13 @@ int cmd_dd(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv)
}
}
#ifndef CAN_PIPE_FROM_STD
if (infile == NULL || outfile == NULL)
/* If verify enabled, infile and outfile are mandatory */
if ((dd.oflags & O_RDONLY) && (infile == NULL || outfile == NULL))
{
nsh_error(vtbl, g_fmtargrequired, g_dd);
goto errout_with_paths;
}
#endif
/* Allocate the I/O buffer */
@@ -373,18 +367,24 @@ int cmd_dd(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv)
/* Open the input file */
ret = dd_infopen(infile, &dd);
if (ret < 0)
if (infile)
{
goto errout_with_alloc;
ret = dd_infopen(infile, &dd);
if (ret < 0)
{
goto errout_with_alloc;
}
}
/* Open the output file */
ret = dd_outfopen(outfile, &dd);
if (ret < 0)
if (outfile)
{
goto errout_with_inf;
ret = dd_outfopen(outfile, &dd);
if (ret < 0)
{
goto errout_with_inf;
}
}
/* Then perform the data transfer */
@@ -467,10 +467,16 @@ int cmd_dd(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv)
}
errout_with_outf:
close(dd.outfd);
if (outfile)
{
close(dd.outfd);
}
errout_with_inf:
close(dd.infd);
if (infile)
{
close(dd.infd);
}
errout_with_alloc:
free(dd.buffer);