diff --git a/exec_cmd.c b/exec_cmd.c index 13e036fc37..408e4e55e1 100644 --- a/exec_cmd.c +++ b/exec_cmd.c @@ -28,10 +28,9 @@ const char *system_path(const char *path) !(prefix = strip_path_suffix(argv0_path, BINDIR)) && !(prefix = strip_path_suffix(argv0_path, "git"))) { prefix = PREFIX; - /* - * RUNTIME_PREFIX requested, but prefix computation failed. - * Using static fallback. - */ + fprintf(stderr, "RUNTIME_PREFIX requested, " + "but prefix computation failed. " + "Using static fallback '%s'.\n", prefix); } #endif diff --git a/git-compat-util.h b/git-compat-util.h index d94c683e0c..f09f244061 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -150,7 +150,6 @@ #endif /* General helper functions */ -extern void vreport(const char *prefix, const char *err, va_list params); extern void usage(const char *err) NORETURN; extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2))); extern int error(const char *err, ...) __attribute__((format (printf, 1, 2))); diff --git a/gitk-git/gitk b/gitk-git/gitk index f43ca48dff..a2c589f749 100644 --- a/gitk-git/gitk +++ b/gitk-git/gitk @@ -2057,7 +2057,7 @@ proc makewindow {} { button .tf.lbar.fnext -text [mc "next"] -command {dofind 1 1} button .tf.lbar.fprev -text [mc "prev"] -command {dofind -1 1} label .tf.lbar.flab2 -text " [mc "commit"] " - pack .tf.lbar.flabel .tf.lbar.fprev .tf.lbar.fnext .tf.lbar.flab2 \ + pack .tf.lbar.flabel .tf.lbar.fnext .tf.lbar.fprev .tf.lbar.flab2 \ -side left -fill y set gdttype [mc "containing:"] set gm [tk_optionMenu .tf.lbar.gdttype gdttype \ diff --git a/run-command.c b/run-command.c index 09725b983f..b05c734d05 100644 --- a/run-command.c +++ b/run-command.c @@ -293,22 +293,9 @@ int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const } #ifdef __MINGW32__ -static int close_fd = -1; -NORETURN void die_from_thread(const char *err, va_list params) -{ - vreport("fatal: ", err, params); - if (close_fd >= 0) - close(close_fd); - _endthreadex(128); - exit(128); /* silence compiler */ -} - static __stdcall unsigned run_thread(void *data) { struct async *async = data; - close_fd = async->fd_for_proc; - extern NORETURN void die_from_thread(const char *err, va_list params); - set_die_routine(die_from_thread); return async->proc(async->fd_for_proc, async->data); } #endif @@ -362,9 +349,6 @@ int finish_async(struct async *async) else if (!GetExitCodeThread(async->tid, &ret)) ret = error("cannot get thread exit code: %lu", GetLastError()); CloseHandle(async->tid); - if (ret) - /* test suite tests for this string */ - error("waitpid (async) failed"); #endif return ret; } diff --git a/t/.gitignore b/t/.gitignore index dbe58eb9b3..7dcbb232cd 100644 --- a/t/.gitignore +++ b/t/.gitignore @@ -1,3 +1,2 @@ /trash directory* /test-results -/test-log diff --git a/t/Makefile b/t/Makefile index 6eefc08fea..bf816fc850 100644 --- a/t/Makefile +++ b/t/Makefile @@ -21,7 +21,7 @@ $(T): @echo "*** $@ ***"; GIT_CONFIG=.git/config '$(SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS) pre-clean: - $(RM) -r test-results test-log + $(RM) -r test-results clean: $(RM) -r 'trash directory'.* test-results @@ -42,24 +42,3 @@ valgrind: GIT_TEST_OPTS=--valgrind $(MAKE) .PHONY: pre-clean $(T) aggregate-results clean valgrind - --include Makefile.local - -GIT_SKIP_TESTS := $(GIT_SKIP_TESTS_LOCAL) -# git am does not treat absolute path to mbox file correctly -GIT_SKIP_TESTS += t4150.18 -# output contains CRLF (I think) -GIT_SKIP_TESTS += t7401.14 -# output contains CRLF (I think) -GIT_SKIP_TESTS += t7508.1[68] -# cannot run fake.sendmail for some reason -GIT_SKIP_TESTS += t9001 -# there's a problem with GIT_DIR in test 12 (why only there?) -# needs fixups with $PWD instead of $(pwd) - tries to run rsh c -GIT_SKIP_TESTS += t9200 -# CGI.pm not found -GIT_SKIP_TESTS += t9500 -export GIT_SKIP_TESTS - -NO_SVN_TESTS=SkipThem -export NO_SVN_TESTS diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh index da272e0124..e38241c80a 100755 --- a/t/t0040-parse-options.sh +++ b/t/t0040-parse-options.sh @@ -39,7 +39,6 @@ Standard options EOF test_expect_success 'test help' ' - set +x && test_must_fail test-parse-options -h > output 2> output.err && test ! -s output && test_cmp expect.err output.err @@ -159,7 +158,6 @@ error: did you mean \`--boolean\` (with two dashes ?) EOF test_expect_success 'detect possible typos' ' - set +x && test_must_fail test-parse-options -boolean > output 2> output.err && test ! -s output && test_cmp typo.err output.err @@ -225,7 +223,6 @@ Callback: "not set", 1 EOF test_expect_success 'OPT_CALLBACK() and callback errors work' ' - set +x && test_must_fail test-parse-options --no-length > output 2> output.err && test_cmp expect output && test_cmp expect.err output.err diff --git a/t/t1503-rev-parse-verify.sh b/t/t1503-rev-parse-verify.sh index 4c677340f4..cc65394947 100755 --- a/t/t1503-rev-parse-verify.sh +++ b/t/t1503-rev-parse-verify.sh @@ -71,7 +71,6 @@ test_expect_success 'fails with any bad rev or many good revs' ' ' test_expect_success 'fails silently when using -q' ' - set +x && test_must_fail git rev-parse --verify --quiet 2>error && test -z "$(cat error)" && test_must_fail git rev-parse -q --verify foo 2>error && diff --git a/t/t4150-am.sh b/t/t4150-am.sh index 5e65afa0c1..a8aa02e936 100755 --- a/t/t4150-am.sh +++ b/t/t4150-am.sh @@ -245,7 +245,11 @@ test_expect_success 'am works from file (relative path given) in subdirectory' ' test -z "$(git diff second)" ' -test_expect_success 'am works from file (absolute path given) in subdirectory' ' +case $(uname -s) in +*MINGW*) test_expect=test_expect_failure;; +*) test_expect=test_expect_success;; +esac +$test_expect 'am works from file (absolute path given) in subdirectory' ' rm -fr subdir && git checkout first && P=$(pwd) && diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index 7267b1ae70..5ec668d6d8 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -247,7 +247,6 @@ EOF test_expect_success 'set-head --auto fails w/multiple HEADs' ' (cd test && - set +x && test_must_fail git remote set-head --auto two >output 2>&1 && test_cmp expect output) ' diff --git a/t/t6022-merge-rename.sh b/t/t6022-merge-rename.sh index d69a364cae..e3f7ae8120 100755 --- a/t/t6022-merge-rename.sh +++ b/t/t6022-merge-rename.sh @@ -95,15 +95,30 @@ git checkout master' test_expect_success 'pull renaming branch into unrenaming one' \ ' git show-branch - test_must_fail git pull . white && - git ls-files -s && - test "$(git ls-files -u B | wc -l)" -eq 3 && - test "$(git ls-files -s N | wc -l)" -eq 1 && + git pull . white && { + echo "BAD: should have conflicted" + return 1 + } + git ls-files -s + test "$(git ls-files -u B | wc -l)" -eq 3 || { + echo "BAD: should have left stages for B" + return 1 + } + test "$(git ls-files -s N | wc -l)" -eq 1 || { + echo "BAD: should have merged N" + return 1 + } sed -ne "/^g/{ p q - }" B | grep master && - test "$(git diff white N | wc -l)" -eq 0 + }" B | grep master || { + echo "BAD: should have listed our change first" + return 1 + } + test "$(git diff white N | wc -l)" -eq 0 || { + echo "BAD: should have taken colored branch" + return 1 + } ' test_expect_success 'pull renaming branch into another renaming one' \ @@ -111,44 +126,95 @@ test_expect_success 'pull renaming branch into another renaming one' \ rm -f B git reset --hard git checkout red - test_must_fail git pull . white && - test "$(git ls-files -u B | wc -l)" -eq 3 && - test "$(git ls-files -s N | wc -l)" -eq 1 && + git pull . white && { + echo "BAD: should have conflicted" + return 1 + } + test "$(git ls-files -u B | wc -l)" -eq 3 || { + echo "BAD: should have left stages" + return 1 + } + test "$(git ls-files -s N | wc -l)" -eq 1 || { + echo "BAD: should have merged N" + return 1 + } sed -ne "/^g/{ p q - }" B | grep red && - test "$(git diff white N | wc -l)" -eq 0 + }" B | grep red || { + echo "BAD: should have listed our change first" + return 1 + } + test "$(git diff white N | wc -l)" -eq 0 || { + echo "BAD: should have taken colored branch" + return 1 + } ' test_expect_success 'pull unrenaming branch into renaming one' \ ' git reset --hard git show-branch - test_must_fail git pull . master && - test "$(git ls-files -u B | wc -l)" -eq 3 && - test "$(git ls-files -s N | wc -l)" -eq 1 && + git pull . master && { + echo "BAD: should have conflicted" + return 1 + } + test "$(git ls-files -u B | wc -l)" -eq 3 || { + echo "BAD: should have left stages" + return 1 + } + test "$(git ls-files -s N | wc -l)" -eq 1 || { + echo "BAD: should have merged N" + return 1 + } sed -ne "/^g/{ p q - }" B | grep red && - test "$(git diff white N | wc -l)" -eq 0 + }" B | grep red || { + echo "BAD: should have listed our change first" + return 1 + } + test "$(git diff white N | wc -l)" -eq 0 || { + echo "BAD: should have taken colored branch" + return 1 + } ' test_expect_success 'pull conflicting renames' \ ' git reset --hard git show-branch - test_must_fail git pull . blue && - test "$(git ls-files -u A | wc -l)" -eq 1 && - test "$(git ls-files -u B | wc -l)" -eq 1 && - test "$(git ls-files -u C | wc -l)" -eq 1 && - test "$(git ls-files -s N | wc -l)" -eq 1 && + git pull . blue && { + echo "BAD: should have conflicted" + return 1 + } + test "$(git ls-files -u A | wc -l)" -eq 1 || { + echo "BAD: should have left a stage" + return 1 + } + test "$(git ls-files -u B | wc -l)" -eq 1 || { + echo "BAD: should have left a stage" + return 1 + } + test "$(git ls-files -u C | wc -l)" -eq 1 || { + echo "BAD: should have left a stage" + return 1 + } + test "$(git ls-files -s N | wc -l)" -eq 1 || { + echo "BAD: should have merged N" + return 1 + } sed -ne "/^g/{ p q - }" B | grep red && - test "$(git diff white N | wc -l)" -eq 0 + }" B | grep red || { + echo "BAD: should have listed our change first" + return 1 + } + test "$(git diff white N | wc -l)" -eq 0 || { + echo "BAD: should have taken colored branch" + return 1 + } ' test_expect_success 'interference with untracked working tree file' ' @@ -156,8 +222,14 @@ test_expect_success 'interference with untracked working tree file' ' git reset --hard git show-branch echo >A this file should not matter - test_must_fail git pull . white && - test -f A + git pull . white && { + echo "BAD: should have conflicted" + return 1 + } + test -f A || { + echo "BAD: should have left A intact" + return 1 + } ' test_expect_success 'interference with untracked working tree file' ' @@ -167,8 +239,14 @@ test_expect_success 'interference with untracked working tree file' ' git show-branch rm -f A echo >A this file should not matter - test_must_fail git pull . red && - test -f A + git pull . red && { + echo "BAD: should have conflicted" + return 1 + } + test -f A || { + echo "BAD: should have left A intact" + return 1 + } ' test_expect_success 'interference with untracked working tree file' ' @@ -178,8 +256,14 @@ test_expect_success 'interference with untracked working tree file' ' git checkout -f master git tag -f anchor git show-branch - git pull . yellow - test ! -f M && + git pull . yellow || { + echo "BAD: should have cleanly merged" + return 1 + } + test -f M && { + echo "BAD: should have removed M" + return 1 + } git reset --hard anchor ' @@ -192,8 +276,14 @@ test_expect_success 'updated working tree file should prevent the merge' ' git show-branch echo >>M one line addition cat M >M.saved - test_must_fail git pull . yellow && - diff M M.saved && + git pull . yellow && { + echo "BAD: should have complained" + return 1 + } + diff M M.saved || { + echo "BAD: should have left M intact" + return 1 + } rm -f M.saved ' @@ -207,8 +297,14 @@ test_expect_success 'updated working tree file should prevent the merge' ' echo >>M one line addition cat M >M.saved git update-index M - test_must_fail git pull . yellow && - diff M M.saved && + git pull . yellow && { + echo "BAD: should have complained" + return 1 + } + diff M M.saved || { + echo "BAD: should have left M intact" + return 1 + } rm -f M.saved ' @@ -220,9 +316,18 @@ test_expect_success 'interference with untracked working tree file' ' git tag -f anchor git show-branch echo >M this file should not matter - git pull . master && - test -f M && - ! (git ls-files -s | grep M) && + git pull . master || { + echo "BAD: should have cleanly merged" + return 1 + } + test -f M || { + echo "BAD: should have left M intact" + return 1 + } + git ls-files -s | grep M && { + echo "BAD: M must be untracked in the result" + return 1 + } git reset --hard anchor ' diff --git a/t/t6034-merge-rename-nocruft.sh b/t/t6034-merge-rename-nocruft.sh index d1b1d1a441..65be95fbaa 100755 --- a/t/t6034-merge-rename-nocruft.sh +++ b/t/t6034-merge-rename-nocruft.sh @@ -73,12 +73,33 @@ test_expect_success 'merge white into red (A->B,M->N)' \ ' git checkout -b red-white red && git merge white && - git write-tree >/dev/null && - test -f B && - test -f N && - test -f R && - ! test -f A && - ! test -f M + git write-tree >/dev/null || { + echo "BAD: merge did not complete" + return 1 + } + + test -f B || { + echo "BAD: B does not exist in working directory" + return 1 + } + test -f N || { + echo "BAD: N does not exist in working directory" + return 1 + } + test -f R || { + echo "BAD: R does not exist in working directory" + return 1 + } + + test -f A && { + echo "BAD: A still exists in working directory" + return 1 + } + test -f M && { + echo "BAD: M still exists in working directory" + return 1 + } + return 0 ' # This test broke in 8371234ecaaf6e14fe3f2082a855eff1bbd79ae9 @@ -87,12 +108,32 @@ test_expect_success 'merge blue into white (A->B, mod A, A untracked)' \ git checkout -b white-blue white && echo dirty >A && git merge blue && - git write-tree >/dev/null && - test -f A && - test `cat A` = dirty && - test -f B && - test -f N && - ! test -f M + git write-tree >/dev/null || { + echo "BAD: merge did not complete" + return 1 + } + + test -f A || { + echo "BAD: A does not exist in working directory" + return 1 + } + test `cat A` = dirty || { + echo "BAD: A content is wrong" + return 1 + } + test -f B || { + echo "BAD: B does not exist in working directory" + return 1 + } + test -f N || { + echo "BAD: N does not exist in working directory" + return 1 + } + test -f M && { + echo "BAD: M still exists in working directory" + return 1 + } + return 0 ' test_done diff --git a/t/t7401-submodule-summary.sh b/t/t7401-submodule-summary.sh index 50030c1a49..d2d6d5be25 100755 --- a/t/t7401-submodule-summary.sh +++ b/t/t7401-submodule-summary.sh @@ -14,8 +14,6 @@ esac . ./test-lib.sh -export GIT_TEST_CMP='diff -u -b' # some lines end in CRLF - add_file () { sm=$1 shift diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh index a7a13b7e57..821be7ce8d 100755 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@ -399,8 +399,20 @@ from refs/heads/branch INPUT_END test_expect_success \ 'F: non-fast-forward update skips' \ - 'test_must_fail git fast-import &1 if test "$verbose" = "t" then - set_x= set_nox= exec 4>&2 3>&1 else - test_log_dir="$TEST_DIRECTORY/test-log" - mkdir -p "$test_log_dir" - test_log_path="$test_log_dir/${0%.sh}-$$" - set_x='set -x;' - set_nox='set +x' - exec 3>"$test_log_path" 4>&3 + exec 4>/dev/null 3>/dev/null fi test_failure=0 @@ -310,9 +303,8 @@ test_debug () { } test_run_ () { - eval >&3 2>&4 $set_x "$1" ' - eval_ret=$? - $set_nox' + eval >&3 2>&4 "$1" + eval_ret="$?" return 0 } @@ -548,6 +540,7 @@ test_done () { # Test the binaries we have just built. The tests are kept in # t/ subdirectory and are run in 'trash directory' subdirectory. +TEST_DIRECTORY=$(pwd) if test -z "$valgrind" then if test -z "$GIT_TEST_INSTALLED" diff --git a/test-stat.c b/test-stat.c deleted file mode 100644 index ff859412f0..0000000000 --- a/test-stat.c +++ /dev/null @@ -1,170 +0,0 @@ -#include -#include -#include - -#ifdef EMULATE -#define HINT fprintf(stderr, "emulated stat\n") -#include -#include -#include - -/* Use mingw_lstat() instead of lstat()/stat() and - * mingw_fstat() instead of fstat() on Windows. - */ -int mingw_lstat(const char *file_name, struct stat *buf); -int mingw_fstat(int fd, struct stat *buf); -#define fstat mingw_fstat -#define lstat mingw_lstat -#define stat(x,y) mingw_lstat(x,y) - -#define PATH_MAX 260 - -static inline int file_attr_to_st_mode (DWORD attr) -{ - int fMode = S_IREAD; - if (attr & FILE_ATTRIBUTE_DIRECTORY) - fMode |= S_IFDIR; - else - fMode |= S_IFREG; - if (!(attr & FILE_ATTRIBUTE_READONLY)) - fMode |= S_IWRITE; - return fMode; -} - -static inline int get_file_attr(const char *fname, WIN32_FILE_ATTRIBUTE_DATA *fdata) -{ - if (GetFileAttributesExA(fname, GetFileExInfoStandard, fdata)) - return 0; - - switch (GetLastError()) { - case ERROR_ACCESS_DENIED: - case ERROR_SHARING_VIOLATION: - case ERROR_LOCK_VIOLATION: - case ERROR_SHARING_BUFFER_EXCEEDED: - return EACCES; - case ERROR_BUFFER_OVERFLOW: - return ENAMETOOLONG; - case ERROR_NOT_ENOUGH_MEMORY: - return ENOMEM; - default: - return ENOENT; - } -} - -static inline time_t filetime_to_time_t(const FILETIME *ft) -{ - long long winTime = ((long long)ft->dwHighDateTime << 32) + ft->dwLowDateTime; - winTime -= 116444736000000000LL; /* Windows to Unix Epoch conversion */ - winTime /= 10000000; /* Nano to seconds resolution */ - return (time_t)winTime; -} - -/* We keep the do_lstat code in a separate function to avoid recursion. - * When a path ends with a slash, the stat will fail with ENOENT. In - * this case, we strip the trailing slashes and stat again. - */ -static int do_lstat(const char *file_name, struct stat *buf) -{ - WIN32_FILE_ATTRIBUTE_DATA fdata; - - if (!(errno = get_file_attr(file_name, &fdata))) { - buf->st_ino = 0; - buf->st_gid = 0; - buf->st_uid = 0; - buf->st_nlink = 1; - buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes); - buf->st_size = fdata.nFileSizeLow; /* Can't use nFileSizeHigh, since it's not a stat64 */ - buf->st_dev = buf->st_rdev = 0; /* not used by Git */ - buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime)); - buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime)); - buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime)); - return 0; - } - return -1; -} - -/* We provide our own lstat/fstat functions, since the provided - * lstat/fstat functions are so slow. These stat functions are - * tailored for Git's usage (read: fast), and are not meant to be - * complete. Note that Git stat()s are redirected to mingw_lstat() - * too, since Windows doesn't really handle symlinks that well. - */ -int mingw_lstat(const char *file_name, struct stat *buf) -{ - int namelen; - static char alt_name[PATH_MAX]; - - if (!do_lstat(file_name, buf)) - return 0; - - /* if file_name ended in a '/', Windows returned ENOENT; - * try again without trailing slashes - */ - if (errno != ENOENT) - return -1; - - namelen = strlen(file_name); - if (namelen && file_name[namelen-1] != '/') - return -1; - while (namelen && file_name[namelen-1] == '/') - --namelen; - if (!namelen || namelen >= PATH_MAX) - return -1; - - memcpy(alt_name, file_name, namelen); - alt_name[namelen] = 0; - return do_lstat(alt_name, buf); -} - -#undef fstat -int mingw_fstat(int fd, struct stat *buf) -{ - HANDLE fh = (HANDLE)_get_osfhandle(fd); - BY_HANDLE_FILE_INFORMATION fdata; - - if (fh == INVALID_HANDLE_VALUE) { - errno = EBADF; - return -1; - } - /* direct non-file handles to MS's fstat() */ - if (GetFileType(fh) != FILE_TYPE_DISK) - return fstat(fd, buf); - - if (GetFileInformationByHandle(fh, &fdata)) { - buf->st_ino = 0; - buf->st_gid = 0; - buf->st_uid = 0; - buf->st_nlink = 1; - buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes); - buf->st_size = fdata.nFileSizeLow; /* Can't use nFileSizeHigh, since it's not a stat64 */ - buf->st_dev = buf->st_rdev = 0; /* not used by Git */ - buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime)); - buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime)); - buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime)); - return 0; - } - errno = EBADF; - return -1; -} - -#else -#define HINT (void)0 -#endif - -int main(int argc, char**argv) -{ - int i; - int err = 0; - HINT; - for (i = 1; i < argc; i++) - { - struct stat st; - if (stat(argv[i], &st)) { - perror(argv[i]); - err = 1; - continue; - } - printf("%s: %s\n", argv[i], ctime(&st.st_mtime)); - } - return err; -} diff --git a/usage.c b/usage.c index 9e35e8a390..820d09f92b 100644 --- a/usage.c +++ b/usage.c @@ -5,7 +5,7 @@ */ #include "git-compat-util.h" -void vreport(const char *prefix, const char *err, va_list params) +static void report(const char *prefix, const char *err, va_list params) { char msg[1024]; vsnprintf(msg, sizeof(msg), err, params); @@ -20,52 +20,30 @@ static NORETURN void usage_builtin(const char *err) static NORETURN void die_builtin(const char *err, va_list params) { - vreport("fatal: ", err, params); + report("fatal: ", err, params); exit(128); } static void error_builtin(const char *err, va_list params) { - vreport("error: ", err, params); + report("error: ", err, params); } static void warn_builtin(const char *warn, va_list params) { - vreport("warning: ", warn, params); + report("warning: ", warn, params); } -typedef void (*die_fn_t)(const char *err, va_list params) NORETURN; - -static DWORD tls_index; - -static void tls_init(void) __attribute__((constructor)); -static void tls_init(void) -{ - tls_index = TlsAlloc(); -} - -struct routines { - die_fn_t die_routine; -}; /* If we are in a dlopen()ed .so write to a global variable would segfault * (ugh), so keep things static. */ static void (*usage_routine)(const char *err) NORETURN = usage_builtin; +static void (*die_routine)(const char *err, va_list params) NORETURN = die_builtin; static void (*error_routine)(const char *err, va_list params) = error_builtin; static void (*warn_routine)(const char *err, va_list params) = warn_builtin; void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN) { - struct routines *r = TlsGetValue(tls_index); - if (r == NULL) { - /* avoid die()! */ - r = calloc(sizeof(*r), 1); - if (r == NULL) { - fprintf(stderr, "cannot allocate thread-local storage"); - return; - } - TlsSetValue(tls_index, r); - } - r->die_routine = routine; + die_routine = routine; } void usage(const char *err) @@ -76,13 +54,9 @@ void usage(const char *err) void die(const char *err, ...) { va_list params; - struct routines *r = TlsGetValue(tls_index); va_start(params, err); - if (r == NULL || r->die_routine == NULL) - die_builtin(err, params); - else - r->die_routine(err, params); + die_routine(err, params); va_end(params); }