# HG changeset patch # User Jerry James # Date 1400098584 21600 # Node ID d2c0ff38ad5cf62e35cfe32960c50e923b651bbb # Parent 2d20d57d4e7b7a80564de5fb065779557994edb2 Report lstream errors when encoding/decoding. See in xemacs-patches. diff -r 2d20d57d4e7b -r d2c0ff38ad5c src/ChangeLog --- a/src/ChangeLog Wed May 07 13:33:50 2014 -0600 +++ b/src/ChangeLog Wed May 14 14:16:24 2014 -0600 @@ -1,3 +1,22 @@ +2014-05-06 Jerry James + + * file-coding.c (encode_decode_coding_region): Signal an error if + Lstream_read encounters an error (returns -1). + (detect_coding_type): Ditto. Add an argument for the stream error. + (look_for_coding_system_magic_cookie): Ditto. + (determine_real_coding_system): Pass new stream error argument. + (undecided_convert): Ditto. + (Ffind_coding_system_magic_cookie_in_file): Ditto. + * lstream.c (Lstream_errno): New function. + (struct filedesc_stream): Add saved_errno member. + (make_filedesc_stream_1): Initialize it. + (filedesc_reader): Set it. + (filedesc_writer): Set it. + (filedesc_error): New function. + (lstream_type_create): Record that filedesc has an error method. + * lstream.h (struct lstream_implementation): Add error member. + (Lstream_errno): Declare. + 2014-01-27 Michael Sperber * symbols.c (Fdefine_function): Allow optional `docstring' diff -r 2d20d57d4e7b -r d2c0ff38ad5c src/file-coding.c --- a/src/file-coding.c Wed May 07 13:33:50 2014 -0600 +++ b/src/file-coding.c Wed May 14 14:16:24 2014 -0600 @@ -2294,6 +2294,23 @@ Bytecount size_in_bytes = Lstream_read (istr, tempbuf, sizeof (tempbuf)); + if (size_in_bytes < 0) + { + int err = Lstream_errno (istr); + if (err) + signal_error_2 (Qtext_conversion_error, + direction == CODING_DECODE + ? "Internal error while decoding" + : "Internal error while encoding", + XCODING_SYSTEM_NAME (coding_system), + lisp_strerror (err)); + else + signal_error (Qtext_conversion_error, + direction == CODING_DECODE + ? "Internal error while decoding" + : "Internal error while encoding", + XCODING_SYSTEM_NAME (coding_system)); + } if (!size_in_bytes) break; newpos = lisp_buffer_stream_startpos (istr); @@ -3563,12 +3580,17 @@ static int detect_coding_type (struct detection_state *st, const UExtbyte *src, - Bytecount n) + Bytecount n, int err) { Bytecount n2 = n; const UExtbyte *src2 = src; int i; + if (n < 0) + signal_error (Qtext_conversion_error, + "Error reading file to determine coding system", + err ? lisp_strerror (err) : Qnil); + #ifdef DEBUG_XEMACS if (!NILP (Vdebug_coding_detection)) { @@ -3784,12 +3806,19 @@ static Lisp_Object look_for_coding_system_magic_cookie (const UExtbyte *data, Bytecount len, - Boolint find_coding_system_p) + Boolint find_coding_system_p, int err) { const UExtbyte *p; const UExtbyte *scan_end; Bytecount cookie_len; + if (len < 0) + { + signal_error (Qtext_conversion_error, + "Internal error while looking for coding cookie", + err ? lisp_strerror (err) : Qnil); + } + /* Look for initial "-*-"; mode line prefix */ for (p = data, scan_end = data + len - LENGTH ("-*-coding:?-*-"); @@ -3864,13 +3893,14 @@ UExtbyte buf[4096]; Bytecount nread = Lstream_read (stream, buf, sizeof (buf)); Lisp_Object coding_system - = look_for_coding_system_magic_cookie (buf, nread, 1); + = look_for_coding_system_magic_cookie (buf, nread, 1, + Lstream_errno (stream)); if (NILP (coding_system)) { while (1) { - if (detect_coding_type (st, buf, nread)) + if (detect_coding_type (st, buf, nread, Lstream_errno (stream))) break; nread = Lstream_read (stream, buf, sizeof (buf)); if (nread == 0) @@ -3968,6 +3998,7 @@ XCODING_SYSTEM_TYPE_DATA (str->codesys, undecided); struct undecided_coding_stream *data = CODING_STREAM_TYPE_DATA (str, undecided); + int err = 0; if (str->eof) { @@ -4011,6 +4042,7 @@ first_time = 1; data->c.initted = 1; + err = Lstream_errno (str->other_end); } /* If necessary, do encoding-detection now. We do this when we're a @@ -4028,13 +4060,14 @@ /* #### This is cheesy. What we really ought to do is buffer up a certain minimum amount of data to get a better result. */ - data->actual = look_for_coding_system_magic_cookie (src, n, 1); + data->actual = + look_for_coding_system_magic_cookie (src, n, 1, err); if (NILP (data->actual)) { /* #### This is cheesy. What we really ought to do is buffer up a certain minimum amount of data so as to get a less random result when doing subprocess detection. */ - detect_coding_type (data->st, src, n); + detect_coding_type (data->st, src, n, err); data->actual = detected_coding_system (data->st); /* kludge to prevent infinite recursion */ if (XCODING_SYSTEM(data->actual)->methods->enumtype == undecided_coding_system) @@ -4291,7 +4324,7 @@ Lisp_Object lstream; UExtbyte buf[4096]; Bytecount nread; - int fd = -1; + int fd = -1, err; struct stat st; filename = Fexpand_file_name (filename, Qnil); @@ -4312,10 +4345,11 @@ lstream = make_filedesc_input_stream (fd, 0, -1, 0); Lstream_set_buffering (XLSTREAM (lstream), LSTREAM_UNBUFFERED, 0); nread = Lstream_read (XLSTREAM (lstream), buf, sizeof (buf)); + err = Lstream_errno (XLSTREAM (lstream)); Lstream_delete (XLSTREAM (lstream)); retry_close (fd); - return look_for_coding_system_magic_cookie (buf, nread, 0); + return look_for_coding_system_magic_cookie (buf, nread, 0, err); } diff -r 2d20d57d4e7b -r d2c0ff38ad5c src/lstream.c --- a/src/lstream.c Wed May 07 13:33:50 2014 -0600 +++ b/src/lstream.c Wed May 14 14:16:24 2014 -0600 @@ -742,6 +742,12 @@ return Lstream_read_1 (lstr, data, size, 0); } +int +Lstream_errno (Lstream *lstr) +{ + return (lstr->imp->error) ? (lstr->imp->error) (lstr) : 0; +} + Charcount Lstream_character_tell (Lstream *lstr) { @@ -1118,6 +1124,7 @@ int current_pos; int end_pos; int chars_sans_newline; + int saved_errno; unsigned int closing :1; unsigned int allow_quit :1; unsigned int blocked_ok :1; @@ -1146,6 +1153,7 @@ fstr->pty_flushing = !!(flags & LSTR_PTY_FLUSHING); fstr->blocking_error_p = 0; fstr->chars_sans_newline = 0; + fstr->saved_errno = 0; fstr->starting_pos = lseek (filedesc, offset, SEEK_CUR); fstr->current_pos = max (fstr->starting_pos, 0); if (count < 0) @@ -1192,6 +1200,7 @@ { Bytecount nread; struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream); + str->saved_errno = 0; if (str->end_pos >= 0) size = min (size, (Bytecount) (str->end_pos - str->current_pos)); nread = str->allow_quit ? @@ -1202,7 +1211,10 @@ if (nread == 0) return 0; /* LSTREAM_EOF; */ if (nread < 0) - return LSTREAM_ERROR; + { + str->saved_errno = errno; + return LSTREAM_ERROR; + } return nread; } @@ -1228,6 +1240,8 @@ Bytecount retval; int need_newline = 0; + str->saved_errno = 0; + /* This function would be simple if it were not for the blasted PTY max-bytes stuff. Why the hell can't they just have written the PTY drivers right so this problem doesn't exist? @@ -1266,7 +1280,10 @@ } str->blocking_error_p = 0; if (retval < 0) - return LSTREAM_ERROR; + { + str->saved_errno = errno; + return LSTREAM_ERROR; + } /**** end non-PTY-crap ****/ if (str->pty_flushing) @@ -1298,7 +1315,10 @@ return 0; } else - return LSTREAM_ERROR; + { + str->saved_errno = errno; + return LSTREAM_ERROR; + } } else return retval; @@ -1334,7 +1354,10 @@ return 0; } else - return LSTREAM_ERROR; + { + str->saved_errno = errno; + return LSTREAM_ERROR; + } } else return retval; @@ -1345,6 +1368,13 @@ } static int +filedesc_error (Lstream *stream) +{ + struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream); + return str->saved_errno; +} + +static int filedesc_rewinder (Lstream *stream) { struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream); @@ -1926,6 +1956,7 @@ LSTREAM_HAS_METHOD (filedesc, reader); LSTREAM_HAS_METHOD (filedesc, writer); + LSTREAM_HAS_METHOD (filedesc, error); LSTREAM_HAS_METHOD (filedesc, was_blocked_p); LSTREAM_HAS_METHOD (filedesc, rewinder); LSTREAM_HAS_METHOD (filedesc, seekable_p); diff -r 2d20d57d4e7b -r d2c0ff38ad5c src/lstream.h --- a/src/lstream.h Wed May 07 13:33:50 2014 -0600 +++ b/src/lstream.h Wed May 14 14:16:24 2014 -0600 @@ -174,6 +174,10 @@ in an attempt to block (EWOULDBLOCK). If this method does not exists, the implementation returns 0 */ int (*was_blocked_p) (Lstream *stream); + /* If the reader or writer method returned LSTREAM_ERROR, the errno + associated with the error, or zero if there was no system error or this + method is not implemented. */ + int (*error) (Lstream *stream); /* Rewind the stream. If this is NULL, the stream is not seekable. */ int (*rewinder) (Lstream *stream); /* Indicate whether this stream is seekable -- i.e. it can be rewound. @@ -306,6 +310,7 @@ Charcount Lstream_character_tell (Lstream *); int Lstream_write (Lstream *lstr, const void *data, Bytecount size); +int Lstream_errno (Lstream *lstr); int Lstream_was_blocked_p (Lstream *lstr); void Lstream_unread (Lstream *lstr, const void *data, Bytecount size); int Lstream_rewind (Lstream *lstr);