| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * tmpfile.c - functions to create and safely open temp files for the shell. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Copyright (C) 2000 Free Software Foundation, Inc.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    This file is part of GNU Bash, the Bourne Again SHell. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |    Bash is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  |    it under the terms of the GNU General Public License as published by | 
					
						
							|  |  |  |    the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  |    (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |    Bash is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |    GNU General Public License for more details. | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |    You should have received a copy of the GNU General Public License | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |    along with Bash.  If not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <config.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <bashtypes.h>
 | 
					
						
							|  |  |  | #include <posixstat.h>
 | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | #include <posixtime.h>
 | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | #include <filecntl.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined (HAVE_UNISTD_H)
 | 
					
						
							|  |  |  | #  include <unistd.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-26 09:36:43 -05:00
										 |  |  | #include <bashansi.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <errno.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <shell.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef errno
 | 
					
						
							|  |  |  | extern int errno; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-22 19:11:26 -05:00
										 |  |  | #define BASEOPENFLAGS	(O_CREAT | O_TRUNC | O_EXCL | O_BINARY)
 | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define DEFAULT_TMPDIR		"."	/* bogus default, should be changed */
 | 
					
						
							|  |  |  | #define DEFAULT_NAMEROOT	"shtmp"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  | extern pid_t dollar_dollar_pid; | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-10 14:15:34 +00:00
										 |  |  | static char *get_sys_tmpdir __P((void)); | 
					
						
							|  |  |  | static char *get_tmpdir __P((int)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | static char *sys_tmpdir = (char *)NULL; | 
					
						
							|  |  |  | static int ntmpfiles; | 
					
						
							|  |  |  | static int tmpnamelen = -1; | 
					
						
							|  |  |  | static unsigned long filenum = 1L; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char * | 
					
						
							|  |  |  | get_sys_tmpdir () | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (sys_tmpdir) | 
					
						
							|  |  |  |     return sys_tmpdir; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  | #ifdef P_tmpdir
 | 
					
						
							|  |  |  |   sys_tmpdir = P_tmpdir; | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  |   if (file_iswdir (sys_tmpdir)) | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |     return sys_tmpdir; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |   sys_tmpdir = "/tmp"; | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  |   if (file_iswdir (sys_tmpdir)) | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |     return sys_tmpdir; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   sys_tmpdir = "/var/tmp"; | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  |   if (file_iswdir (sys_tmpdir)) | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |     return sys_tmpdir; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   sys_tmpdir = "/usr/tmp"; | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  |   if (file_iswdir (sys_tmpdir)) | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |     return sys_tmpdir; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   sys_tmpdir = DEFAULT_TMPDIR; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return sys_tmpdir; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char * | 
					
						
							|  |  |  | get_tmpdir (flags) | 
					
						
							|  |  |  |      int flags; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   char *tdir; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   tdir = (flags & MT_USETMPDIR) ? get_string_value ("TMPDIR") : (char *)NULL; | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |   if (tdir && (file_iswdir (tdir) == 0 || strlen (tdir) > PATH_MAX)) | 
					
						
							|  |  |  |     tdir = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |   if (tdir == 0) | 
					
						
							|  |  |  |     tdir = get_sys_tmpdir (); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined (HAVE_PATHCONF) && defined (_PC_NAME_MAX)
 | 
					
						
							|  |  |  |   if (tmpnamelen == -1) | 
					
						
							|  |  |  |     tmpnamelen = pathconf (tdir, _PC_NAME_MAX); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   tmpnamelen = 0; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return tdir; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | char * | 
					
						
							|  |  |  | sh_mktmpname (nameroot, flags) | 
					
						
							|  |  |  |      char *nameroot; | 
					
						
							|  |  |  |      int flags; | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |   char *filename, *tdir, *lroot; | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |   struct stat sb; | 
					
						
							|  |  |  |   int r, tdlen; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |   filename = (char *)xmalloc (PATH_MAX + 1); | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |   tdir = get_tmpdir (flags); | 
					
						
							|  |  |  |   tdlen = strlen (tdir); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |   lroot = nameroot ? nameroot : DEFAULT_NAMEROOT; | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  | #ifdef USE_MKTEMP
 | 
					
						
							|  |  |  |   sprintf (filename, "%s/%s.XXXXXX", tdir, lroot); | 
					
						
							|  |  |  |   if (mktemp (filename) == 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       free (filename); | 
					
						
							|  |  |  |       filename = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #else  /* !USE_MKTEMP */
 | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |   while (1) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |       filenum = (filenum << 1) ^ | 
					
						
							|  |  |  | 		(unsigned long) time ((time_t *)0) ^ | 
					
						
							|  |  |  | 		(unsigned long) dollar_dollar_pid ^ | 
					
						
							| 
									
										
										
										
											2014-02-26 09:36:43 -05:00
										 |  |  | 		(unsigned long) ((flags & MT_USERANDOM) ? random () : ntmpfiles++); | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |       sprintf (filename, "%s/%s-%lu", tdir, lroot, filenum); | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |       if (tmpnamelen > 0 && tmpnamelen < 32) | 
					
						
							|  |  |  | 	filename[tdlen + 1 + tmpnamelen] = '\0'; | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  | #  ifdef HAVE_LSTAT
 | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |       r = lstat (filename, &sb); | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  | #  else
 | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |       r = stat (filename, &sb); | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  | #  endif
 | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |       if (r < 0 && errno == ENOENT) | 
					
						
							|  |  |  | 	break; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  | #endif /* !USE_MKTEMP */
 | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return filename; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | sh_mktmpfd (nameroot, flags, namep) | 
					
						
							|  |  |  |      char *nameroot; | 
					
						
							|  |  |  |      int flags; | 
					
						
							|  |  |  |      char **namep; | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |   char *filename, *tdir, *lroot; | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |   int fd, tdlen; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |   filename = (char *)xmalloc (PATH_MAX + 1); | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |   tdir = get_tmpdir (flags); | 
					
						
							|  |  |  |   tdlen = strlen (tdir); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |   lroot = nameroot ? nameroot : DEFAULT_NAMEROOT; | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  | #ifdef USE_MKSTEMP
 | 
					
						
							|  |  |  |   sprintf (filename, "%s/%s.XXXXXX", tdir, lroot); | 
					
						
							|  |  |  |   fd = mkstemp (filename); | 
					
						
							|  |  |  |   if (fd < 0 || namep == 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       free (filename); | 
					
						
							|  |  |  |       filename = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   if (namep) | 
					
						
							|  |  |  |     *namep = filename; | 
					
						
							|  |  |  |   return fd; | 
					
						
							|  |  |  | #else /* !USE_MKSTEMP */
 | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |   do | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |       filenum = (filenum << 1) ^ | 
					
						
							|  |  |  | 		(unsigned long) time ((time_t *)0) ^ | 
					
						
							|  |  |  | 		(unsigned long) dollar_dollar_pid ^ | 
					
						
							| 
									
										
										
										
											2014-02-26 09:36:43 -05:00
										 |  |  | 		(unsigned long) ((flags & MT_USERANDOM) ? random () : ntmpfiles++); | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |       sprintf (filename, "%s/%s-%lu", tdir, lroot, filenum); | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |       if (tmpnamelen > 0 && tmpnamelen < 32) | 
					
						
							|  |  |  | 	filename[tdlen + 1 + tmpnamelen] = '\0'; | 
					
						
							|  |  |  |       fd = open (filename, BASEOPENFLAGS | ((flags & MT_READWRITE) ? O_RDWR : O_WRONLY), 0600); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   while (fd < 0 && errno == EEXIST); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (namep) | 
					
						
							|  |  |  |     *namep = filename; | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     free (filename); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return fd; | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  | #endif /* !USE_MKSTEMP */
 | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | FILE * | 
					
						
							|  |  |  | sh_mktmpfp (nameroot, flags, namep) | 
					
						
							|  |  |  |      char *nameroot; | 
					
						
							|  |  |  |      int flags; | 
					
						
							|  |  |  |      char **namep; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   int fd; | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |   FILE *fp; | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   fd = sh_mktmpfd (nameroot, flags, namep); | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |   if (fd < 0) | 
					
						
							|  |  |  |     return ((FILE *)NULL); | 
					
						
							|  |  |  |   fp = fdopen (fd, (flags & MT_READWRITE) ? "w+" : "w"); | 
					
						
							|  |  |  |   if (fp == 0) | 
					
						
							|  |  |  |     close (fd); | 
					
						
							|  |  |  |   return fp; | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | } |