{"id":200,"url":"http://patchwork.ozlabs.org/api/1.1/patches/200/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-mtd/patch/1220848159-22407-1-git-send-email-gerickson@nuovations.com/","project":{"id":3,"url":"http://patchwork.ozlabs.org/api/1.1/projects/3/?format=json","name":"Linux MTD development","link_name":"linux-mtd","list_id":"linux-mtd.lists.infradead.org","list_email":"linux-mtd@lists.infradead.org","web_url":null,"scm_url":null,"webscm_url":null},"msgid":"<1220848159-22407-1-git-send-email-gerickson@nuovations.com>","date":"2008-09-08T04:29:19","name":"nandwrite: Add Support for Reading from Standard Input","commit_ref":"2d0b9f58998c54dd114ff5c4476d10cc03a21864","pull_url":null,"state":"accepted","archived":false,"hash":"b1b472a5869146c9ec131cd2e8164758ab71c997","submitter":{"id":115,"url":"http://patchwork.ozlabs.org/api/1.1/people/115/?format=json","name":"Grant Erickson","email":"gerickson@nuovations.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/linux-mtd/patch/1220848159-22407-1-git-send-email-gerickson@nuovations.com/mbox/","series":[],"comments":"http://patchwork.ozlabs.org/api/patches/200/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/200/checks/","tags":{},"headers":{"Return-Path":"<linux-mtd-bounces+patchwork=ozlabs.org@lists.infradead.org>","X-Original-To":"patchwork@ozlabs.org","Delivered-To":"patchwork@ozlabs.org","Received":["from bombadil.infradead.org (bombadil.infradead.org [18.85.46.34])\n\t(using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))\n\t(Client did not present a certificate)\n\tby ozlabs.org (Postfix) with ESMTPS id D3E77DDDED\n\tfor <patchwork@ozlabs.org>; Mon,  8 Sep 2008 14:29:30 +1000 (EST)","from localhost ([127.0.0.1] helo=bombadil.infradead.org)\n\tby bombadil.infradead.org with esmtp (Exim 4.68 #1 (Red Hat Linux))\n\tid 1KcYNQ-0003X3-QY; Mon, 08 Sep 2008 04:29:24 +0000","from relay02.pair.com ([209.68.5.16])\n\tby bombadil.infradead.org with smtp (Exim 4.68 #1 (Red Hat Linux))\n\tid 1KcYNO-0003Oc-Mv\n\tfor linux-mtd@lists.infradead.org; Mon, 08 Sep 2008 04:29:23 +0000","(qmail 64434 invoked by uid 0); 8 Sep 2008 04:29:20 -0000","from unknown (HELO localhost.localdomain) (unknown)\n\tby unknown with SMTP; 8 Sep 2008 04:29:20 -0000"],"X-pair-Authenticated":"66.134.71.115","From":"Grant Erickson <gerickson@nuovations.com>","To":"linux-mtd@lists.infradead.org","Subject":"[PATCH 6/6] [MTD-UTILS] nandwrite: Add Support for Reading from\n\tStandard Input","Date":"Sun,  7 Sep 2008 21:29:19 -0700","Message-Id":"<1220848159-22407-1-git-send-email-gerickson@nuovations.com>","X-Mailer":"git-send-email 1.6.0.1","Organization":"Nuovation System Designs, LLC","X-Spam-Score":"0.0 (/)","Cc":"Tommi Airikka <tommi.airikka@ericsson.com>,\n\tRichard Titmuss <titmuss@slimdevices.com>","X-BeenThere":"linux-mtd@lists.infradead.org","X-Mailman-Version":"2.1.9","Precedence":"list","List-Id":"Linux MTD discussion mailing list <linux-mtd.lists.infradead.org>","List-Unsubscribe":"<http://lists.infradead.org/mailman/listinfo/linux-mtd>,\n\t<mailto:linux-mtd-request@lists.infradead.org?subject=unsubscribe>","List-Archive":"<http://lists.infradead.org/pipermail/linux-mtd>","List-Post":"<mailto:linux-mtd@lists.infradead.org>","List-Help":"<mailto:linux-mtd-request@lists.infradead.org?subject=help>","List-Subscribe":"<http://lists.infradead.org/mailman/listinfo/linux-mtd>,\n\t<mailto:linux-mtd-request@lists.infradead.org?subject=subscribe>","MIME-Version":"1.0","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Sender":"linux-mtd-bounces@lists.infradead.org","Errors-To":"linux-mtd-bounces+patchwork=ozlabs.org@lists.infradead.org"},"content":"Added suppport for reading in band data from standard input based on a\npatch originally generated by Richard Titmuss <titmuss@slimdevices.com>\nat <http://lists.slimdevices.com/pipermail/jive-checkins/2008-May/001918.html>.\n\nSigned-off-by: Grant Erickson <gerickson@nuovations.com>","diff":"diff --git a/nandwrite.c b/nandwrite.c\nindex b7cd72e..fc23e85 100644\n--- a/nandwrite.c\n+++ b/nandwrite.c\n@@ -24,6 +24,8 @@\n #include <errno.h>\n #include <fcntl.h>\n #include <stdbool.h>\n+#include <stddef.h>\n+#include <stdint.h>\n #include <stdio.h>\n #include <stdlib.h>\n #include <string.h>\n@@ -74,7 +76,7 @@ static struct nand_oobinfo autoplace_oobinfo = {\n static void display_help (void)\n {\n \tprintf(\n-\"Usage: nandwrite [OPTION] MTD_DEVICE INPUTFILE\\n\"\n+\"Usage: nandwrite [OPTION] MTD_DEVICE [INPUTFILE|-]\\n\"\n \"Writes to the specified MTD device.\\n\"\n \"\\n\"\n \"  -a, --autoplace         Use auto oob layout\\n\"\n@@ -110,6 +112,7 @@ static void display_version (void)\n \texit (EXIT_SUCCESS);\n }\n \n+static const char\t*standard_input = \"-\";\n static const char\t*mtd_device, *img;\n static int\t\tmtdoffset = 0;\n static bool\t\tquiet = false;\n@@ -198,16 +201,46 @@ static void process_options (int argc, char * const argv[])\n \t\t\t\tblockalign = atoi (optarg);\n \t\t\t\tbreak;\n \t\t\tcase '?':\n-\t\t\t\terror = 1;\n+\t\t\t\terror++;\n \t\t\t\tbreak;\n \t\t}\n \t}\n \n-\tif ((argc - optind) != 2 || error)\n+\tif (mtdoffset < 0) {\n+\t\tfprintf(stderr, \"Can't specify a negative device offset `%d'\\n\",\n+\t\t\t\tmtdoffset);\n+\t\texit (EXIT_FAILURE);\n+\t}\n+\n+\targc -= optind;\n+\targv += optind;\n+\n+\t/*\n+\t * There must be at least the MTD device node positional\n+\t * argument remaining and, optionally, the input file.\n+\t */\n+\n+\tif (argc < 1 || argc > 2 || error)\n \t\tdisplay_help ();\n \n-\tmtd_device = argv[optind++];\n-\timg = argv[optind];\n+\tmtd_device = argv[0];\n+\n+\t/*\n+\t * Standard input may be specified either explictly as \"-\" or\n+\t * implicity by simply omitting the second of the two\n+\t * positional arguments.\n+\t */\n+\n+\timg = ((argc == 2) ? argv[1] : standard_input);\n+}\n+\n+static void erase_buffer(void *buffer, size_t size)\n+{\n+\tconst uint8_t kEraseByte = 0xff;\n+\n+\tif (buffer != NULL && size > 0) {\n+\t\tmemset(buffer, kEraseByte, size);\n+\t}\n }\n \n /*\n@@ -215,8 +248,12 @@ static void process_options (int argc, char * const argv[])\n  */\n int main(int argc, char * const argv[])\n {\n-\tint cnt, fd, ifd, imglen = 0, pagelen, blockstart = -1;\n+\tint cnt = 0;\n+\tint fd = -1;\n+\tint ifd = -1;\n+\tint imglen = 0, pagelen;\n \tbool baderaseblock = false;\n+\tint blockstart = -1;\n \tstruct mtd_info_user meminfo;\n \tstruct mtd_oob_buf oob;\n \tloff_t offs;\n@@ -226,7 +263,7 @@ int main(int argc, char * const argv[])\n \n \tprocess_options(argc, argv);\n \n-\tmemset(oobbuf, 0xff, sizeof(oobbuf));\n+\terase_buffer(oobbuf, sizeof(oobbuf));\n \n \tif (pad && writeoob) {\n \t\tfprintf(stderr, \"Can't pad when oob data is present.\\n\");\n@@ -340,21 +377,48 @@ int main(int argc, char * const argv[])\n \toob.length = meminfo.oobsize;\n \toob.ptr = noecc ? oobreadbuf : oobbuf;\n \n-\t/* Open the input file */\n-\tif ((ifd = open(img, O_RDONLY)) == -1) {\n+\t/* Determine if we are reading from standard input or from a file. */\n+\tif (strcmp(img, standard_input) == 0) {\n+\t\tifd = STDIN_FILENO;\n+\t} else {\n+\t\tifd = open(img, O_RDONLY);\n+\t}\n+\n+\tif (ifd == -1) {\n \t\tperror(img);\n \t\tgoto restoreoob;\n \t}\n \n-\t// get image length\n-\timglen = lseek(ifd, 0, SEEK_END);\n-\tlseek (ifd, 0, SEEK_SET);\n+\t/* For now, don't allow writing oob when reading from standard input. */\n+\tif (ifd == STDIN_FILENO && writeoob) {\n+\t\tfprintf(stderr, \"Can't write oob when reading from standard input.\\n\");\n+\t\tgoto closeall;\n+\t}\n \n \tpagelen = meminfo.writesize + ((writeoob) ? meminfo.oobsize : 0);\n \n-\t// Check, if file is pagealigned\n+\t/*\n+\t * For the standard input case, the input size is merely an\n+\t * invariant placeholder and is set to the write page\n+\t * size. Otherwise, just use the input file size.\n+\t *\n+\t * TODO: Add support for the -l,--length=length option (see\n+\t * previous discussion by Tommi Airikka <tommi.airikka@ericsson.com> at\n+\t * <http://lists.infradead.org/pipermail/linux-mtd/2008-September/\n+\t * 022913.html>\n+\t */\n+\n+\tif (ifd == STDIN_FILENO) {\n+\t    imglen = pagelen;\n+\t} else {\n+\t    imglen = lseek(ifd, 0, SEEK_END);\n+\t    lseek (ifd, 0, SEEK_SET);\n+\t}\n+\n+\t// Check, if file is page-aligned\n \tif ((!pad) && ((imglen % pagelen) != 0)) {\n-\t\tfprintf (stderr, \"Input file is not page aligned\\n\");\n+\t\tfprintf (stderr, \"Input file is not page-aligned. Use the padding \"\n+\t\t\t\t \"option.\\n\");\n \t\tgoto closeall;\n \t}\n \n@@ -366,7 +430,13 @@ int main(int argc, char * const argv[])\n \t\tgoto closeall;\n \t}\n \n-\t/* Get data from input and write to the device */\n+\t/*\n+\t * Get data from input and write to the device while there is\n+\t * still input to read and we are still within the device\n+\t * bounds. Note that in the case of standard input, the input\n+\t * length is simply a quasi-boolean flag whose values are page\n+\t * length or zero.\n+\t */\n \twhile (imglen && (mtdoffset < meminfo.size)) {\n \t\t// new eraseblock , check for bad block(s)\n \t\t// Stay in the loop to be sure if the mtdoffset changes because\n@@ -379,7 +449,8 @@ int main(int argc, char * const argv[])\n \t\t\toffs = blockstart;\n \t\t\tbaderaseblock = false;\n \t\t\tif (!quiet)\n-\t\t\t\tfprintf (stdout, \"Writing data to block %x\\n\", blockstart);\n+\t\t\t\tfprintf (stdout, \"Writing data to block %d at offset 0x%x\\n\",\n+\t\t\t\t\t\t blockstart / meminfo.erasesize, blockstart);\n \n \t\t\t/* Check all the blocks in an erase block for bad blocks */\n \t\t\tdo {\n@@ -404,18 +475,50 @@ int main(int argc, char * const argv[])\n \t\t}\n \n \t\treadlen = meminfo.writesize;\n-\t\tif (pad && (imglen < readlen))\n-\t\t{\n-\t\t\treadlen = imglen;\n-\t\t\tmemset(writebuf + readlen, 0xff, meminfo.writesize - readlen);\n-\t\t}\n \n-\t\t/* Read Page Data from input file */\n-\t\tif ((cnt = read(ifd, writebuf, readlen)) != readlen) {\n-\t\t\tif (cnt == 0)\t// EOF\n+\t\tif (ifd != STDIN_FILENO) {\n+\t\t\tif (pad && (imglen < readlen))\n+\t\t\t{\n+\t\t\t\treadlen = imglen;\n+\t\t\t\terase_buffer(writebuf + readlen, meminfo.writesize - readlen);\n+\t\t\t}\n+\n+\t\t\t/* Read Page Data from input file */\n+\t\t\tif ((cnt = read(ifd, writebuf, readlen)) != readlen) {\n+\t\t\t\tif (cnt == 0)\t// EOF\n+\t\t\t\t\tbreak;\n+\t\t\t\tperror (\"File I/O error on input file\");\n+\t\t\t\tgoto closeall;\n+\t\t\t}\n+\t\t} else {\n+\t\t\tint tinycnt = 0;\n+\n+\t\t\twhile(tinycnt < readlen) {\n+\t\t\t\tcnt = read(ifd, writebuf + tinycnt, readlen - tinycnt);\n+\t\t\t\tif (cnt == 0) { // EOF\n+\t\t\t\t\tbreak;\n+\t\t\t\t} else if (cnt < 0) {\n+\t\t\t\t\tperror (\"File I/O error on stdin\");\n+\t\t\t\t\tgoto closeall;\n+\t\t\t\t}\n+\t\t\t\ttinycnt += cnt;\n+\t\t\t}\n+\n+\t\t\t/* No padding needed - we are done */\n+\t\t\tif (tinycnt == 0) {\n+\t\t\t\timglen = 0;\n \t\t\t\tbreak;\n-\t\t\tperror (\"File I/O error on input file\");\n-\t\t\tgoto closeall;\n+\t\t\t}\n+\n+\t\t\t/* No more bytes - we are done after writing the remaining bytes */\n+\t\t\tif (cnt == 0) {\n+\t\t\t\timglen = 0;\n+\t\t\t}\n+\n+\t\t\t/* Padding */\n+\t\t\tif (pad && (tinycnt < readlen)) {\n+\t\t\t\terase_buffer(writebuf + tinycnt, meminfo.writesize - tinycnt);\n+\t\t\t}\n \t\t}\n \n \t\tif (writeoob) {\n@@ -499,7 +602,9 @@ int main(int argc, char * const argv[])\n \n \t\t\tcontinue;\n \t\t}\n-\t\timglen -= readlen;\n+\t\tif (ifd != STDIN_FILENO) {\n+\t\t\timglen -= readlen;\n+\t\t}\n \t\tmtdoffset += meminfo.writesize;\n \t}\n \n@@ -517,7 +622,7 @@ restoreoob:\n \n \tclose(fd);\n \n-\tif (imglen > 0) {\n+\tif ((ifd != STDIN_FILENO) && (imglen > 0)) {\n \t\tperror (\"Data was only partially written due to error\\n\");\n \t\texit (EXIT_FAILURE);\n \t}\n","prefixes":[]}