From f2017567d00911ff04f7665672cbdd65f719f97d Mon Sep 17 00:00:00 2001 From: Michael Greenberg Date: Mon, 3 Aug 2026 12:52:00 -0400 Subject: [PATCH 1/7] drop stray file --- test/try | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 test/try diff --git a/test/try b/test/try deleted file mode 100644 index e69de29b..00000000 From e8bb1fb8f88aa8279d80fea7c81e18047cb068c1 Mon Sep 17 00:00:00 2001 From: Michael Greenberg Date: Mon, 3 Aug 2026 12:52:52 -0400 Subject: [PATCH 2/7] handle failed execvp --- utils/try-commit.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/utils/try-commit.c b/utils/try-commit.c index cd061621..e24e98ed 100644 --- a/utils/try-commit.c +++ b/utils/try-commit.c @@ -31,7 +31,9 @@ void run(char *argv[], char *file) { if (pid == 0) { execvp(argv[0], argv); - return; // unreachable + // reachable only when we can't exec `argv[0]` + fprintf(stderr, "try-commit: couldn't run '%s': %s\n", argv[0], strerror(errno)); + _exit(127); } int status = -1; From 76bff0dbe726700eafa43852bd0f8a3ff5bae004 Mon Sep 17 00:00:00 2001 From: Michael Greenberg Date: Mon, 3 Aug 2026 13:15:21 -0400 Subject: [PATCH 3/7] add flags for optimization and safety; turn on -Werror --- Makefile.in | 7 ++++--- configure.ac | 19 ++++++++++++------- utils/excludes.c | 12 ++++++------ utils/try-commit.c | 7 ++++--- utils/try-summary.c | 3 ++- 5 files changed, 28 insertions(+), 20 deletions(-) diff --git a/Makefile.in b/Makefile.in index 464f6369..e33e54ce 100644 --- a/Makefile.in +++ b/Makefile.in @@ -9,6 +9,7 @@ CC=@CC@ endif CFLAGS=@CFLAGS@ CPPFLAGS=@CPPFLAGS@ +LDFLAGS=@LDFLAGS@ INSTALL=@INSTALL@ .PHONY: all install test dist lint clean @@ -55,13 +56,13 @@ man/try.1: docs/try.1.md pandoc --standalone --from markdown-smart --to man $< -o $@ utils/try-summary: utils/excludes.o utils/try-summary.o - $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -g $^ + $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ -g $^ utils/try-commit: utils/excludes.o utils/try-commit.o - $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -g $^ + $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ -g $^ utils/make-socket: utils/make-socket.o - $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -g $^ + $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ -g $^ test: try $(if $(findstring yes,@enable_utils@),utils/try-summary utils/try-commit) utils/make-socket scripts/run_tests.sh diff --git a/configure.ac b/configure.ac index 7a99cbe7..8f4527b4 100644 --- a/configure.ac +++ b/configure.ac @@ -13,21 +13,26 @@ AC_ARG_ENABLE([utils], AC_REQUIRE_AUX_FILE([utils/make-socket.c]) -# build tools -AC_PROG_CC - -# CFLAGS AND CPPFLAGGS -AUTO_CFLAGS="" -AUTO_CPPFLAGS="" if test "$enable_utils" = "yes" then - AC_REQUIRE_AUX_FILE([utils/try-commit.c]) + AC_REQUIRE_AUX_FILE([utils/try-commit.c]) + + # -O2 is required for -D_FORTIFY_SOURCE to do anything; -U_FORTIFY_SOURCE + # first avoids a redefinition warning on distros whose GCC predefines it. + AUTO_CFLAGS="-O2 -Wall -Wextra -Werror -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fstack-protector-strong -fPIE" + AUTO_CPPFLAGS="" + AUTO_LDFLAGS="-pie -Wl,-z,relro,-z,now" CFLAGS=${CFLAGS-"$AUTO_CFLAGS"} CPPFLAGS=${CPPFLAGS-"$AUTO_CPPFLAGS"} + LDFLAGS=${LDFLAGS-"$AUTO_LDFLAGS"} AC_SUBST(CFLAGS) AC_SUBST(CPPFLAGS) + AC_SUBST(LDFLAGS) + + # build tools + AC_PROG_CC # needed C types AC_TYPE_PID_T diff --git a/utils/excludes.c b/utils/excludes.c index 0e38b29b..122c873e 100644 --- a/utils/excludes.c +++ b/utils/excludes.c @@ -6,13 +6,13 @@ static regex_t *excludes = NULL; static size_t excludes_len = 0; -static int num_excludes = 0; +static size_t num_excludes = 0; static regex_t *includes = NULL; static size_t includes_len = 0; -static int num_includes = 0; +static size_t num_includes = 0; int should_exclude(char *filename) { - for (int i = 0; i < num_excludes; i += 1) { + for (size_t i = 0; i < num_excludes; i += 1) { if (regexec(&excludes[i], filename, 0, NULL, 0) == 0) { return 1; } @@ -26,7 +26,7 @@ int should_include(char *filename) { return 1; } - for (int i = 0; i < num_includes; i += 1) { + for (size_t i = 0; i < num_includes; i += 1) { if (regexec(&includes[i], filename, 0, NULL, 0) == 0) { return 1; } @@ -114,7 +114,7 @@ void load_includes(char *progname, char *include_filename) { } void free_excludes() { - for (int i = 0; i < num_excludes; i += 1) { + for (size_t i = 0; i < num_excludes; i += 1) { regfree(&excludes[i]); } free(excludes); @@ -124,7 +124,7 @@ void free_excludes() { } void free_includes() { - for (int i = 0; i < num_includes; i += 1) { + for (size_t i = 0; i < num_includes; i += 1) { regfree(&includes[i]); } free(includes); diff --git a/utils/try-commit.c b/utils/try-commit.c index e24e98ed..f14bb91a 100644 --- a/utils/try-commit.c +++ b/utils/try-commit.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -79,7 +80,7 @@ void remove_local(char *local_file, int local_exists, struct stat *local_stat) { } } -void usage(int status) { +noreturn void usage(int status) { fprintf(stderr, "Usage: try-commit [-c] [-E EXCLUDE_FILE] [-I INCLUDE_FILE] SANDBOX_DIR\n"); fprintf(stderr, "\t-c\tcopy files instead of moving them\n"); exit(status); @@ -239,12 +240,12 @@ int main(int argc, char *argv[]) { } char *tgt = malloc(sizeof(char) * tgt_len); - int nbytes = readlink(ent->fts_path, tgt, tgt_len); + ssize_t nbytes = readlink(ent->fts_path, tgt, tgt_len); if (nbytes == -1) { commit_error(ent->fts_path, "ln -s"); } - while (nbytes == tgt_len) { + while ((size_t) nbytes == tgt_len) { tgt_len *= 2; tgt = realloc(tgt, sizeof(char) * tgt_len); nbytes = readlink(ent->fts_path, tgt, tgt_len); diff --git a/utils/try-summary.c b/utils/try-summary.c index fd9600bf..5c6afdcc 100644 --- a/utils/try-summary.c +++ b/utils/try-summary.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -27,7 +28,7 @@ void show_change(char *local_file, char *msg) { fputs(")\n", stdout); } -void usage(int status) { +noreturn void usage(int status) { fprintf(stderr, "Usage: try-summary [-q] [-E EXCLUDE_FILE] [-I INCLUDE_FILE] SANDBOX_DIR\n"); exit(status); } From 9e4e0ec922f42481037dfe11b229511536535bea Mon Sep 17 00:00:00 2001 From: Michael Greenberg Date: Mon, 3 Aug 2026 13:25:13 -0400 Subject: [PATCH 4/7] update checkout actions, run on draft PRs too --- .github/workflows/test.yaml | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index e18539f5..5c28d6b6 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -14,7 +14,6 @@ jobs: fail-fast: true runs-on: ubuntu-latest - if: github.event.pull_request.draft == false steps: - name: Allow unprivileged user namespaces (for Ubuntu 24.04) @@ -26,7 +25,7 @@ jobs: sudo apt-get install expect mergerfs attr pandoc - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v7 with: ref: ${{ github.event.pull_request.head.sha }} @@ -107,7 +106,6 @@ jobs: fail-fast: false runs-on: ubuntu-latest - if: github.event.pull_request.draft == false steps: - name: Allow unprivileged user namespaces (for Ubuntu 24.04) @@ -119,7 +117,7 @@ jobs: sudo apt-get install expect mergerfs attr pandoc - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v7 with: ref: ${{ github.event.pull_request.head.sha }} @@ -162,7 +160,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v7 with: ref: ${{ github.event.pull_request.head.sha }} @@ -172,7 +170,7 @@ jobs: trycase-check: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 with: ref: ${{ github.event.pull_request.head.sha }} @@ -181,11 +179,10 @@ jobs: version-check: runs-on: ubuntu-latest - if: github.event.pull_request.draft == false steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v7 with: ref: ${{ github.event.pull_request.head.sha }} @@ -196,7 +193,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v7 with: ref: ${{ github.event.pull_request.head.sha }} @@ -212,7 +209,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v7 with: ref: ${{ github.event.pull_request.head.sha }} From d72fc3492e9ce06d22f247777660e47aa353fb30 Mon Sep 17 00:00:00 2001 From: Michael Greenberg Date: Tue, 4 Aug 2026 09:31:12 -0400 Subject: [PATCH 5/7] s/make-socket/try-make-socket/, avoid installing as it is a test dep --- Makefile.in | 7 ++--- configure.ac | 36 ++++++++++++---------- package.nix | 9 +++++- shell.nix | 6 +++- test/all-commit-cases.sh | 11 ++++--- utils/.gitignore | 2 +- utils/{make-socket.c => try-make-socket.c} | 0 7 files changed, 43 insertions(+), 28 deletions(-) rename utils/{make-socket.c => try-make-socket.c} (100%) diff --git a/Makefile.in b/Makefile.in index e33e54ce..4b38eadf 100644 --- a/Makefile.in +++ b/Makefile.in @@ -17,14 +17,13 @@ INSTALL=@INSTALL@ DISTDIR=@PACKAGE_TARNAME@-@PACKAGE_VERSION@ DISTTGZ=$(DISTDIR).tgz -TARGETS=utils/make-socket $(if $(findstring yes,@enable_utils@),utils/try-summary utils/try-commit) man/try.1.gz +TARGETS=utils/try-make-socket $(if $(findstring yes,@enable_utils@),utils/try-summary utils/try-commit) man/try.1.gz all: $(TARGETS) install: $(TARGETS) $(INSTALL) -d $(bindir) $(INSTALL) -m 755 try $(bindir) - $(INSTALL) -m 755 utils/make-socket $(bindir) $(INSTALL) -m 755 utils/try-parse-trace $(bindir) ifeq (@enable_utils@, yes) $(INSTALL) -m 755 utils/try-summary $(bindir) @@ -61,10 +60,10 @@ utils/try-summary: utils/excludes.o utils/try-summary.o utils/try-commit: utils/excludes.o utils/try-commit.o $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ -g $^ -utils/make-socket: utils/make-socket.o +utils/try-make-socket: utils/try-make-socket.o $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ -g $^ -test: try $(if $(findstring yes,@enable_utils@),utils/try-summary utils/try-commit) utils/make-socket +test: try $(if $(findstring yes,@enable_utils@),utils/try-summary utils/try-commit) utils/try-make-socket scripts/run_tests.sh lint: diff --git a/configure.ac b/configure.ac index 8f4527b4..980fd081 100644 --- a/configure.ac +++ b/configure.ac @@ -11,29 +11,31 @@ AC_ARG_ENABLE([utils], [enable_utils=${enableval}], [enable_utils=yes]) -AC_REQUIRE_AUX_FILE([utils/make-socket.c]) +AC_REQUIRE_AUX_FILE([utils/try-make-socket.c]) + +# unconditionally require CC and its flags (for try-make-socket) + +# -O2 is required for -D_FORTIFY_SOURCE to do anything; -U_FORTIFY_SOURCE +# first avoids a redefinition warning on distros whose GCC predefines it. +AUTO_CFLAGS="-O2 -Wall -Wextra -Werror -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fstack-protector-strong -fPIE" +AUTO_CPPFLAGS="" +AUTO_LDFLAGS="-pie -Wl,-z,relro,-z,now" + +CFLAGS=${CFLAGS-"$AUTO_CFLAGS"} +CPPFLAGS=${CPPFLAGS-"$AUTO_CPPFLAGS"} +LDFLAGS=${LDFLAGS-"$AUTO_LDFLAGS"} +AC_SUBST(CFLAGS) +AC_SUBST(CPPFLAGS) +AC_SUBST(LDFLAGS) + +# build tools +AC_PROG_CC if test "$enable_utils" = "yes" then AC_REQUIRE_AUX_FILE([utils/try-commit.c]) - # -O2 is required for -D_FORTIFY_SOURCE to do anything; -U_FORTIFY_SOURCE - # first avoids a redefinition warning on distros whose GCC predefines it. - AUTO_CFLAGS="-O2 -Wall -Wextra -Werror -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fstack-protector-strong -fPIE" - AUTO_CPPFLAGS="" - AUTO_LDFLAGS="-pie -Wl,-z,relro,-z,now" - - CFLAGS=${CFLAGS-"$AUTO_CFLAGS"} - CPPFLAGS=${CPPFLAGS-"$AUTO_CPPFLAGS"} - LDFLAGS=${LDFLAGS-"$AUTO_LDFLAGS"} - AC_SUBST(CFLAGS) - AC_SUBST(CPPFLAGS) - AC_SUBST(LDFLAGS) - - # build tools - AC_PROG_CC - # needed C types AC_TYPE_PID_T AC_TYPE_SIZE_T diff --git a/package.nix b/package.nix index f2276dc1..9219f544 100644 --- a/package.nix +++ b/package.nix @@ -18,6 +18,10 @@ stdenv.mkDerivation { src = ./.; + # "out" is the real product; "test" holds try-make-socket, a helper the + # test suite needs but that should never be installed onto a user's PATH. + outputs = [ "out" "test" ]; + # skip TRY_REQUIRE_PROG as it detects executable dependencies by running it postPatch = '' sed -i '/^AC_DEFUN(\[TRY_REQUIRE_PROG\]/,/^])$/c\AC_DEFUN([TRY_REQUIRE_PROG], [])' configure.ac @@ -35,7 +39,6 @@ stdenv.mkDerivation { install -Dt $out/bin try install -Dt $out/bin utils/try-commit install -Dt $out/bin utils/try-summary - install -Dt $out/bin utils/make-socket wrapProgram $out/bin/try --prefix PATH : ${ lib.makeBinPath [ coreutils @@ -46,6 +49,9 @@ stdenv.mkDerivation { } installManPage man/try.1.gz installShellCompletion --bash --name try.bash completions/try.bash + + install -Dt $test/bin utils/try-make-socket + runHook postInstall ''; @@ -68,6 +74,7 @@ stdenv.mkDerivation { ]; license = with lib.licenses; [ mit ]; platforms = lib.platforms.linux; + outputsToInstall = [ "out" ]; }; } diff --git a/shell.nix b/shell.nix index 42d9bbda..aabc907c 100644 --- a/shell.nix +++ b/shell.nix @@ -1,5 +1,8 @@ { pkgs ? import {}}: +let + tryPkg = pkgs.callPackage ./package.nix {}; +in pkgs.mkShell { buildInputs = with pkgs; [ expect @@ -10,7 +13,8 @@ pkgs.mkShell { shellcheck autoconf pandoc - (pkgs.callPackage ./package.nix {}) + tryPkg + tryPkg.test ]; } diff --git a/test/all-commit-cases.sh b/test/all-commit-cases.sh index bdfef0e8..b1ab5a44 100755 --- a/test/all-commit-cases.sh +++ b/test/all-commit-cases.sh @@ -15,6 +15,9 @@ cleanup() { trap 'cleanup' EXIT +PATH="$TRY_TOP/utils:$PATH" +export PATH + try_workspace="$(mktemp -d)" cd "$try_workspace" || exit 99 @@ -276,7 +279,7 @@ rm newpipe "$TRY" -y "touch newsock; echo hello> newsock" [ -f newsock ] || fail [ "$(cat newsock)" = "hello" ] || fail -"$TRY" -y "rm newsock; make-socket newsock" +"$TRY" -y "rm newsock; try-make-socket newsock" [ -S newsock ] || fail rm newsock @@ -287,7 +290,7 @@ rm newsock ! [ -e newsock ] || fail "$TRY" -y "mkdir newsock" [ -d newsock ] || fail -"$TRY" -y "rm -r newsock; make-socket newsock" +"$TRY" -y "rm -r newsock; try-make-socket newsock" [ -S newsock ] || fail rm newsock @@ -298,7 +301,7 @@ rm newsock ! [ -e newsock ] || fail ln -s "$TRY" newsock [ -L newsock ] || fail -"$TRY" -y "rm newsock; make-socket newsock" +"$TRY" -y "rm newsock; try-make-socket newsock" ! [ -e newlink ] || fail [ -S newsock ] || fail rm newsock @@ -308,6 +311,6 @@ rm newsock : $((COUNT += 1)) ! [ -e newsock ] -"$TRY" -y "make-socket newsock" +"$TRY" -y "try-make-socket newsock" [ -S newsock ] || fail rm newsock diff --git a/utils/.gitignore b/utils/.gitignore index 6b3b1acc..81aa7a29 100644 --- a/utils/.gitignore +++ b/utils/.gitignore @@ -1,4 +1,4 @@ try-summary try-commit *.o -make-socket +try-make-socket diff --git a/utils/make-socket.c b/utils/try-make-socket.c similarity index 100% rename from utils/make-socket.c rename to utils/try-make-socket.c From aa8c832c4d9accb95fc2a6e41a87ada691b3697b Mon Sep 17 00:00:00 2001 From: Michael Greenberg Date: Tue, 4 Aug 2026 09:38:16 -0400 Subject: [PATCH 6/7] use recent versions of upload- and download-artifact --- .github/workflows/test.yaml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 5c28d6b6..a3b8a770 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -41,7 +41,7 @@ jobs: make dist - name: Upload dist tarball - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: try-dist.tgz path: try-*.tgz @@ -64,12 +64,13 @@ jobs: sudo apt-get install expect mergerfs attr pandoc - name: Download dist tarball - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 - name: Unpack tarball; configure and build utilities run: | - tar xzf try-dist.tgz/try-*.tgz --strip-components=1 - rm -r try-dist.tgz + ls -lR + tar xzf try-*.tgz --strip-components=1 + rm try-*.tgz ./configure --disable-utils make all sudo make install From 69197c177a6250891fce3da2b7cea16afe52e1cd Mon Sep 17 00:00:00 2001 From: Michael Greenberg Date: Tue, 4 Aug 2026 09:56:29 -0400 Subject: [PATCH 7/7] comment and debug output for test --- test/all-commit-cases.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/all-commit-cases.sh b/test/all-commit-cases.sh index b1ab5a44..8512d39d 100755 --- a/test/all-commit-cases.sh +++ b/test/all-commit-cases.sh @@ -15,6 +15,7 @@ cleanup() { trap 'cleanup' EXIT +# expose test-only utils, like `try-make-socket` PATH="$TRY_TOP/utils:$PATH" export PATH @@ -275,6 +276,11 @@ rm newpipe : $((COUNT += 1)) +if ! type try-make-socket >/dev/null 2>&1 +then + echo "could not find try-make-socket in PATH=$PATH" + fail +fi ! [ -e newsock ] || fail "$TRY" -y "touch newsock; echo hello> newsock" [ -f newsock ] || fail