clib/mktemp.c & shell/If: Fix checking for existing file.
[AROS.git] / compiler / clib / mktemp.c
blob64263149c86cee0da5abd5c52c0a72584e1959d3
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <string.h>
7 #include <proto/exec.h>
8 #include <proto/dos.h>
9 #include <dos/dos.h>
11 #include <exec/types.h>
12 #include <assert.h>
14 #define DEBUG 0
15 #include <aros/debug.h>
17 /*****************************************************************************
19 NAME */
20 #include <stdlib.h>
22 char *mktemp (
24 /* SYNOPSIS */
25 char *template)
27 /* FUNCTION
28 Make a unique temporary file name.
30 INPUTS
31 template - template to change into unique filename
33 RESULT
34 Returns template.
36 NOTES
37 Template must end in "XXXXXX" (i.e at least 6 X's).
39 Prior to this paragraph being created, mktemp() sometimes produced filenames
40 with '/' in them. AROS doesn't like that at all. Fortunately, the bug in this
41 function which produced it has been fixed. -- blippy
43 For clarity, define the HEAD of the template to be the part before the tail,
44 and the TAIL to be the succession of X's. So in, T:temp.XXXXXX , the head is
45 T:temp. and the tail is XXXXXX .
47 EXAMPLE
49 BUGS
50 Cannot create more than 26 filenames for the same process id. This is because
51 the "bumping" is only done to the first tail character - it should be
52 generalised to bump more characters if necessary.
54 SEE ALSO
56 INTERNALS
57 Based on libnix mktemp
59 ******************************************************************************/
61 IPTR pid = (IPTR)FindTask(0L);
62 char *c = template + strlen(template);
63 BPTR lock;
64 IPTR remainder;
66 while (*--c == 'X')
68 remainder = pid % 10;
69 assert(remainder>=0 && remainder<10);
70 *c = remainder + '0';
71 pid /= 10L;
74 c++; /* ... c now points to the 1st char of the template tail */
76 /* If template errornously does not end in X c will point to '\0';
77 exit gracefully
79 if (*c)
81 /* Loop over the first position of the tail, bumping it up as necessary */
82 for(*c = 'A'; *c <= 'Z'; (*c)++)
84 if (!(lock = Lock(template, SHARED_LOCK)))
86 if (IoErr() != ERROR_OBJECT_IN_USE)
88 D(bug("No lock (IoErr: %d); returning '%s'\n", IoErr(), template));
89 return template;
92 UnLock(lock);
96 D(bug("26 tries exhausted; Returning '%s'\n", template));
97 return template;
98 } /* mktemp */