2007/10/3, Kazuo TAKADA <[EMAIL PROTECTED]>:
>
> Hi,
>
> If the dd command fails in a sequence of copying, it always returns
> EXIT_SUCCESS.  So, I can't judge whether the command had succeeded or
> failed.
>
> Its behavior doesn't conform to POSIX.
>
>   POSIX 1003.1:
>   http://www.opengroup.org/onlinepubs/009695399/utilities/dd.html
>   | EXIT STATUS
>   | The following exit values shall be returned:
>   |
>   |  0
>   |     The input file was copied successfully.
>   | >0
>   |     An error occurred.
>
> For example, copy some data to a small size device repeatly.
>
> --------------------------------------------------
> (with a root account)
> # ./busybox dd if=/dev/zero of=/dev/ram
> dd: writing '/dev/ram': No space left on device
> 32769+0 records in
> 32768+0 records out
> # echo $?
> 0                       <= should be failed!!
>
> # ./busybox dd if=/dev/zero of=/dev/ram count=1
> 1+0 records in
> 1+0 records out
> # echo $?
> 0
>
> # /bin/dd if=/dev/zero of=/dev/ram      <= GNU's one
> dd: writing to `/dev/ram': No space left on device
> 32769+0 records in
> 32768+0 records out
> # echo $?
> 1
> --------------------------------------------------
>
> The old busybox-1.2.2.1 returns EXIT_FAILURE.  It is the version that
> dd had not reconstructed yet.
>
> Can you accept the patch below?
> write_and_stats() is the function which returns a bool value.
>
> ----------------------------------------------------------------------
> --- coreutils/dd.c.orig 2007-09-03 20:48:39.000000000 +0900
> +++ coreutils/dd.c      2007-10-03 10:31:50.000000000 +0900
> @@ -106,7 +106,7 @@
> #endif
>         };
>         size_t ibs = 512, obs = 512;
> -       ssize_t n, w;
> +       ssize_t n, w = 0;
>         char *ibuf, *obuf;
>         /* And these are all zeroed at once! */
>         struct {
> @@ -303,13 +303,17 @@
>                                 tmp += d;
>                                 oc += d;
>                                 if (oc == obs) {
> -                                       if (write_and_stats(ofd, obuf,
> obs, obs, outfile))
> +                                       if (write_and_stats(ofd, obuf,
> obs, obs, outfile)) {
> +                                               w = -1;
>                                                 goto out_status;
> +                                       }
>                                         oc = 0;
>                                 }
>                         }
> -               } else if (write_and_stats(ofd, ibuf, n, obs, outfile))
> +               } else if (write_and_stats(ofd, ibuf, n, obs, outfile)) {
> +                       w = -1;
>                         goto out_status;
> +               }
>         }
>
>         if (ENABLE_FEATURE_DD_IBS_OBS && oc) {
> @@ -330,5 +334,5 @@
>   out_status:
>         dd_output_status(0);
>
> -       return EXIT_SUCCESS;
> +       return (w >= 0 ? EXIT_SUCCESS : EXIT_FAILURE);
> }
> ----------------------------------------------------------------------


    It may be faster to do

if ((w = write_and_stats(...)))
  goto out_status;

  and

return w;

  because write_and_stats returns 1 on failure. You can even tweak
  it to return either EXIT_SUCCESS or EXIT_FAILURE and change the
  if to:

if ((w = write_and_stats(...)) == EXIT_SUCCESS)
  goto out_status;

  (which is the same but symbolically different).

     Loïc
_______________________________________________
busybox mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/busybox

Reply via email to