diff options
| author | Richard M. Stallman | 2005-06-25 22:37:49 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 2005-06-25 22:37:49 +0000 |
| commit | 586702ceeb85856b076b7eec369791c1bb66e765 (patch) | |
| tree | 7a0d02d4df6f34e6fd3174af3fc9257d72534be3 /src | |
| parent | 29e952546a2a2d16c5e397d5924a2a2086b370ec (diff) | |
| download | emacs-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.c | 57 |
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 | ||
| 2409 | DEFUN ("copy-file", Fcopy_file, Scopy_file, 2, 5, | 2409 | DEFUN ("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. |
| 2412 | If NEWNAME names a directory, copy FILE there. | 2412 | If NEWNAME names a directory, copy FILE there. |
| @@ -2426,9 +2426,13 @@ for an existing file with the same name. If MUSTBENEW is `excl', | |||
| 2426 | that means to get an error if the file already exists; never overwrite. | 2426 | that means to get an error if the file already exists; never overwrite. |
| 2427 | If MUSTBENEW is neither nil nor `excl', that means ask for | 2427 | If MUSTBENEW is neither nil nor `excl', that means ask for |
| 2428 | confirmation before overwriting, but do go ahead and overwrite the file | 2428 | confirmation before overwriting, but do go ahead and overwrite the file |
| 2429 | if the user confirms. */) | 2429 | if the user confirms. |
| 2430 | (file, newname, ok_if_already_exists, keep_time, mustbenew) | 2430 | |
| 2431 | If PRESERVE-UID-GID is non-nil, we try to transfer the | ||
| 2432 | uid 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 | } |