~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/perf/util/path.c

Version: ~ [ linux-5.6-rc3 ] ~ [ linux-5.5.6 ] ~ [ linux-5.4.22 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.106 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.171 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.214 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.214 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.82 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * I'm tired of doing "vsnprintf()" etc just to open a
  3  * file, so here's a "return static buffer with printf"
  4  * interface for paths.
  5  *
  6  * It's obviously not thread-safe. Sue me. But it's quite
  7  * useful for doing things like
  8  *
  9  *   f = open(mkpath("%s/%s.perf", base, name), O_RDONLY);
 10  *
 11  * which is what it's designed for.
 12  */
 13 #include "cache.h"
 14 
 15 static char bad_path[] = "/bad-path/";
 16 /*
 17  * Two hacks:
 18  */
 19 
 20 static const char *get_perf_dir(void)
 21 {
 22         return ".";
 23 }
 24 
 25 /*
 26  * If libc has strlcpy() then that version will override this
 27  * implementation:
 28  */
 29 size_t __weak strlcpy(char *dest, const char *src, size_t size)
 30 {
 31         size_t ret = strlen(src);
 32 
 33         if (size) {
 34                 size_t len = (ret >= size) ? size - 1 : ret;
 35 
 36                 memcpy(dest, src, len);
 37                 dest[len] = '\0';
 38         }
 39 
 40         return ret;
 41 }
 42 
 43 static char *get_pathname(void)
 44 {
 45         static char pathname_array[4][PATH_MAX];
 46         static int idx;
 47 
 48         return pathname_array[3 & ++idx];
 49 }
 50 
 51 static char *cleanup_path(char *path)
 52 {
 53         /* Clean it up */
 54         if (!memcmp(path, "./", 2)) {
 55                 path += 2;
 56                 while (*path == '/')
 57                         path++;
 58         }
 59         return path;
 60 }
 61 
 62 static char *perf_vsnpath(char *buf, size_t n, const char *fmt, va_list args)
 63 {
 64         const char *perf_dir = get_perf_dir();
 65         size_t len;
 66 
 67         len = strlen(perf_dir);
 68         if (n < len + 1)
 69                 goto bad;
 70         memcpy(buf, perf_dir, len);
 71         if (len && !is_dir_sep(perf_dir[len-1]))
 72                 buf[len++] = '/';
 73         len += vsnprintf(buf + len, n - len, fmt, args);
 74         if (len >= n)
 75                 goto bad;
 76         return cleanup_path(buf);
 77 bad:
 78         strlcpy(buf, bad_path, n);
 79         return buf;
 80 }
 81 
 82 char *perf_pathdup(const char *fmt, ...)
 83 {
 84         char path[PATH_MAX];
 85         va_list args;
 86         va_start(args, fmt);
 87         (void)perf_vsnpath(path, sizeof(path), fmt, args);
 88         va_end(args);
 89         return xstrdup(path);
 90 }
 91 
 92 char *mkpath(const char *fmt, ...)
 93 {
 94         va_list args;
 95         unsigned len;
 96         char *pathname = get_pathname();
 97 
 98         va_start(args, fmt);
 99         len = vsnprintf(pathname, PATH_MAX, fmt, args);
100         va_end(args);
101         if (len >= PATH_MAX)
102                 return bad_path;
103         return cleanup_path(pathname);
104 }
105 
106 char *perf_path(const char *fmt, ...)
107 {
108         const char *perf_dir = get_perf_dir();
109         char *pathname = get_pathname();
110         va_list args;
111         unsigned len;
112 
113         len = strlen(perf_dir);
114         if (len > PATH_MAX-100)
115                 return bad_path;
116         memcpy(pathname, perf_dir, len);
117         if (len && perf_dir[len-1] != '/')
118                 pathname[len++] = '/';
119         va_start(args, fmt);
120         len += vsnprintf(pathname + len, PATH_MAX - len, fmt, args);
121         va_end(args);
122         if (len >= PATH_MAX)
123                 return bad_path;
124         return cleanup_path(pathname);
125 }
126 
127 /* strip arbitrary amount of directory separators at end of path */
128 static inline int chomp_trailing_dir_sep(const char *path, int len)
129 {
130         while (len && is_dir_sep(path[len - 1]))
131                 len--;
132         return len;
133 }
134 
135 /*
136  * If path ends with suffix (complete path components), returns the
137  * part before suffix (sans trailing directory separators).
138  * Otherwise returns NULL.
139  */
140 char *strip_path_suffix(const char *path, const char *suffix)
141 {
142         int path_len = strlen(path), suffix_len = strlen(suffix);
143 
144         while (suffix_len) {
145                 if (!path_len)
146                         return NULL;
147 
148                 if (is_dir_sep(path[path_len - 1])) {
149                         if (!is_dir_sep(suffix[suffix_len - 1]))
150                                 return NULL;
151                         path_len = chomp_trailing_dir_sep(path, path_len);
152                         suffix_len = chomp_trailing_dir_sep(suffix, suffix_len);
153                 }
154                 else if (path[--path_len] != suffix[--suffix_len])
155                         return NULL;
156         }
157 
158         if (path_len && !is_dir_sep(path[path_len - 1]))
159                 return NULL;
160         return strndup(path, chomp_trailing_dir_sep(path, path_len));
161 }
162 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp