diff options
| author | Joakim Verona | 2013-08-12 12:29:06 +0200 |
|---|---|---|
| committer | Joakim Verona | 2013-08-12 12:29:06 +0200 |
| commit | 5ff84f8a17c73bf63cc7532e14149380d9f83b3f (patch) | |
| tree | 501ac3b99a49aaa25adedc516bb4ea7a34c22a5c /src/fileio.c | |
| parent | c39e73975f7371a6458cd63967d39ba77a1e871a (diff) | |
| parent | 7a67e06b99a85ae700a7ccc75468397d53af59ed (diff) | |
| download | emacs-5ff84f8a17c73bf63cc7532e14149380d9f83b3f.tar.gz emacs-5ff84f8a17c73bf63cc7532e14149380d9f83b3f.zip | |
merge from trunk
Diffstat (limited to 'src/fileio.c')
| -rw-r--r-- | src/fileio.c | 74 |
1 files changed, 49 insertions, 25 deletions
diff --git a/src/fileio.c b/src/fileio.c index 6b24e592bb3..6ec5f78c2cf 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -4746,25 +4746,39 @@ This does code conversion according to the value of | |||
| 4746 | 4746 | ||
| 4747 | This calls `write-region-annotate-functions' at the start, and | 4747 | This calls `write-region-annotate-functions' at the start, and |
| 4748 | `write-region-post-annotation-function' at the end. */) | 4748 | `write-region-post-annotation-function' at the end. */) |
| 4749 | (Lisp_Object start, Lisp_Object end, Lisp_Object filename, Lisp_Object append, Lisp_Object visit, Lisp_Object lockname, Lisp_Object mustbenew) | 4749 | (Lisp_Object start, Lisp_Object end, Lisp_Object filename, Lisp_Object append, |
| 4750 | Lisp_Object visit, Lisp_Object lockname, Lisp_Object mustbenew) | ||
| 4751 | { | ||
| 4752 | return write_region (start, end, filename, append, visit, lockname, mustbenew, | ||
| 4753 | -1); | ||
| 4754 | } | ||
| 4755 | |||
| 4756 | /* Like Fwrite_region, except that if DESC is nonnegative, it is a file | ||
| 4757 | descriptor for FILENAME, so do not open or close FILENAME. */ | ||
| 4758 | |||
| 4759 | Lisp_Object | ||
| 4760 | write_region (Lisp_Object start, Lisp_Object end, Lisp_Object filename, | ||
| 4761 | Lisp_Object append, Lisp_Object visit, Lisp_Object lockname, | ||
| 4762 | Lisp_Object mustbenew, int desc) | ||
| 4750 | { | 4763 | { |
| 4751 | int desc; | ||
| 4752 | int open_flags; | 4764 | int open_flags; |
| 4753 | int mode; | 4765 | int mode; |
| 4754 | off_t offset IF_LINT (= 0); | 4766 | off_t offset IF_LINT (= 0); |
| 4767 | bool open_and_close_file = desc < 0; | ||
| 4755 | bool ok; | 4768 | bool ok; |
| 4756 | int save_errno = 0; | 4769 | int save_errno = 0; |
| 4757 | const char *fn; | 4770 | const char *fn; |
| 4758 | struct stat st; | 4771 | struct stat st; |
| 4759 | EMACS_TIME modtime; | 4772 | EMACS_TIME modtime; |
| 4760 | ptrdiff_t count = SPECPDL_INDEX (); | 4773 | ptrdiff_t count = SPECPDL_INDEX (); |
| 4761 | ptrdiff_t count1; | 4774 | ptrdiff_t count1 IF_LINT (= 0); |
| 4762 | Lisp_Object handler; | 4775 | Lisp_Object handler; |
| 4763 | Lisp_Object visit_file; | 4776 | Lisp_Object visit_file; |
| 4764 | Lisp_Object annotations; | 4777 | Lisp_Object annotations; |
| 4765 | Lisp_Object encoded_filename; | 4778 | Lisp_Object encoded_filename; |
| 4766 | bool visiting = (EQ (visit, Qt) || STRINGP (visit)); | 4779 | bool visiting = (EQ (visit, Qt) || STRINGP (visit)); |
| 4767 | bool quietly = !NILP (visit); | 4780 | bool quietly = !NILP (visit); |
| 4781 | bool file_locked = 0; | ||
| 4768 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; | 4782 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; |
| 4769 | struct buffer *given_buffer; | 4783 | struct buffer *given_buffer; |
| 4770 | struct coding_system coding; | 4784 | struct coding_system coding; |
| @@ -4832,7 +4846,6 @@ This calls `write-region-annotate-functions' at the start, and | |||
| 4832 | record_unwind_protect (build_annotations_unwind, | 4846 | record_unwind_protect (build_annotations_unwind, |
| 4833 | Vwrite_region_annotation_buffers); | 4847 | Vwrite_region_annotation_buffers); |
| 4834 | Vwrite_region_annotation_buffers = list1 (Fcurrent_buffer ()); | 4848 | Vwrite_region_annotation_buffers = list1 (Fcurrent_buffer ()); |
| 4835 | count1 = SPECPDL_INDEX (); | ||
| 4836 | 4849 | ||
| 4837 | given_buffer = current_buffer; | 4850 | given_buffer = current_buffer; |
| 4838 | 4851 | ||
| @@ -4871,8 +4884,11 @@ This calls `write-region-annotate-functions' at the start, and | |||
| 4871 | coding.mode |= CODING_MODE_SELECTIVE_DISPLAY; | 4884 | coding.mode |= CODING_MODE_SELECTIVE_DISPLAY; |
| 4872 | 4885 | ||
| 4873 | #ifdef CLASH_DETECTION | 4886 | #ifdef CLASH_DETECTION |
| 4874 | if (!auto_saving) | 4887 | if (open_and_close_file && !auto_saving) |
| 4875 | lock_file (lockname); | 4888 | { |
| 4889 | lock_file (lockname); | ||
| 4890 | file_locked = 1; | ||
| 4891 | } | ||
| 4876 | #endif /* CLASH_DETECTION */ | 4892 | #endif /* CLASH_DETECTION */ |
| 4877 | 4893 | ||
| 4878 | encoded_filename = ENCODE_FILE (filename); | 4894 | encoded_filename = ENCODE_FILE (filename); |
| @@ -4889,19 +4905,23 @@ This calls `write-region-annotate-functions' at the start, and | |||
| 4889 | mode = auto_saving ? auto_save_mode_bits : 0666; | 4905 | mode = auto_saving ? auto_save_mode_bits : 0666; |
| 4890 | #endif | 4906 | #endif |
| 4891 | 4907 | ||
| 4892 | desc = emacs_open (fn, open_flags, mode); | 4908 | if (open_and_close_file) |
| 4893 | |||
| 4894 | if (desc < 0) | ||
| 4895 | { | 4909 | { |
| 4896 | int open_errno = errno; | 4910 | desc = emacs_open (fn, open_flags, mode); |
| 4911 | if (desc < 0) | ||
| 4912 | { | ||
| 4913 | int open_errno = errno; | ||
| 4897 | #ifdef CLASH_DETECTION | 4914 | #ifdef CLASH_DETECTION |
| 4898 | if (!auto_saving) unlock_file (lockname); | 4915 | if (file_locked) |
| 4916 | unlock_file (lockname); | ||
| 4899 | #endif /* CLASH_DETECTION */ | 4917 | #endif /* CLASH_DETECTION */ |
| 4900 | UNGCPRO; | 4918 | UNGCPRO; |
| 4901 | report_file_errno ("Opening output file", filename, open_errno); | 4919 | report_file_errno ("Opening output file", filename, open_errno); |
| 4902 | } | 4920 | } |
| 4903 | 4921 | ||
| 4904 | record_unwind_protect_int (close_file_unwind, desc); | 4922 | count1 = SPECPDL_INDEX (); |
| 4923 | record_unwind_protect_int (close_file_unwind, desc); | ||
| 4924 | } | ||
| 4905 | 4925 | ||
| 4906 | if (NUMBERP (append)) | 4926 | if (NUMBERP (append)) |
| 4907 | { | 4927 | { |
| @@ -4910,7 +4930,8 @@ This calls `write-region-annotate-functions' at the start, and | |||
| 4910 | { | 4930 | { |
| 4911 | int lseek_errno = errno; | 4931 | int lseek_errno = errno; |
| 4912 | #ifdef CLASH_DETECTION | 4932 | #ifdef CLASH_DETECTION |
| 4913 | if (!auto_saving) unlock_file (lockname); | 4933 | if (file_locked) |
| 4934 | unlock_file (lockname); | ||
| 4914 | #endif /* CLASH_DETECTION */ | 4935 | #endif /* CLASH_DETECTION */ |
| 4915 | UNGCPRO; | 4936 | UNGCPRO; |
| 4916 | report_file_errno ("Lseek error", filename, lseek_errno); | 4937 | report_file_errno ("Lseek error", filename, lseek_errno); |
| @@ -4945,9 +4966,9 @@ This calls `write-region-annotate-functions' at the start, and | |||
| 4945 | 4966 | ||
| 4946 | immediate_quit = 0; | 4967 | immediate_quit = 0; |
| 4947 | 4968 | ||
| 4948 | /* fsync is not crucial for auto-save files, since they might lose | 4969 | /* fsync is not crucial for temporary files. Nor for auto-save |
| 4949 | some work anyway. */ | 4970 | files, since they might lose some work anyway. */ |
| 4950 | if (!auto_saving && !write_region_inhibit_fsync) | 4971 | if (open_and_close_file && !auto_saving && !write_region_inhibit_fsync) |
| 4951 | { | 4972 | { |
| 4952 | /* Transfer data and metadata to disk, retrying if interrupted. | 4973 | /* Transfer data and metadata to disk, retrying if interrupted. |
| 4953 | fsync can report a write failure here, e.g., due to disk full | 4974 | fsync can report a write failure here, e.g., due to disk full |
| @@ -4971,12 +4992,15 @@ This calls `write-region-annotate-functions' at the start, and | |||
| 4971 | ok = 0, save_errno = errno; | 4992 | ok = 0, save_errno = errno; |
| 4972 | } | 4993 | } |
| 4973 | 4994 | ||
| 4974 | /* NFS can report a write failure now. */ | 4995 | if (open_and_close_file) |
| 4975 | if (emacs_close (desc) < 0) | 4996 | { |
| 4976 | ok = 0, save_errno = errno; | 4997 | /* NFS can report a write failure now. */ |
| 4998 | if (emacs_close (desc) < 0) | ||
| 4999 | ok = 0, save_errno = errno; | ||
| 4977 | 5000 | ||
| 4978 | /* Discard the unwind protect for close_file_unwind. */ | 5001 | /* Discard the unwind protect for close_file_unwind. */ |
| 4979 | specpdl_ptr = specpdl + count1; | 5002 | specpdl_ptr = specpdl + count1; |
| 5003 | } | ||
| 4980 | 5004 | ||
| 4981 | /* Some file systems have a bug where st_mtime is not updated | 5005 | /* Some file systems have a bug where st_mtime is not updated |
| 4982 | properly after a write. For example, CIFS might not see the | 5006 | properly after a write. For example, CIFS might not see the |
| @@ -5052,7 +5076,7 @@ This calls `write-region-annotate-functions' at the start, and | |||
| 5052 | unbind_to (count, Qnil); | 5076 | unbind_to (count, Qnil); |
| 5053 | 5077 | ||
| 5054 | #ifdef CLASH_DETECTION | 5078 | #ifdef CLASH_DETECTION |
| 5055 | if (!auto_saving) | 5079 | if (file_locked) |
| 5056 | unlock_file (lockname); | 5080 | unlock_file (lockname); |
| 5057 | #endif /* CLASH_DETECTION */ | 5081 | #endif /* CLASH_DETECTION */ |
| 5058 | 5082 | ||