diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2009-01-02 16:43:50 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2009-01-02 16:43:50 (GMT) |
commit | 4123c4bbf735f1e0910f1ae529ee6a5fa4a841a4 (patch) | |
tree | e72f06db7689cdca26c0e91537e5a0eecf4e2d9a | |
parent | 337a6648fee48d63d97c16579b72703b39647564 (diff) | |
download | tcl-4123c4bbf735f1e0910f1ae529ee6a5fa4a841a4.zip tcl-4123c4bbf735f1e0910f1ae529ee6a5fa4a841a4.tar.gz tcl-4123c4bbf735f1e0910f1ae529ee6a5fa4a841a4.tar.bz2 |
Fix various mkstemp()-related issues. [Bugs 741967,878333]
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | compat/mkstemp.c | 78 | ||||
-rw-r--r-- | unix/Makefile.in | 5 | ||||
-rw-r--r-- | unix/configure.in | 4 | ||||
-rw-r--r-- | unix/tcl.m4 | 3 |
5 files changed, 96 insertions, 3 deletions
@@ -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}']) |