You've already forked macports-base
mirror of
https://github.com/macports/macports-base.git
synced 2026-07-12 18:18:43 -07:00
vendor/install: correct file handling
Handle existing target files and source symlinks in the expected way. Closes: https://trac.macports.org/ticket/72850
This commit is contained in:
Vendored
+36
-25
@@ -93,6 +93,7 @@ mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
|
||||
char *suffix = BACKUP_SUFFIX;
|
||||
|
||||
static int clone __P((const char *, const char *, int, char *, size_t));
|
||||
static void handle_existing_file __P((char *path, struct stat *sbp));
|
||||
void copy __P((int, char *, int, char *, off_t));
|
||||
int compare __P((int, const char *, size_t, int, const char *, size_t));
|
||||
int create_newfile __P((char *, int, struct stat *));
|
||||
@@ -339,6 +340,9 @@ install(char *from_name, char *to_name,
|
||||
if (!files_match) {
|
||||
int done_clone = 0;
|
||||
if (tryclone && !devnull && !dostrip) {
|
||||
if (!tempcopy && target) {
|
||||
handle_existing_file(to_name, &to_sb);
|
||||
}
|
||||
done_clone = (clone(from_name, to_name, tempcopy, tempfile, sizeof(tempfile)) == 0);
|
||||
}
|
||||
if (done_clone &&
|
||||
@@ -640,6 +644,36 @@ create_tempfile(char *path,
|
||||
return (mkstemp(temp));
|
||||
}
|
||||
|
||||
/* unlink or move (backup) an existing file */
|
||||
static void
|
||||
handle_existing_file(char *path, struct stat *sbp)
|
||||
{
|
||||
char backup[MAXPATHLEN];
|
||||
/*
|
||||
* Unlink now... avoid ETXTBSY errors later. Try to turn
|
||||
* off the append/immutable bits -- if we fail, go ahead,
|
||||
* it might work.
|
||||
*/
|
||||
if (sbp->st_flags & NOCHANGEBITS)
|
||||
(void)chflags(path, sbp->st_flags & ~NOCHANGEBITS);
|
||||
|
||||
if (dobackup) {
|
||||
if (snprintf(backup, MAXPATHLEN, "%s%s",
|
||||
path, suffix) != strlen(path) + strlen(suffix))
|
||||
errx(EX_OSERR, "%s: backup filename too long",
|
||||
path);
|
||||
(void)snprintf(backup, MAXPATHLEN, "%s%s",
|
||||
path, suffix);
|
||||
if (verbose)
|
||||
(void)printf("install: %s -> %s\n",
|
||||
path, backup);
|
||||
if (rename(path, backup) < 0)
|
||||
err(EX_OSERR, "rename: %s to %s", path, backup);
|
||||
} else {
|
||||
(void)unlink(path);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* create_newfile --
|
||||
* create a new file, overwriting an existing one if necessary
|
||||
@@ -649,31 +683,8 @@ create_newfile(char *path,
|
||||
int target,
|
||||
struct stat *sbp)
|
||||
{
|
||||
char backup[MAXPATHLEN];
|
||||
|
||||
if (target) {
|
||||
/*
|
||||
* Unlink now... avoid ETXTBSY errors later. Try to turn
|
||||
* off the append/immutable bits -- if we fail, go ahead,
|
||||
* it might work.
|
||||
*/
|
||||
if (sbp->st_flags & NOCHANGEBITS)
|
||||
(void)chflags(path, sbp->st_flags & ~NOCHANGEBITS);
|
||||
|
||||
if (dobackup) {
|
||||
if (snprintf(backup, MAXPATHLEN, "%s%s",
|
||||
path, suffix) != strlen(path) + strlen(suffix))
|
||||
errx(EX_OSERR, "%s: backup filename too long",
|
||||
path);
|
||||
(void)snprintf(backup, MAXPATHLEN, "%s%s",
|
||||
path, suffix);
|
||||
if (verbose)
|
||||
(void)printf("install: %s -> %s\n",
|
||||
path, backup);
|
||||
if (rename(path, backup) < 0)
|
||||
err(EX_OSERR, "rename: %s to %s", path, backup);
|
||||
} else
|
||||
(void)unlink(path);
|
||||
handle_existing_file(path, sbp);
|
||||
}
|
||||
|
||||
return (open(path, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR));
|
||||
@@ -775,7 +786,7 @@ clone(const char *from_name, const char *to_name,
|
||||
mktemp(temp_name);
|
||||
to_name = temp_name;
|
||||
}
|
||||
return clonefile(from_name, to_name, CLONE_NOFOLLOW|CLONE_NOOWNERCOPY);
|
||||
return clonefile(from_name, to_name, CLONE_NOOWNERCOPY);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+79
-11
@@ -1,8 +1,8 @@
|
||||
Applied to original from file_cmds-430.140.2
|
||||
|
||||
--- xinstall.c.orig 2024-08-20 16:07:42
|
||||
+++ xinstall.c 2024-08-27 16:58:56
|
||||
@@ -70,9 +70,9 @@
|
||||
+++ xinstall.c 2025-08-18 10:03:32
|
||||
@@ -70,9 +70,9 @@ __used static const char rcsid[] =
|
||||
#ifdef __APPLE__
|
||||
#include <TargetConditionals.h>
|
||||
#include <copyfile.h>
|
||||
@@ -14,15 +14,16 @@ Applied to original from file_cmds-430.140.2
|
||||
|
||||
/* Bootstrap aid - this doesn't exist in most older releases */
|
||||
#ifndef MAP_FAILED
|
||||
@@ -92,6 +92,7 @@
|
||||
@@ -92,6 +92,8 @@ char *suffix = BACKUP_SUFFIX;
|
||||
mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
|
||||
char *suffix = BACKUP_SUFFIX;
|
||||
|
||||
+static int clone __P((const char *, const char *, int, char *, size_t));
|
||||
+static void handle_existing_file __P((char *path, struct stat *sbp));
|
||||
void copy __P((int, char *, int, char *, off_t));
|
||||
int compare __P((int, const char *, size_t, int, const char *, size_t));
|
||||
int create_newfile __P((char *, int, struct stat *));
|
||||
@@ -100,6 +101,7 @@
|
||||
@@ -100,6 +102,7 @@ void strip __P((char *));
|
||||
void install_dir __P((char *));
|
||||
u_long numeric_id __P((char *, char *));
|
||||
void strip __P((char *));
|
||||
@@ -30,7 +31,7 @@ Applied to original from file_cmds-430.140.2
|
||||
int trymmap __P((int));
|
||||
void usage __P((void));
|
||||
|
||||
@@ -276,9 +278,10 @@
|
||||
@@ -276,9 +279,10 @@ install(char *from_name, char *to_name,
|
||||
{
|
||||
struct stat from_sb, temp_sb, to_sb;
|
||||
struct utimbuf utb;
|
||||
@@ -43,12 +44,15 @@ Applied to original from file_cmds-430.140.2
|
||||
|
||||
files_match = 0;
|
||||
|
||||
@@ -334,6 +337,17 @@
|
||||
@@ -334,6 +338,20 @@ install(char *from_name, char *to_name,
|
||||
}
|
||||
|
||||
if (!files_match) {
|
||||
+ int done_clone = 0;
|
||||
+ if (tryclone && !devnull && !dostrip) {
|
||||
+ if (!tempcopy && target) {
|
||||
+ handle_existing_file(to_name, &to_sb);
|
||||
+ }
|
||||
+ done_clone = (clone(from_name, to_name, tempcopy, tempfile, sizeof(tempfile)) == 0);
|
||||
+ }
|
||||
+ if (done_clone &&
|
||||
@@ -61,7 +65,7 @@ Applied to original from file_cmds-430.140.2
|
||||
if (tempcopy) {
|
||||
to_fd = create_tempfile(to_name, tempfile,
|
||||
sizeof(tempfile));
|
||||
@@ -350,6 +364,7 @@
|
||||
@@ -350,6 +368,7 @@ install(char *from_name, char *to_name,
|
||||
if (!devnull)
|
||||
copy(from_fd, from_name, to_fd,
|
||||
tempcopy ? tempfile : to_name, from_sb.st_size);
|
||||
@@ -69,7 +73,7 @@ Applied to original from file_cmds-430.140.2
|
||||
}
|
||||
|
||||
if (dostrip) {
|
||||
@@ -592,11 +607,11 @@
|
||||
@@ -592,11 +611,11 @@ compare(int from_fd, const char *from_name, size_t fro
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -85,7 +89,7 @@ Applied to original from file_cmds-430.140.2
|
||||
char *temp,
|
||||
size_t tsize)
|
||||
{
|
||||
@@ -610,6 +625,18 @@
|
||||
@@ -610,7 +629,49 @@ create_tempfile(char *path,
|
||||
p = temp;
|
||||
(void)strncpy(p, "INS@XXXX", &temp[tsize - 1] - p);
|
||||
temp[tsize - 1] = '\0';
|
||||
@@ -102,9 +106,73 @@ Applied to original from file_cmds-430.140.2
|
||||
+{
|
||||
+ tempfile_template(path, temp, tsize);
|
||||
return (mkstemp(temp));
|
||||
+}
|
||||
+
|
||||
+/* unlink or move (backup) an existing file */
|
||||
+static void
|
||||
+handle_existing_file(char *path, struct stat *sbp)
|
||||
+{
|
||||
+ char backup[MAXPATHLEN];
|
||||
+ /*
|
||||
+ * Unlink now... avoid ETXTBSY errors later. Try to turn
|
||||
+ * off the append/immutable bits -- if we fail, go ahead,
|
||||
+ * it might work.
|
||||
+ */
|
||||
+ if (sbp->st_flags & NOCHANGEBITS)
|
||||
+ (void)chflags(path, sbp->st_flags & ~NOCHANGEBITS);
|
||||
+
|
||||
+ if (dobackup) {
|
||||
+ if (snprintf(backup, MAXPATHLEN, "%s%s",
|
||||
+ path, suffix) != strlen(path) + strlen(suffix))
|
||||
+ errx(EX_OSERR, "%s: backup filename too long",
|
||||
+ path);
|
||||
+ (void)snprintf(backup, MAXPATHLEN, "%s%s",
|
||||
+ path, suffix);
|
||||
+ if (verbose)
|
||||
+ (void)printf("install: %s -> %s\n",
|
||||
+ path, backup);
|
||||
+ if (rename(path, backup) < 0)
|
||||
+ err(EX_OSERR, "rename: %s to %s", path, backup);
|
||||
+ } else {
|
||||
+ (void)unlink(path);
|
||||
+ }
|
||||
}
|
||||
|
||||
@@ -736,6 +763,22 @@
|
||||
/*
|
||||
@@ -622,31 +683,8 @@ create_newfile(char *path,
|
||||
int target,
|
||||
struct stat *sbp)
|
||||
{
|
||||
- char backup[MAXPATHLEN];
|
||||
-
|
||||
if (target) {
|
||||
- /*
|
||||
- * Unlink now... avoid ETXTBSY errors later. Try to turn
|
||||
- * off the append/immutable bits -- if we fail, go ahead,
|
||||
- * it might work.
|
||||
- */
|
||||
- if (sbp->st_flags & NOCHANGEBITS)
|
||||
- (void)chflags(path, sbp->st_flags & ~NOCHANGEBITS);
|
||||
-
|
||||
- if (dobackup) {
|
||||
- if (snprintf(backup, MAXPATHLEN, "%s%s",
|
||||
- path, suffix) != strlen(path) + strlen(suffix))
|
||||
- errx(EX_OSERR, "%s: backup filename too long",
|
||||
- path);
|
||||
- (void)snprintf(backup, MAXPATHLEN, "%s%s",
|
||||
- path, suffix);
|
||||
- if (verbose)
|
||||
- (void)printf("install: %s -> %s\n",
|
||||
- path, backup);
|
||||
- if (rename(path, backup) < 0)
|
||||
- err(EX_OSERR, "rename: %s to %s", path, backup);
|
||||
- } else
|
||||
- (void)unlink(path);
|
||||
+ handle_existing_file(path, sbp);
|
||||
}
|
||||
|
||||
return (open(path, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR));
|
||||
@@ -736,6 +774,22 @@ copy(int from_fd, char *from_name,
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -120,7 +188,7 @@ Applied to original from file_cmds-430.140.2
|
||||
+ mktemp(temp_name);
|
||||
+ to_name = temp_name;
|
||||
+ }
|
||||
+ return clonefile(from_name, to_name, CLONE_NOFOLLOW|CLONE_NOOWNERCOPY);
|
||||
+ return clonefile(from_name, to_name, CLONE_NOOWNERCOPY);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
|
||||
Reference in New Issue
Block a user