Merge tag 'locks-v3.16-2' of git://git.samba.org/jlayton/linux
[linux/fpc-iii.git] / tools / lib / api / fs / fs.c
blobc1b49c36a951d74b1c12b417b20428b0f4326e70
1 /* TODO merge/factor in debugfs.c here */
3 #include <ctype.h>
4 #include <errno.h>
5 #include <stdbool.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <sys/vfs.h>
11 #include "debugfs.h"
12 #include "fs.h"
14 static const char * const sysfs__fs_known_mountpoints[] = {
15 "/sys",
19 static const char * const procfs__known_mountpoints[] = {
20 "/proc",
24 struct fs {
25 const char *name;
26 const char * const *mounts;
27 char path[PATH_MAX + 1];
28 bool found;
29 long magic;
32 enum {
33 FS__SYSFS = 0,
34 FS__PROCFS = 1,
37 static struct fs fs__entries[] = {
38 [FS__SYSFS] = {
39 .name = "sysfs",
40 .mounts = sysfs__fs_known_mountpoints,
41 .magic = SYSFS_MAGIC,
43 [FS__PROCFS] = {
44 .name = "proc",
45 .mounts = procfs__known_mountpoints,
46 .magic = PROC_SUPER_MAGIC,
50 static bool fs__read_mounts(struct fs *fs)
52 bool found = false;
53 char type[100];
54 FILE *fp;
56 fp = fopen("/proc/mounts", "r");
57 if (fp == NULL)
58 return NULL;
60 while (!found &&
61 fscanf(fp, "%*s %" STR(PATH_MAX) "s %99s %*s %*d %*d\n",
62 fs->path, type) == 2) {
64 if (strcmp(type, fs->name) == 0)
65 found = true;
68 fclose(fp);
69 return fs->found = found;
72 static int fs__valid_mount(const char *fs, long magic)
74 struct statfs st_fs;
76 if (statfs(fs, &st_fs) < 0)
77 return -ENOENT;
78 else if (st_fs.f_type != magic)
79 return -ENOENT;
81 return 0;
84 static bool fs__check_mounts(struct fs *fs)
86 const char * const *ptr;
88 ptr = fs->mounts;
89 while (*ptr) {
90 if (fs__valid_mount(*ptr, fs->magic) == 0) {
91 fs->found = true;
92 strcpy(fs->path, *ptr);
93 return true;
95 ptr++;
98 return false;
101 static void mem_toupper(char *f, size_t len)
103 while (len) {
104 *f = toupper(*f);
105 f++;
106 len--;
111 * Check for "NAME_PATH" environment variable to override fs location (for
112 * testing). This matches the recommendation in Documentation/sysfs-rules.txt
113 * for SYSFS_PATH.
115 static bool fs__env_override(struct fs *fs)
117 char *override_path;
118 size_t name_len = strlen(fs->name);
119 /* name + "_PATH" + '\0' */
120 char upper_name[name_len + 5 + 1];
121 memcpy(upper_name, fs->name, name_len);
122 mem_toupper(upper_name, name_len);
123 strcpy(&upper_name[name_len], "_PATH");
125 override_path = getenv(upper_name);
126 if (!override_path)
127 return false;
129 fs->found = true;
130 strncpy(fs->path, override_path, sizeof(fs->path));
131 return true;
134 static const char *fs__get_mountpoint(struct fs *fs)
136 if (fs__env_override(fs))
137 return fs->path;
139 if (fs__check_mounts(fs))
140 return fs->path;
142 if (fs__read_mounts(fs))
143 return fs->path;
145 return NULL;
148 static const char *fs__mountpoint(int idx)
150 struct fs *fs = &fs__entries[idx];
152 if (fs->found)
153 return (const char *)fs->path;
155 return fs__get_mountpoint(fs);
158 #define FS__MOUNTPOINT(name, idx) \
159 const char *name##__mountpoint(void) \
161 return fs__mountpoint(idx); \
164 FS__MOUNTPOINT(sysfs, FS__SYSFS);
165 FS__MOUNTPOINT(procfs, FS__PROCFS);