[m-dev.] For review: io.m
Thomas Charles CONWAY
conway at cs.mu.oz.au
Tue Jun 10 09:18:20 AEST 1997
ON
> Thomas Charles CONWAY, you wrote:
> >
> > -% 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 different to the name of any existing file.
> > + % 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'.
>
> Please change "unique" here too.
>
> > +#ifdef IO_HAVE_TEMPNAM
> > + String tmp;
> > +
> > + tmp = tempnam(Dir, Prefix);
> > + if (tmp == NULL) {
> > + fatal_error(""unable to create temporary filename"");
> > + }
> > + incr_saved_hp_atomic(LVALUE_CAST(Word *,FileName),
> > + (strlen((String) tmp) + sizeof(Word)) / sizeof(Word));
>
> The cast to (String) here is unnecessary. `tmp' is already a String.
>
> > + i=0;
>
> s/i=0/i = 0/
>
> Also, a more meaningful variable name would be better:
> s/i/num_tries/g
>
> Otherwise that looks good.
Here is the diff with those issues fixed.
--
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.92
diff -u -r1.92 configure.in
--- configure.in 1997/06/06 08:46:34 1.92
+++ configure.in 1997/06/09 22:14:44
@@ -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.123
diff -u -r1.123 io.m
--- io.m 1997/06/04 09:59:29 1.123
+++ io.m 1997/06/09 23:07:16
@@ -792,13 +792,27 @@
%-----------------------------------------------------------------------------%
-% 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 different to the name of any existing file.
+ % 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 different to the name of any
+ % existing file. 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,18 +2528,100 @@
").
/*---------------------------------------------------------------------------*/
+
+ % 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));
if (tmpnam((char *)tmp) == NULL) {
- fprintf(stderr,
- ""Mercury runtime: unable to create temporary filename\\n"");
- exit(1);
+ fatal_error(""unable to create temporary filename"");
}
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 ML_io_tempnam_counter;
+ #define MAX_TEMPNAME_TRIES 5
+#endif
+").
+
+:- 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
+ String tmp;
+
+ tmp = tempnam(Dir, Prefix);
+ if (tmp == NULL) {
+ fatal_error(""unable to create temporary filename"");
+ }
+ incr_saved_hp_atomic(LVALUE_CAST(Word *,FileName),
+ (strlen(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, num_tries;
+ char countstr[256];
+ struct stat buf;
+
+ len = strlen(Dir) + 1+ 5 + 3 + 1; /* Dir + / + Prefix + counter + \\0 */
+ incr_saved_hp_atomic(LVALUE_CAST(Word *,FileName),
+ (len + sizeof(Word)) / sizeof(Word));
+ if (ML_io_tempnam_counter == 0)
+ ML_io_tempnam_counter = getpid();
+ num_tries=0;
+ do {
+ sprintf(countstr, ""%0d"", ML_io_tempnam_counter % 1000);
+ ML_io_tempnam_counter++;
+ strcpy(FileName, Dir);
+ strcat(FileName, ""/"");
+ strncat(FileName, Prefix, 5);
+ strncat(FileName, countstr, 3);
+ err = stat(FileName, &buf);
+ num_tries++;
+ } while (err != -1 && errno != ENOENT
+ && num_tries < MAX_TEMPNAME_TRIES);
+ if (err != -1 && errno != ENOENT) {
+ fatal_error(""unable to create temporary filename"");
+ }
+ 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