commit - b22138f5dbdf02a4800b44caa215bfa102ee321b
commit + 2be5e1a234aeec2c4e8d6b84f0405034ed8664fa
blob - a56994ab50aea3ed8cbe907c4d8fa2cc65f6ae14
blob + 6e4f19aa3e9703b1e7a3b57f3d76fe41a2b801ac
--- 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 - 93a9570fa38f33af30ac5d909b03d23f7c63eda3
blob + 8fc9edf2163e5db80ebfc2641f66fd8d288fa8bd
--- 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