Tcl Source Code

Changes On Branch bug-1224888
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch bug-1224888 Excluding Merge-Ins

This is equivalent to a diff from 7163cf716b to d6a83ef702

2017-11-17
10:50
TIP #422, Tcl 9.0 part: Don't Use stdarg.h/va_list in Public API check-in: 717b28b47a user: jan.nijtmans tags: trunk
04:46
merge trunk Leaf check-in: d6a83ef702 user: aspect tags: bug-1224888
2017-11-16
22:32
remove test code check-in: 98ee6f28a0 user: aspect tags: bug-1224888
11:17
re-base "novem-more-memory-API" to trunk. TIP not submitted yet, but upcoming. check-in: 3cb46ea71b user: jan.nijtmans tags: memory-API
2017-11-15
13:39
merge trunk check-in: c782871a43 user: dgp tags: dgp-refactor
13:39
merge trunk check-in: 5d829c82fa user: dgp tags: dgp-properbytearray
10:20
merge trunk check-in: a12a0623f0 user: jan.nijtmans tags: novem
10:01
merge core-8-branch check-in: 7163cf716b user: jan.nijtmans tags: trunk
09:42
Remove compat/float.h and related machinery. The last system known where this was needed was SunOS-4... check-in: bf8e546c42 user: jan.nijtmans tags: core-8-branch
08:56
merge core-8-branch check-in: 8322a4ab21 user: jan.nijtmans tags: trunk

Changes to unix/configure.

7412
7413
7414
7415
7416
7417
7418



































































































7419
7420
7421
7422
7423
7424
7425
ac_fn_c_check_func "$LINENO" "uname" "ac_cv_func_uname"
if test "x$ac_cv_func_uname" = xyes; then :

else

$as_echo "#define NO_UNAME 1" >>confdefs.h




































































































fi


if test "`uname -s`" = "Darwin" && test "${TCL_THREADS}" = 1 && \
	test "`uname -r | awk -F. '{print $1}'`" -lt 7; then
    # prior to Darwin 7, realpath is not threadsafe, so don't
    # use it when threads are enabled, c.f. bug # 711232







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
7424
7425
7426
7427
7428
7429
7430
7431
7432
7433
7434
7435
7436
7437
7438
7439
7440
7441
7442
7443
7444
7445
7446
7447
7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
7471
7472
7473
7474
7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524
ac_fn_c_check_func "$LINENO" "uname" "ac_cv_func_uname"
if test "x$ac_cv_func_uname" = xyes; then :

else

$as_echo "#define NO_UNAME 1" >>confdefs.h

fi

echo "$as_me:$LINENO: checking for dladdr" >&5
echo $ECHO_N "checking for dladdr... $ECHO_C" >&6
if test "${ac_cv_func_dladdr+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
/* Define dladdr to an innocuous variant, in case <limits.h> declares dladdr.
   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
#define dladdr innocuous_dladdr

/* System header to define __stub macros and hopefully few prototypes,
    which can conflict with char dladdr (); below.
    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
    <limits.h> exists even on freestanding compilers.  */

#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif

#undef dladdr

/* Override any gcc2 internal prototype to avoid an error.  */
#ifdef __cplusplus
extern "C"
{
#endif
/* We use char because int might match the return type of a gcc2
   builtin and then its argument prototype would still apply.  */
char dladdr ();
/* The GNU C library defines this for functions which it implements
    to always fail with ENOSYS.  Some functions are actually named
    something starting with __ and the normal name is an alias.  */
#if defined (__stub_dladdr) || defined (__stub___dladdr)
choke me
#else
char (*f) () = dladdr;
#endif
#ifdef __cplusplus
}
#endif

