1 /* ISC license. */
2 
3 #include <sys/uio.h>
4 #include <string.h>
5 #include <errno.h>
6 #include <unistd.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <skalibs/djbunix.h>
10 
11 #define SUFFIX ":skalibs-openwritevnclose:XXXXXX"
12 
openwritevnclose_internal(char const * fn,struct iovec const * v,unsigned int vlen,dev_t * dev,ino_t * ino,int dosync)13 int openwritevnclose_internal (char const *fn, struct iovec const *v, unsigned int vlen, dev_t *dev, ino_t *ino, int dosync)
14 {
15   dev_t tmpdev ;
16   ino_t tmpino ;
17   size_t fnlen = strlen(fn) ;
18   int fd ;
19   char tmp[fnlen + sizeof(SUFFIX)] ;
20   memcpy(tmp, fn, fnlen) ;
21   memcpy(tmp + fnlen, SUFFIX, sizeof(SUFFIX)) ;
22   fd = mkstemp(tmp) ;
23   if (fd < 0) return 0 ;
24   if (!writevnclose_unsafe_internal(fd, v, vlen, dev ? &tmpdev : 0, ino ? &tmpino : 0, dosync)) goto failclose ;
25   if (rename(tmp, fn) < 0) goto fail ;
26   if (dev) *dev = tmpdev ;
27   if (ino) *ino = tmpino ;
28   return 1 ;
29 
30  failclose:
31   fd_close(fd) ;
32  fail:
33   {
34     int e = errno ;
35     unlink(tmp) ;
36     errno = e ;
37   }
38   return 0 ;
39 }
40