diff: bug fixes for io__tmpnam/5

Fergus Henderson fjh at cs.mu.OZ.AU
Sat Feb 28 03:10:07 AEDT 1998


Estimated hours taken: 0.5

Fix some bugs in `io__tmpnam/5'.

library/io.m:
	Change the implementation of io__tmpnam so that it never uses
	tempnam().  We can't use tempnam() to implement io__tmpnam/5,
	because tempnam() ignores the directory name passed if TMP_DIR
	is set (or at least it does this on dec-alpha-osf3.2).

	Note that we should not change the specification for io__tmpnam/5
	to match that of tempnam(), because the current specification
	for io__tmpnam/5 is much more useful.

	Also fix another bug: in a couple of places the C code was
	using `&&' where it should have used `||'.

	Also change MAX_TEMPNAME_RETRIES from 5 to 10.

Index: io.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/io.m,v
retrieving revision 1.150
diff -u -u -r1.150 io.m
--- io.m	1998/02/27 11:43:24	1.150
+++ io.m	1998/02/27 12:59:35
@@ -2670,23 +2670,29 @@
 %#include <stdio.h>
 
 :- pragma c_header_code("
-#ifndef IO_HAVE_TEMPNAM
 	#include <sys/stat.h>
 	#include <unistd.h>
-	extern int	ML_io_tempnam_counter;
-	#define	MAX_TEMPNAME_TRIES	5
-#endif
+
+	#define	MAX_TEMPNAME_TRIES	10
+
+	extern int ML_io_tempnam_counter;
 ").
 
 :- pragma c_code("
-#ifndef IO_HAVE_TEMPNAM
 	int	ML_io_tempnam_counter = 0;
-#endif
 ").
 
-:- pragma(c_code, io__tmpnam(Dir::in, Prefix::in, FileName::out,
-		IO0::di, IO::uo), "{
-#ifdef	IO_HAVE_TEMPNAM
+:- pragma c_code(io__tmpnam(Dir::in, Prefix::in, FileName::out,
+		IO0::di, IO::uo),
+		will_not_call_mercury,
+"{
+#if 0
+/*
+** We used to use this code #ifdef IO_HAVE_TEMPNAM,
+** but it does the wrong thing:
+** tempnam() uses the environment variable TMP_DIR
+** in preference to the directory specified by `Dir'.
+*/
 	String tmp;
 
 	tmp = tempnam(Dir, Prefix);
@@ -2700,9 +2706,9 @@
 	update_io(IO0, IO);
 #else
 	/*
-	** tempnam was unavailable, so construct a temporary name by
-	** concatenating Dir, `/', the first 5 chars of Prefix, and
-	** a three digit number. The three digit number is generated
+	** Construct a temporary name by concatenating Dir, `/',
+	** the first 5 chars of Prefix, and a three digit number.
+	** The three digit number is generated
 	** by starting with the pid of this process.
 	** Stat is used to check that the file does not exist.
 	*/
@@ -2710,11 +2716,13 @@
 	char	countstr[256];
 	struct stat buf;
 
-	len = strlen(Dir) + 1+ 5 + 3 + 1; /* Dir + / + Prefix + counter + \\0 */
+	len = strlen(Dir) + 1 + 5 + 3 + 1;
+		/* Dir + / + Prefix + counter + \\0 */
 	incr_hp_atomic(LVALUE_CAST(Word *,FileName),
 		(len + sizeof(Word)) / sizeof(Word));
-	if (ML_io_tempnam_counter == 0)
+	if (ML_io_tempnam_counter == 0) {
 		ML_io_tempnam_counter = getpid();
+	}
 	num_tries=0;
 	do {
 		sprintf(countstr, ""%0d"", ML_io_tempnam_counter % 1000);
@@ -2725,9 +2733,9 @@
 		strncat(FileName, countstr, 3);
 		err = stat(FileName, &buf);
 		num_tries++;
-	} while (err != -1 && errno != ENOENT
+	} while ((err != -1 || errno != ENOENT)
 		&& num_tries < MAX_TEMPNAME_TRIES);
-	if (err != -1 && errno != ENOENT) {
+	if (err != -1 || errno != ENOENT) {
 		fatal_error(""unable to create temporary filename"");
 	}
 	update_io(IO0, IO);

-- 
Fergus Henderson <fjh at cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3         |     -- the last words of T. S. Garp.



More information about the developers mailing list