aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa2012-10-13 22:11:40 +0900
committerKenichi Handa2012-10-13 22:11:40 +0900
commit2e58893d168a90c475d4b5ba738b19113f6494ea (patch)
tree0688fdb217a0cf7f6ad1ca212c4ddb508d845301 /src
parent0ba06a77fd4ccf92f1106b8ab7d8d64d6d812a1d (diff)
parent076a4db2fe51a9a1d3a379955499a12059c50d45 (diff)
downloademacs-2e58893d168a90c475d4b5ba738b19113f6494ea.tar.gz
emacs-2e58893d168a90c475d4b5ba738b19113f6494ea.zip
merge trunk
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog17
-rw-r--r--src/fileio.c71
-rw-r--r--src/image.c44
-rw-r--r--src/process.c17
4 files changed, 57 insertions, 92 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 3787e006c4f..56131aca4b2 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -3,6 +3,23 @@
3 * coding.c (detect_coding): Set coding->id before calling 3 * coding.c (detect_coding): Set coding->id before calling
4 this->detector. 4 this->detector.
5 5
62012-10-13 Andreas Schwab <schwab@linux-m68k.org>
7
8 * fileio.c: Formatting fixes.
9
102012-10-13 Paul Eggert <eggert@cs.ucla.edu>
11
12 Fix some stat-related races.
13 * fileio.c (Fwrite_region): Avoid race condition if a file is
14 removed or renamed by some other process immediately after Emacs
15 writes it but before Emacs stats it. Do not assume that stat (or
16 fstat) succeeds.
17 * image.c (slurp_file): Resolve the file name with fopen + fstat
18 rather than stat + fopen.
19 (pbm_read_file) [0]: Remove unused code with stat race.
20 * process.c (allocate_pty) [HAVE_PTYS && !PTY_ITERATION && !PTY_OPEN]:
21 Remove ineffective code with stat race.
22
62012-10-12 Stefan Monnier <monnier@iro.umontreal.ca> 232012-10-12 Stefan Monnier <monnier@iro.umontreal.ca>
7 24
8 * doc.c (get_doc_string): Don't signal an error if the file is missing. 25 * doc.c (get_doc_string): Don't signal an error if the file is missing.
diff --git a/src/fileio.c b/src/fileio.c
index 5de5bc2b021..e3a91c2c9da 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -1370,8 +1370,7 @@ See also the function `substitute-in-file-name'.")
1370 p = nm; 1370 p = nm;
1371 while (*p) 1371 while (*p)
1372 { 1372 {
1373 if (p[0] == '/' && p[1] == '/' 1373 if (p[0] == '/' && p[1] == '/')
1374 )
1375 nm = p + 1; 1374 nm = p + 1;
1376 if (p[0] == '/' && p[1] == '~') 1375 if (p[0] == '/' && p[1] == '~')
1377 nm = p + 1, lose = 1; 1376 nm = p + 1, lose = 1;
@@ -1510,17 +1509,16 @@ search_embedded_absfilename (char *nm, char *endp)
1510 1509
1511 for (p = nm + 1; p < endp; p++) 1510 for (p = nm + 1; p < endp; p++)
1512 { 1511 {
1513 if ((0 1512 if (IS_DIRECTORY_SEP (p[-1])
1514 || IS_DIRECTORY_SEP (p[-1]))
1515 && file_name_absolute_p (p) 1513 && file_name_absolute_p (p)
1516#if defined (WINDOWSNT) || defined (CYGWIN) 1514#if defined (WINDOWSNT) || defined (CYGWIN)
1517 /* // at start of file name is meaningful in Apollo, 1515 /* // at start of file name is meaningful in Apollo,
1518 WindowsNT and Cygwin systems. */ 1516 WindowsNT and Cygwin systems. */
1519 && !(IS_DIRECTORY_SEP (p[0]) && p - 1 == nm) 1517 && !(IS_DIRECTORY_SEP (p[0]) && p - 1 == nm)
1520#endif /* not (WINDOWSNT || CYGWIN) */ 1518#endif /* not (WINDOWSNT || CYGWIN) */
1521 ) 1519 )
1522 { 1520 {
1523 for (s = p; *s && (!IS_DIRECTORY_SEP (*s)); s++); 1521 for (s = p; *s && !IS_DIRECTORY_SEP (*s); s++);
1524 if (p[0] == '~' && s > p + 1) /* We've got "/~something/". */ 1522 if (p[0] == '~' && s > p + 1) /* We've got "/~something/". */
1525 { 1523 {
1526 char *o = alloca (s - p + 1); 1524 char *o = alloca (s - p + 1);
@@ -1735,7 +1733,7 @@ those `/' is discarded. */)
1735 *x = 0; 1733 *x = 0;
1736 1734
1737 /* If /~ or // appears, discard everything through first slash. */ 1735 /* If /~ or // appears, discard everything through first slash. */
1738 while ((p = search_embedded_absfilename (xnm, x))) 1736 while ((p = search_embedded_absfilename (xnm, x)) != NULL)
1739 /* This time we do not start over because we've already expanded envvars 1737 /* This time we do not start over because we've already expanded envvars
1740 and replaced $$ with $. Maybe we should start over as well, but we'd 1738 and replaced $$ with $. Maybe we should start over as well, but we'd
1741 need to quote some $ to $$ first. */ 1739 need to quote some $ to $$ first. */
@@ -2169,7 +2167,7 @@ With a prefix argument, TRASH is nil. */)
2169 2167
2170 encoded_file = ENCODE_FILE (filename); 2168 encoded_file = ENCODE_FILE (filename);
2171 2169
2172 if (0 > unlink (SSDATA (encoded_file))) 2170 if (unlink (SSDATA (encoded_file)) < 0)
2173 report_file_error ("Removing old name", list1 (filename)); 2171 report_file_error ("Removing old name", list1 (filename));
2174 return Qnil; 2172 return Qnil;
2175} 2173}
@@ -2218,8 +2216,8 @@ This is what happens in interactive use with M-x. */)
2218#endif 2216#endif
2219 ) 2217 )
2220 { 2218 {
2221 Lisp_Object fname = NILP (Ffile_directory_p (file)) 2219 Lisp_Object fname = (NILP (Ffile_directory_p (file))
2222 ? file : Fdirectory_file_name (file); 2220 ? file : Fdirectory_file_name (file));
2223 newname = Fexpand_file_name (Ffile_name_nondirectory (fname), newname); 2221 newname = Fexpand_file_name (Ffile_name_nondirectory (fname), newname);
2224 } 2222 }
2225 else 2223 else
@@ -2247,7 +2245,7 @@ This is what happens in interactive use with M-x. */)
2247 || INTEGERP (ok_if_already_exists)) 2245 || INTEGERP (ok_if_already_exists))
2248 barf_or_query_if_file_exists (newname, "rename to it", 2246 barf_or_query_if_file_exists (newname, "rename to it",
2249 INTEGERP (ok_if_already_exists), 0, 0); 2247 INTEGERP (ok_if_already_exists), 0, 0);
2250 if (0 > rename (SSDATA (encoded_file), SSDATA (encoded_newname))) 2248 if (rename (SSDATA (encoded_file), SSDATA (encoded_newname)) < 0)
2251 { 2249 {
2252 if (errno == EXDEV) 2250 if (errno == EXDEV)
2253 { 2251 {
@@ -2328,7 +2326,7 @@ This is what happens in interactive use with M-x. */)
2328 INTEGERP (ok_if_already_exists), 0, 0); 2326 INTEGERP (ok_if_already_exists), 0, 0);
2329 2327
2330 unlink (SSDATA (newname)); 2328 unlink (SSDATA (newname));
2331 if (0 > link (SSDATA (encoded_file), SSDATA (encoded_newname))) 2329 if (link (SSDATA (encoded_file), SSDATA (encoded_newname)) < 0)
2332 report_file_error ("Adding new name", list2 (file, newname)); 2330 report_file_error ("Adding new name", list2 (file, newname));
2333 2331
2334 UNGCPRO; 2332 UNGCPRO;
@@ -2385,15 +2383,14 @@ This happens for interactive use with M-x. */)
2385 || INTEGERP (ok_if_already_exists)) 2383 || INTEGERP (ok_if_already_exists))
2386 barf_or_query_if_file_exists (linkname, "make it a link", 2384 barf_or_query_if_file_exists (linkname, "make it a link",
2387 INTEGERP (ok_if_already_exists), 0, 0); 2385 INTEGERP (ok_if_already_exists), 0, 0);
2388 if (0 > symlink (SSDATA (encoded_filename), 2386 if (symlink (SSDATA (encoded_filename), SSDATA (encoded_linkname)) < 0)
2389 SSDATA (encoded_linkname)))
2390 { 2387 {
2391 /* If we didn't complain already, silently delete existing file. */ 2388 /* If we didn't complain already, silently delete existing file. */
2392 if (errno == EEXIST) 2389 if (errno == EEXIST)
2393 { 2390 {
2394 unlink (SSDATA (encoded_linkname)); 2391 unlink (SSDATA (encoded_linkname));
2395 if (0 <= symlink (SSDATA (encoded_filename), 2392 if (symlink (SSDATA (encoded_filename), SSDATA (encoded_linkname))
2396 SSDATA (encoded_linkname))) 2393 >= 0)
2397 { 2394 {
2398 UNGCPRO; 2395 UNGCPRO;
2399 return Qnil; 2396 return Qnil;
@@ -3203,7 +3200,7 @@ emacs_lseek (int fd, EMACS_INT offset, int whence)
3203{ 3200{
3204 /* Use "&" rather than "&&" to suppress a bogus GCC warning; see 3201 /* Use "&" rather than "&&" to suppress a bogus GCC warning; see
3205 <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43772>. */ 3202 <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43772>. */
3206 if (! ((TYPE_MINIMUM (off_t) <= offset) & (offset <= TYPE_MAXIMUM (off_t)))) 3203 if (! ((offset >= TYPE_MINIMUM (off_t)) & (offset <= TYPE_MAXIMUM (off_t))))
3207 { 3204 {
3208 errno = EINVAL; 3205 errno = EINVAL;
3209 return -1; 3206 return -1;
@@ -3376,7 +3373,7 @@ variable `last-coding-system-used' to the coding system actually used. */)
3376 3373
3377 if (!NILP (beg)) 3374 if (!NILP (beg))
3378 { 3375 {
3379 if (! (RANGED_INTEGERP (0, beg, TYPE_MAXIMUM (off_t)))) 3376 if (! RANGED_INTEGERP (0, beg, TYPE_MAXIMUM (off_t)))
3380 wrong_type_argument (intern ("file-offset"), beg); 3377 wrong_type_argument (intern ("file-offset"), beg);
3381 beg_offset = XFASTINT (beg); 3378 beg_offset = XFASTINT (beg);
3382 } 3379 }
@@ -3385,7 +3382,7 @@ variable `last-coding-system-used' to the coding system actually used. */)
3385 3382
3386 if (!NILP (end)) 3383 if (!NILP (end))
3387 { 3384 {
3388 if (! (RANGED_INTEGERP (0, end, TYPE_MAXIMUM (off_t)))) 3385 if (! RANGED_INTEGERP (0, end, TYPE_MAXIMUM (off_t)))
3389 wrong_type_argument (intern ("file-offset"), end); 3386 wrong_type_argument (intern ("file-offset"), end);
3390 end_offset = XFASTINT (end); 3387 end_offset = XFASTINT (end);
3391 } 3388 }
@@ -3421,8 +3418,8 @@ variable `last-coding-system-used' to the coding system actually used. */)
3421 3418
3422 if (beg_offset < likely_end) 3419 if (beg_offset < likely_end)
3423 { 3420 {
3424 ptrdiff_t buf_bytes = 3421 ptrdiff_t buf_bytes
3425 Z_BYTE - (!NILP (replace) ? ZV_BYTE - BEGV_BYTE : 0); 3422 = Z_BYTE - (!NILP (replace) ? ZV_BYTE - BEGV_BYTE : 0);
3426 ptrdiff_t buf_growth_max = BUF_BYTES_MAX - buf_bytes; 3423 ptrdiff_t buf_growth_max = BUF_BYTES_MAX - buf_bytes;
3427 off_t likely_growth = likely_end - beg_offset; 3424 off_t likely_growth = likely_end - beg_offset;
3428 if (buf_growth_max < likely_growth) 3425 if (buf_growth_max < likely_growth)
@@ -4545,6 +4542,7 @@ This calls `write-region-annotate-functions' at the start, and
4545 int save_errno = 0; 4542 int save_errno = 0;
4546 const char *fn; 4543 const char *fn;
4547 struct stat st; 4544 struct stat st;
4545 EMACS_TIME modtime;
4548 ptrdiff_t count = SPECPDL_INDEX (); 4546 ptrdiff_t count = SPECPDL_INDEX ();
4549 int count1; 4547 int count1;
4550 Lisp_Object handler; 4548 Lisp_Object handler;
@@ -4757,12 +4755,19 @@ This calls `write-region-annotate-functions' at the start, and
4757 } 4755 }
4758#endif 4756#endif
4759 4757
4758 modtime = invalid_emacs_time ();
4759 if (visiting)
4760 {
4761 if (fstat (desc, &st) == 0)
4762 modtime = get_stat_mtime (&st);
4763 else
4764 ok = 0, save_errno = errno;
4765 }
4766
4760 /* NFS can report a write failure now. */ 4767 /* NFS can report a write failure now. */
4761 if (emacs_close (desc) < 0) 4768 if (emacs_close (desc) < 0)
4762 ok = 0, save_errno = errno; 4769 ok = 0, save_errno = errno;
4763 4770
4764 stat (fn, &st);
4765
4766 /* Discard the unwind protect for close_file_unwind. */ 4771 /* Discard the unwind protect for close_file_unwind. */
4767 specpdl_ptr = specpdl + count1; 4772 specpdl_ptr = specpdl + count1;
4768 4773
@@ -4790,9 +4795,9 @@ This calls `write-region-annotate-functions' at the start, and
4790 /* Do this before reporting IO error 4795 /* Do this before reporting IO error
4791 to avoid a "file has changed on disk" warning on 4796 to avoid a "file has changed on disk" warning on
4792 next attempt to save. */ 4797 next attempt to save. */
4793 if (visiting) 4798 if (EMACS_TIME_VALID_P (modtime))
4794 { 4799 {
4795 current_buffer->modtime = get_stat_mtime (&st); 4800 current_buffer->modtime = modtime;
4796 current_buffer->modtime_size = st.st_size; 4801 current_buffer->modtime_size = st.st_size;
4797 } 4802 }
4798 4803
@@ -5042,12 +5047,12 @@ e_write (int desc, Lisp_Object string, ptrdiff_t start, ptrdiff_t end,
5042 5047
5043 if (coding->produced > 0) 5048 if (coding->produced > 0)
5044 { 5049 {
5045 coding->produced -= 5050 coding->produced
5046 emacs_write (desc, 5051 -= emacs_write (desc,
5047 STRINGP (coding->dst_object) 5052 STRINGP (coding->dst_object)
5048 ? SSDATA (coding->dst_object) 5053 ? SSDATA (coding->dst_object)
5049 : (char *) BYTE_POS_ADDR (coding->dst_pos_byte), 5054 : (char *) BYTE_POS_ADDR (coding->dst_pos_byte),
5050 coding->produced); 5055 coding->produced);
5051 5056
5052 if (coding->produced) 5057 if (coding->produced)
5053 return 0; 5058 return 0;
@@ -5226,8 +5231,8 @@ auto_save_1 (void)
5226 if (stat (SSDATA (BVAR (current_buffer, filename)), &st) >= 0) 5231 if (stat (SSDATA (BVAR (current_buffer, filename)), &st) >= 0)
5227 /* But make sure we can overwrite it later! */ 5232 /* But make sure we can overwrite it later! */
5228 auto_save_mode_bits = (st.st_mode | 0600) & 0777; 5233 auto_save_mode_bits = (st.st_mode | 0600) & 0777;
5229 else if ((modes = Ffile_modes (BVAR (current_buffer, filename)), 5234 else if (modes = Ffile_modes (BVAR (current_buffer, filename)),
5230 INTEGERP (modes))) 5235 INTEGERP (modes))
5231 /* Remote files don't cooperate with stat. */ 5236 /* Remote files don't cooperate with stat. */
5232 auto_save_mode_bits = (XINT (modes) | 0600) & 0777; 5237 auto_save_mode_bits = (XINT (modes) | 0600) & 0777;
5233 } 5238 }
diff --git a/src/image.c b/src/image.c
index 9b41cf74993..d52c3a29a27 100644
--- a/src/image.c
+++ b/src/image.c
@@ -2140,12 +2140,11 @@ x_find_image_file (Lisp_Object file)
2140static unsigned char * 2140static unsigned char *
2141slurp_file (char *file, ptrdiff_t *size) 2141slurp_file (char *file, ptrdiff_t *size)
2142{ 2142{
2143 FILE *fp = NULL; 2143 FILE *fp = fopen (file, "rb");
2144 unsigned char *buf = NULL; 2144 unsigned char *buf = NULL;
2145 struct stat st; 2145 struct stat st;
2146 2146
2147 if (stat (file, &st) == 0 2147 if (fp && fstat (fileno (fp), &st) == 0
2148 && (fp = fopen (file, "rb")) != NULL
2149 && 0 <= st.st_size && st.st_size <= min (PTRDIFF_MAX, SIZE_MAX) 2148 && 0 <= st.st_size && st.st_size <= min (PTRDIFF_MAX, SIZE_MAX)
2150 && (buf = xmalloc (st.st_size), 2149 && (buf = xmalloc (st.st_size),
2151 fread (buf, 1, st.st_size, fp) == st.st_size)) 2150 fread (buf, 1, st.st_size, fp) == st.st_size))
@@ -5004,45 +5003,6 @@ pbm_scan_number (unsigned char **s, unsigned char *end)
5004} 5003}
5005 5004
5006 5005
5007#ifdef HAVE_NTGUI
5008#if 0 /* Unused. ++kfs */
5009
5010/* Read FILE into memory. Value is a pointer to a buffer allocated
5011 with xmalloc holding FILE's contents. Value is null if an error
5012 occurred. *SIZE is set to the size of the file. */
5013
5014static char *
5015pbm_read_file (Lisp_Object file, int *size)
5016{
5017 FILE *fp = NULL;
5018 char *buf = NULL;
5019 struct stat st;
5020
5021 if (stat (SDATA (file), &st) == 0
5022 && (fp = fopen (SDATA (file), "rb")) != NULL
5023 && 0 <= st.st_size && st.st_size <= min (PTRDIFF_MAX, SIZE_MAX)
5024 && (buf = xmalloc (st.st_size),
5025 fread (buf, 1, st.st_size, fp) == st.st_size))
5026 {
5027 *size = st.st_size;
5028 fclose (fp);
5029 }
5030 else
5031 {
5032 if (fp)
5033 fclose (fp);
5034 if (buf)
5035 {
5036 xfree (buf);
5037 buf = NULL;
5038 }
5039 }
5040
5041 return buf;
5042}
5043#endif
5044#endif /* HAVE_NTGUI */
5045
5046/* Load PBM image IMG for use on frame F. */ 5006/* Load PBM image IMG for use on frame F. */
5047 5007
5048static bool 5008static bool
diff --git a/src/process.c b/src/process.c
index 2cbce9d28ea..d45a2c6e8e0 100644
--- a/src/process.c
+++ b/src/process.c
@@ -646,23 +646,6 @@ allocate_pty (void)
646 PTY_OPEN; 646 PTY_OPEN;
647#else /* no PTY_OPEN */ 647#else /* no PTY_OPEN */
648 { 648 {
649 { /* Some systems name their pseudoterminals so that there are gaps in
650 the usual sequence - for example, on HP9000/S700 systems, there
651 are no pseudoterminals with names ending in 'f'. So we wait for
652 three failures in a row before deciding that we've reached the
653 end of the ptys. */
654 int failed_count = 0;
655 struct stat stb;
656
657 if (stat (pty_name, &stb) < 0)
658 {
659 failed_count++;
660 if (failed_count >= 3)
661 return -1;
662 }
663 else
664 failed_count = 0;
665 }
666# ifdef O_NONBLOCK 649# ifdef O_NONBLOCK
667 fd = emacs_open (pty_name, O_RDWR | O_NONBLOCK, 0); 650 fd = emacs_open (pty_name, O_RDWR | O_NONBLOCK, 0);
668# else 651# else