aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman2005-06-25 22:37:49 +0000
committerRichard M. Stallman2005-06-25 22:37:49 +0000
commit586702ceeb85856b076b7eec369791c1bb66e765 (patch)
tree7a0d02d4df6f34e6fd3174af3fc9257d72534be3 /src
parent29e952546a2a2d16c5e397d5924a2a2086b370ec (diff)
downloademacs-586702ceeb85856b076b7eec369791c1bb66e765.tar.gz
emacs-586702ceeb85856b076b7eec369791c1bb66e765.zip
(Fcopy_file): New arg PRESERVE_UID_GID.
Use fchmod to copy the file modes. (Frename_file): Don't copy UID and GID here; instead, specify t for PRESERVE_UID_GID when calling Fcopy_file.
Diffstat (limited to 'src')
-rw-r--r--src/fileio.c57
1 files changed, 32 insertions, 25 deletions
diff --git a/src/fileio.c b/src/fileio.c
index 6bdc030bc6c..c4a267f4ea1 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -2406,7 +2406,7 @@ barf_or_query_if_file_exists (absname, querystring, interactive, statptr, quick)
2406 return; 2406 return;
2407} 2407}
2408 2408
2409DEFUN ("copy-file", Fcopy_file, Scopy_file, 2, 5, 2409DEFUN ("copy-file", Fcopy_file, Scopy_file, 2, 6,
2410 "fCopy file: \nGCopy %s to file: \np\nP", 2410 "fCopy file: \nGCopy %s to file: \np\nP",
2411 doc: /* Copy FILE to NEWNAME. Both args must be strings. 2411 doc: /* Copy FILE to NEWNAME. Both args must be strings.
2412If NEWNAME names a directory, copy FILE there. 2412If NEWNAME names a directory, copy FILE there.
@@ -2426,9 +2426,13 @@ for an existing file with the same name. If MUSTBENEW is `excl',
2426that means to get an error if the file already exists; never overwrite. 2426that means to get an error if the file already exists; never overwrite.
2427If MUSTBENEW is neither nil nor `excl', that means ask for 2427If MUSTBENEW is neither nil nor `excl', that means ask for
2428confirmation before overwriting, but do go ahead and overwrite the file 2428confirmation before overwriting, but do go ahead and overwrite the file
2429if the user confirms. */) 2429if the user confirms.
2430 (file, newname, ok_if_already_exists, keep_time, mustbenew) 2430
2431If PRESERVE-UID-GID is non-nil, we try to transfer the
2432uid and gid of FILE to NEWNAME. */)
2433 (file, newname, ok_if_already_exists, keep_time, mustbenew, preserve_uid_gid)
2431 Lisp_Object file, newname, ok_if_already_exists, keep_time, mustbenew; 2434 Lisp_Object file, newname, ok_if_already_exists, keep_time, mustbenew;
2435 Lisp_Object preserve_uid_gid;
2432{ 2436{
2433 int ifd, ofd, n; 2437 int ifd, ofd, n;
2434 char buf[16 * 1024]; 2438 char buf[16 * 1024];
@@ -2570,6 +2574,26 @@ if the user confirms. */)
2570 report_file_error ("I/O error", Fcons (newname, Qnil)); 2574 report_file_error ("I/O error", Fcons (newname, Qnil));
2571 immediate_quit = 0; 2575 immediate_quit = 0;
2572 2576
2577 /* Preserve the owner and group, if requested. */
2578 if (input_file_statable_p && ! NILP (preserve_uid_gid))
2579 fchown (ofd, st.st_uid, st.st_gid);
2580
2581 if (input_file_statable_p)
2582 {
2583#ifndef MSDOS
2584 fchmod (ofd, st.st_mode & 07777);
2585#else /* MSDOS */
2586#if defined (__DJGPP__) && __DJGPP__ > 1
2587 /* In DJGPP v2.0 and later, fstat usually returns true file mode bits,
2588 and if it can't, it tells so. Otherwise, under MSDOS we usually
2589 get only the READ bit, which will make the copied file read-only,
2590 so it's better not to chmod at all. */
2591 if ((_djstat_flags & _STFAIL_WRITEBIT) == 0)
2592 chmod (SDATA (encoded_newname), st.st_mode & 07777);
2593#endif /* DJGPP version 2 or newer */
2594#endif /* MSDOS */
2595 }
2596
2573 /* Closing the output clobbers the file times on some systems. */ 2597 /* Closing the output clobbers the file times on some systems. */
2574 if (emacs_close (ofd) < 0) 2598 if (emacs_close (ofd) < 0)
2575 report_file_error ("I/O error", Fcons (newname, Qnil)); 2599 report_file_error ("I/O error", Fcons (newname, Qnil));
@@ -2587,18 +2611,6 @@ if the user confirms. */)
2587 Fcons (build_string ("Cannot set file date"), 2611 Fcons (build_string ("Cannot set file date"),
2588 Fcons (newname, Qnil))); 2612 Fcons (newname, Qnil)));
2589 } 2613 }
2590#ifndef MSDOS
2591 chmod (SDATA (encoded_newname), st.st_mode & 07777);
2592#else /* MSDOS */
2593#if defined (__DJGPP__) && __DJGPP__ > 1
2594 /* In DJGPP v2.0 and later, fstat usually returns true file mode bits,
2595 and if it can't, it tells so. Otherwise, under MSDOS we usually
2596 get only the READ bit, which will make the copied file read-only,
2597 so it's better not to chmod at all. */
2598 if ((_djstat_flags & _STFAIL_WRITEBIT) == 0)
2599 chmod (SDATA (encoded_newname), st.st_mode & 07777);
2600#endif /* DJGPP version 2 or newer */
2601#endif /* MSDOS */
2602 } 2614 }
2603 2615
2604 emacs_close (ifd); 2616 emacs_close (ifd);
@@ -2775,7 +2787,6 @@ This is what happens in interactive use with M-x. */)
2775 { 2787 {
2776 if (errno == EXDEV) 2788 if (errno == EXDEV)
2777 { 2789 {
2778 struct stat data;
2779#ifdef S_IFLNK 2790#ifdef S_IFLNK
2780 symlink_target = Ffile_symlink_p (file); 2791 symlink_target = Ffile_symlink_p (file);
2781 if (! NILP (symlink_target)) 2792 if (! NILP (symlink_target))
@@ -2783,15 +2794,11 @@ This is what happens in interactive use with M-x. */)
2783 NILP (ok_if_already_exists) ? Qnil : Qt); 2794 NILP (ok_if_already_exists) ? Qnil : Qt);
2784 else 2795 else
2785#endif 2796#endif
2786 Fcopy_file (file, newname, 2797 Fcopy_file (file, newname,
2787 /* We have already prompted if it was an integer, 2798 /* We have already prompted if it was an integer,
2788 so don't have copy-file prompt again. */ 2799 so don't have copy-file prompt again. */
2789 NILP (ok_if_already_exists) ? Qnil : Qt, 2800 NILP (ok_if_already_exists) ? Qnil : Qt,
2790 Qt, Qnil); 2801 Qt, Qnil, Qt);
2791
2792 /* Preserve owner and group, if possible (if we are root). */
2793 if (stat (SDATA (encoded_file), &data) >= 0)
2794 chown (SDATA (encoded_file), data.st_uid, data.st_gid);
2795 2802
2796 Fdelete_file (file); 2803 Fdelete_file (file);
2797 } 2804 }