source: squid-ssl/trunk/fuentes/compat/tempnam.c @ 5495

Last change on this file since 5495 was 5495, checked in by Juanma, 2 years ago

Initial release

File size: 2.8 KB
Line 
1/*
2 * Copyright (C) 1996-2015 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
57static 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
118char *
119tempnam(const char *dir, const char *pfx)
120{
121    return _tmpnam();
122}
123
124#ifdef TEST
125int
126main()
127{
128    char *t;
129    int n = 0;
130    while ((t = tempnam(NULL, NULL))) {
131        printf("%s\n", t);
132        if (++n == 1000)
133            break;
134    }
135    return 1;
136}
137#endif
138
Note: See TracBrowser for help on using the repository browser.