Blob Blame History Raw
---
 lib/sh/tmpfile.c |   49 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 48 insertions(+), 1 deletion(-)

--- lib/sh/tmpfile.c
+++ lib/sh/tmpfile.c	2018-01-24 12:38:42.410481352 +0000
@@ -36,6 +36,14 @@
 #include <stdio.h>
 #include <errno.h>
 
+#if defined(__linux__)
+#  include <sys/statfs.h>
+#  include <unistd.h>
+#  ifndef  TMPFS_MAGIC
+#    define TMPFS_MAGIC 0x01021994
+#  endif
+#endif
+
 #include <shell.h>
 
 #ifndef errno
@@ -65,6 +73,8 @@ static unsigned long filenum = 1L;
 static char *
 get_sys_tmpdir ()
 {
+  static int doshm;
+
   if (sys_tmpdir)
     return sys_tmpdir;
 
@@ -91,6 +101,31 @@ get_sys_tmpdir ()
   return sys_tmpdir;
 }
 
+#if defined(__linux__)
+static int
+emergency_sys_tmpdir ()
+{
+  static char *shm = "/dev/shm";
+  static size_t pgsz;
+  struct statfs fs;
+  static int doshm;
+
+  if (getuid() != 0)
+    return 0;
+
+  if (doshm)
+    return 0;
+
+  doshm++;
+
+  if (statfs(shm, &fs) < 0 || fs.f_type != TMPFS_MAGIC || eaccess(shm, W_OK|X_OK))
+    return 0;
+	  
+  sys_tmpdir = shm;
+  return 1;
+}
+#endif
+
 static char *
 get_tmpdir (flags)
      int flags;
@@ -194,7 +229,8 @@ sh_mktmpfd (nameroot, flags, namep)
 {
   char *filename, *tdir, *lroot;
   int fd, tdlen;
-  
+
+enospace:
   filename = (char *)xmalloc (PATH_MAX + 1);
   tdir = get_tmpdir (flags);
   tdlen = strlen (tdir);
@@ -217,6 +253,10 @@ sh_mktmpfd (nameroot, flags, namep)
       free (filename);
       filename = NULL;
     }
+
+  if (fd < 0 && errno == ENOSPC && emergency_sys_tmpdir())
+    goto enospace;
+
   if (namep)
     *namep = filename;
   return fd;
@@ -235,6 +275,13 @@ sh_mktmpfd (nameroot, flags, namep)
     }
   while (fd < 0 && errno == EEXIST);
 
+  if (fd < 0 && errno == ENOSPC && emergency_sys_tmpdir())
+    {
+      free (filename);
+      filename = NULL;
+      goto enospace;
+    }
+
   if (namep)
     *namep = filename;
   else