mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-28 11:57:28 +00:00
Make mv more robust. A race has been fixed, as well as an extra warning
added when sbits are cleared. Fixes PR 1351 and 1377 (I hope).
This commit is contained in:
parent
f71e91691c
commit
03001f577f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=23525
38
bin/mv/mv.c
38
bin/mv/mv.c
@ -33,7 +33,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
* $Id: mv.c,v 1.11 1997/02/22 14:04:12 peter Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
@ -206,20 +206,29 @@ fastcopy(from, to, sbp)
|
||||
struct timeval tval[2];
|
||||
static u_int blen;
|
||||
static char *bp;
|
||||
mode_t oldmode;
|
||||
register int nread, from_fd, to_fd;
|
||||
|
||||
if ((from_fd = open(from, O_RDONLY, 0)) < 0) {
|
||||
warn("%s", from);
|
||||
return (1);
|
||||
}
|
||||
if ((to_fd =
|
||||
open(to, O_CREAT | O_TRUNC | O_WRONLY, sbp->st_mode)) < 0) {
|
||||
warn("%s", to);
|
||||
(void)close(from_fd);
|
||||
if (blen < sbp->st_blksize) {
|
||||
if (bp != NULL)
|
||||
free(bp);
|
||||
if ((bp = malloc(sbp->st_blksize)) == NULL) {
|
||||
blen = 0;
|
||||
warnx("malloc failed");
|
||||
return (1);
|
||||
}
|
||||
if (!blen && !(bp = malloc(blen = sbp->st_blksize))) {
|
||||
warn(NULL);
|
||||
blen = sbp->st_blksize;
|
||||
}
|
||||
while ((to_fd =
|
||||
open(to, O_CREAT | O_EXCL | O_TRUNC | O_WRONLY, 0)) < 0) {
|
||||
if (errno == EEXIST && unlink(to) == 0)
|
||||
continue;
|
||||
warn("%s", to);
|
||||
(void)close(from_fd);
|
||||
return (1);
|
||||
}
|
||||
while ((nread = read(from_fd, bp, blen)) > 0)
|
||||
@ -237,10 +246,19 @@ err: if (unlink(to))
|
||||
}
|
||||
(void)close(from_fd);
|
||||
|
||||
if (fchown(to_fd, sbp->st_uid, sbp->st_gid))
|
||||
warn("%s: set owner/group", to);
|
||||
oldmode = sbp->st_mode & ALLPERMS;
|
||||
if (fchown(to_fd, sbp->st_uid, sbp->st_gid)) {
|
||||
warn("%s: set owner/group (was: %u/%u)", to, sbp->st_uid,
|
||||
sbp->st_gid);
|
||||
if (oldmode & (S_ISUID | S_ISGID)) {
|
||||
warnx(
|
||||
"%s: owner/group changed; clearing suid/sgid (mode was 0%03o)",
|
||||
to, oldmode);
|
||||
sbp->st_mode &= ~(S_ISUID | S_ISGID);
|
||||
}
|
||||
}
|
||||
if (fchmod(to_fd, sbp->st_mode))
|
||||
warn("%s: set mode", to);
|
||||
warn("%s: set mode (was: 0%03o)", to, oldmode);
|
||||
|
||||
tval[0].tv_sec = sbp->st_atime;
|
||||
tval[1].tv_sec = sbp->st_mtime;
|
||||
|
Loading…
Reference in New Issue
Block a user