From 0ce2a3994f63c21742fc4f937f58852e167e996a Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 15 Oct 2020 14:51:07 +0000 Subject: Sync rules.vc with Tcl --- win/rules.vc | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/win/rules.vc b/win/rules.vc index 6dca6d9..f3e5439 100644 --- a/win/rules.vc +++ b/win/rules.vc @@ -415,9 +415,6 @@ _INSTALLDIR=$(_INSTALLDIR)\lib # NATIVE_ARCH - set to IX86 or AMD64 for the host machine # MACHINE - same as $(ARCH) - legacy # _VC_MANIFEST_EMBED_{DLL,EXE} - commands for embedding a manifest if needed -# CFG_ENCODING - set to an character encoding. -# TBD - this is passed to compiler as TCL_CFGVAL_ENCODING but can't -# see where it is used cc32 = $(CC) # built-in default. link32 = link @@ -503,10 +500,6 @@ _VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -ou _VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2 !endif -!ifndef CFG_ENCODING -CFG_ENCODING = \"cp1252\" -!endif - ################################################################ # 4. Build the nmakehlp program # This is a helper app we need to overcome nmake's limiting @@ -1043,7 +1036,7 @@ BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE) BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER) !endif -!if !$(DEBUG) || $(DEBUG) && $(UNCHECKED) +!if !$(DEBUG) || $(TCL_VERSION) > 86 || $(DEBUG) && $(UNCHECKED) SUFX = $(SUFX:g=) !endif @@ -1292,7 +1285,7 @@ INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\..\include # baselibs - minimum Windows libraries required. Parent makefile can # define PRJ_LIBS before including rules.rc if additional libs are needed -OPTDEFINES = /DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) /DSTDC_HEADERS +OPTDEFINES = /DSTDC_HEADERS !if $(VCVERSION) >= 1600 OPTDEFINES = $(OPTDEFINES) /DHAVE_STDINT_H=1 !else -- cgit v0.12 From ba6beed687edac8e849dc8fcd7eb32aeae1939ce Mon Sep 17 00:00:00 2001 From: marc_culler Date: Thu, 15 Oct 2020 17:48:14 +0000 Subject: Simpler, better fix of [c2483bfe4b]: unwanted fontchooser can appear. Uses Tcl_SetExitProc. --- macosx/tkMacOSXHLEvents.c | 5 ++++ macosx/tkMacOSXInit.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++ macosx/tkMacOSXPrivate.h | 1 + 3 files changed, 70 insertions(+) diff --git a/macosx/tkMacOSXHLEvents.c b/macosx/tkMacOSXHLEvents.c index 258740b..615653d 100644 --- a/macosx/tkMacOSXHLEvents.c +++ b/macosx/tkMacOSXHLEvents.c @@ -68,6 +68,11 @@ static const char *scriptTextProc = "::tk::mac::DoScriptText"; [self handleQuitApplicationEvent:Nil withReplyEvent:Nil]; } +- (void) superTerminate: (id) sender +{ + [super terminate:nil]; +} + - (void) preferences: (id) sender { [self handleShowPreferencesEvent:Nil withReplyEvent:Nil]; diff --git a/macosx/tkMacOSXInit.c b/macosx/tkMacOSXInit.c index bda5f46..cfaf631 100644 --- a/macosx/tkMacOSXInit.c +++ b/macosx/tkMacOSXInit.c @@ -270,6 +270,55 @@ static int TkMacOSXGetAppPathCmd(ClientData cd, Tcl_Interp *ip, *---------------------------------------------------------------------- */ +/* + * Helper function which closes the shared NSFontPanel and NSColorPanel. + */ + +static void closePanels( + void) +{ + if ([NSFontPanel sharedFontPanelExists]) { + [[NSFontPanel sharedFontPanel] orderOut:nil]; + } + if ([NSColorPanel sharedColorPanelExists]) { + [[NSColorPanel sharedColorPanel] orderOut:nil]; + } +} + +/* + * This custom exit procedure is called by Tcl_Exit in place of the exit + * function from the C runtime. It calls the terminate method of the + * NSApplication class (superTerminate for a TKApplication). The purpose of + * doing this is to ensure that the NSFontPanel and the NSColorPanel are closed + * before the process exits, and that the application state is recorded + * correctly for all termination scenarios. If this is called a second time + * (as can happen) call the C runtime exit function. + */ + +TCL_NORETURN void TkMacOSXExitProc( + ClientData clientdata) +{ + static bool calledBefore = NO; + if (!calledBefore) { + calledBefore = YES; + closePanels(); + Tcl_Finalize(); + [(TKApplication *)NSApp superTerminate:nil]; /* Should not return. */ + } + exit((int)clientdata); +} + +/* + * This SIGINT handler is installed when Wish is run in a shell to make sure + * that normal finalization occurs when SIGINT is received (i.e. when ^C is + * pressed in the shell). It calls Tcl_Exit instead of the C runtime exit + * function called by the default handler. + */ + +static void sigintHandler(int signal) { + Tcl_Exit(1); +} + int TkpInit( Tcl_Interp *interp) @@ -439,6 +488,21 @@ TkpInit( break; } } + + /* + * Install our custom exit proc, which terminates the NSApplication. + */ + + Tcl_SetExitProc(TkMacOSXExitProc); + + /* + * When Wish is run from a terminal, install a sigint handler to make + * sure that normal cleanup takes place if the app is killed with ^C. + */ + + if (isatty(0)) { + signal(SIGINT, sigintHandler); + } } /* diff --git a/macosx/tkMacOSXPrivate.h b/macosx/tkMacOSXPrivate.h index 4c07557..9617712 100644 --- a/macosx/tkMacOSXPrivate.h +++ b/macosx/tkMacOSXPrivate.h @@ -381,6 +381,7 @@ VISIBILITY_HIDDEN @end @interface TKApplication(TKHLEvents) - (void) terminate: (id) sender; +- (void) superTerminate: (id) sender; - (void) preferences: (id) sender; - (void) handleQuitApplicationEvent: (NSAppleEventDescriptor *)event withReplyEvent: (NSAppleEventDescriptor *)replyEvent; -- cgit v0.12 From 2a312582921609ee854c5af4e608e2e3065371c8 Mon Sep 17 00:00:00 2001 From: marc_culler Date: Thu, 15 Oct 2020 18:08:31 +0000 Subject: Even simpler - remove out of place calls to Tcl_Finalize --- macosx/tkMacOSXInit.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/macosx/tkMacOSXInit.c b/macosx/tkMacOSXInit.c index cfaf631..e1d586c 100644 --- a/macosx/tkMacOSXInit.c +++ b/macosx/tkMacOSXInit.c @@ -291,21 +291,15 @@ static void closePanels( * NSApplication class (superTerminate for a TKApplication). The purpose of * doing this is to ensure that the NSFontPanel and the NSColorPanel are closed * before the process exits, and that the application state is recorded - * correctly for all termination scenarios. If this is called a second time - * (as can happen) call the C runtime exit function. + * correctly for all termination scenarios. */ TCL_NORETURN void TkMacOSXExitProc( ClientData clientdata) { - static bool calledBefore = NO; - if (!calledBefore) { - calledBefore = YES; - closePanels(); - Tcl_Finalize(); - [(TKApplication *)NSApp superTerminate:nil]; /* Should not return. */ - } - exit((int)clientdata); + closePanels(); + [(TKApplication *)NSApp superTerminate:nil]; /* Does not return. */ + exit((int)clientdata); /* Convince the compiler that we don't return. */ } /* -- cgit v0.12 From 6379b15d7f1ac05c4943c92f28ad7cc2486facc5 Mon Sep 17 00:00:00 2001 From: marc_culler Date: Thu, 15 Oct 2020 18:37:42 +0000 Subject: Use Tcl_Exit when handling SIGHUP and SIGTERM too. --- macosx/tkMacOSXInit.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/macosx/tkMacOSXInit.c b/macosx/tkMacOSXInit.c index e1d586c..950a50f 100644 --- a/macosx/tkMacOSXInit.c +++ b/macosx/tkMacOSXInit.c @@ -303,13 +303,15 @@ TCL_NORETURN void TkMacOSXExitProc( } /* - * This SIGINT handler is installed when Wish is run in a shell to make sure - * that normal finalization occurs when SIGINT is received (i.e. when ^C is - * pressed in the shell). It calls Tcl_Exit instead of the C runtime exit - * function called by the default handler. + * This signal handler is installed for the SIGINT, SIGHUP and SIGTERM signals + * so that normal finalization occurs when a Tk app is killed by one of these + * signals (e.g when ^C is pressed while running Wish in the shell). It calls + * Tcl_Exit instead of the C runtime exit function called by the default handler. + * This is consistent with the Tcl_Exit manual page, which says that Tcl_Exit + * should always be called instead of exit. */ -static void sigintHandler(int signal) { +static void TkMacOSXSignalHandler(int signal) { Tcl_Exit(1); } @@ -490,13 +492,14 @@ TkpInit( Tcl_SetExitProc(TkMacOSXExitProc); /* - * When Wish is run from a terminal, install a sigint handler to make - * sure that normal cleanup takes place if the app is killed with ^C. + * Install a signal handler for SIGINT, SIGHUP and SIGTERM which uses + * Tcl_Exit instead of exit so that normal cleanup takes place if a TK + * application is killed with one of these signals. */ - if (isatty(0)) { - signal(SIGINT, sigintHandler); - } + signal(SIGINT, TkMacOSXSignalHandler); + signal(SIGHUP, TkMacOSXSignalHandler); + signal(SIGTERM, TkMacOSXSignalHandler); } /* -- cgit v0.12 From 5783d04a34a4c680ea7db932c5db2c4aa8691a2e Mon Sep 17 00:00:00 2001 From: marc_culler Date: Fri, 16 Oct 2020 13:11:57 +0000 Subject: Do not call Tcl_SetExitProc when the Tk process is part of an exec pipeline. --- macosx/tkMacOSXInit.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/macosx/tkMacOSXInit.c b/macosx/tkMacOSXInit.c index 950a50f..73d2b82 100644 --- a/macosx/tkMacOSXInit.c +++ b/macosx/tkMacOSXInit.c @@ -308,7 +308,8 @@ TCL_NORETURN void TkMacOSXExitProc( * signals (e.g when ^C is pressed while running Wish in the shell). It calls * Tcl_Exit instead of the C runtime exit function called by the default handler. * This is consistent with the Tcl_Exit manual page, which says that Tcl_Exit - * should always be called instead of exit. + * should always be called instead of exit. When Tk is killed by a signal we + * return exit status 1. */ static void TkMacOSXSignalHandler(int signal) { @@ -329,6 +330,7 @@ TkpInit( if (!initialized) { struct stat st; Bool shouldOpenConsole = NO; + Bool isLaunched = NO; Bool stdinIsNullish = (!isatty(0) && (fstat(0, &st) || (S_ISCHR(st.st_mode) && st.st_blocks == 0))); @@ -343,6 +345,7 @@ TkpInit( initialized = 1; #ifdef TK_FRAMEWORK + /* * When Tk is in a framework, force tcl_findLibrary to look in the * framework scripts directory. @@ -449,6 +452,7 @@ TkpInit( FILE *null = fopen("/dev/null", "w"); dup2(fileno(null), STDOUT_FILENO); dup2(fileno(null), STDERR_FILENO); + isLaunched = YES; } /* @@ -486,10 +490,15 @@ TkpInit( } /* - * Install our custom exit proc, which terminates the NSApplication. + * Install our custom exit proc, which terminates the process by + * calling [NSApplication terminate]. This does not work correctly if + * we are part of an exec pipeline, so only use it if this process + * was launched by the launcher or if both stdin and stdout are tttys. */ - Tcl_SetExitProc(TkMacOSXExitProc); + if (isLaunched || (isatty(0) && isatty(1))) { + Tcl_SetExitProc(TkMacOSXExitProc); + } /* * Install a signal handler for SIGINT, SIGHUP and SIGTERM which uses -- cgit v0.12 From ff9955565a1fcf3cec963f198a2f48e61e7fc402 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 16 Oct 2020 16:40:55 +0000 Subject: Another select-* testcase which sometimes fails --- tests/select.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/select.test b/tests/select.test index 31d6494..6bd2c9d 100644 --- a/tests/select.test +++ b/tests/select.test @@ -1132,7 +1132,7 @@ test select-12.6 {DefaultSelection procedure} -body { } -result {{Targets value} {TARGETS.f1 0 4000} {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW}} test select-13.1 {SelectionSize procedure, handler deleted} -constraints { - x11 + x11 failsOnUbuntu } -setup { setup setupbg -- cgit v0.12 From c85b5609e7aad61ee31d389f004694f3be62db35 Mon Sep 17 00:00:00 2001 From: culler Date: Fri, 16 Oct 2020 20:45:29 +0000 Subject: Allow opting out of using the custom Tcl_ExitProc by defining USE_SYSTEM_EXIT --- macosx/tkMacOSXInit.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/macosx/tkMacOSXInit.c b/macosx/tkMacOSXInit.c index 73d2b82..e895cc0 100644 --- a/macosx/tkMacOSXInit.c +++ b/macosx/tkMacOSXInit.c @@ -492,14 +492,19 @@ TkpInit( /* * Install our custom exit proc, which terminates the process by * calling [NSApplication terminate]. This does not work correctly if - * we are part of an exec pipeline, so only use it if this process - * was launched by the launcher or if both stdin and stdout are tttys. + * the process is part of an exec pipeline, so it is only used if the + * process was launched by the launcher or if both stdin and stdout are + * ttys. */ +# if !defined(USE_SYSTEM_EXIT) + if (isLaunched || (isatty(0) && isatty(1))) { Tcl_SetExitProc(TkMacOSXExitProc); } +# endif + /* * Install a signal handler for SIGINT, SIGHUP and SIGTERM which uses * Tcl_Exit instead of exit so that normal cleanup takes place if a TK -- cgit v0.12 From 2a92717a443e8caee17f51dae951666b9191d803 Mon Sep 17 00:00:00 2001 From: marc_culler Date: Sat, 17 Oct 2020 17:31:40 +0000 Subject: Small adjustment to d69b5cec: make sure Tcl_Finalize *always* gets called. --- macosx/tkMacOSXInit.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/macosx/tkMacOSXInit.c b/macosx/tkMacOSXInit.c index e895cc0..c7ee971 100644 --- a/macosx/tkMacOSXInit.c +++ b/macosx/tkMacOSXInit.c @@ -298,7 +298,20 @@ TCL_NORETURN void TkMacOSXExitProc( ClientData clientdata) { closePanels(); - [(TKApplication *)NSApp superTerminate:nil]; /* Does not return. */ + + /* + * Make sure we don't get called again. This can happen, e.g. with + * fossil diff -tk. + */ + + Tcl_SetExitProc(NULL); + + /* + * Tcl_Exit does not call Tcl_Finalize if there is an exit proc installed. + */ + + Tcl_Finalize(); + [(TKApplication *)NSApp superTerminate:nil]; /* Should not return. */ exit((int)clientdata); /* Convince the compiler that we don't return. */ } @@ -430,6 +443,7 @@ TkpInit( Tcl_SetVar2(interp, "tcl_interactive", NULL, "1", TCL_GLOBAL_ONLY); } + isLaunched = YES; shouldOpenConsole = YES; } if (shouldOpenConsole) { @@ -494,13 +508,16 @@ TkpInit( * calling [NSApplication terminate]. This does not work correctly if * the process is part of an exec pipeline, so it is only used if the * process was launched by the launcher or if both stdin and stdout are - * ttys. + * ttys. If an exit proc was already installed we leave it in place. */ # if !defined(USE_SYSTEM_EXIT) if (isLaunched || (isatty(0) && isatty(1))) { - Tcl_SetExitProc(TkMacOSXExitProc); + Tcl_ExitProc *prevExitProc = Tcl_SetExitProc(TkMacOSXExitProc); + if (prevExitProc) { + Tcl_SetExitProc(prevExitProc); + } } # endif -- cgit v0.12 From b8204820666fbfae9d5ea23deb3e1281ed131164 Mon Sep 17 00:00:00 2001 From: marc_culler Date: Sat, 17 Oct 2020 18:07:39 +0000 Subject: Add cast to fix annoying compiler warning. --- macosx/tkMacOSXInit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/macosx/tkMacOSXInit.c b/macosx/tkMacOSXInit.c index c7ee971..0e7dfe4 100644 --- a/macosx/tkMacOSXInit.c +++ b/macosx/tkMacOSXInit.c @@ -516,7 +516,7 @@ TkpInit( if (isLaunched || (isatty(0) && isatty(1))) { Tcl_ExitProc *prevExitProc = Tcl_SetExitProc(TkMacOSXExitProc); if (prevExitProc) { - Tcl_SetExitProc(prevExitProc); + Tcl_SetExitProc((TCL_NORETURN Tcl_ExitProc *)prevExitProc); } } -- cgit v0.12 From ee57c6cb6fe12b3fb2cceb7d3112f03c66f36c3f Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 19 Oct 2020 12:41:45 +0000 Subject: Update to latest 'install-sh' --- unix/install-sh | 412 +++++++++++++++++++++++++++----------------------------- 1 file changed, 201 insertions(+), 211 deletions(-) diff --git a/unix/install-sh b/unix/install-sh index 7c34c3f..21b733a 100755 --- a/unix/install-sh +++ b/unix/install-sh @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2011-04-20.01; # UTC +scriptversion=2020-07-26.22; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -35,25 +35,21 @@ scriptversion=2011-04-20.01; # UTC # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it +# 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. +tab=' ' nl=' ' -IFS=" "" $nl" +IFS=" $tab$nl" -# set DOITPROG to echo to test this script +# Set DOITPROG to "echo" to test this script. -# Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} -if test -z "$doit"; then - doit_exec=exec -else - doit_exec=$doit -fi +doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. @@ -68,22 +64,15 @@ mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} -posix_glob='?' -initialize_posix_glob=' - test "$posix_glob" != "?" || { - if (set -f) 2>/dev/null; then - posix_glob= - else - posix_glob=: - fi - } -' - posix_mkdir= # Desired mode of installed file. mode=0755 +# Create dirs (including intermediate dirs) using mode 755. +# This is like GNU 'install' as of coreutils 8.32 (2020). +mkdir_umask=22 + chgrpcmd= chmodcmd=$chmodprog chowncmd= @@ -97,7 +86,7 @@ dir_arg= dst_arg= copy_on_change=false -no_target_directory= +is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE @@ -120,7 +109,7 @@ Options: -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. - -S $stripprog installed files. + -S OPTION $stripprog installed files using OPTION. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. @@ -138,45 +127,60 @@ while test $# -ne 0; do -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" - shift;; + shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 - case $mode in - *' '* | *' '* | *' -'* | *'*'* | *'?'* | *'['*) - echo "$0: invalid mode: $mode" >&2 - exit 1;; - esac - shift;; + case $mode in + *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; -o) chowncmd="$chownprog $2" - shift;; + shift;; -s) stripcmd=$stripprog;; -S) stripcmd="$stripprog $2" - shift;; + shift;; - -t) dst_arg=$2 - shift;; + -t) + is_target_a_directory=always + dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; - -T) no_target_directory=true;; + -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; - --) shift - break;; + --) shift + break;; - -*) echo "$0: invalid option: $1" >&2 - exit 1;; + -*) echo "$0: invalid option: $1" >&2 + exit 1;; *) break;; esac shift done +# We allow the use of options -d and -T together, by making -d +# take the precedence; this is for compatibility with GNU install. + +if test -n "$dir_arg"; then + if test -n "$dst_arg"; then + echo "$0: target directory not allowed when installing a directory." >&2 + exit 1 + fi +fi + if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. @@ -190,6 +194,10 @@ if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then fi shift # arg dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac done fi @@ -198,12 +206,21 @@ if test $# -eq 0; then echo "$0: no input file specified." >&2 exit 1 fi - # It's OK to call `install-sh -d' without argument. + # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then + if test $# -gt 1 || test "$is_target_a_directory" = always; then + if test ! -d "$dst_arg"; then + echo "$0: $dst_arg: Is not a directory." >&2 + exit 1 + fi + fi +fi + +if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 @@ -219,16 +236,16 @@ if test -z "$dir_arg"; then *[0-7]) if test -z "$stripcmd"; then - u_plus_rw= + u_plus_rw= else - u_plus_rw='% 200' + u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then - u_plus_rw= + u_plus_rw= else - u_plus_rw=,u+rw + u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac @@ -236,9 +253,9 @@ fi for src do - # Protect names starting with `-'. + # Protect names problematic for 'test' and other utilities. case $src in - -*) src=./$src;; + -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then @@ -260,185 +277,150 @@ do echo "$0: no destination specified." >&2 exit 1 fi - dst=$dst_arg - # Protect names starting with `-'. - case $dst in - -*) dst=./$dst;; - esac - # If destination is a directory, append the input filename; won't work - # if double slashes aren't ignored. + # If destination is a directory, append the input filename. if test -d "$dst"; then - if test -n "$no_target_directory"; then - echo "$0: $dst_arg: Is a directory" >&2 - exit 1 + if test "$is_target_a_directory" = never; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 fi dstdir=$dst - dst=$dstdir/`basename "$src"` + dstbase=`basename "$src"` + case $dst in + */) dst=$dst$dstbase;; + *) dst=$dst/$dstbase;; + esac dstdir_status=0 else - # Prefer dirname, but fall back on a substitute if dirname fails. - dstdir=` - (dirname "$dst") 2>/dev/null || - expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$dst" : 'X\(//\)[^/]' \| \ - X"$dst" : 'X\(//\)$' \| \ - X"$dst" : 'X\(/\)' \| . 2>/dev/null || - echo X"$dst" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q' - ` - + dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi fi + case $dstdir in + */) dstdirslash=$dstdir;; + *) dstdirslash=$dstdir/;; + esac + obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') - # Create intermediate dirs using mode 755 as modified by the umask. - # This is like FreeBSD 'install' as of 1997-10-28. - umask=`umask` - case $stripcmd.$umask in - # Optimize common cases. - *[2367][2367]) mkdir_umask=$umask;; - .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; - - *[0-7]) - mkdir_umask=`expr $umask + 22 \ - - $umask % 100 % 40 + $umask % 20 \ - - $umask % 10 % 4 + $umask % 2 - `;; - *) mkdir_umask=$umask,go-w;; - esac - - # With -d, create the new directory with the user-specified mode. - # Otherwise, rely on $mkdir_umask. - if test -n "$dir_arg"; then - mkdir_mode=-m$mode + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + # The $RANDOM variable is not portable (e.g., dash). Use it + # here however when possible just to lower collision chance. + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + + trap ' + ret=$? + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null + exit $ret + ' 0 + + # Because "mkdir -p" follows existing symlinks and we likely work + # directly in world-writeable /tmp, make sure that the '$tmpdir' + # directory is successfully created first before we actually test + # 'mkdir -p'. + if (umask $mkdir_umask && + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" else - mkdir_mode= + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null fi - - posix_mkdir=false - case $umask in - *[123567][0-7][0-7]) - # POSIX mkdir -p sets u+wx bits regardless of umask, which - # is incompatible with FreeBSD 'install' when (umask & 300) != 0. - ;; - *) - tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 - - if (umask $mkdir_umask && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 - then - if test -z "$dir_arg" || { - # Check for POSIX incompatibilities with -m. - # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writeable bit of parent directory when it shouldn't. - # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - ls_ld_tmpdir=`ls -ld "$tmpdir"` - case $ls_ld_tmpdir in - d????-?r-*) different_mode=700;; - d????-?--*) different_mode=755;; - *) false;; - esac && - $mkdirprog -m$different_mode -p -- "$tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$tmpdir"` - test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" - } - } - then posix_mkdir=: - fi - rmdir "$tmpdir/d" "$tmpdir" - else - # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null - fi - trap '' 0;; - esac;; + trap '' 0;; esac if $posix_mkdir && ( - umask $mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else - # The umask is ridiculous, or mkdir does not conform to POSIX, + # mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in - /*) prefix='/';; - -*) prefix='./';; - *) prefix='';; + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; esac - eval "$initialize_posix_glob" - oIFS=$IFS IFS=/ - $posix_glob set -f + set -f set fnord $dstdir shift - $posix_glob set +f + set +f IFS=$oIFS prefixes= for d do - test -z "$d" && continue - - prefix=$prefix$d - if test -d "$prefix"; then - prefixes= - else - if $posix_mkdir; then - (umask=$mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break - # Don't fail if two instances are running concurrently. - test -d "$prefix" || exit 1 - else - case $prefix in - *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; - *) qprefix=$prefix;; - esac - prefixes="$prefixes '$qprefix'" - fi - fi - prefix=$prefix/ + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ done if test -n "$prefixes"; then - # Don't fail if two instances are running concurrently. - (umask $mkdir_umask && - eval "\$doit_exec \$mkdirprog $prefixes") || - test -d "$dstdir" || exit 1 - obsolete_mkdir_used=true + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true fi fi fi @@ -451,14 +433,25 @@ do else # Make a couple of temp file names in the proper directory. - dsttmp=$dstdir/_inst.$$_ - rmtmp=$dstdir/_rm.$$_ + dsttmp=${dstdirslash}_inst.$$_ + rmtmp=${dstdirslash}_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. - (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + (umask $cp_umask && + { test -z "$stripcmd" || { + # Create $dsttmp read-write so that cp doesn't create it read-only, + # which would cause strip to fail. + if test -z "$doit"; then + : >"$dsttmp" # No need to fork-exec 'touch'. + else + $doit touch "$dsttmp" + fi + } + } && + $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # @@ -473,15 +466,12 @@ do # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && - old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && - new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && - - eval "$initialize_posix_glob" && - $posix_glob set -f && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && - $posix_glob set +f && - + set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then @@ -494,24 +484,24 @@ do # to itself, or perhaps because mv is so ancient that it does not # support -f. { - # Now remove or move aside any old file at destination location. - # We try this two ways since rm can't unlink itself on some - # systems and the destination file might be busy for other - # reasons. In this case, the final cleanup might fail but the new - # file should still install successfully. - { - test ! -f "$dst" || - $doit $rmcmd -f "$dst" 2>/dev/null || - { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && - { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } - } || - { echo "$0: cannot unlink or rename $dst" >&2 - (exit 1); exit 1 - } - } && - - # Now rename the file to the real destination. - $doit $mvcmd "$dsttmp" "$dst" + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 @@ -520,9 +510,9 @@ do done # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" -# End: +# End: \ No newline at end of file -- cgit v0.12