int
main ()
{
return f != dladdr;
  ;
  return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
  (eval $ac_link) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } &&
	 { ac_try='test -z "$ac_c_werror_flag"
			 || test ! -s conftest.err'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } &&
	 { ac_try='test -s conftest$ac_exeext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  ac_cv_func_dladdr=yes
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

ac_cv_func_dladdr=no
fi
rm -f conftest.err conftest.$ac_objext \
      conftest$ac_exeext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_func_dladdr" >&5
echo "${ECHO_T}$ac_cv_func_dladdr" >&6
if test $ac_cv_func_dladdr = yes; then
  :
else
  cat >>confdefs.h <<\_ACEOF
#define NO_DLADDR 1
_ACEOF

fi


if test "`uname -s`" = "Darwin" && test "${TCL_THREADS}" = 1 && \
	test "`uname -r | awk -F. '{print $1}'`" -lt 7; then
    # prior to Darwin 7, realpath is not threadsafe, so don't
    # use it when threads are enabled, c.f. bug # 711232

Changes to unix/configure.ac.

210
211
212
213
214
215
216

217
218
219
220
221
222
223
# define USEGETWD even if the posix getcwd exists. Add a test ?

AC_REPLACE_FUNCS(mkstemp opendir strtol waitpid)
AC_CHECK_FUNC(strerror, , [AC_DEFINE(NO_STRERROR, 1, [Do we have strerror()])])
AC_CHECK_FUNC(getwd, , [AC_DEFINE(NO_GETWD, 1, [Do we have getwd()])])
AC_CHECK_FUNC(wait3, , [AC_DEFINE(NO_WAIT3, 1, [Do we have wait3()])])
AC_CHECK_FUNC(uname, , [AC_DEFINE(NO_UNAME, 1, [Do we have uname()])])


if test "`uname -s`" = "Darwin" && test "${TCL_THREADS}" = 1 && \
	test "`uname -r | awk -F. '{print [$]1}'`" -lt 7; then
    # prior to Darwin 7, realpath is not threadsafe, so don't
    # use it when threads are enabled, c.f. bug # 711232
    ac_cv_func_realpath=no
fi







>







210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# define USEGETWD even if the posix getcwd exists. Add a test ?

AC_REPLACE_FUNCS(mkstemp opendir strtol waitpid)
AC_CHECK_FUNC(strerror, , [AC_DEFINE(NO_STRERROR, 1, [Do we have strerror()])])
AC_CHECK_FUNC(getwd, , [AC_DEFINE(NO_GETWD, 1, [Do we have getwd()])])
AC_CHECK_FUNC(wait3, , [AC_DEFINE(NO_WAIT3, 1, [Do we have wait3()])])
AC_CHECK_FUNC(uname, , [AC_DEFINE(NO_UNAME, 1, [Do we have uname()])])
AC_CHECK_FUNC(dladdr, , [AC_DEFINE(NO_DLADDR)])

if test "`uname -s`" = "Darwin" && test "${TCL_THREADS}" = 1 && \
	test "`uname -r | awk -F. '{print [$]1}'`" -lt 7; then
    # prior to Darwin 7, realpath is not threadsafe, so don't
    # use it when threads are enabled, c.f. bug # 711232
    ac_cv_func_realpath=no
fi

Changes to unix/tclAppInit.c.

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#ifndef TCL_LOCAL_APPINIT
#define TCL_LOCAL_APPINIT Tcl_AppInit
#endif
#ifndef MODULE_SCOPE
#   define MODULE_SCOPE extern
#endif
MODULE_SCOPE int TCL_LOCAL_APPINIT(Tcl_Interp *);
MODULE_SCOPE int main(int, char **);

/*
 * The following #if block allows you to change how Tcl finds the startup
 * script, prime the library or encoding paths, fiddle with the argv, etc.,
 * without needing to rewrite Tcl_Main()
 */








|







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#ifndef TCL_LOCAL_APPINIT
#define TCL_LOCAL_APPINIT Tcl_AppInit
#endif
#ifndef MODULE_SCOPE
#   define MODULE_SCOPE extern
#endif
MODULE_SCOPE int TCL_LOCAL_APPINIT(Tcl_Interp *);
int main(int, char **);

/*
 * The following #if block allows you to change how Tcl finds the startup
 * script, prime the library or encoding paths, fiddle with the argv, etc.,
 * without needing to rewrite Tcl_Main()
 */

Changes to unix/tclUnixFile.c.

8
9
10
11
12
13
14






15
16
17
18
19
20
21
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tclInt.h"
#include "tclFileSystem.h"







static int NativeMatchType(Tcl_Interp *interp, const char* nativeEntry,
	const char* nativeName, Tcl_GlobTypeData *types);

/*
 *---------------------------------------------------------------------------
 *







>
>
>
>
>
>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tclInt.h"
#include "tclFileSystem.h"
#if !defined(NO_DLADDR) && !defined(NO_DLFCN_H)
#include <dlfcn.h>
#endif
#ifdef __APPLE__
#include <mach-o/dyld.h>
#endif

static int NativeMatchType(Tcl_Interp *interp, const char* nativeEntry,
	const char* nativeName, Tcl_GlobTypeData *types);

/*
 *---------------------------------------------------------------------------
 *
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54
55
56
57
58
59
60

















61
62
63
64
65




























































66
67
68
69
70
71
72
				 * (native). */
{
    Tcl_Encoding encoding;
#ifdef __CYGWIN__
    int length;
    char buf[PATH_MAX * 2];
    char name[PATH_MAX * TCL_UTF_MAX + 1];

    GetModuleFileNameW(NULL, buf, PATH_MAX);
    cygwin_conv_path(3, buf, name, PATH_MAX);
    length = strlen(name);
    if ((length > 4) && !strcasecmp(name + length - 4, ".exe")) {
	/* Strip '.exe' part. */
	length -= 4;
    }
    encoding = Tcl_GetEncoding(NULL, NULL);
    TclSetObjNameOfExecutable(
	    Tcl_NewStringObj(name, length), encoding);
#else
    const char *name, *p;
    Tcl_StatBuf statBuf;
    Tcl_DString buffer, nameString, cwd, utfName;


















    if (argv0 == NULL) {
	return;
    }
    Tcl_DStringInit(&buffer);





























































    name = argv0;
    for (p = name; *p != '\0'; p++) {
	if (*p == '/') {
	    /*
	     * The name contains a slash, so use the name directly without
	     * doing a path search.







>














>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
				 * (native). */
{
    Tcl_Encoding encoding;
#ifdef __CYGWIN__
    int length;
    char buf[PATH_MAX * 2];
    char name[PATH_MAX * TCL_UTF_MAX + 1];

    GetModuleFileNameW(NULL, buf, PATH_MAX);
    cygwin_conv_path(3, buf, name, PATH_MAX);
    length = strlen(name);
    if ((length > 4) && !strcasecmp(name + length - 4, ".exe")) {
	/* Strip '.exe' part. */
	length -= 4;
    }
    encoding = Tcl_GetEncoding(NULL, NULL);
    TclSetObjNameOfExecutable(
	    Tcl_NewStringObj(name, length), encoding);
#else
    const char *name, *p;
    Tcl_StatBuf statBuf;
    Tcl_DString buffer, nameString, cwd, utfName;
#ifdef __APPLE__
    char *buf;
    uint32_t bufSize;
#elif !defined(DJGPP)
    int i;
    unsigned long pid;
    static CONST char *exepaths[] = {
	"/proc/%lu/exe", "/proc/%lu/file", "/proc/%lu/object/a.out",
	"/proc/curproc/file"
    };
    char buf1[PATH_MAX+1], buf2[64];
    ssize_t readlink_res;
#endif
#if !defined(NO_DLADDR) && !defined(NO_DLFCN_H)
    Dl_info dlinfoBuffer;
    void *sym;
#endif

    if (argv0 == NULL) {
	return;
    }
    Tcl_DStringInit(&buffer);

    /*
     * The executable name is sometimes available to us directly, which is
     * useful because it's not always there in argv[0]; that's a value that is
     * set by the code that invoked this process and it sometimes lies.  [Bug
     * 1224888]
     *
     * Our options for independently determining it are to scrape it out of
     * /proc (if that's mounted, and we have readlink(2)) or to pick the
     * information out of the dynamic loader (assuming we're using a
     * compatible one and it supports the relevant - common - extension).
     *
     * On OSX, we can use the _NSGetExecutablePath function to retrieve the
     * name of the main process. This is documented on the dyld(3) manual
     * page.
     *
     * For a list of various techniques and links to more details on how to
     * implement them, see the Stack Overflow master question at
     * http://stackoverflow.com/q/1023306/301832
     */

#ifdef __APPLE__
    buf = NULL;
    bufSize = 0;
    _NSGetExecutablePath(buf, &bufSize);
    if (bufSize > 0) {
	buf = ckalloc(bufSize+1);
	if (_NSGetExecutablePath(buf, &bufSize) == 0) {
	    name = buf;
	    goto gotName;
	}
	ckfree(buf);
	buf = NULL;
    }
#endif /* __APPLE__ */

#if !defined(__APPLE__) && !defined(DJGPP)
    pid = getpid();
    for (i=0 ; i<sizeof(exepaths)/sizeof(*exepaths) ; i++) {
	sprintf(buf2, exepaths[i], pid);
	readlink_res = readlink(buf2, buf1, PATH_MAX);
	if (readlink_res > 0 && buf1[0] == '/') {
	    buf1[readlink_res] = '\0';
	    name = buf1;
	    goto gotName;
	}
    }
#endif

#if !defined(NO_DLADDR) && !defined(NO_DLFCN_H)
    sym = dlsym(RTLD_DEFAULT, "main");
    if (sym == NULL) {
	sym = dlsym(RTLD_DEFAULT, "_main");
    }
    if (sym != NULL && dladdr(sym, &dlinfoBuffer)
	    && dlinfoBuffer.dli_fname[0] == '/') {
	name = dlinfoBuffer.dli_fname;
	goto gotName;
    }
#endif

    name = argv0;
    for (p = name; *p != '\0'; p++) {
	if (*p == '/') {
	    /*
	     * The name contains a slash, so use the name directly without
	     * doing a path search.
187
188
189
190
191
192
193





194
195
196
197
198
199
200
    Tcl_ExternalToUtfDString(encoding, Tcl_DStringValue(&buffer), -1,
	    &utfName);
    TclSetObjNameOfExecutable(
	    Tcl_NewStringObj(Tcl_DStringValue(&utfName), -1), encoding);
    Tcl_DStringFree(&utfName);

  done:





    Tcl_DStringFree(&buffer);
#endif
}

/*
 *----------------------------------------------------------------------
 *







>
>
>
>
>







271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
    Tcl_ExternalToUtfDString(encoding, Tcl_DStringValue(&buffer), -1,
	    &utfName);
    TclSetObjNameOfExecutable(
	    Tcl_NewStringObj(Tcl_DStringValue(&utfName), -1), encoding);
    Tcl_DStringFree(&utfName);

  done:
#ifdef __APPLE__
    if (buf != NULL) {
	ckfree(buf);
    }
#endif /* __APPLE__ */
    Tcl_DStringFree(&buffer);
#endif
}

/*
 *----------------------------------------------------------------------
 *