m4-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Changes to m4/src/Attic/builtin.c,v [branch-1_4]


From: Eric Blake
Subject: Changes to m4/src/Attic/builtin.c,v [branch-1_4]
Date: Thu, 19 Oct 2006 23:13:06 +0000

CVSROOT:        /sources/m4
Module name:    m4
Branch:         branch-1_4
Changes by:     Eric Blake <ericb>      06/10/19 23:13:05

Index: src/builtin.c
===================================================================
RCS file: /sources/m4/m4/src/Attic/builtin.c,v
retrieving revision 1.1.1.1.2.44
retrieving revision 1.1.1.1.2.45
diff -u -b -r1.1.1.1.2.44 -r1.1.1.1.2.45
--- src/builtin.c       14 Oct 2006 14:14:54 -0000      1.1.1.1.2.44
+++ src/builtin.c       19 Oct 2006 23:13:05 -0000      1.1.1.1.2.45
@@ -73,6 +73,7 @@
 DECLARE (m4_m4exit);
 DECLARE (m4_m4wrap);
 DECLARE (m4_maketemp);
+DECLARE (m4_mkstemp);
 DECLARE (m4_patsubst);
 DECLARE (m4_popdef);
 DECLARE (m4_pushdef);
@@ -128,6 +129,7 @@
   { "m4exit",          FALSE,  FALSE,  FALSE,  m4_m4exit },
   { "m4wrap",          FALSE,  FALSE,  TRUE,   m4_m4wrap },
   { "maketemp",                FALSE,  FALSE,  TRUE,   m4_maketemp },
+  { "mkstemp",         FALSE,  FALSE,  TRUE,   m4_mkstemp },
   { "patsubst",                TRUE,   FALSE,  TRUE,   m4_patsubst },
   { "popdef",          FALSE,  FALSE,  TRUE,   m4_popdef },
   { "pushdef",         FALSE,  TRUE,   TRUE,   m4_pushdef },
@@ -1242,21 +1244,86 @@
 | Use the first argument as at template for a temporary file name.  |
 `------------------------------------------------------------------*/
 
+/* Add trailing 'X' to NAME if necessary, securely create the file,
+   and place the new file name on OBS.  */
 static void
-m4_maketemp (struct obstack *obs, int argc, token_data **argv)
+mkstemp_helper (struct obstack *obs, const char *name)
 {
   int fd;
-  if (bad_argc (argv[0], argc, 2, 2))
-    return;
+  int len;
+  int i;
+
+  /* Guarantee that there are six trailing 'X' characters, even if the
+     user forgot to supply them.  */
+  len = strlen (name);
+  obstack_grow (obs, name, len);
+  for (i = 0; len > 0 && i < 6; i++)
+    if (name[--len] != 'X')
+      break;
+  for (; i < 6; i++)
+    obstack_1grow (obs, 'X');
+  obstack_1grow (obs, '\0');
+
   errno = 0;
-  if ((fd = mkstemp (ARG (1))) < 0)
+  fd = mkstemp (obstack_base (obs));
+  if (fd < 0)
     {
-      M4ERROR ((warning_status, errno, "cannot create tempfile `%s'",
-               ARG (1)));
+      M4ERROR ((0, errno, "cannot create tempfile `%s'", name));
+      obstack_free (obs, obstack_finish (obs));
+    }
+  else
+    close (fd);
+}
+
+static void
+m4_maketemp (struct obstack *obs, int argc, token_data **argv)
+{
+  if (bad_argc (argv[0], argc, 2, 2))
       return;
+  if (no_gnu_extensions)
+    {
+      /* POSIX states "any trailing 'X' characters [are] replaced with
+        the current process ID as a string", without referencing the
+        file system.  Horribly insecure, but we have to do it when we
+        are in traditional mode.
+
+        For reference, Solaris m4 does:
+          maketemp() -> `'
+          maketemp(X) -> `X'
+          maketemp(XX) -> `Xn', where n is last digit of pid
+          maketemp(XXXXXXXX) -> `X00nnnnn', where nnnnn is 16-bit pid
+      */
+      const char *str = ARG (1);
+      int len = strlen (str);
+      int i;
+      int len2;
+
+      M4ERROR ((warning_status, 0, "recommend using mkstemp instead"));
+      for (i = len; i > 1; i--)
+       if (str[i - 1] != 'X')
+         break;
+      obstack_grow (obs, str, i);
+      str = ntoa ((eval_t) getpid (), 10);
+      len2 = strlen (str);
+      if (len2 > len - i)
+       obstack_grow0 (obs, str + len2 - (len - i), len - i);
+      else
+       {
+         while (i++ < len - len2)
+           obstack_1grow (obs, '0');
+         obstack_grow0 (obs, str, len2);
     }
-  close(fd);
-  obstack_grow (obs, ARG (1), strlen (ARG (1)));
+    }
+  else
+    mkstemp_helper (obs, ARG (1));
+}
+
+static void
+m4_mkstemp (struct obstack *obs, int argc, token_data **argv)
+{
+  if (bad_argc (argv[0], argc, 2, 2))
+    return;
+  mkstemp_helper (obs, ARG (1));
 }
 
 /*----------------------------------------.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]