diff options
author | Tor Lillqvist <tml@iki.fi> | 2000-10-30 21:55:21 +0000 |
---|---|---|
committer | Tor Lillqvist <tml@src.gnome.org> | 2000-10-30 21:55:21 +0000 |
commit | 6acee58bdfc7e90ff8be4130b3eb3aaa319cfd3b (patch) | |
tree | 912feaf2b3e8a1fb61c52561f5f938f480610f0d /gutils.c | |
parent | 3de6638d23b43da5a8d3ee50993c95b0a8e94fa9 (diff) | |
download | glib-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.c | 80 |
1 files changed, 80 insertions, 0 deletions
@@ -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 +} |