aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs6f/s6f_confdir_open.c
blob: 5958e46141948eff86994108205bdd1de1c3afe3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/* ISC license. */

#include <skalibs/bsdsnowflake.h>

#include <unistd.h>
#include <errno.h>

#include <skalibs/stat.h>
#include <skalibs/posixplz.h>
#include <skalibs/strerr.h>
#include <skalibs/djbunix.h>
#include <skalibs/unix-transactional.h>

#include "s6f.h"

int s6f_confdir_open (char const *s, int flagcreate)
{
  struct stat st ;
  int fd = open_read(s) ;
  if (fd == -1)
  {
    if (errno != ENOENT || !flagcreate)
      strerr_diefu3sys(111, "open ", s, " for reading") ;
    if (flagcreate)
    {
      if (mkdirp(s, 02755) == -1)
        strerr_diefu2sys(111, "mkdirp ", s) ;
      fd = open_read(s) ;
      if (fd == -1)
        strerr_diefu3sys(111, "open ", s, " for reading") ;
    }
  }
  if (fstat(fd, &st) == -1)
    strerr_diefu2sys(111, "fstat ", s) ;
  if (!S_ISDIR(st.st_mode))
    strerr_dief2x(111, s, " is not a directory") ;
  if (access_at(fd, ".", R_OK|W_OK, 1) == -1)
    strerr_diefu2sys(111, "access ", s) ;
  return fd ;
}