[U-Boot] [PATCH] tools: mkimage can read input on /dev/stdin

Julien Castets castets.j at gmail.com
Fri Sep 26 21:33:50 CEST 2014


Hi,

I would like to give /dev/stdin to the flag -d of mkimage. The only
thing that prevent doing it is the function copy_file of mkimage.c,
which:
- calls stat(2) on the file to get the input file size
- calls mmap(2) with this size as length

When the file is a pipe, its size is set to 0 and mmap(2) fails.

This patch replaces the use of mmap(2) with read(2). If accepted, I
could give a look to accept /dev/stdout as output file (which is
currently also required to be a file).

>From e107bdc73ee7b2159956cfc753328f9f03c058e8 Mon Sep 17 00:00:00 2001
From: Julien Castets <castets.j at gmail.com>
Date: Fri, 26 Sep 2014 11:28:49 +0200
Subject: [PATCH] tools: mkimage can read input on /dev/stdin

Use a sequential read(2) instead of a mmap(2) in copy_file.

Signed-off-by: Julien Castets <castets.j at gmail.com>
---
 tools/mkimage.c |   64 +++++++++++++++++++++++++++----------------------------
 1 file changed, 31 insertions(+), 33 deletions(-)

diff --git a/tools/mkimage.c b/tools/mkimage.c
index c70408c..bb35110 100644
--- a/tools/mkimage.c
+++ b/tools/mkimage.c
@@ -522,14 +522,14 @@ static void
 copy_file (int ifd, const char *datafile, int pad)
 {
     int dfd;
-    struct stat sbuf;
-    unsigned char *ptr;
     int tail;
     int zero = 0;
     uint8_t zeros[4096];
-    int offset = 0;
-    int size;
     struct image_type_params *tparams = mkimage_get_type (params.type);
+    unsigned char buf[4096];
+    ssize_t nbytes;
+    ssize_t i;
+    ssize_t size = 0;

     if (pad >= sizeof(zeros)) {
         fprintf(stderr, "%s: Can't pad to %d\n",
@@ -549,63 +549,62 @@ copy_file (int ifd, const char *datafile, int pad)
         exit (EXIT_FAILURE);
     }

-    if (fstat(dfd, &sbuf) < 0) {
-        fprintf (stderr, "%s: Can't stat %s: %s\n",
-            params.cmdname, datafile, strerror(errno));
-        exit (EXIT_FAILURE);
-    }
-
-    ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, dfd, 0);
-    if (ptr == MAP_FAILED) {
-        fprintf (stderr, "%s: Can't read %s: %s\n",
-            params.cmdname, datafile, strerror(errno));
-        exit (EXIT_FAILURE);
-    }
-
     if (params.xflag) {
-        unsigned char *p = NULL;
         /*
          * XIP: do not append the image_header_t at the
          * beginning of the file, but consume the space
          * reserved for it.
          */
+        nbytes = read(dfd, buf, tparams->header_size);
+        if (nbytes == -1) {
+            fprintf (stderr, "%s: Can't read XIP header of %s: %s\n",
+                 params.cmdname, datafile, strerror(errno));
+            exit (EXIT_FAILURE);
+        }

-        if ((unsigned)sbuf.st_size < tparams->header_size) {
+        if (nbytes < tparams->header_size) {
             fprintf (stderr,
                 "%s: Bad size: \"%s\" is too small for XIP\n",
                 params.cmdname, datafile);
             exit (EXIT_FAILURE);
         }

-        for (p = ptr; p < ptr + tparams->header_size; p++) {
-            if ( *p != 0xff ) {
+        for (i = 0; i < nbytes; ++i) {
+            if (buf[i] != 0xff) {
                 fprintf (stderr,
                     "%s: Bad file: \"%s\" has invalid buffer for XIP\n",
                     params.cmdname, datafile);
                 exit (EXIT_FAILURE);
             }
         }
+    }

-        offset = tparams->header_size;
+    while ((nbytes = read(dfd, buf, sizeof(buf))) > 0) {
+        if (write(ifd, buf, nbytes) != nbytes) {
+            fprintf (stderr, "%s: Write error on %s: %s\n",
+                 params.cmdname, params.imagefile, strerror(errno));
+            exit (EXIT_FAILURE);
+        }
+        size += nbytes;
     }

-    size = sbuf.st_size - offset;
-    if (write(ifd, ptr + offset, size) != size) {
-        fprintf (stderr, "%s: Write error on %s: %s\n",
-            params.cmdname, params.imagefile, strerror(errno));
-        exit (EXIT_FAILURE);
+    if (nbytes == -1) {
+        fprintf (stderr, "%s: Read error on %s: %s\n",
+             params.cmdname, params.imagefile, strerror(errno));
+             exit (EXIT_FAILURE);
     }

     tail = size % 4;
     if ((pad == 1) && (tail != 0)) {
-
-        if (write(ifd, (char *)&zero, 4-tail) != 4-tail) {
+        if (write(ifd, (char *)&zero, 4 - tail) != 4 - tail) {
             fprintf (stderr, "%s: Write error on %s: %s\n",
-                params.cmdname, params.imagefile,
-                strerror(errno));
+                 params.cmdname, params.imagefile,
+                 strerror(errno));
             exit (EXIT_FAILURE);
         }
-    } else if (pad > 1) {
+    }
+
+    else if (pad > 1) {
         if (write(ifd, (char *)&zeros, pad) != pad) {
             fprintf(stderr, "%s: Write error on %s: %s\n",
                 params.cmdname, params.imagefile,
@@ -614,7 +613,6 @@ copy_file (int ifd, const char *datafile, int pad)
         }
     }

-    (void) munmap((void *)ptr, sbuf.st_size);
     (void) close (dfd);
 }

-- 
1.7.9.5



-- 
Julien Castets


More information about the U-Boot mailing list