From d5cda1d9de1e19b958e61c62244d9854c7889a8b Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Mon, 22 Sep 2008 14:09:53 +1200 Subject: [PATCH] Bug 455259. Don't use access() to check if a file is writeable, since with at least some Linux kernels it will return OK for a file that will give 'text file busy' when written. Just try to open the file and take the rename/unlink path if we can't open it. r=bsmedberg --- config/nsinstall.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/config/nsinstall.c b/config/nsinstall.c index b46aeaa1a049..b6ca0e3694e3 100644 --- a/config/nsinstall.c +++ b/config/nsinstall.c @@ -164,7 +164,7 @@ static void copyfile( char *name, char *toname, mode_t mode, char *group, char *owner, int dotimes, uid_t uid, gid_t gid ) { - int fromfd, tofd, cc, wc, exists; + int fromfd, tofd = -1, cc, wc, exists; char buf[BUFSIZ], *bp; struct stat sb, tosb; struct utimbuf utb; @@ -174,11 +174,20 @@ copyfile( char *name, char *toname, mode_t mode, char *group, char *owner, fromfd = open(name, O_RDONLY); if (fromfd < 0 || fstat(fromfd, &sb) < 0) fail("cannot access %s", name); - if (exists && (!S_ISREG(tosb.st_mode) || access(toname, W_OK) < 0)) - (void) (S_ISDIR(tosb.st_mode) ? rmdir : unlink)(toname); - tofd = open(toname, O_CREAT | O_WRONLY, 0666); - if (tofd < 0) - fail("cannot create %s", toname); + if (exists) { + if (S_ISREG(tosb.st_mode)) { + /* See if we can open it. This is more reliable than 'access'. */ + tofd = open(toname, O_CREAT | O_WRONLY, 0666); + } + if (tofd < 0) { + (void) (S_ISDIR(tosb.st_mode) ? rmdir : unlink)(toname); + } + } + if (tofd < 0) { + tofd = open(toname, O_CREAT | O_WRONLY, 0666); + if (tofd < 0) + fail("cannot create %s", toname); + } bp = buf; while ((cc = read(fromfd, bp, sizeof buf)) > 0)