summaryrefslogtreecommitdiff
path: root/gutils.c
diff options
context:
space:
mode:
authorTor Lillqvist <tml@iki.fi>2000-10-30 21:55:21 +0000
committerTor Lillqvist <tml@src.gnome.org>2000-10-30 21:55:21 +0000
commit6acee58bdfc7e90ff8be4130b3eb3aaa319cfd3b (patch)
tree912feaf2b3e8a1fb61c52561f5f938f480610f0d /gutils.c
parent3de6638d23b43da5a8d3ee50993c95b0a8e94fa9 (diff)
downloadglib-6acee58bdfc7e90ff8be4130b3eb3aaa319cfd3b.tar.gz
Check for mkstemp.
2000-10-30 Tor Lillqvist <tml@iki.fi> * configure.in: Check for mkstemp. * gutils.c (g_mkstemp): New function. If HAVE_MKSTEMP, just call it, otherwise use code lifted from glibc. * gutils.h: Declare it. * glib.def: Here, too.
Diffstat (limited to 'gutils.c')
-rw-r--r--gutils.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/gutils.c b/gutils.c
index fac67375d..b7b786da9 100644
--- a/gutils.c
+++ b/gutils.c
@@ -40,6 +40,7 @@
#include <stdio.h>
#include <string.h>
#include <errno.h>
+#include <fcntl.h>
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
@@ -76,6 +77,10 @@
#include <langinfo.h>
#endif
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
const guint glib_major_version = GLIB_MAJOR_VERSION;
const guint glib_minor_version = GLIB_MINOR_VERSION;
const guint glib_micro_version = GLIB_MICRO_VERSION;
@@ -964,3 +969,78 @@ g_get_codeset (void)
#endif
#endif
}
+
+/**
+ * g_mkstemp:
+ *
+ * Open a temporary file
+ *
+ * The parameter is a string that should match the rules for mktemp, i.e.
+ * end in "XXXXXX". The X string will be modified to form the name
+ * of a file that didn't exist.
+ *
+ * Return value: A file handle (as from open()) to the file file
+ * opened for reading and writing. The file is opened in binary mode
+ * on platforms where there is a difference. The file handle should be
+ * closed with close(). In case of errors, -1 is returned.
+ *
+ * From the GNU C library.
+ * Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc.
+ */
+int
+g_mkstemp (char *tmpl)
+{
+#ifdef HAVE_MKSTEMP
+ return mkstemp (tmpl);
+#else
+ int len;
+ char *XXXXXX;
+ int count, fd;
+ static const char letters[] =
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+ glong value;
+ GTimeVal tv;
+
+ len = strlen (tmpl);
+ if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
+ return -1;
+
+ /* This is where the Xs start. */
+ XXXXXX = &tmpl[len - 6];
+
+ /* Get some more or less random data. */
+ g_get_current_time (&tv);
+ value = tv.tv_usec ^ tv.tv_sec;
+
+ for (count = 0; count < 100; value += 7777, ++count)
+ {
+ glong v = value;
+
+ /* Fill in the random bits. */
+ XXXXXX[0] = letters[v % 62];
+ v /= 62;
+ XXXXXX[1] = letters[v % 62];
+ v /= 62;
+ XXXXXX[2] = letters[v % 62];
+ v /= 62;
+ XXXXXX[3] = letters[v % 62];
+ v /= 62;
+ XXXXXX[4] = letters[v % 62];
+ v /= 62;
+ XXXXXX[5] = letters[v % 62];
+
+ fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
+
+ if (fd >= 0)
+ return fd;
+ else if (errno != EEXIST)
+ /* Any other error will apply also to other names we might
+ * try, and there are 2^32 or so of them, so give up now.
+ */
+ return -1;
+ }
+
+ /* We got out of the loop because we ran out of combinations to try. */
+ return -1;
+#endif
+}