[m-dev.] For review: io.m
Thomas Charles CONWAY
conway at cs.mu.oz.au
Tue Jun 3 10:53:02 AEST 1997
ON
> Thomas Charles CONWAY, you wrote:
> >
> > Can someone please review this small change to io.m?
>
> > library/io.m:
> > add io__tmpnam(Dir, Prefix, Name, IO0, IO) which interfaces to
> > tempnam. Fix the implementation of io__tmpnam/3 so that it
> > respects the TMPDIR environment variable. (The stdio implementation
> > on linux DIDN'T)
>
> This change is fine, except for one thing: it relies on tempnam(),
> and that is not an ANSI C function. (tmpnam() is ANSI, tempnam() is not.)
>
> Hence, before committing this you should add a check for tempnam()
> in configure.in & runtime/conf.h.in, and do something appropriate
> if the system doesn't have tempnam().
>
Urk! This required C programming. :-( ;-)
I would welcome comments on the generation of tmp file names.
--
ZZ:wq!
^X^C
Thomas Conway conway at cs.mu.oz.au
AD DEUM ET VINUM Every sword has two edges.
configure.in:
add a check for tempnam
library/io.m:
add io__tmpnam(Dir, Prefix, Name, IO0, IO) which interfaces to
tempnam. Fix the implementation of io__tmpnam/3 so that it
respects the TMPDIR environment variable. (The stdio implementation
on linux DIDN'T)
If tempnam doesn't exist then create a new temporary file name from
the prefix, dir, the pid and a counter.
cvs diff: Diffing .
Index: configure.in
===================================================================
RCS file: /home/staff/zs/imp/mercury/configure.in,v
retrieving revision 1.90
diff -u -r1.90 configure.in
--- configure.in 1997/04/26 07:56:41 1.90
+++ configure.in 1997/06/03 00:13:50
@@ -868,6 +868,27 @@
fi
AC_SUBST(MR_LITTLE_ENDIAN)
#-----------------------------------------------------------------------------#
+AC_MSG_CHECKING(for tempnam)
+AC_CACHE_VAL(mercury_cv_has_tempnam,
+ AC_TRY_RUN([
+ #include <stdio.h>
+ int main() {
+ char *name;
+
+ name = tempnam("/tmp", "foobie");
+
+ exit(name == NULL);
+ }],
+ [mercury_cv_has_tempnam=yes],
+ [mercury_cv_has_tempnam=no],
+ [mercury_cv_has_tempnam=no])
+)
+AC_MSG_RESULT($mercury_cv_has_tempnam)
+if test "$mercury_cv_has_tempnam" = yes; then
+ AC_DEFINE(IO_HAVE_TEMPNAM)
+fi
+AC_SUBST(IO_HAVE_TEMPNAM)
+#-----------------------------------------------------------------------------#
#
# For Irix 5, gcc labels don't work with shared libraries,
# so if we're using gcc labels, we need to use non-shared libraries,
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
cvs diff: Diffing compiler/notes
cvs diff: Diffing doc
cvs diff: Diffing library
Index: library/io.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/io.m,v
retrieving revision 1.122
diff -u -r1.122 io.m
--- io.m 1997/05/26 23:06:10 1.122
+++ io.m 1997/06/03 00:21:40
@@ -792,13 +792,26 @@
%-----------------------------------------------------------------------------%
-% returns a unique temporary filename.
:- pred io__tmpnam(string, io__state, io__state).
:- mode io__tmpnam(out, di, uo) is det.
+ % io__tmpnam(Name, IO0, IO) binds `Name' to a temporary
+ % file name which is unique on the filesystem.
+ % It will reside in /tmp if the TMPDIR environment variable
+ % is not set, or in the directory specified by TMPDIR if it
+ % is set.
+
+:- pred io__tmpnam(string, string, string, io__state, io__state).
+:- mode io__tmpnam(in, in, out, di, uo) is det.
+ % io__tmpnam(Dir, Prefix, Name, IO0, IO) binds `Name' to a
+ % temporary file name which is unique. It will reside in the
+ % directory specified by `Dir' and have a prefix using up to the
+ % first 5 characters of `Prefix'.
-% deletes a file
:- pred io__remove_file(string, io__res, io__state, io__state).
:- mode io__remove_file(in, out, di, uo) is det.
+ % io__remove_file(FileName, Result, IO0, IO) attempts to remove the
+ % file `FileName', binding Result to ok/0 if it succeeds, or
+ % error/1 if it fails.
%-----------------------------------------------------------------------------%
@@ -2514,8 +2527,23 @@
").
/*---------------------------------------------------------------------------*/
+
+ % We need to do an explicit check of TMPDIR because not all
+ % systems check TMPDIR for us (eg Linux #$%*@&).
+io__tmpnam(Name) -->
+ io__get_environment_var("TMPDIR", Result),
+ (
+ { Result = yes(Dir) },
+ io__tmpnam(Dir, "mtmp", Name)
+ ;
+ { Result = no },
+ io__tmpnam_2(Name)
+ ).
+
+:- pred io__tmpnam_2(string::out, io__state::di, io__state::uo) is det.
+
%#include <stdio.h>
-:- pragma(c_code, io__tmpnam(FileName::out, IO0::di, IO::uo), "{
+:- pragma(c_code, io__tmpnam_2(FileName::out, IO0::di, IO::uo), "{
Word tmp;
incr_hp_atomic(tmp, (L_tmpnam + sizeof(Word)) / sizeof(Word));
@@ -2526,6 +2554,73 @@
}
FileName = (char *)tmp;
update_io(IO0, IO);
+}").
+
+/*---------------------------------------------------------------------------*/
+
+%#include <stdio.h>
+
+:- pragma c_header_code("
+#ifndef IO_HAVE_TEMPNAM
+ #include <sys/stat.h>
+ #include <unistd.h>
+ extern int mercury_io_tempnam_counter;
+#endif
+").
+
+:- pragma c_code("
+#ifndef IO_HAVE_TEMPNAM
+ int mercury_io_tempnam_counter = 0;
+#endif
+").
+
+:- pragma(c_code, io__tmpnam(Dir::in, Prefix::in, FileName::out,
+ IO0::di, IO::uo), "{
+#ifdef IO_HAVE_TEMPNAM
+ String tmp;
+
+ tmp = (String) tempnam(Dir, Prefix);
+ if (tmp == NULL) {
+ fprintf(stderr,
+ ""Mercury runtime: unable to create temporary filename\\n"");
+ exit(1);
+ }
+ incr_saved_hp_atomic((Word *) FileName,
+ (strlen((String) tmp) + sizeof(Word)) / sizeof(Word));
+ strcpy(FileName, tmp);
+ free(tmp);
+ 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
+ ** by starting with the pid of this process.
+ ** Stat is used to check that the file does not exist.
+ */
+ int len, err;
+ char countstr[256];
+ struct stat buf;
+
+ len = strlen(Dir) + 5 + 3 + 1; /* Dir + Prefix + counter + \\0 */
+ incr_saved_hp_atomic((Word *)FileName,
+ (len + sizeof(Word)) / sizeof(Word));
+ if (mercury_io_tempnam_counter == 0)
+ mercury_io_tempnam_counter = getpid();
+ sprintf(countstr, ""%0d"", mercury_io_tempnam_counter % 1000);
+ mercury_io_tempnam_counter++;
+ strcpy(FileName, Dir);
+ strcat(FileName, ""/"");
+ strncat(FileName, Prefix, 5);
+ strncat(FileName, countstr, 3);
+ err = stat(FileName, &buf);
+ if (err != -1 && errno != ENOENT) {
+ fprintf(stderr,
+ ""Mercury runtime: unable to create temporary filename\\n"");
+ exit(1);
+ }
+ update_io(IO0, IO);
+#endif
}").
/*---------------------------------------------------------------------------*/
cvs diff: Diffing lp_solve
cvs diff: Diffing lp_solve/lp_examples
cvs diff: Diffing profiler
cvs diff: Diffing runtime
Index: runtime/conf.h.in
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/conf.h.in,v
retrieving revision 1.16
diff -u -r1.16 conf.h.in
--- conf.h.in 1997/05/30 15:29:03 1.16
+++ conf.h.in 1997/06/03 00:14:05
@@ -158,4 +158,11 @@
#undef MR_BIG_ENDIAN
#undef MR_LITTLE_ENDIAN
+/*
+** The following macro specifies whether the non-ANSI, non-POSIX,
+** but usually available standard library function `tempnam' is
+** available.
+*/
+#undef IO_HAVE_TEMPNAM
+
#endif /* CONF_H */
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/diff
cvs diff: Diffing scripts
cvs diff: Diffing tools
cvs diff: Diffing trial
cvs diff: Diffing util
More information about the developers
mailing list