Skip to content

Commit b918f35

Browse files
committed
Fix interactive behaviour of iconv program.
1 parent 93c428b commit b918f35

File tree

4 files changed

+25
-9
lines changed

4 files changed

+25
-9
lines changed

ChangeLog

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
2011-07-03 Bruno Haible <bruno@clisp.org>
2+
3+
Fix interactive behaviour of iconv program.
4+
* Makefile.devel (GNULIB_MODULES): Add safe-read.
5+
* src/iconv.c: Include safe-read.h.
6+
(convert): Take the infile as a file descriptor, not as a FILE stream.
7+
Use safe_read() instead of fread().
8+
(main): Update.
9+
Reported by Xavier Pucel <xpucel@hotmail.com>.
10+
111
2011-05-02 Bruno Haible <bruno@clisp.org>
212

313
Update after gnulib changed.

Makefile.devel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ GNULIB_MODULES = \
7373
memmove \
7474
progname \
7575
relocatable-prog \
76+
safe-read \
7677
sigpipe \
7778
stdio \
7879
stdlib \

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
* The 'iconv' program now produces its output as soon as it can. It no longer
2+
unnecessarily waits for more input.
13
* Updated the BIG5-HKSCS converter. The old BIG5-HKSCS converter is renamed to
24
BIG5-HKSCS:2004. A new converter BIG5-HKSCS:2008 is added. BIG5-HKSCS is now
35
an alias for BIG5-HKSCS:2008.

src/iconv.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (C) 2000-2009 Free Software Foundation, Inc.
1+
/* Copyright (C) 2000-2009, 2011 Free Software Foundation, Inc.
22
This file is part of the GNU LIBICONV Library.
33
44
This program is free software: you can redistribute it and/or modify
@@ -38,6 +38,7 @@
3838
#include "binary-io.h"
3939
#include "progname.h"
4040
#include "relocatable.h"
41+
#include "safe-read.h"
4142
#include "xalloc.h"
4243
#include "uniwidth.h"
4344
#include "uniwidth/cjk.h"
@@ -667,23 +668,25 @@ static void conversion_error_other (int errnum, const char* infilename)
667668

668669
/* Convert the input given in infile. */
669670

670-
static int convert (iconv_t cd, FILE* infile, const char* infilename)
671+
static int convert (iconv_t cd, int infile, const char* infilename)
671672
{
672673
char inbuf[4096+4096];
673674
size_t inbufrest = 0;
675+
int infile_error = 0;
674676
char initial_outbuf[4096];
675677
char *outbuf = initial_outbuf;
676678
size_t outbufsize = sizeof(initial_outbuf);
677679
int status = 0;
678680

679681
#if O_BINARY
680-
SET_BINARY(fileno(infile));
682+
SET_BINARY(infile);
681683
#endif
682684
line = 1; column = 0;
683685
iconv(cd,NULL,NULL,NULL,NULL);
684686
for (;;) {
685-
size_t inbufsize = fread(inbuf+4096,1,4096,infile);
686-
if (inbufsize == 0) {
687+
size_t inbufsize = safe_read(infile,inbuf+4096,4096);
688+
if (inbufsize == 0 || inbufsize == SAFE_READ_ERROR) {
689+
infile_error = (inbufsize == SAFE_READ_ERROR ? errno : 0);
687690
if (inbufrest == 0)
688691
break;
689692
else {
@@ -809,11 +812,11 @@ static int convert (iconv_t cd, FILE* infile, const char* infilename)
809812
} else
810813
break;
811814
}
812-
if (ferror(infile)) {
815+
if (infile_error) {
813816
fflush(stdout);
814817
if (column > 0)
815818
putc('\n',stderr);
816-
error(0,0,
819+
error(0,infile_error,
817820
/* TRANSLATORS: An error message.
818821
The placeholder expands to the input file name. */
819822
_("%s: I/O error"),
@@ -1076,7 +1079,7 @@ int main (int argc, char* argv[])
10761079
hooks.data = NULL;
10771080
iconvctl(cd, ICONV_SET_HOOKS, &hooks);
10781081
if (i == argc)
1079-
status = convert(cd,stdin,
1082+
status = convert(cd,fileno(stdin),
10801083
/* TRANSLATORS: A filename substitute denoting standard input. */
10811084
_("(stdin)"));
10821085
else {
@@ -1094,7 +1097,7 @@ int main (int argc, char* argv[])
10941097
infilename);
10951098
status = 1;
10961099
} else {
1097-
status |= convert(cd,infile,infilename);
1100+
status |= convert(cd,fileno(infile),infilename);
10981101
fclose(infile);
10991102
}
11001103
}

0 commit comments

Comments
 (0)