[PATCH 21.5] Report lstream errors when encoding/decoding
Jerry James <[email protected]>
| Newsgroups | gmane.emacs.xemacs.patches |
|---|---|
| Message-ID | <CAHCOHQ=FAieD-2nP303fMvwkii8HK2z+X7gRZ2+4PH1CA5_-NA@mail.gmail.com> |
PATCH 21.5 This is the latest version of the patch to throw an error if we encounter an error while trying to do an lstream read when decoding or encoding. This version adds a new function, Lstream_errno(), to retrieve the latest value of errno generated when trying to do an Lstream_read() or Lstream_write(). Currently only the filedesc lstream implements the corresponding method. The patch is attached. -- Jerry James http://www.jamezone.org/ _______________________________________________ XEmacs-Patches mailing list [email protected] http://lists.xemacs.org/mailman/listinfo/xemacs-patches
xemacs-lread.patch
(text/x-patch, 9.2 KB)
diff -r cf0201de66df src/ChangeLog --- a/src/ChangeLog Fri Apr 25 23:38:16 2014 +0200 +++ b/src/ChangeLog Tue May 06 10:33:38 2014 -0600 @@ -1,3 +1,22 @@ +2014-05-06 Jerry James <[email protected]> + + * 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 <[email protected]> * symbols.c (Fdefine_function): Allow optional `docstring' diff -r cf0201de66df src/file-coding.c --- a/src/file-coding.c Fri Apr 25 23:38:16 2014 +0200 +++ b/src/file-coding.c Tue May 06 10:33:38 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 cf0201de66df src/lstream.c --- a/src/lstream.c Fri Apr 25 23:38:16 2014 +0200 +++ b/src/lstream.c Tue May 06 10:33:38 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 cf0201de66df src/lstream.h --- a/src/lstream.h Fri Apr 25 23:38:16 2014 +0200 +++ b/src/lstream.h Tue May 06 10:33:38 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);