COOPY » Guide
version 0.6.5
|
00001 /* Copyright (C) 1999, 2001-2002, 2006, 2009-2012 Free Software Foundation, 00002 Inc. 00003 This file is part of the GNU C Library. 00004 00005 This program is free software: you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation; either version 3 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00017 00018 /* Extracted from sysdeps/posix/tempname.c. */ 00019 00020 /* PFMOD #include <config.h> */ 00021 00022 /* Specification. */ 00023 #include "tmpdir.h" 00024 00025 #include <stdbool.h> 00026 #include <stdlib.h> 00027 #include <string.h> 00028 00029 #include <errno.h> 00030 #ifndef __set_errno 00031 # define __set_errno(Val) errno = (Val) 00032 #endif 00033 00034 #include <stdio.h> 00035 #ifndef P_tmpdir 00036 # ifdef _P_tmpdir /* native Windows */ 00037 # define P_tmpdir _P_tmpdir 00038 # else 00039 # define P_tmpdir "/tmp" 00040 # endif 00041 #endif 00042 00043 #include <sys/stat.h> 00044 00045 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ 00046 # define WIN32_LEAN_AND_MEAN /* avoid including junk */ 00047 # include <windows.h> 00048 #endif 00049 00050 #include "pathmax.h" 00051 00052 #if _LIBC 00053 # define struct_stat64 struct stat64 00054 #else 00055 # define struct_stat64 struct stat 00056 # define __xstat64(version, path, buf) stat (path, buf) 00057 #endif 00058 00059 #if ! (HAVE___SECURE_GETENV || _LIBC) 00060 # define __secure_getenv getenv 00061 #endif 00062 00063 /* Pathname support. 00064 ISSLASH(C) tests whether C is a directory separator character. 00065 */ 00066 #if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__ 00067 /* Native Windows, Cygwin, OS/2, DOS */ 00068 # define ISSLASH(C) ((C) == '/' || (C) == '\\') 00069 #else 00070 /* Unix */ 00071 # define ISSLASH(C) ((C) == '/') 00072 #endif 00073 00074 00075 /* Return nonzero if DIR is an existent directory. */ 00076 static bool 00077 direxists (const char *dir) 00078 { 00079 struct_stat64 buf; 00080 return __xstat64 (_STAT_VER, dir, &buf) == 0 && S_ISDIR (buf.st_mode); 00081 } 00082 00083 /* Path search algorithm, for tmpnam, tmpfile, etc. If DIR is 00084 non-null and exists, uses it; otherwise uses the first of $TMPDIR, 00085 P_tmpdir, /tmp that exists. Copies into TMPL a template suitable 00086 for use with mk[s]temp. Will fail (-1) if DIR is non-null and 00087 doesn't exist, none of the searched dirs exists, or there's not 00088 enough space in TMPL. */ 00089 int 00090 path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx, 00091 bool try_tmpdir) 00092 { 00093 const char *d; 00094 size_t dlen, plen; 00095 00096 if (!pfx || !pfx[0]) 00097 { 00098 pfx = "file"; 00099 plen = 4; 00100 } 00101 else 00102 { 00103 plen = strlen (pfx); 00104 if (plen > 5) 00105 plen = 5; 00106 } 00107 00108 if (try_tmpdir) 00109 { 00110 d = __secure_getenv ("TMPDIR"); 00111 if (d != NULL && direxists (d)) 00112 dir = d; 00113 else if (dir != NULL && direxists (dir)) 00114 /* nothing */ ; 00115 else 00116 dir = NULL; 00117 } 00118 if (dir == NULL) 00119 { 00120 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ 00121 char dirbuf[PATH_MAX]; 00122 DWORD retval; 00123 00124 /* Find Windows temporary file directory. 00125 We try this before P_tmpdir because Windows defines P_tmpdir to "\\" 00126 and will therefore try to put all temporary files in the root 00127 directory (unless $TMPDIR is set). */ 00128 retval = GetTempPath (PATH_MAX, dirbuf); 00129 if (retval > 0 && retval < PATH_MAX && direxists (dirbuf)) { 00130 dir = dirbuf; 00131 } 00132 else 00133 #endif 00134 { 00135 if (direxists (P_tmpdir)) { 00136 dir = P_tmpdir; 00137 if (P_tmpdir[0]=='\\'&&P_tmpdir[1]=='\0') { 00138 if (direxists("/tmp")) { 00139 dir = "/tmp"; 00140 } 00141 } 00142 } else if (strcmp (P_tmpdir, "/tmp") != 0 && direxists ("/tmp")) { 00143 dir = "/tmp"; 00144 } else { 00145 __set_errno (ENOENT); 00146 return -1; 00147 } 00148 } 00149 } 00150 00151 dlen = strlen (dir); 00152 while (dlen >= 1 && ISSLASH (dir[dlen - 1])) 00153 dlen--; /* remove trailing slashes */ 00154 00155 /* check we have room for "${dir}/${pfx}XXXXXX\0" */ 00156 if (tmpl_len < dlen + 1 + plen + 6 + 1) 00157 { 00158 __set_errno (EINVAL); 00159 return -1; 00160 } 00161 00162 sprintf (tmpl, "%.*s/%.*sXXXXXX", (int) dlen, dir, (int) plen, pfx); 00163 return 0; 00164 } 00165 00166