Changed license terms to the plain LGPL thru-out.
[bpt/guile.git] / libguile / mkstemp.c
CommitLineData
98cb9664 1/* Copyright (C) 1991, 1992, 1996, 1998, 2001 Free Software Foundation, Inc.
23cc5968
MV
2 This file is derived from mkstemps.c from the GNU Libiberty Library
3 which in turn is derived from the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
57e2f421 18 Boston, MA 02111-1307, USA.
73be1d9e 19*/
23cc5968 20
2a7b2583
RB
21#if HAVE_CONFIG_H
22# include <config.h>
23#endif
24
25#include "libguile/__scm.h"
23cc5968
MV
26
27#ifdef HAVE_STDLIB_H
28#include <stdlib.h>
29#endif
30#ifdef HAVE_STRING_H
31#include <string.h>
32#endif
33#include <errno.h>
34#include <stdio.h>
35#include <fcntl.h>
36#ifdef HAVE_UNISTD_H
37#include <unistd.h>
38#endif
39#ifdef HAVE_SYS_TIME_H
40#include <sys/time.h>
41#endif
5507e726
MV
42#ifdef __MINGW32__
43#include <process.h>
44#endif
23cc5968 45
23cc5968
MV
46#ifndef TMP_MAX
47#define TMP_MAX 16384
48#endif
49
50/* Generate a unique temporary file name from TEMPLATE.
51
52 TEMPLATE has the form:
53
54 <path>/ccXXXXXX
55
56 The last six characters of TEMPLATE must be "XXXXXX"; they are
57 replaced with a string that makes the filename unique.
58
59 Returns a file descriptor open on the file for reading and writing. */
60int
61mkstemp (template)
62 char *template;
63{
64 static const char letters[]
65 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
2a7b2583 66 static scm_t_uint64 value;
23cc5968
MV
67#ifdef HAVE_GETTIMEOFDAY
68 struct timeval tv;
69#endif
70 char *XXXXXX;
71 size_t len;
72 int count;
73
74 len = strlen (template);
75
76 if ((int) len < 6
77 || strncmp (&template[len - 6], "XXXXXX", 6))
78 {
79 return -1;
80 }
81
82 XXXXXX = &template[len - 6];
83
84#ifdef HAVE_GETTIMEOFDAY
85 /* Get some more or less random data. */
86 gettimeofday (&tv, NULL);
2a7b2583 87 value += ((scm_t_uint64) tv.tv_usec << 16) ^ tv.tv_sec ^ getpid ();
23cc5968
MV
88#else
89 value += getpid ();
90#endif
91
92 for (count = 0; count < TMP_MAX; ++count)
93 {
2a7b2583 94 scm_t_uint64 v = value;
23cc5968
MV
95 int fd;
96
97 /* Fill in the random bits. */
98 XXXXXX[0] = letters[v % 62];
99 v /= 62;
100 XXXXXX[1] = letters[v % 62];
101 v /= 62;
102 XXXXXX[2] = letters[v % 62];
103 v /= 62;
104 XXXXXX[3] = letters[v % 62];
105 v /= 62;
106 XXXXXX[4] = letters[v % 62];
107 v /= 62;
108 XXXXXX[5] = letters[v % 62];
109
110 fd = open (template, O_RDWR|O_CREAT|O_EXCL, 0600);
111 if (fd >= 0)
112 /* The file does not exist. */
113 return fd;
114
115 /* This is a random value. It is only necessary that the next
116 TMP_MAX values generated by adding 7777 to VALUE are different
117 with (module 2^32). */
118 value += 7777;
119 }
120
121 /* We return the null string if we can't find a unique file name. */
122 template[0] = '\0';
123 return -1;
124}