diff options
| author | Lars Ingebrigtsen | 2022-06-11 14:39:54 +0200 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2022-06-11 14:39:54 +0200 |
| commit | cb4579ed6ba45c81ee7ec627bf197e1def121f24 (patch) | |
| tree | 1876c474349aad31d42f06587f68510ed8988ad2 /src | |
| parent | 36758096961930baaf0e271522abfb78ff7f656d (diff) | |
| download | emacs-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.c | 31 |
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 | |||
| 3898 | of the file to insert. These arguments count bytes in the file, not | 3898 | of the file to insert. These arguments count bytes in the file, not |
| 3899 | characters in the buffer. If VISIT is non-nil, BEG and END must be nil. | 3899 | characters in the buffer. If VISIT is non-nil, BEG and END must be nil. |
| 3900 | 3900 | ||
| 3901 | When inserting data from a special file (e.g., /dev/urandom), you | ||
| 3902 | can't specify VISIT or BEG, and END should be specified to avoid | ||
| 3903 | inserting unlimited data into the buffer. | ||
| 3904 | |||
| 3901 | If optional fifth argument REPLACE is non-nil, replace the current | 3905 | If optional fifth argument REPLACE is non-nil, replace the current |
| 3902 | buffer contents (in the accessible portion) with the file contents. | 3906 | buffer contents (in the accessible portion) with the file contents. |
| 3903 | This is better than simply deleting and inserting the whole thing | 3907 | This 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 | } |