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 #endif
#ifndef CONFIG_NSH_DISABLE_DD #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>] " "if=<infile> of=<outfile> [bs=<sectsize>] [count=<sectors>] "
"[skip=<sectors>] [seek=<sectors>] [verify] [conv=<nocreat,notrunc>]"), "[skip=<sectors>] [seek=<sectors>] [verify] [conv=<nocreat,notrunc>]"),
#endif #endif

View File

@@ -54,13 +54,6 @@
*/ */
#define DEFAULT_SECTSIZE 512 #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" #define g_dd "dd"
/**************************************************************************** /****************************************************************************
@@ -258,10 +251,15 @@ static int dd_verify(FAR const char *infile, FAR const char *outfile,
/**************************************************************************** /****************************************************************************
* Name: cmd_dd * 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) 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; struct dd_s dd;
FAR char *infile = NULL; FAR char *infile = NULL;
FAR char *outfile = 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. * from stdin.
*/ */
#ifdef CAN_PIPE_FROM_STD dd.infd = INFD(pstate); /* stdin */
dd->infd = 0; /* stdin */
#endif
/* If no OF= option is provided on the command line, then write /* If no OF= option is provided on the command line, then write
* to stdout. * to stdout.
*/ */
#ifdef CAN_PIPE_FROM_STD dd.outfd = OUTFD(pstate); /* stdout */
dd->outfd = 1; /* stdout */
#endif
/* Parse command line parameters */ /* 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 verify enabled, infile and outfile are mandatory */
if (infile == NULL || outfile == NULL)
if ((dd.oflags & O_RDONLY) && (infile == NULL || outfile == NULL))
{ {
nsh_error(vtbl, g_fmtargrequired, g_dd); nsh_error(vtbl, g_fmtargrequired, g_dd);
goto errout_with_paths; goto errout_with_paths;
} }
#endif
/* Allocate the I/O buffer */ /* 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 */ /* Open the input file */
ret = dd_infopen(infile, &dd); if (infile)
if (ret < 0)
{ {
goto errout_with_alloc; ret = dd_infopen(infile, &dd);
if (ret < 0)
{
goto errout_with_alloc;
}
} }
/* Open the output file */ /* Open the output file */
ret = dd_outfopen(outfile, &dd); if (outfile)
if (ret < 0)
{ {
goto errout_with_inf; ret = dd_outfopen(outfile, &dd);
if (ret < 0)
{
goto errout_with_inf;
}
} }
/* Then perform the data transfer */ /* 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: errout_with_outf:
close(dd.outfd); if (outfile)
{
close(dd.outfd);
}
errout_with_inf: errout_with_inf:
close(dd.infd); if (infile)
{
close(dd.infd);
}
errout_with_alloc: errout_with_alloc:
free(dd.buffer); free(dd.buffer);