1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0 286470930SIngo Molnar /* 386470930SIngo Molnar * I'm tired of doing "vsnprintf()" etc just to open a 486470930SIngo Molnar * file, so here's a "return static buffer with printf" 586470930SIngo Molnar * interface for paths. 686470930SIngo Molnar * 786470930SIngo Molnar * It's obviously not thread-safe. Sue me. But it's quite 886470930SIngo Molnar * useful for doing things like 986470930SIngo Molnar * 1086470930SIngo Molnar * f = open(mkpath("%s/%s.perf", base, name), O_RDONLY); 1186470930SIngo Molnar * 1286470930SIngo Molnar * which is what it's designed for. 1386470930SIngo Molnar */ 1486470930SIngo Molnar #include "cache.h" 159a3993d4SArnaldo Carvalho de Melo #include "path.h" 169a3993d4SArnaldo Carvalho de Melo #include <linux/kernel.h> 17175729fcSArnaldo Carvalho de Melo #include <limits.h> 189a3993d4SArnaldo Carvalho de Melo #include <stdio.h> 199a3993d4SArnaldo Carvalho de Melo #include <sys/types.h> 209a3993d4SArnaldo Carvalho de Melo #include <sys/stat.h> 21*06c3f2aaSJiri Olsa #include <dirent.h> 229a3993d4SArnaldo Carvalho de Melo #include <unistd.h> 2386470930SIngo Molnar 2486470930SIngo Molnar static char bad_path[] = "/bad-path/"; 2586470930SIngo Molnar /* 26814b3f51SArnaldo Carvalho de Melo * One hack: 2786470930SIngo Molnar */ 2886470930SIngo Molnar static char *get_pathname(void) 2986470930SIngo Molnar { 3086470930SIngo Molnar static char pathname_array[4][PATH_MAX]; 3183a0944fSIngo Molnar static int idx; 3283a0944fSIngo Molnar 3383a0944fSIngo Molnar return pathname_array[3 & ++idx]; 3486470930SIngo Molnar } 3586470930SIngo Molnar 3686470930SIngo Molnar static char *cleanup_path(char *path) 3786470930SIngo Molnar { 3886470930SIngo Molnar /* Clean it up */ 3986470930SIngo Molnar if (!memcmp(path, "./", 2)) { 4086470930SIngo Molnar path += 2; 4186470930SIngo Molnar while (*path == '/') 4286470930SIngo Molnar path++; 4386470930SIngo Molnar } 4486470930SIngo Molnar return path; 4586470930SIngo Molnar } 4686470930SIngo Molnar 4786470930SIngo Molnar char *mkpath(const char *fmt, ...) 4886470930SIngo Molnar { 4986470930SIngo Molnar va_list args; 5086470930SIngo Molnar unsigned len; 5186470930SIngo Molnar char *pathname = get_pathname(); 5286470930SIngo Molnar 5386470930SIngo Molnar va_start(args, fmt); 5486470930SIngo Molnar len = vsnprintf(pathname, PATH_MAX, fmt, args); 5586470930SIngo Molnar va_end(args); 5686470930SIngo Molnar if (len >= PATH_MAX) 5786470930SIngo Molnar return bad_path; 5886470930SIngo Molnar return cleanup_path(pathname); 5986470930SIngo Molnar } 609a3993d4SArnaldo Carvalho de Melo 619a3993d4SArnaldo Carvalho de Melo int path__join(char *bf, size_t size, const char *path1, const char *path2) 629a3993d4SArnaldo Carvalho de Melo { 639a3993d4SArnaldo Carvalho de Melo return scnprintf(bf, size, "%s%s%s", path1, path1[0] ? "/" : "", path2); 649a3993d4SArnaldo Carvalho de Melo } 659a3993d4SArnaldo Carvalho de Melo 669a3993d4SArnaldo Carvalho de Melo int path__join3(char *bf, size_t size, const char *path1, const char *path2, const char *path3) 679a3993d4SArnaldo Carvalho de Melo { 689a3993d4SArnaldo Carvalho de Melo return scnprintf(bf, size, "%s%s%s%s%s", path1, path1[0] ? "/" : "", 699a3993d4SArnaldo Carvalho de Melo path2, path2[0] ? "/" : "", path3); 709a3993d4SArnaldo Carvalho de Melo } 719a3993d4SArnaldo Carvalho de Melo 729a3993d4SArnaldo Carvalho de Melo bool is_regular_file(const char *file) 739a3993d4SArnaldo Carvalho de Melo { 749a3993d4SArnaldo Carvalho de Melo struct stat st; 759a3993d4SArnaldo Carvalho de Melo 769a3993d4SArnaldo Carvalho de Melo if (stat(file, &st)) 779a3993d4SArnaldo Carvalho de Melo return false; 789a3993d4SArnaldo Carvalho de Melo 799a3993d4SArnaldo Carvalho de Melo return S_ISREG(st.st_mode); 809a3993d4SArnaldo Carvalho de Melo } 81*06c3f2aaSJiri Olsa 82*06c3f2aaSJiri Olsa /* Helper function for filesystems that return a dent->d_type DT_UNKNOWN */ 83*06c3f2aaSJiri Olsa bool is_directory(const char *base_path, const struct dirent *dent) 84*06c3f2aaSJiri Olsa { 85*06c3f2aaSJiri Olsa char path[PATH_MAX]; 86*06c3f2aaSJiri Olsa struct stat st; 87*06c3f2aaSJiri Olsa 88*06c3f2aaSJiri Olsa sprintf(path, "%s/%s", base_path, dent->d_name); 89*06c3f2aaSJiri Olsa if (stat(path, &st)) 90*06c3f2aaSJiri Olsa return false; 91*06c3f2aaSJiri Olsa 92*06c3f2aaSJiri Olsa return S_ISDIR(st.st_mode); 93*06c3f2aaSJiri Olsa } 94