Parcourir la source

Replacement for mkstemp() etc (issue https://trac.osgeo.org/grass/ticket/2153)

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@58740 15284696-431f-4ddb-bdfa-cd5b030d7da7
Glynn Clements il y a 11 ans
Parent
commit
cc6f2603d0
1 fichiers modifiés avec 103 ajouts et 0 suppressions
  1. 103 0
      lib/gis/mkstemp.c

+ 103 - 0
lib/gis/mkstemp.c

@@ -0,0 +1,103 @@
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+
+#define MAX_REPLACE 5
+
+static int next(char **replace, int num_replace)
+{
+    int i;
+
+    for (i = 0; i < num_replace; i++) {
+	char *p = replace[i];
+	if (*p < 'z') {
+	    (*p)++;
+	    return 1;
+	}
+	else
+	    *p = 'a';
+    }
+
+    return 0;
+}
+
+static int G__mkstemp(char *template, int flags, int mode)
+{
+    char *replace[MAX_REPLACE];
+    int num_replace = 0;
+    char *ptr = template;
+    int fd;
+
+    while (num_replace < MAX_REPLACE) {
+	char *p = strchr(ptr, 'X');
+	if (!p)
+	    break;
+	replace[num_replace++] = p;
+	*p = 'a';
+	ptr = p + 1;
+    }
+
+    if (!num_replace)
+	return -1;
+
+    for (;;) {
+	if (!next(replace, num_replace))
+	    return -1;
+
+	if (access(template, F_OK) == 0)
+	    continue;
+
+	if (!flags)
+	    return 0;
+
+	fd = open(template, flags, mode);
+	if (fd < 0) {
+	    if (errno == EEXIST)
+		continue;
+	    return -1;
+	}
+
+	return fd;
+    }
+
+    return -1;
+}
+
+
+char *G_mktemp(char *template)
+{
+    return G__mkstemp(template, 0, 0) < 0 ? NULL : template;
+}
+
+int G_mkstemp(char *template, int flags, int mode)
+{
+
+    switch (flags & O_ACCMODE) {
+    case O_RDONLY:
+	G_fatal_error(_("Attempt to create read-only temporary file"));
+	return -1;
+    case O_WRONLY:
+    case O_RDWR:
+	break;
+    default:
+	G_fatal_error(_("Unrecognised access mode: %o"), flags & O_ACCMODE);
+	return -1;
+    }
+
+    return G__mkstemp(template, flags | O_CREAT | O_EXCL, mode);
+}
+
+FILE *G_mkstemp_fp(char *template, int flags, int mode)
+{
+    const char *fmode = (flags & O_ACCMODE == O_RDWR)
+	? ((flags & O_APPEND) ? "a+" : "w+")
+	: ((flags & O_APPEND) ? "a" : "w");
+    int fd = G_mkstemp(template, flags, mode);
+    if (fd < 0)
+	return NULL;
+    return fdopen(fd, fmode);
+}