diff --git a/ChangeLog b/ChangeLog index 25a0c3848..d077a5b11 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-10-15 Vladimir Serbinenko + + Define grub_util_is_directory/regular/special_file and + use OS-dependent versions rather than to rely on stat(). + 2013-10-15 Vladimir Serbinenko * util/grub-mkimage.c: Move backend part to ... diff --git a/grub-core/kern/emu/hostfs.c b/grub-core/kern/emu/hostfs.c index 719c624de..b51462641 100644 --- a/grub-core/kern/emu/hostfs.c +++ b/grub-core/kern/emu/hostfs.c @@ -30,11 +30,8 @@ #include #include -#include #include #include - -#include #include static int @@ -52,10 +49,7 @@ is_dir (const char *path, const char *name) strcat (pathname, name); - struct stat st; - if (stat (pathname, &st)) - return 0; - return S_ISDIR (st.st_mode); + return grub_util_is_directory (pathname); } struct grub_hostfs_data diff --git a/grub-core/osdep/unix/hostdisk.c b/grub-core/osdep/unix/hostdisk.c index 3ef379742..9734a1db5 100644 --- a/grub-core/osdep/unix/hostdisk.c +++ b/grub-core/osdep/unix/hostdisk.c @@ -216,4 +216,36 @@ grub_util_fopen (const char *path, const char *mode) return fopen (path, mode); } +int +grub_util_is_directory (const char *path) +{ + struct stat st; + + if (stat (path, &st) == -1) + return 0; + + return S_ISDIR (st.st_mode); +} + +int +grub_util_is_regular (const char *path) +{ + struct stat st; + + if (stat (path, &st) == -1) + return 0; + + return S_ISREG (st.st_mode); +} + +int +grub_util_is_special_file (const char *path) +{ + struct stat st; + + if (lstat (path, &st) == -1) + return 1; + return (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode)); +} + #endif diff --git a/grub-core/osdep/windows/hostdisk.c b/grub-core/osdep/windows/hostdisk.c index aaaa519c0..256dc1dbd 100644 --- a/grub-core/osdep/windows/hostdisk.c +++ b/grub-core/osdep/windows/hostdisk.c @@ -410,6 +410,39 @@ grub_util_unlink (const char *name) return ret; } +int +grub_util_is_directory (const char *name) +{ + LPTSTR name_windows; + DWORD attr; + + name_windows = grub_util_get_windows_path (name); + if (!name_windows) + return 0; + + attr = GetFileAttributes (name_windows); + grub_free (name_windows); + + return !!(attr & FILE_ATTRIBUTE_DIRECTORY); +} + +int +grub_util_is_regular (const char *name) +{ + LPTSTR name_windows; + DWORD attr; + + name_windows = grub_util_get_windows_path (name); + if (!name_windows) + return 0; + + attr = GetFileAttributes (name_windows); + grub_free (name_windows); + + return !(attr & FILE_ATTRIBUTE_DIRECTORY) + && !(attr & FILE_ATTRIBUTE_REPARSE_POINT) && attr; +} + #ifdef __MINGW32__ FILE * @@ -438,6 +471,22 @@ int fsync (int fno) return 0; } +int +grub_util_is_special_file (const char *name) +{ + LPTSTR name_windows; + DWORD attr; + + name_windows = grub_util_get_windows_path (name); + if (!name_windows) + return 1; + + attr = GetFileAttributes (name_windows); + grub_free (name_windows); + + return !!(attr & FILE_ATTRIBUTE_REPARSE_POINT) || !attr; +} + #else FILE * @@ -446,4 +495,14 @@ grub_util_fopen (const char *path, const char *mode) return fopen (path, mode); } +int +grub_util_is_special_file (const char *path) +{ + struct stat st; + + if (lstat (destnew, &st) == -1) + return 1; + return (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode)); +} + #endif diff --git a/include/grub/emu/hostfile.h b/include/grub/emu/hostfile.h index 0c796e21b..3ca1ab248 100644 --- a/include/grub/emu/hostfile.h +++ b/include/grub/emu/hostfile.h @@ -24,6 +24,13 @@ #include #include +int +grub_util_is_directory (const char *path); +int +grub_util_is_special_file (const char *path); +int +grub_util_is_regular (const char *path); + int grub_util_fd_seek (grub_util_fd_t fd, grub_uint64_t off); ssize_t diff --git a/util/grub-fstest.c b/util/grub-fstest.c index db5da5f44..802733963 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -34,18 +34,11 @@ #include #include #include -#include +#include #include -#include +#include #include -#include - -#include -#include -#include -#include -#include #include "progname.h" #include "argp.h" @@ -265,22 +258,17 @@ cmd_cmp (char *src, char *dest) { FILE *ff; - struct stat st; - if (stat (dest, &st) == -1) - grub_util_error (_("OS file %s open error: %s"), dest, - strerror (errno)); - - if (S_ISDIR (st.st_mode)) + if (grub_util_is_directory (dest)) { - DIR *dir = opendir (dest); - struct dirent *entry; + grub_util_fd_dir_t dir = grub_util_fd_opendir (dest); + grub_util_fd_dirent_t entry; if (dir == NULL) { grub_util_error (_("OS file %s open error: %s"), dest, - strerror (errno)); + grub_util_fd_strerror ()); return; } - while ((entry = readdir (dir))) + while ((entry = grub_util_fd_readdir (dir))) { char *srcnew, *destnew; char *ptr; @@ -298,15 +286,12 @@ cmd_cmp (char *src, char *dest) *ptr++ = '/'; strcpy (ptr, entry->d_name); -#if !defined (_WIN32) || defined (__CYGWIN__) - if (lstat (destnew, &st) == -1 || (!S_ISREG (st.st_mode) - && !S_ISDIR (st.st_mode))) + if (grub_util_is_special_file (destnew)) continue; -#endif cmd_cmp (srcnew, destnew); } - closedir (dir); + grub_util_fd_closedir (dir); return; }