On Mon, Oct 20, 2014 at 2:56 PM, Bartosz Golaszewski
<[email protected]> wrote:
> +#if ENABLE_FEATURE_USE_SENDFILE
> +#include <sys/sendfile.h>
> +#endif
> +
> +/*
> + * Returns 1 if all bytes have been copied, 0 otherwise.
> + */
> +static int check_status(int *status, off_t *size, off_t *total, ssize_t rd)
> +{
> +       *total += rd;
> +       if (*status < 0) { /* if we aren't copying till EOF... */
> +               *size -= rd;
> +               if (!(*size)) {
> +                       /* 'size' bytes copied - all done */
> +                       *status = 0;
> +                       return 1;
> +               }
> +       }
> +
> +       return 0;
> +}
> +
>  /* Used by NOFORK applets (e.g. cat) - must not use xmalloc.
>   * size < 0 means "ignore write errors", used by tar --to-command
>   * size = 0 means "copy till EOF"
> @@ -18,6 +40,7 @@ static off_t bb_full_fd_action(int src_fd, int dst_fd, 
> off_t size)
>         int status = -1;
>         off_t total = 0;
>         bool continue_on_write_error = 0;
> +       ssize_t rd;
>  #if CONFIG_FEATURE_COPYBUF_KB <= 4
>         char buffer[CONFIG_FEATURE_COPYBUF_KB * 1024];
>         enum { buffer_size = sizeof(buffer) };
> @@ -56,10 +79,29 @@ static off_t bb_full_fd_action(int src_fd, int dst_fd, 
> off_t size)
>                 status = 1; /* copy until eof */
>         }
>
> -       while (1) {
> -               ssize_t rd;
> +#if ENABLE_FEATURE_USE_SENDFILE
> +       {
> +               ssize_t sz = size && (size < buffer_size)
> +                               ? size : MAXINT(ssize_t) - 0xffff;
>
> -               rd = safe_read(src_fd, buffer, size > buffer_size ? 
> buffer_size : size);
> +               while (1) {
> +                       rd = sendfile(dst_fd, src_fd, NULL, sz);
> +                       if (rd <= 0) {
> +                               /* Might be EOF, might be an error,
> +                                * to make sure fall back to the read-write
> +                                * loop.
> +                                */
> +                               break;
> +                       } else if (check_status(&status, &size, &total, rd)) {
> +                               break;
> +                       }
> +               }
> +       }

Looks like it will always allocate the copy buffer,
and always attempt the final read, even if sendfile worked perfectly.
Can this be avoided?
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to