1 /* This is file MKTEMP.C */
2 /* This file may have been modified by DJ Delorie (Jan 1991). If so,
3 ** these modifications are Copyright (C) 1991 DJ Delorie.
7 * Copyright (c) 1987 Regents of the University of California.
10 * Redistribution and use in source and binary forms are permitted
11 * provided that: (1) source distributions retain this entire copyright
12 * notice and comment, and (2) distributions including binaries display
13 * the following acknowledgement: ``This product includes software
14 * developed by the University of California, Berkeley and its contributors''
15 * in the documentation or other materials provided with the distribution
16 * and in all advertising materials mentioning features or use of this
17 * software. Neither the name of the University nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27 <<mktemp>>, <<mkstemp>>---generate unused file name
40 char *mktemp(char *<[path]>);
41 int mkstemp(char *<[path]>);
43 char *_mktemp_r(void *<[reent]>, char *<[path]>);
44 int *_mkstemp_r(void *<[reent]>, char *<[path]>);
48 char *mktemp(<[path]>)
54 char *_mktemp_r(<[reent]>, <[path]>)
58 int _mkstemp_r(<[reent]>, <[path]>)
63 <<mktemp>> and <<mkstemp>> attempt to generate a file name that is not
64 yet in use for any existing file. <<mkstemp>> creates the file and
65 opens it for reading and writing; <<mktemp>> simply generates the file name.
67 You supply a simple pattern for the generated file name, as the string
68 at <[path]>. The pattern should be a valid filename (including path
69 information if you wish) ending with some number of `<<X>>'
70 characters. The generated filename will match the leading part of the
71 name you supply, with the trailing `<<X>>' characters replaced by some
72 combination of digits and letters.
74 The alternate functions <<_mktemp_r>> and <<_mkstemp_r>> are reentrant
75 versions. The extra argument <[reent]> is a pointer to a reentrancy
79 <<mktemp>> returns the pointer <[path]> to the modified string
80 representing an unused filename, unless it could not generate one, or
81 the pattern you provided is not suitable for a filename; in that case,
84 <<mkstemp>> returns a file descriptor to the newly created file,
85 unless it could not generate an unused filename, or the pattern you
86 provided is not suitable for a filename; in that case, it returns
90 ANSI C does not require either <<mktemp>> or <<mkstemp>>; the System
91 V Interface Definition requires <<mktemp>> as of Issue 2.
93 Supporting OS subroutines required: <<getpid>>, <<open>>, <<stat>>.
96 #include <sys/types.h>
105 _DEFUN (_gettemp
, (ptr
, path
, doopen
),
106 struct _reent
*ptr _AND
108 register int *doopen
)
110 register char *start
, *trv
;
114 pid
= _getpid_r (ptr
);
115 for (trv
= path
; *trv
; ++trv
) /* extra X's get set to 0's */
117 while (*--trv
== 'X')
119 *trv
= (pid
% 10) + '0';
124 * Check the target directory; if you have six X's and it
125 * doesn't exist this runs for a *very* long time.
128 for (start
= trv
+ 1;; --trv
)
135 #ifdef __USE_INTERNAL_STAT64
136 if (_stat64_r (ptr
, path
, &sbuf
))
138 if (_stat_r (ptr
, path
, &sbuf
))
141 if (!(sbuf
.st_mode
& S_IFDIR
))
143 ptr
->_errno
= ENOTDIR
;
155 if ((*doopen
= _open_r (ptr
, path
, O_CREAT
| O_EXCL
| O_RDWR
, 0600))
158 #if defined(__CYGWIN__)
159 if (ptr
->_errno
!= EEXIST
&& ptr
->_errno
!= EACCES
)
161 if (ptr
->_errno
!= EEXIST
)
165 #ifdef __USE_INTERNAL_STAT64
166 else if (_stat64_r (ptr
, path
, &sbuf
))
168 else if (_stat_r (ptr
, path
, &sbuf
))
170 return (ptr
->_errno
== ENOENT
? 1 : 0);
172 /* tricky little algorithm for backward compatibility */
193 _DEFUN (_mkstemp_r
, (ptr
, path
),
194 struct _reent
*ptr _AND
199 return (_gettemp (ptr
, path
, &fd
) ? fd
: -1);
203 _DEFUN (_mktemp_r
, (ptr
, path
),
204 struct _reent
*ptr _AND
207 return (_gettemp (ptr
, path
, (int *) NULL
) ? path
: (char *) NULL
);
213 _DEFUN (mkstemp
, (path
),
218 return (_gettemp (_REENT
, path
, &fd
) ? fd
: -1);
222 _DEFUN (mktemp
, (path
),
225 return (_gettemp (_REENT
, path
, (int *) NULL
) ? path
: (char *) NULL
);
228 #endif /* ! defined (_REENT_ONLY) */