This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.
Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hi! iconv -c doesn't seem to work properly. For a testcase, see http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=117021 The problem is, if iconv () returns -1/EILSEQ, iconv -c will not flush the state encoding, process further characters if iconv () has not processed yet all input, and will stop processing other files on the command line. 2004-03-04 Jakub Jelinek <jakub@redhat.com> * iconv/iconv_prog.c (process_block): Handle omit_invalid. If iconv returns EILSEQ with omit_invalid, continue converting and return 1 if no other errors are seen. (main): Set status to EXIT_FAILURE whenever process_* returns nonzero, but only stop processing further files if iy returns negative value. --- libc/iconv/iconv_prog.c.jj 2004-01-12 10:52:33.000000000 +0100 +++ libc/iconv/iconv_prog.c 2004-03-04 15:46:31.169002268 +0100 @@ -280,7 +280,7 @@ conversion from `%s' and to `%s' are not struct stat st; char *addr; #endif - int fd; + int fd, ret; if (verbose) printf ("%s:\n", argv[remaining]); @@ -313,43 +313,42 @@ conversion from `%s' and to `%s' are not _("error while closing input `%s'"), argv[remaining]); - if (process_block (cd, addr, st.st_size, output) < 0) - { - /* Something went wrong. */ - status = EXIT_FAILURE; + ret = process_block (cd, addr, st.st_size, output); - /* We don't need the input data anymore. */ - munmap ((void *) addr, st.st_size); + /* We don't need the input data anymore. */ + munmap ((void *) addr, st.st_size); + if (ret != 0) + status = EXIT_FAILURE; + + if (ret < 0) + { /* We cannot go on with producing output since it might lead to problem because the last output might leave the output stream in an undefined state. */ break; } - - /* We don't need the input data anymore. */ - munmap ((void *) addr, st.st_size); } else #endif /* _POSIX_MAPPED_FILES */ { /* Read the file in pieces. */ - if (process_fd (cd, fd, output) != 0) - { - /* Something went wrong. */ - status = EXIT_FAILURE; + ret = process_fd (cd, fd, output); + + /* Now close the file. */ + close (fd); - /* We don't need the input file anymore. */ - close (fd); + if (ret != 0) + /* Something went wrong. */ + status = EXIT_FAILURE; + if (ret < 0) + { /* We cannot go on with producing output since it might lead to problem because the last output might leave the output stream in an undefined state. */ break; } - - /* Now close the file. */ - close (fd); } } while (++remaining < argc); @@ -438,6 +437,7 @@ process_block (iconv_t cd, char *addr, s char *outptr; size_t outlen; size_t n; + int ret = 0; while (len > 0) { @@ -445,6 +445,15 @@ process_block (iconv_t cd, char *addr, s outlen = OUTBUF_SIZE; n = iconv (cd, &addr, &len, &outptr, &outlen); + if (n == (size_t) -1 && omit_invalid && errno == EILSEQ) + { + ret = 1; + if (len == 0) + n = 0; + else + errno = E2BIG; + } + if (outptr != outbuf) { /* We have something to write out. */ @@ -469,7 +478,7 @@ conversion stopped due to problem in wri character sets we have to flush the state now. */ outptr = outbuf; outlen = OUTBUF_SIZE; - (void) iconv (cd, NULL, NULL, &outptr, &outlen); + n = iconv (cd, NULL, NULL, &outptr, &outlen); if (outptr != outbuf) { @@ -489,7 +498,14 @@ conversion stopped due to problem in wri errno = errno_save; } - break; + if (n != (size_t) -1) + break; + + if (omit_invalid && errno == EILSEQ) + { + ret = 1; + break; + } } if (errno != E2BIG) @@ -518,7 +534,7 @@ incomplete character or shift sequence a } } - return 0; + return ret; } Jakub
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |