summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2009-01-02 16:43:50 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2009-01-02 16:43:50 (GMT)
commit4123c4bbf735f1e0910f1ae529ee6a5fa4a841a4 (patch)
treee72f06db7689cdca26c0e91537e5a0eecf4e2d9a
parent337a6648fee48d63d97c16579b72703b39647564 (diff)
downloadtcl-4123c4bbf735f1e0910f1ae529ee6a5fa4a841a4.zip
tcl-4123c4bbf735f1e0910f1ae529ee6a5fa4a841a4.tar.gz
tcl-4123c4bbf735f1e0910f1ae529ee6a5fa4a841a4.tar.bz2
Fix various mkstemp()-related issues. [Bugs 741967,878333]
-rw-r--r--ChangeLog9
-rw-r--r--compat/mkstemp.c78
-rw-r--r--unix/Makefile.in5
-rw-r--r--unix/configure.in4
-rw-r--r--unix/tcl.m43
5 files changed, 96 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index fe39617..36c691d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2009-01-02 Donal K. Fellows <dkf@users.sf.net>
+
+ * unix/tcl.m4 (SC_CONFIG_CFLAGS): Force the use of the compatibility
+ version of mkstemp() on IRIX. [Bug 878333]
+ * unix/configure.in, unix/Makefile.in (mkstemp.o):
+ * compat/mkstemp.c (new file): Added a compatibility implementation of
+ the mkstemp() function, which is apparently needed on some platforms.
+ [Bug 741967]
+
2008-12-31 Don Porter <dgp@users.sourceforge.net>
* unix/Makefile.in: Set TCLLIBPATH in SHELL_ENV so that targets
diff --git a/compat/mkstemp.c b/compat/mkstemp.c
new file mode 100644
index 0000000..8adc11b
--- /dev/null
+++ b/compat/mkstemp.c
@@ -0,0 +1,78 @@
+/*
+ * mkstemp.c --
+ *
+ * Source code for the "mkstemp" library routine.
+ *
+ * Copyright (c) 2009 Donal K. Fellows
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id: mkstemp.c,v 1.1 2009/01/02 16:43:50 dkf Exp $
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * mkstemp --
+ *
+ * Create an open temporary file from a template.
+ *
+ * Results:
+ * A file descriptor, or -1 (with errno set) in the case of an error.
+ *
+ * Side effects:
+ * The template is updated to contain the real filename.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+mkstemp(
+ char *template) /* Template for filename. */
+{
+ static const char alphanumerics[] =
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+ register char *a, *b;
+ int fd, count, alphanumericsLen = strlen(alphanumerics); /* == 62 */
+
+ a = template + strlen(template);
+ while (a > template && *(a-1) == 'X') {
+ a--;
+ }
+
+ if (a == template) {
+ errno = ENOENT;
+ return -1;
+ }
+
+ /*
+ * We'll only try up to 10 times; after that, we're suffering from enemy
+ * action and should let the caller know.
+ */
+
+ count = 10;
+ do {
+ /*
+ * Replace the X's in the original template with random alphanumeric
+ * digits.
+ */
+
+ for (b=a ; *b ; b++) {
+ float r = random() / ((float) RAND_MAX);
+
+ *b = alphanumerics[(int)(r * alphanumericsLen)];
+ }
+
+ /*
+ * Template is now realized; try to open (with correct options).
+ */
+
+ fd = open(template, O_RDWR|O_CREAT|O_EXCL, 0600);
+ } while (fd == -1 && errno == EEXIST && --count > 0);
+
+ return fd;
+}
diff --git a/unix/Makefile.in b/unix/Makefile.in
index 070b472..8ce29ec 100644
--- a/unix/Makefile.in
+++ b/unix/Makefile.in
@@ -4,7 +4,7 @@
# "./configure", which is a configuration script generated by the "autoconf"
# program (constructs like "@foo@" will get replaced in the actual Makefile.
#
-# RCS: @(#) $Id: Makefile.in,v 1.259 2008/12/31 18:22:04 dgp Exp $
+# RCS: @(#) $Id: Makefile.in,v 1.260 2009/01/02 16:43:50 dkf Exp $
VERSION = @TCL_VERSION@
MAJOR_VERSION = @TCL_MAJOR_VERSION@
@@ -1546,6 +1546,9 @@ fixstrtod.o: $(COMPAT_DIR)/fixstrtod.c
opendir.o: $(COMPAT_DIR)/opendir.c
$(CC) -c $(STUB_CC_SWITCHES) $(COMPAT_DIR)/opendir.c
+mkstemp.o: $(COMPAT_DIR)/mkstemp.c
+ $(CC) -c $(STUB_CC_SWITCHES) $(COMPAT_DIR)/mkstemp.c
+
memcmp.o: $(COMPAT_DIR)/memcmp.c
$(CC) -c $(STUB_CC_SWITCHES) $(COMPAT_DIR)/memcmp.c
diff --git a/unix/configure.in b/unix/configure.in
index 607ac02..a08dddc 100644
--- a/unix/configure.in
+++ b/unix/configure.in
@@ -3,7 +3,7 @@ dnl This file is an input file used by the GNU "autoconf" program to
dnl generate the file "configure", which is run during Tcl installation
dnl to configure the system for the local environment.
#
-# RCS: @(#) $Id: configure.in,v 1.202 2008/12/21 20:55:07 das Exp $
+# RCS: @(#) $Id: configure.in,v 1.203 2009/01/02 16:43:50 dkf Exp $
AC_INIT([tcl],[8.6])
AC_PREREQ(2.59)
@@ -190,7 +190,7 @@ AC_CHECK_FUNCS(getcwd, , [AC_DEFINE(USEGETWD, 1, [Is getcwd Posix-compliant?])])
# Nb: if getcwd uses popen and pwd(1) (like SunOS 4) we should really
# define USEGETWD even if the posix getcwd exists. Add a test ?
-AC_REPLACE_FUNCS(opendir strtol waitpid)
+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()])])
diff --git a/unix/tcl.m4 b/unix/tcl.m4
index f7c2e59..730faaa 100644
--- a/unix/tcl.m4
+++ b/unix/tcl.m4
@@ -1327,6 +1327,7 @@ dnl AC_CHECK_TOOL(AR, ar)
SHLIB_SUFFIX=".so"
DL_OBJS="tclLoadDl.o"
DL_LIBS=""
+ AC_LIBOBJ(mkstemp)
AS_IF([test $doRpath = yes], [
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
@@ -1338,6 +1339,7 @@ dnl AC_CHECK_TOOL(AR, ar)
SHLIB_SUFFIX=".so"
DL_OBJS="tclLoadDl.o"
DL_LIBS=""
+ AC_LIBOBJ(mkstemp)
AS_IF([test $doRpath = yes], [
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
@@ -1364,6 +1366,7 @@ dnl AC_CHECK_TOOL(AR, ar)
SHLIB_SUFFIX=".so"
DL_OBJS="tclLoadDl.o"
DL_LIBS=""
+ AC_LIBOBJ(mkstemp)
AS_IF([test $doRpath = yes], [
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])