Commit b3fbb395 authored by Paul Eggert's avatar Paul Eggert
Browse files

Allow floating-point file offsets.

Problem reported by Vitalie Spinu in
<http://lists.gnu.org/archive/html/emacs-devel/2013-01/msg00411.html>.
* doc/lispref/files.texi (Reading from Files, Writing to Files):
Say that file offsets can be numbers, not just integers.
* src/fileio.c (emacs_lseek): Remove.
(file_offset): New function.
(Finsert_file_contents, Fwrite_region): Use it.
parent 73c14218
2013-01-19 Paul Eggert <eggert@cs.ucla.edu>
Allow floating-point file offsets.
* files.texi (Reading from Files, Writing to Files):
Say that file offsets can be numbers, not just integers.
2013-01-09 Glenn Morris <rgm@gnu.org> 2013-01-09 Glenn Morris <rgm@gnu.org>
* commands.texi (Interactive Codes): * commands.texi (Interactive Codes):
......
...@@ -533,9 +533,9 @@ is visiting the file @var{filename}: these include the buffer's visited ...@@ -533,9 +533,9 @@ is visiting the file @var{filename}: these include the buffer's visited
file name and its last save file modtime. This feature is used by file name and its last save file modtime. This feature is used by
@code{find-file-noselect} and you probably should not use it yourself. @code{find-file-noselect} and you probably should not use it yourself.
If @var{beg} and @var{end} are non-@code{nil}, they should be integers If @var{beg} and @var{end} are non-@code{nil}, they should be numbers
specifying the portion of the file to insert. In this case, @var{visit} that are byte offsets specifying the portion of the file to insert.
must be @code{nil}. For example, In this case, @var{visit} must be @code{nil}. For example,
@example @example
(insert-file-contents filename nil 0 500) (insert-file-contents filename nil 0 500)
...@@ -605,8 +605,8 @@ that string, rather than text from the buffer. @var{end} is ignored in ...@@ -605,8 +605,8 @@ that string, rather than text from the buffer. @var{end} is ignored in
this case. this case.
If @var{append} is non-@code{nil}, then the specified text is appended If @var{append} is non-@code{nil}, then the specified text is appended
to the existing file contents (if any). If @var{append} is an to the existing file contents (if any). If @var{append} is a
integer, @code{write-region} seeks to that byte offset from the start number, @code{write-region} seeks to that byte offset from the start
of the file and writes the data from there. of the file and writes the data from there.
If @var{mustbenew} is non-@code{nil}, then @code{write-region} asks If @var{mustbenew} is non-@code{nil}, then @code{write-region} asks
......
2013-01-19 Paul Eggert <eggert@cs.ucla.edu>
Allow floating-point file offsets.
Problem reported by Vitalie Spinu in
<http://lists.gnu.org/archive/html/emacs-devel/2013-01/msg00411.html>.
* fileio.c (emacs_lseek): Remove.
(file_offset): New function.
(Finsert_file_contents, Fwrite_region): Use it.
2013-01-19 Chong Yidong <cyd@gnu.org> 2013-01-19 Chong Yidong <cyd@gnu.org>
   
