aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Ingebrigtsen2022-06-11 14:39:54 +0200
committerLars Ingebrigtsen2022-06-11 14:39:54 +0200
commitcb4579ed6ba45c81ee7ec627bf197e1def121f24 (patch)
tree1876c474349aad31d42f06587f68510ed8988ad2 /src
parent36758096961930baaf0e271522abfb78ff7f656d (diff)
downloademacs-cb4579ed6ba45c81ee7ec627bf197e1def121f24.tar.gz
emacs-cb4579ed6ba45c81ee7ec627bf197e1def121f24.zip
Allow inserting parts of /dev/urandom with insert-file-contents
* doc/lispref/files.texi (Reading from Files): Document it. * src/fileio.c (Finsert_file_contents): Allow specifying END for special files (bug#18370).
Diffstat (limited to 'src')
-rw-r--r--src/fileio.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/src/fileio.c b/src/fileio.c
index 094516bfef5..94cbc14371d 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3898,6 +3898,10 @@ The optional third and fourth arguments BEG and END specify what portion
3898of the file to insert. These arguments count bytes in the file, not 3898of the file to insert. These arguments count bytes in the file, not
3899characters in the buffer. If VISIT is non-nil, BEG and END must be nil. 3899characters in the buffer. If VISIT is non-nil, BEG and END must be nil.
3900 3900
3901When inserting data from a special file (e.g., /dev/urandom), you
3902can't specify VISIT or BEG, and END should be specified to avoid
3903inserting unlimited data into the buffer.
3904
3901If optional fifth argument REPLACE is non-nil, replace the current 3905If optional fifth argument REPLACE is non-nil, replace the current
3902buffer contents (in the accessible portion) with the file contents. 3906buffer contents (in the accessible portion) with the file contents.
3903This is better than simply deleting and inserting the whole thing 3907This is better than simply deleting and inserting the whole thing
@@ -3925,7 +3929,7 @@ by calling `format-decode', which see. */)
3925 Lisp_Object handler, val, insval, orig_filename, old_undo; 3929 Lisp_Object handler, val, insval, orig_filename, old_undo;
3926 Lisp_Object p; 3930 Lisp_Object p;
3927 ptrdiff_t total = 0; 3931 ptrdiff_t total = 0;
3928 bool not_regular = 0; 3932 bool regular = true;
3929 int save_errno = 0; 3933 int save_errno = 0;
3930 char read_buf[READ_BUF_SIZE]; 3934 char read_buf[READ_BUF_SIZE];
3931 struct coding_system coding; 3935 struct coding_system coding;
@@ -3948,6 +3952,7 @@ by calling `format-decode', which see. */)
3948 /* SAME_AT_END_CHARPOS counts characters, because 3952 /* SAME_AT_END_CHARPOS counts characters, because
3949 restore_window_points needs the old character count. */ 3953 restore_window_points needs the old character count. */
3950 ptrdiff_t same_at_end_charpos = ZV; 3954 ptrdiff_t same_at_end_charpos = ZV;
3955 bool seekable = true;
3951 3956
3952 if (current_buffer->base_buffer && ! NILP (visit)) 3957 if (current_buffer->base_buffer && ! NILP (visit))
3953 error ("Cannot do file visiting in an indirect buffer"); 3958 error ("Cannot do file visiting in an indirect buffer");
@@ -4021,7 +4026,8 @@ by calling `format-decode', which see. */)
4021 least signal an error. */ 4026 least signal an error. */
4022 if (!S_ISREG (st.st_mode)) 4027 if (!S_ISREG (st.st_mode))
4023 { 4028 {
4024 not_regular = 1; 4029 regular = false;
4030 seekable = lseek (fd, 0, SEEK_CUR) < 0;
4025 4031
4026 if (! NILP (visit)) 4032 if (! NILP (visit))
4027 { 4033 {
@@ -4029,7 +4035,12 @@ by calling `format-decode', which see. */)
4029 goto notfound; 4035 goto notfound;
4030 } 4036 }
4031 4037
4032 if (! NILP (replace) || ! NILP (beg) || ! NILP (end)) 4038 if (!NILP (beg) && !seekable)
4039 xsignal2 (Qfile_error,
4040 build_string ("trying to use a start positing in a non-seekable file"),
4041 orig_filename);
4042
4043 if (!NILP (replace))
4033 xsignal2 (Qfile_error, 4044 xsignal2 (Qfile_error,
4034 build_string ("not a regular file"), orig_filename); 4045 build_string ("not a regular file"), orig_filename);
4035 } 4046 }
@@ -4051,7 +4062,7 @@ by calling `format-decode', which see. */)
4051 end_offset = file_offset (end); 4062 end_offset = file_offset (end);
4052 else 4063 else
4053 { 4064 {
4054 if (not_regular) 4065 if (!regular)
4055 end_offset = TYPE_MAXIMUM (off_t); 4066 end_offset = TYPE_MAXIMUM (off_t);
4056 else 4067 else
4057 { 4068 {
@@ -4073,7 +4084,7 @@ by calling `format-decode', which see. */)
4073 /* Check now whether the buffer will become too large, 4084 /* Check now whether the buffer will become too large,
4074 in the likely case where the file's length is not changing. 4085 in the likely case where the file's length is not changing.
4075 This saves a lot of needless work before a buffer overflow. */ 4086 This saves a lot of needless work before a buffer overflow. */
4076 if (! not_regular) 4087 if (regular)
4077 { 4088 {
4078 /* The likely offset where we will stop reading. We could read 4089 /* The likely offset where we will stop reading. We could read
4079 more (or less), if the file grows (or shrinks) as we read it. */ 4090 more (or less), if the file grows (or shrinks) as we read it. */
@@ -4111,7 +4122,7 @@ by calling `format-decode', which see. */)
4111 { 4122 {
4112 /* Don't try looking inside a file for a coding system 4123 /* Don't try looking inside a file for a coding system
4113 specification if it is not seekable. */ 4124 specification if it is not seekable. */
4114 if (! not_regular && ! NILP (Vset_auto_coding_function)) 4125 if (regular && !NILP (Vset_auto_coding_function))
4115 { 4126 {
4116 /* Find a coding system specified in the heading two 4127 /* Find a coding system specified in the heading two
4117 lines or in the tailing several lines of the file. 4128 lines or in the tailing several lines of the file.
@@ -4573,7 +4584,7 @@ by calling `format-decode', which see. */)
4573 goto handled; 4584 goto handled;
4574 } 4585 }
4575 4586
4576 if (! not_regular) 4587 if (seekable || !NILP (end))
4577 total = end_offset - beg_offset; 4588 total = end_offset - beg_offset;
4578 else 4589 else
4579 /* For a special file, all we can do is guess. */ 4590 /* For a special file, all we can do is guess. */
@@ -4619,7 +4630,7 @@ by calling `format-decode', which see. */)
4619 ptrdiff_t trytry = min (total - how_much, READ_BUF_SIZE); 4630 ptrdiff_t trytry = min (total - how_much, READ_BUF_SIZE);
4620 ptrdiff_t this; 4631 ptrdiff_t this;
4621 4632
4622 if (not_regular) 4633 if (!seekable && NILP (end))
4623 { 4634 {
4624 Lisp_Object nbytes; 4635 Lisp_Object nbytes;
4625 4636
@@ -4670,7 +4681,7 @@ by calling `format-decode', which see. */)
4670 For a special file, where TOTAL is just a buffer size, 4681 For a special file, where TOTAL is just a buffer size,
4671 so don't bother counting in HOW_MUCH. 4682 so don't bother counting in HOW_MUCH.
4672 (INSERTED is where we count the number of characters inserted.) */ 4683 (INSERTED is where we count the number of characters inserted.) */
4673 if (! not_regular) 4684 if (seekable || !NILP (end))
4674 how_much += this; 4685 how_much += this;
4675 inserted += this; 4686 inserted += this;
4676 } 4687 }
@@ -4848,7 +4859,7 @@ by calling `format-decode', which see. */)
4848 Funlock_file (BVAR (current_buffer, file_truename)); 4859 Funlock_file (BVAR (current_buffer, file_truename));
4849 Funlock_file (filename); 4860 Funlock_file (filename);
4850 } 4861 }
4851 if (not_regular) 4862 if (!regular)
4852 xsignal2 (Qfile_error, 4863 xsignal2 (Qfile_error,
4853 build_string ("not a regular file"), orig_filename); 4864 build_string ("not a regular file"), orig_filename);
4854 } 4865 }