aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael Albinus2017-08-02 11:01:05 +0200
committerMichael Albinus2017-08-02 11:01:05 +0200
commit49d6e59717ad182487910b863656bb6a11080bcf (patch)
tree50e78797cbeb8b243ac3773237ea33dd3725df44 /src
parent4207733f4aefd17fd06e7820775d4c2359daba87 (diff)
parent1f9f514e7c2ba41b0954d0141f99652f6a53a107 (diff)
downloademacs-49d6e59717ad182487910b863656bb6a11080bcf.tar.gz
emacs-49d6e59717ad182487910b863656bb6a11080bcf.zip
Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs
Diffstat (limited to 'src')
-rw-r--r--src/fileio.c141
-rw-r--r--src/filelock.c3
-rw-r--r--src/lisp.h6
-rw-r--r--src/sysdep.c20
4 files changed, 100 insertions, 70 deletions
diff --git a/src/fileio.c b/src/fileio.c
index 7531214fe45..0264c9fa1d8 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -2311,6 +2311,7 @@ This is what happens in interactive use with M-x. */)
2311{ 2311{
2312 Lisp_Object handler; 2312 Lisp_Object handler;
2313 Lisp_Object encoded_file, encoded_newname, symlink_target; 2313 Lisp_Object encoded_file, encoded_newname, symlink_target;
2314 int dirp = -1;
2314 2315
2315 symlink_target = encoded_file = encoded_newname = Qnil; 2316 symlink_target = encoded_file = encoded_newname = Qnil;
2316 CHECK_STRING (file); 2317 CHECK_STRING (file);
@@ -2324,8 +2325,8 @@ This is what happens in interactive use with M-x. */)
2324 && (NILP (Ffile_name_case_insensitive_p (file)) 2325 && (NILP (Ffile_name_case_insensitive_p (file))
2325 || NILP (Fstring_equal (Fdowncase (file), Fdowncase (newname))))) 2326 || NILP (Fstring_equal (Fdowncase (file), Fdowncase (newname)))))
2326 { 2327 {
2327 Lisp_Object fname = (NILP (Ffile_directory_p (file)) 2328 dirp = !NILP (Ffile_directory_p (file));
2328 ? file : Fdirectory_file_name (file)); 2329 Lisp_Object fname = dirp ? Fdirectory_file_name (file) : file;
2329 newname = Fexpand_file_name (Ffile_name_nondirectory (fname), newname); 2330 newname = Fexpand_file_name (Ffile_name_nondirectory (fname), newname);
2330 } 2331 }
2331 else 2332 else
@@ -2343,47 +2344,55 @@ This is what happens in interactive use with M-x. */)
2343 encoded_file = ENCODE_FILE (file); 2344 encoded_file = ENCODE_FILE (file);
2344 encoded_newname = ENCODE_FILE (newname); 2345 encoded_newname = ENCODE_FILE (newname);
2345 2346
2346 /* If the filesystem is case-insensitive and the file names are 2347 if (renameat_noreplace (AT_FDCWD, SSDATA (encoded_file),
2347 identical but for the case, don't ask for confirmation: they 2348 AT_FDCWD, SSDATA (encoded_newname))
2348 simply want to change the letter-case of the file name. */ 2349 == 0)
2349 if ((!(file_name_case_insensitive_p (SSDATA (encoded_file))) 2350 return Qnil;
2350 || NILP (Fstring_equal (Fdowncase (file), Fdowncase (newname)))) 2351 int rename_errno = errno;
2351 && ((NILP (ok_if_already_exists) || INTEGERP (ok_if_already_exists)))) 2352
2352 barf_or_query_if_file_exists (newname, false, "rename to it", 2353 if (rename_errno == EEXIST || rename_errno == ENOSYS)
2353 INTEGERP (ok_if_already_exists), false);
2354 if (rename (SSDATA (encoded_file), SSDATA (encoded_newname)) < 0)
2355 { 2354 {
2356 int rename_errno = errno; 2355 /* If the filesystem is case-insensitive and the file names are
2357 if (rename_errno == EXDEV) 2356 identical but for the case, don't ask for confirmation: they
2358 { 2357 simply want to change the letter-case of the file name. */
2359 ptrdiff_t count; 2358 if ((NILP (ok_if_already_exists) || INTEGERP (ok_if_already_exists))
2360 symlink_target = Ffile_symlink_p (file); 2359 && (! file_name_case_insensitive_p (SSDATA (encoded_file))
2361 if (! NILP (symlink_target)) 2360 || NILP (Fstring_equal (Fdowncase (file), Fdowncase (newname)))))
2362 Fmake_symbolic_link (symlink_target, newname, 2361 barf_or_query_if_file_exists (newname, rename_errno == EEXIST,
2363 NILP (ok_if_already_exists) ? Qnil : Qt); 2362 "rename to it",
2364 else if (!NILP (Ffile_directory_p (file))) 2363 INTEGERP (ok_if_already_exists), false);
2365 call4 (Qcopy_directory, file, newname, Qt, Qnil); 2364 if (rename (SSDATA (encoded_file), SSDATA (encoded_newname)) == 0)
2366 else 2365 return Qnil;
2367 /* We have already prompted if it was an integer, so don't 2366 rename_errno = errno;
2368 have copy-file prompt again. */ 2367 /* Don't prompt again. */
2369 Fcopy_file (file, newname, 2368 ok_if_already_exists = Qt;
2370 NILP (ok_if_already_exists) ? Qnil : Qt, 2369 }
2371 Qt, Qt, Qt); 2370 else if (!NILP (ok_if_already_exists))
2371 ok_if_already_exists = Qt;
2372 2372
2373 count = SPECPDL_INDEX (); 2373 if (rename_errno != EXDEV)
2374 specbind (Qdelete_by_moving_to_trash, Qnil); 2374 report_file_errno ("Renaming", list2 (file, newname), rename_errno);
2375 2375
2376 if (!NILP (Ffile_directory_p (file)) && NILP (symlink_target)) 2376 symlink_target = Ffile_symlink_p (file);
2377 call2 (Qdelete_directory, file, Qt); 2377 if (!NILP (symlink_target))
2378 else 2378 Fmake_symbolic_link (symlink_target, newname, ok_if_already_exists);
2379 Fdelete_file (file, Qnil); 2379 else
2380 unbind_to (count, Qnil); 2380 {
2381 } 2381 if (dirp < 0)
2382 dirp = !NILP (Ffile_directory_p (file));
2383 if (dirp)
2384 call4 (Qcopy_directory, file, newname, Qt, Qnil);
2382 else 2385 else
2383 report_file_errno ("Renaming", list2 (file, newname), rename_errno); 2386 Fcopy_file (file, newname, ok_if_already_exists, Qt, Qt, Qt);
2384 } 2387 }
2385 2388
2386 return Qnil; 2389 ptrdiff_t count = SPECPDL_INDEX ();
2390 specbind (Qdelete_by_moving_to_trash, Qnil);
2391 if (dirp && NILP (symlink_target))
2392 call2 (Qdelete_directory, file, Qt);
2393 else
2394 Fdelete_file (file, Qnil);
2395 return unbind_to (count, Qnil);
2387} 2396}
2388 2397
2389DEFUN ("add-name-to-file", Fadd_name_to_file, Sadd_name_to_file, 2, 3, 2398DEFUN ("add-name-to-file", Fadd_name_to_file, Sadd_name_to_file, 2, 3,
@@ -2425,19 +2434,21 @@ This is what happens in interactive use with M-x. */)
2425 encoded_file = ENCODE_FILE (file); 2434 encoded_file = ENCODE_FILE (file);
2426 encoded_newname = ENCODE_FILE (newname); 2435 encoded_newname = ENCODE_FILE (newname);
2427 2436
2428 if (NILP (ok_if_already_exists) 2437 if (link (SSDATA (encoded_file), SSDATA (encoded_newname)) == 0)
2429 || INTEGERP (ok_if_already_exists)) 2438 return Qnil;
2430 barf_or_query_if_file_exists (newname, false, "make it a new name",
2431 INTEGERP (ok_if_already_exists), false);
2432 2439
2433 unlink (SSDATA (newname)); 2440 if (errno == EEXIST)
2434 if (link (SSDATA (encoded_file), SSDATA (encoded_newname)) < 0)
2435 { 2441 {
2436 int link_errno = errno; 2442 if (NILP (ok_if_already_exists)
2437 report_file_errno ("Adding new name", list2 (file, newname), link_errno); 2443 || INTEGERP (ok_if_already_exists))
2444 barf_or_query_if_file_exists (newname, true, "make it a new name",
2445 INTEGERP (ok_if_already_exists), false);
2446 unlink (SSDATA (newname));
2447 if (link (SSDATA (encoded_file), SSDATA (encoded_newname)) == 0)
2448 return Qnil;
2438 } 2449 }
2439 2450
2440 return Qnil; 2451 report_file_error ("Adding new name", list2 (file, newname));
2441} 2452}
2442 2453
2443DEFUN ("make-symbolic-link", Fmake_symbolic_link, Smake_symbolic_link, 2, 3, 2454DEFUN ("make-symbolic-link", Fmake_symbolic_link, Smake_symbolic_link, 2, 3,
@@ -2484,31 +2495,25 @@ This happens for interactive use with M-x. */)
2484 encoded_target = ENCODE_FILE (target); 2495 encoded_target = ENCODE_FILE (target);
2485 encoded_linkname = ENCODE_FILE (linkname); 2496 encoded_linkname = ENCODE_FILE (linkname);
2486 2497
2487 if (NILP (ok_if_already_exists) 2498 if (symlink (SSDATA (encoded_target), SSDATA (encoded_linkname)) == 0)
2488 || INTEGERP (ok_if_already_exists)) 2499 return Qnil;
2489 barf_or_query_if_file_exists (linkname, false, "make it a link",
2490 INTEGERP (ok_if_already_exists), false);
2491 if (symlink (SSDATA (encoded_target), SSDATA (encoded_linkname)) < 0)
2492 {
2493 /* If we didn't complain already, silently delete existing file. */
2494 int symlink_errno;
2495 if (errno == EEXIST)
2496 {
2497 unlink (SSDATA (encoded_linkname));
2498 if (symlink (SSDATA (encoded_target), SSDATA (encoded_linkname))
2499 >= 0)
2500 return Qnil;
2501 }
2502 if (errno == ENOSYS)
2503 xsignal1 (Qfile_error,
2504 build_string ("Symbolic links are not supported"));
2505 2500
2506 symlink_errno = errno; 2501 if (errno == ENOSYS)
2507 report_file_errno ("Making symbolic link", list2 (target, linkname), 2502 xsignal1 (Qfile_error,
2508 symlink_errno); 2503 build_string ("Symbolic links are not supported"));
2504
2505 if (errno == EEXIST)
2506 {
2507 if (NILP (ok_if_already_exists)
2508 || INTEGERP (ok_if_already_exists))
2509 barf_or_query_if_file_exists (linkname, true, "make it a link",
2510 INTEGERP (ok_if_already_exists), false);
2511 unlink (SSDATA (encoded_linkname));
2512 if (symlink (SSDATA (encoded_target), SSDATA (encoded_linkname)) == 0)
2513 return Qnil;
2509 } 2514 }
2510 2515
2511 return Qnil; 2516 report_file_error ("Making symbolic link", list2 (target, linkname));
2512} 2517}
2513 2518
2514 2519
diff --git a/src/filelock.c b/src/filelock.c
index bfa1d63d833..dd8cb28c425 100644
--- a/src/filelock.c
+++ b/src/filelock.c
@@ -339,6 +339,9 @@ rename_lock_file (char const *old, char const *new, bool force)
339 { 339 {
340 struct stat st; 340 struct stat st;
341 341
342 int r = renameat_noreplace (AT_FDCWD, old, AT_FDCWD, new);
343 if (! (r < 0 && errno == ENOSYS))
344 return r;
342 if (link (old, new) == 0) 345 if (link (old, new) == 0)
343 return unlink (old) == 0 || errno == ENOENT ? 0 : -1; 346 return unlink (old) == 0 || errno == ENOENT ? 0 : -1;
344 if (errno != ENOSYS && errno != LINKS_MIGHT_NOT_WORK) 347 if (errno != ENOSYS && errno != LINKS_MIGHT_NOT_WORK)
diff --git a/src/lisp.h b/src/lisp.h
index cffaf954b3b..4de6fc85ec1 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4298,13 +4298,15 @@ extern ptrdiff_t emacs_write (int, void const *, ptrdiff_t);
4298extern ptrdiff_t emacs_write_sig (int, void const *, ptrdiff_t); 4298extern ptrdiff_t emacs_write_sig (int, void const *, ptrdiff_t);
4299extern ptrdiff_t emacs_write_quit (int, void const *, ptrdiff_t); 4299extern ptrdiff_t emacs_write_quit (int, void const *, ptrdiff_t);
4300extern void emacs_perror (char const *); 4300extern void emacs_perror (char const *);
4301extern int renameat_noreplace (int, char const *, int, char const *);
4302extern int str_collate (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object);
4301 4303
4302extern void unlock_all_files (void); 4304/* Defined in filelock.c. */
4303extern void lock_file (Lisp_Object); 4305extern void lock_file (Lisp_Object);
4304extern void unlock_file (Lisp_Object); 4306extern void unlock_file (Lisp_Object);
4307extern void unlock_all_files (void);
4305extern void unlock_buffer (struct buffer *); 4308extern void unlock_buffer (struct buffer *);
4306extern void syms_of_filelock (void); 4309extern void syms_of_filelock (void);
4307extern int str_collate (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object);
4308 4310
4309/* Defined in sound.c. */ 4311/* Defined in sound.c. */
4310extern void syms_of_sound (void); 4312extern void syms_of_sound (void);
diff --git a/src/sysdep.c b/src/sysdep.c
index db99f53299c..22446b25d16 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -37,6 +37,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
37#include "sysselect.h" 37#include "sysselect.h"
38#include "blockinput.h" 38#include "blockinput.h"
39 39
40#ifdef HAVE_LINUX_FS_H
41# include <linux/fs.h>
42# include <sys/syscall.h>
43#endif
44
40#if defined DARWIN_OS || defined __FreeBSD__ 45#if defined DARWIN_OS || defined __FreeBSD__
41# include <sys/sysctl.h> 46# include <sys/sysctl.h>
42#endif 47#endif
@@ -2678,6 +2683,21 @@ set_file_times (int fd, const char *filename,
2678 timespec[1] = mtime; 2683 timespec[1] = mtime;
2679 return fdutimens (fd, filename, timespec); 2684 return fdutimens (fd, filename, timespec);
2680} 2685}
2686
2687/* Rename directory SRCFD's entry SRC to directory DSTFD's entry DST.
2688 This is like renameat except that it fails if DST already exists,
2689 or if this operation is not supported atomically. Return 0 if
2690 successful, -1 (setting errno) otherwise. */
2691int
2692renameat_noreplace (int srcfd, char const *src, int dstfd, char const *dst)
2693{
2694#ifdef SYS_renameat2
2695 return syscall (SYS_renameat2, srcfd, src, dstfd, dst, RENAME_NOREPLACE);
2696#else
2697 errno = ENOSYS;
2698 return -1;
2699#endif
2700}
2681 2701
2682/* Like strsignal, except async-signal-safe, and this function typically 2702/* Like strsignal, except async-signal-safe, and this function typically
2683 returns a string in the C locale rather than the current locale. */ 2703 returns a string in the C locale rather than the current locale. */