Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifdef HAVE_CONFIG_H
00020 #include <config.h>
00021 #endif
00022
00023 #ifndef HAVE_TEMPNAM
00024
00025 #include <errno.h>
00026 #include <stddef.h>
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030
00031 #include <sys/types.h>
00032 #include <unistd.h>
00033
00034 #include <fcntl.h>
00035
00036 #include "statdefs.h"
00037
00038 #ifndef FILENAME_MAX
00039 #ifdef MAXPATHLEN
00040 #define FILENAME_MAX MAXPATHLEN
00041 #else
00042 #define FILENAME_MAX 1024
00043 #endif
00044 #endif
00045
00046 #ifndef P_tmpdir
00047 #define P_tmpdir "/usr/tmp/"
00048 #endif
00049
00050
00051 static int
00052 diraccess (const char *dir)
00053 {
00054 struct stat buf;
00055 return stat (dir, &buf) == 0 && S_ISDIR (buf.st_mode);
00056 }
00057
00058
00059 static int
00060 exists (const char *file)
00061 {
00062
00063 struct stat st;
00064 int save = errno;
00065 if (stat (file, &st) == 0)
00066 return 1;
00067 else
00068 {
00069
00070
00071
00072
00073
00074 int exists = errno != ENOENT;
00075 errno = save;
00076 return exists;
00077 }
00078 }
00079
00080
00081
00082 static const char letters[] =
00083 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 char *
00100 __stdio_gen_tempname (const char *dir, const char *pfx,
00101 int dir_search, size_t *lenptr,
00102 FILE **streamptr)
00103 {
00104 int saverrno = errno;
00105 static const char tmpdir[] = P_tmpdir;
00106 static size_t indices[2];
00107 size_t *idx;
00108 static char buf[FILENAME_MAX];
00109 static pid_t oldpid = (pid_t) 0;
00110 pid_t pid = getpid();
00111 register size_t len, plen, dlen;
00112
00113 if (dir_search)
00114 {
00115 register const char *d = getenv("TMPDIR");
00116 if (d != NULL && !diraccess(d))
00117 d = NULL;
00118 if (d == NULL && dir != NULL && diraccess(dir))
00119 d = dir;
00120 if (d == NULL && diraccess(tmpdir))
00121 d = tmpdir;
00122 if (d == NULL && diraccess("/tmp"))
00123 d = "/tmp";
00124 if (d == NULL)
00125 {
00126 errno = ENOENT;
00127 return NULL;
00128 }
00129 dir = d;
00130 }
00131 else
00132 dir = tmpdir;
00133
00134 dlen = strlen (dir);
00135
00136
00137 while (dlen > 1 && dir[dlen - 1] == '/')
00138 --dlen;
00139
00140 if (pfx != NULL && *pfx != '\0')
00141 {
00142 plen = strlen(pfx);
00143 if (plen > 5)
00144 plen = 5;
00145 }
00146 else
00147 plen = 0;
00148
00149 if (dir != tmpdir && !strcmp(dir, tmpdir))
00150 dir = tmpdir;
00151 idx = &indices[(plen == 0 && dir == tmpdir) ? 1 : 0];
00152
00153 if (pid != oldpid)
00154 {
00155 oldpid = pid;
00156 indices[0] = indices[1] = 0;
00157 }
00158
00159 len = dlen + 1 + plen + 5 + 3;
00160 for (; *idx < ((sizeof (letters) - 1) * (sizeof (letters) - 1) *
00161 (sizeof (letters) - 1));
00162 ++*idx)
00163 {
00164
00165
00166
00167
00168
00169 if (sizeof (buf) < len)
00170 return NULL;
00171
00172 sprintf (buf, "%.*s/%.*s%.5d%c%c%c",
00173 (int) dlen, dir, (int) plen,
00174 pfx, pid % 100000,
00175 letters[*idx
00176 % (sizeof (letters) - 1)],
00177 letters[(*idx / (sizeof (letters) - 1))
00178 % (sizeof (letters) - 1)],
00179 letters[(*idx / ((sizeof (letters) - 1) *
00180 (sizeof (letters) - 1)))
00181 % (sizeof (letters) - 1)]
00182 );
00183
00184 if (! buf || strlen (buf) != (int) len)
00185 return NULL;
00186
00187 if (streamptr != NULL)
00188 abort ();
00189 else if (exists (buf))
00190 continue;
00191
00192
00193
00194
00195 errno = saverrno;
00196
00197 if (lenptr != NULL)
00198 *lenptr = len + 1;
00199 return buf;
00200 }
00201
00202
00203 errno = EEXIST;
00204 return NULL;
00205 }
00206
00207 #endif