Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Create temp directory

Credits go to bamccaig, CGamesPlay, Rampage, and tobing for helping out!
This thread is locked; no one can reply to it. rss feed Print
Create temp directory
Steve Terry
Member #1,989
March 2002
avatar

I need a way to create a temporary directory name. I've used tempnam(NULL) and it only seems to return 4 digit names with something like "\aer2." which is not exactly what I'm looking for. Anyone know of a better (no .NET) way of creating a unique temporary name consisting of 8-10 characters?

___________________________________
[ Facebook ]
Microsoft is not the Borg collective. The Borg collective has got proper networking. - planetspace.de
Bill Gates is in fact Shawn Hargreaves' ßî+çh. - Gideon Weems

Rampage
Member #3,035
December 2002
avatar

What I do when I need to create temp files is get the current time in milliseconds. That nomber is converted to a string and used as the name for my temp file/dir.

-R

bamccaig
Member #7,536
July 2006
avatar

Yeah, date/time would have to be the only reliable way to generate a unique filename.

Even then, because computers operate so fast it's possible for more than one to be created in the same milisecond (or whatever measure your method of getting time is)(depending on your application, of course) so you'll probably want a way to query the filesystem to make sure that the directory doesn't already exist.

Besides, for all you know there was already a directory named 20070409103029.ext or the like from a separate application or user. :P

Now that I think of it you might get away with hashing a random value, for example with SHA1 or MD5 or something, but I don't know how unique those are.

Okay, generate a random value and hash that, salted with a numeric datetime!

...And then query the filesystem to make sure the file doesn't already exist (if it does start the process over). :P

tobing
Member #5,213
November 2004
avatar

What's wrong with a name like "/aer2"? As long as the name refers to a directory that doesn't already exist...

bamccaig
Member #7,536
July 2006
avatar

tobing said:

What's wrong with a name like "/aer2"? As long as the name refers to a directory that doesn't already exist...

True, there's nothing wrong with that directory name. What was the problem with it?

The only potential problem is the decreased probability of a 4-character string being unique; especially if the directory it's working in is used often or by numerous people at a time.

The time is a better tactic anyway. In any case, you'll always have to check if the file exists or not before writing to make sure you don't damage another file.

tempnam - Manual said:

Creates a file with a unique filename, with access permission set to 0600, in the specified directory. If the directory does not exist, tempnam() may generate a file in the system's temporary directory, and return the name of that.

-Source

In PHP it sounds like it actually returns a unique name, as in PHP checks that it doesn't exist yet (and might even create it for you). What language are you developing with??

CGamesPlay
Member #2,559
July 2002
avatar

Quote:

tempnam(NULL)

tempnam accepts two arguments:

Quote:

SYNOPSIS
#include <stdio.h>

char *tempnam(const char *dir, const char *pfx);

