Checking whether a file exists, possibly of a given type, takes a
struct stat and a call to stat() that are otherwise unused. Many places
do that, some with helpers of their own.

Add a generic file_exists_type() helper that checks for a file of a
given type, and file_exists() on top of it, which checks for a file of
any type. Use file_exists() in place of the helpers of the same name in
the fiptool command and the firmware loader, which would otherwise
conflict with it.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Sascha Hauer <[email protected]>
---
 commands/fiptool.c |  7 -------
 common/firmware.c  |  8 +++-----
 include/libfile.h  | 13 +++++++++++++
 lib/libfile.c      | 28 ++++++++++++++++++++++++++++
 4 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/commands/fiptool.c b/commands/fiptool.c
index a0e67ed439..d83362b96a 100644
--- a/commands/fiptool.c
+++ b/commands/fiptool.c
@@ -174,13 +174,6 @@ static void parse_blob_opt(char *arg, uuid_t *uuid, char 
*filename, size_t len)
        }
 }
 
-static inline bool file_exists(const char *filename)
-{
-       struct stat st;
-
-       return stat(filename, &st) == 0;
-}
-
 static __maybe_unused int create_cmd(struct fip_state *fip, int argc, char 
*argv[])
 {
        unsigned long long toc_flags = 0;
diff --git a/common/firmware.c b/common/firmware.c
index 3df1606ecd..c72fcbe556 100644
--- a/common/firmware.c
+++ b/common/firmware.c
@@ -236,11 +236,9 @@ void firmware_set_searchpath(const char *path)
        firmware_path = strdup(path);
 }
 
-static bool file_exists(const char *filename)
+static bool firmware_exists(const char *filename)
 {
-       struct stat s;
-
-       return !stat(filename, &s);
+       return file_exists(filename);
 }
 
 /*
@@ -266,7 +264,7 @@ int firmwaremgr_load_file(struct firmware_mgr *mgr, const 
char *firmware)
        dst = basprintf("/dev/%s", mgr->handler->id);
 
        if (*firmware != '/') {
-               fw = find_path(firmware_path, firmware, file_exists);
+               fw = find_path(firmware_path, firmware, firmware_exists);
                if (fw)
                        firmware = fw;
        }
diff --git a/include/libfile.h b/include/libfile.h
index 3f5ea5255a..72c736d301 100644
--- a/include/libfile.h
+++ b/include/libfile.h
@@ -37,6 +37,19 @@ int copy_recursive(const char *src, const char *dst, 
unsigned flags);
 
 int compare_file(const char *f1, const char *f2);
 
+bool file_exists_type(const char *path, umode_t type);
+
+/**
+ * file_exists - check whether a file of any type exists
+ * @path: path of the file to check
+ *
+ * Return: true if @path exists, false otherwise
+ */
+static inline bool file_exists(const char *path)
+{
+       return file_exists_type(path, 0);
+}
+
 #if IN_PROPER
 int open_and_lseek(const char *filename, int mode, loff_t pos);
 #else
diff --git a/lib/libfile.c b/lib/libfile.c
index 35ec631de8..2330d52d8e 100644
--- a/lib/libfile.c
+++ b/lib/libfile.c
@@ -745,6 +745,34 @@ int open_and_lseek(const char *filename, int mode, loff_t 
pos)
        return ret;
 }
 
+/**
+ * file_exists_type - check whether a file of a given type exists
+ * @path: path of the file to check
+ * @type: file type the file must have, one of the S_IF* values like
+ *        S_IFREG or S_IFDIR, or 0 for any type
+ *
+ * Symbolic links are followed, unless @type is S_IFLNK, which checks
+ * for the link itself.
+ *
+ * Return: true if @path exists and is of type @type, false otherwise
+ */
+bool file_exists_type(const char *path, umode_t type)
+{
+       struct stat s;
+       int ret;
+
+       if (type == S_IFLNK)
+               ret = lstat(path, &s);
+       else
+               ret = stat(path, &s);
+
+       if (ret)
+               return false;
+
+       return !type || (s.st_mode & S_IFMT) == type;
+}
+EXPORT_SYMBOL(file_exists_type);
+
 /**
  * make_temp - create a name for a temporary file
  * @template:  The filename prefix

-- 
2.47.3


Reply via email to