SDDSlib
Loading...
Searching...
No Matches
tmpname.c
Go to the documentation of this file.
1/**
2 * @file tmpname.c
3 * @brief Provides functions to generate unique temporary filenames.
4 *
5 * @copyright
6 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
7 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
8 *
9 * @license
10 * This file is distributed under the terms of the Software License Agreement
11 * found in the file LICENSE included with this distribution.
12 *
13 * @author M. Borland, C Saunders, R. Soliday
14 */
15
16#include "mdb.h"
17#include <time.h>
18#if defined(_WIN32)
19# include <process.h>
20#else
21# include <unistd.h>
22#endif
23
24/**
25 * @brief Supplies a unique temporary filename.
26 *
27 * Generates a unique temporary filename by appending the process ID and an incrementing
28 * counter to a base name. Ensures that the filename does not already exist.
29 *
30 * @param s Pointer to a buffer where the temporary filename will be stored. If NULL,
31 * the function allocates memory for the filename.
32 * @return A pointer to the unique temporary filename string.
33 */
34char *tmpname(s) char *s;
35{
36 static long i = 1;
37 static long pid = -1;
38 if (s == NULL)
39 s = tmalloc((unsigned)(40 * sizeof(*s)));
40 if (pid < 0)
41#if !defined(vxWorks)
42 pid = getpid();
43#endif
44 do {
45#if defined(vxWorks)
46 sprintf(s, "tmp.%ld", i);
47#else
48 sprintf(s, "tmp%ld.%ld", pid, i);
49#endif
50 i += 1;
51 if (!fexists(s))
52 break;
53 } while (1);
54 return (s);
55}
56
57#include <errno.h>
58#if _LIBC
59# define struct_stat64 struct stat64
60#else
61# define struct_stat64 struct stat
62# define __getpid getpid
63# ifdef _WIN32
64# define __lxstat64(version, path, buf) stat(path, buf)
65# else
66# define __lxstat64(version, path, buf) lstat(path, buf)
67# endif
68#endif
69#ifndef __set_errno
70# define __set_errno(Val) errno = (Val)
71#endif
72
73/**
74 * @brief Generates a unique temporary filename based on a template.
75 *
76 * Replaces the last six characters ('XXXXXX') of the template with random characters
77 * from a predefined set to create a unique temporary filename. It ensures that the
78 * generated filename does not already exist by checking the filesystem.
79 *
80 * @param template A string containing the template for the temporary filename.
81 * The last six characters should be 'XXXXXX'.
82 * @return A pointer to the modified template with the unique temporary filename.
83 * If no unique name could be generated, the first character of the template is set to null.
84 */
85char *mktempOAG(char *template) {
86 int len, pid;
87 char *XXXXXX;
88 static uint64_t value;
89 uint64_t random_time_bits;
90 unsigned int count;
91 int save_errno = errno;
92 struct_stat64 st;
93 static const char letters[] =
94 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
95
96#define ATTEMPTS_MIN (62 * 62 * 62)
97
98#if ATTEMPTS_MIN < TMP_MAX
99 unsigned int attempts = TMP_MAX;
100#else
101 unsigned int attempts = ATTEMPTS_MIN;
102#endif
103
104 len = strlen(template);
105 if (len < 6 || memcmp(&template[len - 6], "XXXXXX", 6)) {
106 template[0] = '\0';
107 return (template);
108 }
109
110 /* This is where the Xs start. */
111 XXXXXX = &template[len - 6];
112
113 /* Get some more or less random data. */
114 random_time_bits = time(NULL);
115
116 pid = __getpid();
117 value += random_time_bits ^ (pid * pid);
118 for (count = 0; count < attempts; value += 7777, ++count) {
119 uint64_t v = value;
120
121 /* Fill in the random bits. */
122 XXXXXX[0] = letters[v % 62];
123 v /= 31;
124 XXXXXX[1] = letters[v % 62];
125 v /= 31;
126 XXXXXX[2] = letters[v % 62];
127 v /= 31;
128 XXXXXX[3] = letters[v % 62];
129 v /= 31;
130 XXXXXX[4] = letters[v % 62];
131 v /= 31;
132 XXXXXX[5] = letters[v % 62];
133
134#if defined(vxWorks)
135 if (!fexists(template) < 0) {
136 return (template);
137 }
138#else
139 if (__lxstat64(_STAT_VER, template, &st) < 0) {
140 if (errno == ENOENT) {
141 __set_errno(save_errno);
142 return (template);
143 } else {
144 /* Give up now. */
145 template[0] = '\0';
146 return (template);
147 }
148 }
149#endif
150 }
151
152 /* We got out of the loop because we ran out of combinations to try. */
153 template[0] = '\0';
154 return (template);
155}
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:59
long fexists(const char *filename)
Checks if a file exists.
Definition fexists.c:27
char * tmpname(char *s)
Supplies a unique temporary filename.
Definition tmpname.c:34
char * mktempOAG(char *template)
Generates a unique temporary filename based on a template.
Definition tmpname.c:85