SDDS ToolKit Programs and Libraries for C and Python
Loading...
Searching...
No Matches
tmpname.c File Reference

Detailed Description

Provides functions to generate unique temporary filenames.

License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
M. Borland, C Saunders, R. Soliday

Definition in file tmpname.c.

#include "mdb.h"
#include "mdb_thread.h"
#include <time.h>
#include <unistd.h>
#include <errno.h>

Go to the source code of this file.

Functions

char * tmpname (char *s)
 Supplies a unique temporary filename.
 
char * mktempOAG (char *template)
 Generates a unique temporary filename based on a template.
 

Function Documentation

◆ mktempOAG()

char * mktempOAG ( char * template)

Generates a unique temporary filename based on a template.

Replaces the last six characters ('XXXXXX') of the template with random characters from a predefined set to create a unique temporary filename. It ensures that the generated filename does not already exist by checking the filesystem.

Parameters
templateA string containing the template for the temporary filename. The last six characters should be 'XXXXXX'.
Returns
A pointer to the modified template with the unique temporary filename. If no unique name could be generated, the first character of the template is set to null.

Definition at line 91 of file tmpname.c.

91 {
92 int len, pid;
93 char *XXXXXX;
94 static uint64_t value;
95 uint64_t random_time_bits;
96 unsigned int count;
97 int save_errno = errno;
98 struct_stat64 st;
99 static const char letters[] =
100 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
101
102#define ATTEMPTS_MIN (62 * 62 * 62)
103
104#if ATTEMPTS_MIN < TMP_MAX
105 unsigned int attempts = TMP_MAX;
106#else
107 unsigned int attempts = ATTEMPTS_MIN;
108#endif
109
110 len = strlen(template);
111 if (len < 6 || memcmp(&template[len - 6], "XXXXXX", 6)) {
112 template[0] = '\0';
113 return (template);
114 }
115
116 /* This is where the Xs start. */
117 XXXXXX = &template[len - 6];
118
119 /* Get some more or less random data. */
120 random_time_bits = time(NULL);
121
122 pid = __getpid();
123 mdb_thread_lock(&tmpname_lock);
124 value += random_time_bits ^ (pid * pid);
125 for (count = 0; count < attempts; value += 7777, ++count) {
126 uint64_t v = value;
127
128 /* Fill in the random bits. */
129 XXXXXX[0] = letters[v % 62];
130 v /= 31;
131 XXXXXX[1] = letters[v % 62];
132 v /= 31;
133 XXXXXX[2] = letters[v % 62];
134 v /= 31;
135 XXXXXX[3] = letters[v % 62];
136 v /= 31;
137 XXXXXX[4] = letters[v % 62];
138 v /= 31;
139 XXXXXX[5] = letters[v % 62];
140
141#if defined(vxWorks)
142 if (!fexists(template) < 0) {
143 mdb_thread_unlock(&tmpname_lock);
144 return (template);
145 }
146#else
147 if (__lxstat64(_STAT_VER, template, &st) < 0) {
148 if (errno == ENOENT) {
149 __set_errno(save_errno);
150 mdb_thread_unlock(&tmpname_lock);
151 return (template);
152 } else {
153 /* Give up now. */
154 template[0] = '\0';
155 mdb_thread_unlock(&tmpname_lock);
156 return (template);
157 }
158 }
159#endif
160 }
161
162 /* We got out of the loop because we ran out of combinations to try. */
163 template[0] = '\0';
164 mdb_thread_unlock(&tmpname_lock);
165 return (template);
166}
long fexists(const char *filename)
Checks if a file exists.
Definition fexists.c:27

◆ tmpname()

char * tmpname ( char * s)

Supplies a unique temporary filename.

Generates a unique temporary filename by appending the process ID and an incrementing counter to a base name. Ensures that the filename does not already exist.

Parameters
sPointer to a buffer where the temporary filename will be stored. If NULL, the function allocates memory for the filename.
Returns
A pointer to the unique temporary filename string.

Definition at line 37 of file tmpname.c.

38{
39 static long i = 1;
40 static long pid = -1;
41 if (s == NULL)
42 s = tmalloc((unsigned)(40 * sizeof(*s)));
43 mdb_thread_lock(&tmpname_lock);
44 if (pid < 0)
45#if !defined(vxWorks)
46 pid = getpid();
47#endif
48 do {
49#if defined(vxWorks)
50 sprintf(s, "tmp.%ld", i);
51#else
52 sprintf(s, "tmp%ld.%ld", pid, i);
53#endif
54 i += 1;
55 if (!fexists(s)) {
56 mdb_thread_unlock(&tmpname_lock);
57 break;
58 }
59 } while (1);
60 return (s);
61}
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:65