[m-rev.] for review: Use format string to build path in io.do_make_temp.

Peter Wang novalazy at gmail.com
Wed Sep 19 10:35:40 AEST 2018


This should fix Mantis bug #469, where gcc emits a warning for a call to
strncat, breaking the build.

library/io.m:
    Simplify the non-mkstemp branch of io.do_make_temp by building the
    temporary path with MR_make_string() instead of a combination of
    strcpy/strcat/strncat. This was already the case in the mkstemp
    branch.

    Be more precise in the documentation of io.make_temp_file regarding
    the truncation of the Prefix argument. Give notification that the
    behaviour is subject to change.
---
 library/io.m | 25 +++++++++----------------
 1 file changed, 9 insertions(+), 16 deletions(-)

diff --git a/library/io.m b/library/io.m
index 38988699d..c85fb3d5d 100644
--- a/library/io.m
+++ b/library/io.m
@@ -1439,24 +1439,29 @@
 
     % Like make_temp_file/3 except it throws an io.error exception if the
     % temporary file could not be created.
     %
 :- pragma obsolete(make_temp/3).
 :- pred make_temp(string::out, io::di, io::uo) is det.
 
     % make_temp_file(Dir, Prefix, Suffix, Result, !IO) creates an empty file
     % whose name is different to the name of any existing file. The file will
     % reside in the directory specified by Dir and will have a prefix using up
-    % to the first 5 characters of Prefix. If successful, Result returns the
+    % to the first 5 code units of Prefix. If successful, Result returns the
     % name of the file. It is the responsibility of the caller to delete the
     % file when it is no longer required.
     %
+    % The reason for truncating Prefix is historical; in future the behaviour
+    % may be changed. Note that the truncation is performed without regard for
+    % code point boundaries. It is recommended to use only (printable) ASCII
+    % characters in the prefix string.
+    %
     % The C backend has the following limitations:
     %   - Suffix may be ignored.
     %
     % The C# backend has the following limitations:
     %   - Dir is ignored.
     %   - Prefix is ignored.
     %   - Suffix is ignored.
     %
     % On the Erlang backend Suffix is ignored.
     %
@@ -11614,42 +11619,30 @@ import java.util.Random;
             Error = errno;
         }
     }
 #else
     // Constructs a temporary name by concatenating Dir, `/', the first 5 chars
     // of Prefix, six hex digits, and Suffix. The six digit hex number is
     // generated by starting with the pid of this process.  Uses
     // `open(..., O_CREATE | O_EXCL, ...)' to create the file, checking that
     // there was no existing file with that name.
 
-    int     len, err, fd, num_tries;
-    char    countstr[256];
-    MR_Word filename_word;
+    int     err, fd, num_tries;
     int     flags;
 
-    len = strlen(Dir) + 1 + 5 + 6 + strlen(Suffix) + 1;
-    // Dir + / + Prefix + counter + Suffix + \\0
-    MR_offset_incr_hp_atomic_msg(filename_word, 0,
-        (len + sizeof(MR_Word)) / sizeof(MR_Word),
-        MR_ALLOC_ID, ""string.string/0"");
-    FileName = (MR_String) filename_word;
     if (ML_io_tempnam_counter == 0) {
         ML_io_tempnam_counter = getpid();
     }
     num_tries = 0;
     do {
-        sprintf(countstr, ""%06lX"", ML_io_tempnam_counter & 0xffffffL);
-        strcpy(FileName, Dir);
-        strcat(FileName, Sep);
-        strncat(FileName, Prefix, 5);
-        strncat(FileName, countstr, 6);
-        strcat(FileName, Suffix);
+        FileName = MR_make_string(MR_ALLOC_ID, ""%s%s%.5s%06lX%s"",
+            Dir, Sep, Prefix, ML_io_tempnam_counter & 0xffffffL, Suffix);
         flags = O_WRONLY | O_CREAT | O_EXCL;
         do {
             #ifdef MR_WIN32
                 fd = _wopen(ML_utf8_to_wide(FileName), flags, 0600);
             #else
                 fd = open(FileName, flags, 0600);
             #endif
         } while (fd == -1 && MR_is_eintr(errno));
         num_tries++;
         ML_io_tempnam_counter += (1 << num_tries);
-- 
2.19.0



More information about the reviews mailing list