watchman/fs/FileInformation.h (88 lines of code) (raw):

/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include <sys/stat.h> #include "watchman/watchman_system.h" #ifndef _WIN32 #include <dirent.h> #endif namespace watchman { #ifdef _WIN32 using mode_t = int; using dev_t = int; using gid_t = int; using uid_t = int; using ino_t = unsigned int; using nlink_t = unsigned int; /** * Convertion between st_mode and d_type on Windows. On Windows the 4th nibble * of mode contains the type of directory entry. Right shifting by 12 bits to * form a d_type. */ static_assert(S_IFMT == 0xF000, "The S_IFMT on Windows should be 0xF000"); #define DT_UNKNOWN 0 #define DT_FIFO ((_S_IFIFO) >> 12) #define DT_CHR ((_S_IFCHR) >> 12) #define DT_DIR ((_S_IFDIR) >> 12) #define DT_REG ((_S_IFREG) >> 12) #endif /** Represents the type of a filesystem entry. * * This is the same type and intent as the d_type field of a dirent struct. * * We provide an explicit type to make it clearer when we're working * with this value. * * https://www.daemon-systems.org/man/DTTOIF.3.html * * Not all systems have a dtype concept so we have some conditional * code here to compensate. */ enum class DType { Unknown = DT_UNKNOWN, Fifo = DT_FIFO, Char = DT_CHR, Dir = DT_DIR, Regular = DT_REG, #ifdef DT_BLK Block = DT_BLK, #else Block, #endif #ifdef DT_LNK Symlink = DT_LNK, #else Symlink, #endif #ifdef DT_SOCK Socket = DT_SOCK, #else Socket, #endif #ifdef DT_WHT Whiteout = DT_WHT, #else Whiteout, #endif }; struct FileInformation { // On POSIX systems, the complete mode information. // On Windows, this is lossy wrt. symlink information, // so it is preferable to use isSymlink() rather than // S_ISLNK() on the mode value. mode_t mode{0}; off_t size{0}; // On Windows systems, these fields are approximated // from cheaply available information in a way that is // consistent with msvcrt which is widely used by many // native win32 applications (including python). uid_t uid{0}; gid_t gid{0}; ino_t ino{0}; dev_t dev{0}; nlink_t nlink{0}; #ifdef _WIN32 uint32_t fileAttributes{0}; #endif struct timespec atime { 0, 0 }; struct timespec mtime { 0, 0 }; struct timespec ctime { 0, 0 }; // Returns the directory entry type for the file. DType dtype() const; // Returns true if this file information references // a symlink, false otherwise. bool isSymlink() const; // Returns true if this file information references // a directory, false otherwise. bool isDir() const; // Returns true if this file information references // a regular file, false otherwise. bool isFile() const; #ifndef _WIN32 explicit FileInformation(const struct stat& st); #else // Partially initialize the common fields. // There are a number of different forms of windows specific data // types that hold the rest of the information and we don't want // to pollute the headers with them, so those are populated // externally by the APIs declared elsewhere in this header file. explicit FileInformation(uint32_t dwFileAttributes); #endif FileInformation() = default; // Construct a placeholder FileInformation instance that represents // a file that has been deleted. This is used in a very specific // circumstance in Source Control Aware query responses to represent // files that were deleted between two revisions. static FileInformation makeDeletedFileInformation(); }; } // namespace watchman #ifndef _WIN32 static inline bool w_path_exists(const char* path) { return access(path, F_OK) == 0; } #else bool w_path_exists(const char* path); #endif