[m-dev.] For review: io.m
Fergus Henderson
fjh at cs.mu.oz.au
Tue Jun 3 16:14:27 AEST 1997
Hi Tom, thanks for that code.
I have a few comments.
>
> :- 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'.
"which is unique" is a bit unclear. I would suggest
"which is different from the name of any existing file".
> +%#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
> +").
s/mercury_/ML_/
The convention we decided on (which is not yet reflected in all the
source code) is that the prefix for C identifiers defined in the
mercury/library directory is `ML_'.
> +:- 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);
Why cast to String here?
> + if (tmp == NULL) {
> + fprintf(stderr,
> + ""Mercury runtime: unable to create temporary filename\\n"");
> + exit(1);
You should just call
fatal_error(""unable to create temporary filename"");
rather than fprintf() and exit().
> + }
> + incr_saved_hp_atomic((Word *) FileName,
> + (strlen((String) tmp) + sizeof(Word)) / sizeof(Word));
The cast on FileName needs to be an `LVALUE_CAST(Word *, FileName)'.
Why cast tmp to String here?
> + int len, err;
> + char countstr[256];
> + struct stat buf;
> +
> + len = strlen(Dir) + 5 + 3 + 1; /* Dir + Prefix + counter + \\0 */
You forgot to count the `/'.
> + incr_saved_hp_atomic((Word *)FileName,
> + (len + sizeof(Word)) / sizeof(Word));
The cast on FileName needs to be an `LVALUE_CAST(Word *, FileName)'.
> + 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);
> + }
You should try this in a loop, say 5 times.
You should use fatal_error() instead of printf() and exit().
--
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