--- embedaddon/libiconv/src/iconv.c 2012/02/21 22:57:48 1.1 +++ embedaddon/libiconv/src/iconv.c 2021/03/17 13:38:46 1.1.1.3 @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2009 Free Software Foundation, Inc. +/* Copyright (C) 2000-2009, 2011-2012, 2016-2019 Free Software Foundation, Inc. This file is part of the GNU LIBICONV Library. This program is free software: you can redistribute it and/or modify @@ -12,7 +12,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program. If not, see . */ + along with this program. If not, see . */ #include "config.h" #ifndef ICONV_CONST @@ -38,6 +38,7 @@ #include "binary-io.h" #include "progname.h" #include "relocatable.h" +#include "safe-read.h" #include "xalloc.h" #include "uniwidth.h" #include "uniwidth/cjk.h" @@ -106,7 +107,7 @@ static void usage (int exitcode) Align it correctly against the first line. */ _("or: iconv -l"); fprintf(stderr, "%s\n%s\n", helpstring1, helpstring2); - fprintf(stderr, _("Try `%s --help' for more information.\n"), program_name); + fprintf(stderr, _("Try '%s --help' for more information.\n"), program_name); } else { /* xgettext: no-wrap */ /* TRANSLATORS: The first line of the long usage message. @@ -190,10 +191,10 @@ static void print_version (void) { printf("iconv (GNU libiconv %d.%d)\n", _libiconv_version >> 8, _libiconv_version & 0xff); - printf("Copyright (C) %s Free Software Foundation, Inc.\n", "2000-2009"); + printf("Copyright (C) %s Free Software Foundation, Inc.\n", "2000-2019"); /* xgettext: no-wrap */ fputs (_("\ -License GPLv3+: GNU GPL version 3 or later \n\ +License GPLv3+: GNU GPL version 3 or later \n\ This is free software: you are free to change and redistribute it.\n\ There is NO WARRANTY, to the extent permitted by law.\n\ "),stdout); @@ -667,23 +668,29 @@ static void conversion_error_other (int errnum, const /* Convert the input given in infile. */ -static int convert (iconv_t cd, FILE* infile, const char* infilename) +static int convert (iconv_t cd, int infile, const char* infilename) { char inbuf[4096+4096]; size_t inbufrest = 0; + int infile_error = 0; char initial_outbuf[4096]; char *outbuf = initial_outbuf; size_t outbufsize = sizeof(initial_outbuf); int status = 0; #if O_BINARY - SET_BINARY(fileno(infile)); + SET_BINARY(infile); #endif line = 1; column = 0; iconv(cd,NULL,NULL,NULL,NULL); for (;;) { - size_t inbufsize = fread(inbuf+4096,1,4096,infile); - if (inbufsize == 0) { + size_t inbufsize; + /* Transfer the accumulated output to its destination, in case the + safe_read() call will block. */ + fflush(stdout); + inbufsize = safe_read(infile,inbuf+4096,4096); + if (inbufsize == 0 || inbufsize == SAFE_READ_ERROR) { + infile_error = (inbufsize == SAFE_READ_ERROR ? errno : 0); if (inbufrest == 0) break; else { @@ -809,11 +816,11 @@ static int convert (iconv_t cd, FILE* infile, const ch } else break; } - if (ferror(infile)) { + if (infile_error) { fflush(stdout); if (column > 0) putc('\n',stderr); - error(0,0, + error(0,infile_error, /* TRANSLATORS: An error message. The placeholder expands to the input file name. */ _("%s: I/O error"), @@ -854,6 +861,15 @@ int main (int argc, char* argv[]) bindtextdomain("libiconv",relocate(LOCALEDIR)); #endif textdomain("libiconv"); + /* No need to invoke the gnulib function stdopen() here, because + (1) the only file descriptor allocations done by this program are + fopen(...,"r"), + (2) when such fopen() calls occur, stdin is not used, + hence + - when an fopen() call happens to open fd 0, it is harmless, by (2), + - when an fopen() call happens to open fd 1 or 2, writing to + stdout or stderr will produce an error, by (1). */ + for (i = 1; i < argc;) { size_t len = strlen(argv[i]); if (!strcmp(argv[i],"--")) { @@ -952,6 +968,7 @@ int main (int argc, char* argv[]) if /* --s ... --silent */ (len >= 3 && len <= 8 && !strncmp(argv[i],"--silent",len)) { silent = 1; + i++; continue; } if /* --h ... --help */ @@ -1076,7 +1093,7 @@ int main (int argc, char* argv[]) hooks.data = NULL; iconvctl(cd, ICONV_SET_HOOKS, &hooks); if (i == argc) - status = convert(cd,stdin, + status = convert(cd,fileno(stdin), /* TRANSLATORS: A filename substitute denoting standard input. */ _("(stdin)")); else { @@ -1094,7 +1111,7 @@ int main (int argc, char* argv[]) infilename); status = 1; } else { - status |= convert(cd,infile,infilename); + status |= convert(cd,fileno(infile),infilename); fclose(infile); } }