tempnam.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 /* A reasonably functional tmpnam. */
10 
11 /* Originally by Tom Hageman, tom@basil.icce.rug.nl */
12 
13 /*
14  * This tmpnam() was changed by Gerben_Wierda@RnA.nl to serve as
15  * tempnam() for squid-1.1.6. It ignores the directory parameter, every
16  * temp file is written in /tmp.
17  */
18 
19 #include "squid.h"
20 #include "compat/tempnam.h"
21 
22 #if HAVE_LIBC_H
23 #include <libc.h>
24 #endif
25 #if HAVE_LIMITS_H
26 #include <limits.h>
27 #endif
28 #if HAVE_UNISTD_H
29 #include <unistd.h>
30 #endif
31 
32 #undef TMP_MAX
33 
34 #define _tmp "/tmp/"
35 #define lengthof_tmp 5
36 
37 #ifndef LONG_BIT
38 #define LONG_BIT (CHAR_BIT * 4) /* assume sizeof(long) == 4 */
39 #endif
40 
41 #define L_tmpmin (lengthof_tmp + 5) /* 5 chars for pid. */
42 
43 #if (L_tmpnam > L_tmpmin)
44 #if (L_tmpnam > L_tmpmin + LONG_BIT / 6) /* base 64 */
45 #define TMP_MAX ULONG_MAX
46 #else
47 #define TMP_MAX ((1L << (6 * (L_tmpnam - L_tmpmin))) - 1)
48 #endif
49 #else
50 #ifndef L_tmpnam
51 #error "tmpnam: L_tmpnam undefined"
52 #else
53 #error "tmpnam: L_tmpnam too small"
54 #endif
55 #endif
56 
57 static char *
58 _tmpnam(void)
59 {
60  static const char digits[] =
61 #if (L_tmpnam >= L_tmpmin + LONG_BIT / 4)
62  "0123456789abcdef";
63 #define TMP_BASE 16
64 #else
65  "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-";
66 #define TMP_BASE 64
67 #endif
68  static unsigned long lastcount = 0;
69  static char buffer[L_tmpnam + 1];
70  char *s = buffer;
71  unsigned long count = lastcount;
72  pid_t pid = getpid();
73 
74  if (sizeof(_tmp) - 1 != lengthof_tmp)
75  abort(); /* Consistency error. */
76 
77  for (;;) {
78  register int i = L_tmpnam;
79  register unsigned long c;
80  register unsigned int p;
81 
82  /* Build filename. (the hard way) */
83  s += i;
84  *s = '\0';
85 
86  c = (count == TMP_MAX) ? 0 : ++count;
87  do {
88  *--s = digits[c % TMP_BASE];
89  c /= TMP_BASE;
90  } while (--i > L_tmpmin);
91 
92  p = (unsigned int) pid;
93  do {
94  *--s = digits[p % 10];
95  p /= 10;
96  } while (--i > lengthof_tmp);
97 
98  do {
99  *--s = _tmp[--i];
100  } while (i > 0);
101 
102  /* Check that the file doesn't exist. */
103  if (access(s, 0) != 0)
104  break;
105 
106  /* It exists; retry unless we tried them all. */
107  if (count == lastcount) {
108  s = NULL;
109  break;
110  }
111  }
112 
113  lastcount = count;
114 
115  return s;
116 }
117 
118 char *
119 tempnam(const char *dir, const char *pfx)
120 {
121  return _tmpnam();
122 }
123 
#define TMP_BASE
static pid_t pid
Definition: IcmpSquid.cc:34
#define lengthof_tmp
Definition: tempnam.c:35
#define _tmp
Definition: tempnam.c:34
static char * _tmpnam(void)
Definition: tempnam.c:58
char * tempnam(const char *dir, const char *pfx)
Definition: tempnam.c:119
#define NULL
Definition: types.h:145
#define L_tmpmin
Definition: tempnam.c:41
int unsigned int
Definition: stub_fd.cc:19

 

Introduction

Documentation

Support

Miscellaneous