commit - c71da4f733c5d4c5d25de860ff717363522a105b
commit + da09d8ed3bab86a28b37ed49300aad928922ede7
blob - 1c02d96fb4e9d928b1d57ab019a1c00492bf4331
blob + ba62c524e9821448547ce28529656a1475da9aa7
--- got/got.c
+++ got/got.c
goto done;
#ifndef PROFILE
- if (pledge("stdio rpath wpath cpath proc exec sendfd flock",
+ if (pledge("stdio rpath wpath cpath fattr proc exec sendfd flock",
NULL) == -1)
err(1, "pledge");
#endif
blob - d906c8c59ea5881a8801313236bdb6bc6966eac3
blob + 19a9c9ce3f9dddc450dbc0e368ae072adf2a1e24
--- lib/patch.c
+++ lib/patch.c
}
static const struct got_error *
-patch_file(struct got_patch *p, const char *path, FILE *tmp, int nop)
+patch_file(struct got_patch *p, const char *path, FILE *tmp, int nop,
+ mode_t *mode)
{
const struct got_error *err = NULL;
struct got_patch_hunk *h;
+ struct stat sb;
size_t i;
long lineno = 0;
FILE *orig;
goto done;
}
+ if (fstat(fileno(orig), &sb) == -1) {
+ err = got_error_from_errno("fstat");
+ goto done;
+ }
+ *mode = sb.st_mode;
+
copypos = 0;
STAILQ_FOREACH(h, &p->head, entries) {
if (h->lines == NULL)
}
}
-
- if (p->new == NULL) {
- struct stat sb;
-
- if (fstat(fileno(orig), &sb) == -1)
- err = got_error_from_errno("fstat");
- else if (sb.st_size != copypos)
- err = got_error(GOT_ERR_PATCH_DONT_APPLY);
- } else if (!nop && !feof(orig))
+ if (p->new == NULL && sb.st_size != copypos)
+ err = got_error(GOT_ERR_PATCH_DONT_APPLY);
+ else if (!nop && !feof(orig))
err = copy(tmp, orig, copypos, -1);
done:
char *oldpath = NULL, *newpath = NULL;
char *tmppath = NULL, *template = NULL;
FILE *tmp = NULL;
+ mode_t mode = GOT_DEFAULT_FILE_MODE;
TAILQ_INIT(&oldpaths);
TAILQ_INIT(&newpaths);
err = got_opentemp_named(&tmppath, &tmp, template);
if (err)
goto done;
- err = patch_file(p, oldpath, tmp, nop);
+ err = patch_file(p, oldpath, tmp, nop, &mode);
if (err)
goto done;
goto done;
}
+ if (fchmod(fileno(tmp), mode) == -1) {
+ err = got_error_from_errno2("chmod", newpath);
+ goto done;
+ }
+
if (rename(tmppath, newpath) == -1) {
err = got_error_from_errno3("rename", tmppath, newpath);
goto done;
blob - 41f290c529e09c20b73b0a6752c3351664a9559d
blob + 6d468d0334318dc22a5552f720bf777276c909d8
--- regress/cmdline/patch.sh
+++ regress/cmdline/patch.sh
diff -u $testroot/stdout.expected $testroot/stdout
fi
test_done $testroot $ret
+}
+
+test_patch_preserve_perm() {
+ local testroot=`test_init patch_preserve_perm`
+
+ got checkout $testroot/repo $testroot/wt > /dev/null
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ test_done $testroot $ret
+ return 1
+ fi
+
+ chmod +x $testroot/wt/alpha
+ (cd $testroot/wt && got commit -m 'alpha executable') > /dev/null
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ test_done $testroot $ret
+ return 1
+ fi
+
+ cat <<EOF > $testroot/wt/patch
+--- alpha
++++ alpha
+@@ -1 +1,2 @@
+ alpha
++was edited
+EOF
+
+ (cd $testroot/wt && got patch patch) > /dev/null
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ test_done $testroot $ret
+ return 1
+ fi
+
+ if [ ! -x $testroot/wt/alpha ]; then
+ echo "alpha is no more executable!" >&2
+ test_done $testroot 1
+ return 1
+ fi
+ test_done $testroot 0
}
test_parseargs "$@"
run_test test_patch_rename
run_test test_patch_illegal_status
run_test test_patch_nop
+run_test test_patch_preserve_perm