xref: /openbmc/linux/tools/perf/util/path.c (revision 9a3993d408bc61b839de1a2c6c783477a04860bb)
186470930SIngo Molnar /*
286470930SIngo Molnar  * I'm tired of doing "vsnprintf()" etc just to open a
386470930SIngo Molnar  * file, so here's a "return static buffer with printf"
486470930SIngo Molnar  * interface for paths.
586470930SIngo Molnar  *
686470930SIngo Molnar  * It's obviously not thread-safe. Sue me. But it's quite
786470930SIngo Molnar  * useful for doing things like
886470930SIngo Molnar  *
986470930SIngo Molnar  *   f = open(mkpath("%s/%s.perf", base, name), O_RDONLY);
1086470930SIngo Molnar  *
1186470930SIngo Molnar  * which is what it's designed for.
1286470930SIngo Molnar  */
1386470930SIngo Molnar #include "cache.h"
14*9a3993d4SArnaldo Carvalho de Melo #include "path.h"
15*9a3993d4SArnaldo Carvalho de Melo #include <linux/kernel.h>
16175729fcSArnaldo Carvalho de Melo #include <limits.h>
17*9a3993d4SArnaldo Carvalho de Melo #include <stdio.h>
18*9a3993d4SArnaldo Carvalho de Melo #include <sys/types.h>
19*9a3993d4SArnaldo Carvalho de Melo #include <sys/stat.h>
20*9a3993d4SArnaldo Carvalho de Melo #include <unistd.h>
2186470930SIngo Molnar 
2286470930SIngo Molnar static char bad_path[] = "/bad-path/";
2386470930SIngo Molnar /*
24814b3f51SArnaldo Carvalho de Melo  * One hack:
2586470930SIngo Molnar  */
2686470930SIngo Molnar static char *get_pathname(void)
2786470930SIngo Molnar {
2886470930SIngo Molnar 	static char pathname_array[4][PATH_MAX];
2983a0944fSIngo Molnar 	static int idx;
3083a0944fSIngo Molnar 
3183a0944fSIngo Molnar 	return pathname_array[3 & ++idx];
3286470930SIngo Molnar }
3386470930SIngo Molnar 
3486470930SIngo Molnar static char *cleanup_path(char *path)
3586470930SIngo Molnar {
3686470930SIngo Molnar 	/* Clean it up */
3786470930SIngo Molnar 	if (!memcmp(path, "./", 2)) {
3886470930SIngo Molnar 		path += 2;
3986470930SIngo Molnar 		while (*path == '/')
4086470930SIngo Molnar 			path++;
4186470930SIngo Molnar 	}
4286470930SIngo Molnar 	return path;
4386470930SIngo Molnar }
4486470930SIngo Molnar 
4586470930SIngo Molnar char *mkpath(const char *fmt, ...)
4686470930SIngo Molnar {
4786470930SIngo Molnar 	va_list args;
4886470930SIngo Molnar 	unsigned len;
4986470930SIngo Molnar 	char *pathname = get_pathname();
5086470930SIngo Molnar 
5186470930SIngo Molnar 	va_start(args, fmt);
5286470930SIngo Molnar 	len = vsnprintf(pathname, PATH_MAX, fmt, args);
5386470930SIngo Molnar 	va_end(args);
5486470930SIngo Molnar 	if (len >= PATH_MAX)
5586470930SIngo Molnar 		return bad_path;
5686470930SIngo Molnar 	return cleanup_path(pathname);
5786470930SIngo Molnar }
58*9a3993d4SArnaldo Carvalho de Melo 
59*9a3993d4SArnaldo Carvalho de Melo int path__join(char *bf, size_t size, const char *path1, const char *path2)
60*9a3993d4SArnaldo Carvalho de Melo {
61*9a3993d4SArnaldo Carvalho de Melo 	return scnprintf(bf, size, "%s%s%s", path1, path1[0] ? "/" : "", path2);
62*9a3993d4SArnaldo Carvalho de Melo }
63*9a3993d4SArnaldo Carvalho de Melo 
64*9a3993d4SArnaldo Carvalho de Melo int path__join3(char *bf, size_t size, const char *path1, const char *path2, const char *path3)
65*9a3993d4SArnaldo Carvalho de Melo {
66*9a3993d4SArnaldo Carvalho de Melo 	return scnprintf(bf, size, "%s%s%s%s%s", path1, path1[0] ? "/" : "",
67*9a3993d4SArnaldo Carvalho de Melo 			 path2, path2[0] ? "/" : "", path3);
68*9a3993d4SArnaldo Carvalho de Melo }
69*9a3993d4SArnaldo Carvalho de Melo 
70*9a3993d4SArnaldo Carvalho de Melo bool is_regular_file(const char *file)
71*9a3993d4SArnaldo Carvalho de Melo {
72*9a3993d4SArnaldo Carvalho de Melo 	struct stat st;
73*9a3993d4SArnaldo Carvalho de Melo 
74*9a3993d4SArnaldo Carvalho de Melo 	if (stat(file, &st))
75*9a3993d4SArnaldo Carvalho de Melo 		return false;
76*9a3993d4SArnaldo Carvalho de Melo 
77*9a3993d4SArnaldo Carvalho de Melo 	return S_ISREG(st.st_mode);
78*9a3993d4SArnaldo Carvalho de Melo }
79