DESCRIPTION
The tempnam() function returns a pointer to a string that is a valid file-
name, and such that a file with this name did not exist when tempnam()
checked. The filename suffix of the pathname generated will start with pfx
in case pfx is a non-NULL string of at most five bytes. The directory pre-
fix part of the pathname generated is required to be `appropriate' (often
that at least implies writable).

Attempts to find an appropriate directory go through the following steps:

a) In case the environment variable TMPDIR exists and contains the name
of an appropriate directory, that is used.

b) Otherwise, if the dir argument is non-NULL and appropriate, it is
used.

c) Otherwise, P_tmpdir (as defined in <stdio.h>) is used when appropri-
ate.

d) Finally an implementation-defined directory may be used.

The string returned by tempnam() is allocated using malloc(3) and hence
should be freed by free(3).

[append]
If I were you, I'd do tempnam(getenv("TEMP"), "MyProgram").

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

Steve Terry
Member #1,989
March 2002
avatar

Ahh the documentation I was looking at only had tmpnam taking in one argument, not two. At any rate I just friggin used abs and rand to generate me a nice number (between 10000 and 99999) and used that for the directory name and checked if it existed first.

___________________________________
[ Facebook ]
Microsoft is not the Borg collective. The Borg collective has got proper networking. - planetspace.de
Bill Gates is in fact Shawn Hargreaves' ßî+çh. - Gideon Weems

Thomas Fjellstrom
Member #476
June 2000
avatar

I wrote a new tmpfile method for allegro 4.3 to handle all this. it atm, returns a file descriptor, so its just for files, but its not hard to make one for dirs either. It handles "anonymous" temp files (ones that are unlinked immediately), and can auto delete upon file close.

I hadn't considered making a temp dir version. Maybe if people request it enough.

code: (for the stdio handler, windows code will likely use one of the Win32 functions, if its deemed necessary)

1#define MAX_MKTEMP_TRIES 1000
2const char mktemp_ok_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
3 
4void _al_fs_mktemp_replace_XX(char *template, char *dst)
5{
6 size_t len = strlen(template);
7 uint32_t i = 0;
8 
9 for(i=0; i<len; ++i) {
10 if(template<i> != 'X') {
11 dst<i> = template<i>;
12 }
13 else {
14 dst<i> = mktemp_ok_chars[ _al_rand() % (sizeof(mktemp_ok_chars)-1) ];
15 }
16 }
17}
18 
19/* FIXME: provide the filename created. */
20/* might have to make AL_FS_ENTRY a strust to provide the filename, and unlink hint. */
21/* by default, temp file is NOT unlink'ed automatically */
22 
23AL_FS_ENTRY *al_fs_stdio_mktemp(const char *template, uint32_t ulink)
24{
25 int32_t fd = -1, tries = 0;
26 int32_t template_len = 0, tmpdir_len = 0;
27 AL_FS_ENTRY *fh = NULL;
28 char *dest = NULL;
29 char tmpdir[PATH_MAX];
30 
31 template_len = strlen( template );
32 
33 if(al_get_path(AL_TEMP_PATH, tmpdir, PATH_MAX) != 0) {
34 ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Failed to find temp directory"));
35 return NULL;
36 }
37 
38 tmpdir_len = strlen( tmpdir_len );
39 
40 dest = AL_MALLOC( template_len + tmpdir_len + 2 );
41 if(!dest) {
42 *allegro_errno = errno;
43 return NULL;
44 }
45 
46 memset(dest, 0, template_len + tmpdir_len + 2);
47 memcpy(dest, tmpdir, strlen( tmpdir ) );
48 
49 /* doing this check makes the path prettier, no extra / laying around */
50 if(dest[tmpdir_len-1] != '/') {
51 dest[tmpdir_len] = '/';
52 tmpdir_len++;
53 }
54 
55 memcpy(dest + tmpdir_len, template, template_len);
56 
57 for(i=0; i<MAX_MKTEMP_TRIES; ++i) {
58 _al_fs_mktemp_replace_XX(template, dest + tmpdir_len);
59 fd = open( dest, O_EXCL | O_CREAT | O_RDWR );
60 if(fd == -1)
61 continue;
62 
63 // changing the hook for create handle in a separate thread will cause some nice errors here,
64 // if you expect it to return a stdio handle ;)
65 fh = al_fs_create_handle( dest );
66 if(!fh) {
67 close(fd);
68 free(dest);
69 return NULL;
70 }
71 
72 fh->handle = fdopen( fd, "r+" );
73 if(!fh->handle) {
74 al_fs_stdio_destroy_handle(fh);
75 close(fd);
76 free(dest);
77 return NULL;
78 }
79 
80 if(ulink == AL_FS_MKTEMP_UNLINK_NOW)
81 unlink( dest );
82 else if(ulink == AL_FS_MKTEMP_UNLINK_ON_CLOSE)
83 fh->ulink = 1;
84 
85 fh->free_on_fclose = 1;
86 fh->path = dest;
87 
88 return fh;
89 }
90 
91 free(dest);
92 ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Failed to create a uniqe temporary file"));
93 return NULL;
94}

It shouldn't be hard to make that do a dir at all. Or turn into code that doesn't rely on my Allegro 4.3 stuff.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Go to: