GRASS GIS 7 Programmer's Manual  7.0.3(2016)-r00000
mkstemp.c
Go to the documentation of this file.
1 
14 #include <stdio.h>
15 #include <string.h>
16 #include <errno.h>
17 #include <unistd.h>
18 #include <fcntl.h>
19 #include <grass/gis.h>
20 #include <grass/glocale.h>
21 
22 #define MAX_REPLACE 5
23 
24 static int next(char **replace, int num_replace)
25 {
26  int i;
27 
28  for (i = 0; i < num_replace; i++) {
29  char *p = replace[i];
30  if (*p < 'z') {
31  (*p)++;
32  return 1;
33  }
34  else
35  *p = 'a';
36  }
37 
38  return 0;
39 }
40 
41 static int G__mkstemp(char *template, int flags, int mode)
42 {
43  char *replace[MAX_REPLACE];
44  int num_replace = 0;
45  char *ptr = template;
46  int fd;
47 
48  while (num_replace < MAX_REPLACE) {
49  char *p = strchr(ptr, 'X');
50  if (!p)
51  break;
52  replace[num_replace++] = p;
53  *p = 'a';
54  ptr = p + 1;
55  }
56 
57  if (!num_replace)
58  return -1;
59 
60  for (;;) {
61  if (!next(replace, num_replace))
62  return -1;
63 
64  if (access(template, F_OK) == 0)
65  continue;
66 
67  if (!flags)
68  return 0;
69 
70  fd = open(template, flags, mode);
71  if (fd < 0) {
72  if (errno == EEXIST)
73  continue;
74  return -1;
75  }
76 
77  return fd;
78  }
79 
80  return -1;
81 }
82 
83 
104 char *G_mktemp(char *template)
105 {
106  return G__mkstemp(template, 0, 0) < 0 ? NULL : template;
107 }
108 
127 int G_mkstemp(char *template, int flags, int mode)
128 {
129 
130  switch (flags & O_ACCMODE) {
131  case O_RDONLY:
132  G_fatal_error(_("Attempt to create read-only temporary file"));
133  return -1;
134  case O_WRONLY:
135  case O_RDWR:
136  break;
137  default:
138  G_fatal_error(_("Unrecognised access mode: %o"), flags & O_ACCMODE);
139  return -1;
140  }
141 
142  return G__mkstemp(template, flags | O_CREAT | O_EXCL, mode);
143 }
144 
162 FILE *G_mkstemp_fp(char *template, int flags, int mode)
163 {
164  const char *fmode = ((flags & O_ACCMODE) == O_RDWR)
165  ? ((flags & O_APPEND) ? "a+" : "w+")
166  : ((flags & O_APPEND) ? "a" : "w");
167  int fd = G_mkstemp(template, flags, mode);
168  if (fd < 0)
169  return NULL;
170  return fdopen(fd, fmode);
171 }
#define NULL
Definition: ccmath.h:32
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition: gis/error.c:159
FILE * G_mkstemp_fp(char *template, int flags, int mode)
Returns a file descriptor.
Definition: mkstemp.c:162
int G_mkstemp(char *template, int flags, int mode)
Returns a file descriptor.
Definition: mkstemp.c:127
#define MAX_REPLACE
Definition: mkstemp.c:22
char * G_mktemp(char *template)
Opens a temporary file.
Definition: mkstemp.c:104