* emacs.c (Fkill_emacs): Set waiting_for_input to 0 to avoid * emacs.c (Fkill_emacs): Set waiting_for_input to 0 to avoid
......
...@@ -3443,19 +3443,25 @@ read_contents_quit (Lisp_Object ignore) ...@@ -3443,19 +3443,25 @@ read_contents_quit (Lisp_Object ignore)
return Qnil; return Qnil;
} }
/* Reposition FD to OFFSET, based on WHENCE. This acts like lseek /* Return the file offset that VAL represents, checking for type
except that it also tests for OFFSET being out of lseek's range. */ errors and overflow. */
static off_t static off_t
emacs_lseek (int fd, EMACS_INT offset, int whence) file_offset (Lisp_Object val)
{ {
/* Use "&" rather than "&&" to suppress a bogus GCC warning; see if (RANGED_INTEGERP (0, val, TYPE_MAXIMUM (off_t)))
<http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43772>. */ return XINT (val);
if (! ((offset >= TYPE_MINIMUM (off_t)) & (offset <= TYPE_MAXIMUM (off_t))))
if (FLOATP (val))
{ {
errno = EINVAL; double v = XFLOAT_DATA (val);
return -1; if (0 <= v
&& (sizeof (off_t) < sizeof v
? v <= TYPE_MAXIMUM (off_t)
: v < TYPE_MAXIMUM (off_t)))
return v;
} }
return lseek (fd, offset, whence);
wrong_type_argument (intern ("file-offset"), val);
} }
/* Return a special time value indicating the error number ERRNUM. */ /* Return a special time value indicating the error number ERRNUM. */
...@@ -3606,20 +3612,12 @@ by calling `format-decode', which see. */) ...@@ -3606,20 +3612,12 @@ by calling `format-decode', which see. */)
} }
if (!NILP (beg)) if (!NILP (beg))
{ beg_offset = file_offset (beg);
if (! RANGED_INTEGERP (0, beg, TYPE_MAXIMUM (off_t)))
wrong_type_argument (intern ("file-offset"), beg);
beg_offset = XFASTINT (beg);
}
else else
beg_offset = 0; beg_offset = 0;
if (!NILP (end)) if (!NILP (end))
{ end_offset = file_offset (end);
if (! RANGED_INTEGERP (0, end, TYPE_MAXIMUM (off_t)))
wrong_type_argument (intern ("file-offset"), end);
end_offset = XFASTINT (end);
}
else else
{ {
if (not_regular) if (not_regular)
...@@ -4714,7 +4712,7 @@ If START is a string, then output that string to the file ...@@ -4714,7 +4712,7 @@ If START is a string, then output that string to the file
instead of any buffer contents; END is ignored. instead of any buffer contents; END is ignored.
Optional fourth argument APPEND if non-nil means Optional fourth argument APPEND if non-nil means
append to existing file contents (if any). If it is an integer, append to existing file contents (if any). If it is a number,
seek to that offset in the file before writing. seek to that offset in the file before writing.
Optional fifth argument VISIT, if t or a string, means Optional fifth argument VISIT, if t or a string, means
set the last-save-file-modtime of buffer to this file's modtime set the last-save-file-modtime of buffer to this file's modtime
...@@ -4743,6 +4741,7 @@ This calls `write-region-annotate-functions' at the start, and ...@@ -4743,6 +4741,7 @@ This calls `write-region-annotate-functions' at the start, and
(Lisp_Object start, Lisp_Object end, Lisp_Object filename, Lisp_Object append, Lisp_Object visit, Lisp_Object lockname, Lisp_Object mustbenew) (Lisp_Object start, Lisp_Object end, Lisp_Object filename, Lisp_Object append, Lisp_Object visit, Lisp_Object lockname, Lisp_Object mustbenew)
{ {
int desc; int desc;
off_t offset;
bool ok; bool ok;
int save_errno = 0; int save_errno = 0;
const char *fn; const char *fn;
...@@ -4864,13 +4863,14 @@ This calls `write-region-annotate-functions' at the start, and ...@@ -4864,13 +4863,14 @@ This calls `write-region-annotate-functions' at the start, and
encoded_filename = ENCODE_FILE (filename); encoded_filename = ENCODE_FILE (filename);
fn = SSDATA (encoded_filename); fn = SSDATA (encoded_filename);
offset = 0;
desc = -1; desc = -1;
if (!NILP (append)) if (!NILP (append))
#ifdef DOS_NT {
desc = emacs_open (fn, O_WRONLY | O_BINARY, 0); if (NUMBERP (append))
#else /* not DOS_NT */ offset = file_offset (append);
desc = emacs_open (fn, O_WRONLY, 0); desc = emacs_open (fn, O_WRONLY | O_BINARY, 0);
#endif /* not DOS_NT */ }
if (desc < 0 && (NILP (append) || errno == ENOENT)) if (desc < 0 && (NILP (append) || errno == ENOENT))
#ifdef DOS_NT #ifdef DOS_NT
...@@ -4897,14 +4897,9 @@ This calls `write-region-annotate-functions' at the start, and ...@@ -4897,14 +4897,9 @@ This calls `write-region-annotate-functions' at the start, and
record_unwind_protect (close_file_unwind, make_number (desc)); record_unwind_protect (close_file_unwind, make_number (desc));
if (!NILP (append) && !NILP (Ffile_regular_p (filename))) if (!NILP (append))
{ {
off_t ret; off_t ret = lseek (desc, offset, NUMBERP (append) ? SEEK_SET : SEEK_END);
if (NUMBERP (append))
ret = emacs_lseek (desc, XINT (append), SEEK_CUR);
else
ret = lseek (desc, 0, SEEK_END);
if (ret < 0) if (ret < 0)
{ {
#ifdef CLASH_DETECTION #ifdef CLASH_DETECTION
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment