Coverage Report

Created: 2025-02-07 06:04

/src/clib/deps/tempdir/tempdir.c
Line
Count
Source (jump to first uncovered line)
1
2
//
3
// tempdir.c
4
//
5
// Copyright (c) 2014 Stephen Mathieson
6
// MIT licensed
7
//
8
9
#include <stdlib.h>
10
#include <sys/types.h>
11
#include <sys/stat.h>
12
#include <unistd.h>
13
#include "strdup/strdup.h"
14
#include "tempdir.h"
15
16
// 1. The directory named by the TMPDIR environment variable.
17
// 2. The directory named by the TEMP environment variable.
18
// 3. The directory named by the TMP environment variable.
19
// 4. A platform-specific location:
20
//   4.1 On RiscOS, the directory named by the Wimp$ScrapDir
21
//       environment variable.
22
//   4.2 On Windows, the directories C:\TEMP, C:\TMP, \TEMP,
23
//       and \TMP, in that order.
24
//   4.3 On all other platforms, the directories /tmp,
25
//       /var/tmp, and /usr/tmp, in that order.
26
// 5. As a last resort, the current working directory.
27
28
static const char *env_vars[] = {
29
  "TMPDIR",
30
  "TEMP",
31
  "TMP",
32
  // RiscOS (4.1)
33
  "Wimp$ScrapDir",
34
  NULL,
35
};
36
37
38
#ifdef _WIN32
39
  // 4.2
40
  static const char *platform_dirs[] = {
41
    "C:\\TEMP",
42
    "C:\\TMP",
43
    "\\TEMP",
44
    "\\TMP",
45
    NULL,
46
  };
47
#else
48
  // 4.3
49
  static const char *platform_dirs[] = {
50
    "/tmp",
51
    "/var/tmp",
52
    "/usr/tmp",
53
    NULL,
54
  };
55
#endif
56
57
/**
58
 * Check if the file at `path` exists and is a directory.
59
 *
60
 * Returns `0` if both checks pass, and `-1` if either fail.
61
 */
62
63
static int
64
0
is_directory(const char *path) {
65
0
  struct stat s;
66
0
  if (-1 == stat(path, &s)) return -1;
67
0
  return 1 == S_ISDIR(s.st_mode) ? 0 : -1;
68
0
}
69
70
char *
71
0
gettempdir(void) {
72
  // check ENV vars (1, 2, 3)
73
0
  for (int i = 0; env_vars[i]; i++) {
74
0
    char *dir = getenv(env_vars[i]);
75
0
    if (dir && 0 == is_directory(dir)) {
76
0
      return strdup(dir);
77
0
    }
78
0
  }
79
80
  // platform-specific checks (4)
81
0
  for (int i = 0; platform_dirs[i]; i++) {
82
0
    if (0 == is_directory(platform_dirs[i])) {
83
0
      return strdup(platform_dirs[i]);
84
0
    }
85
0
  }
86
87
  // fallback to cwd (5)
88
0
  char cwd[256];
89
0
  if (NULL != getcwd(cwd, sizeof(cwd))) {
90
0
    return strdup(cwd);
91
0
  }
92
93
0
  return NULL;
94
0
}