// Copyright (c) 2002 David Muse // See the COPYING file for more information. #ifndef RUDIMENTS_FILE_H #define RUDIMENTS_FILE_H #include <rudiments/private/fileincludes.h> // The file class provides methods for interacting with files and for // discovering the properties associated with a file such as permissions, // ownership, size, etc. // // Many of the static methods are just provided for convenience. Use them // if you need to get a a single property or perform a single operation. // // If you need to get multiple properties or perform multiple operations, // create an instance of the class, call open(), then use the non-static // methods. #ifdef RUDIMENTS_NAMESPACE namespace rudiments { #endif class fileprivate; class file : public filedescriptor { public: file(); // Creates an uninitialized instance of the file class. file(const file &f); file &operator=(const file &f); virtual ~file(); // These methods open the file "name" using "flags". // They return true on success and false on failure. bool open(const char *name, int flags); bool open(const char *name, int flags, mode_t perms); // If flags contains O_CREAT and the file doesn't // already exist, it will be created with permissions // "perms". // These methods creates the file "name" with permissions // "perms". If the file already exists, it will be truncated. bool create(const char *name, mode_t perms); // Returns true on success and false on failure. ssize_t create(const char *name, mode_t perms, unsigned short number); // Sets the initial contents to "number". // Returns the number of bytes written or -1 on error. ssize_t create(const char *name, mode_t perms, unsigned long number); // Sets the initial contents to "number". // Returns the number of bytes written or -1 on error. ssize_t create(const char *name, mode_t perms, float number); // Sets the initial contents to "number". // Returns the number of bytes written or -1 on error. ssize_t create(const char *name, mode_t perms, double number); // Sets the initial contents to "number". // Returns the number of bytes written or -1 on error. ssize_t create(const char *name, mode_t perms, char number); // Sets the initial contents to "number". // Returns the number of bytes written or -1 on error. ssize_t create(const char *name, mode_t perms, const char *string); // Sets the initial contents to "string". // Returns the number of bytes written or -1 on error. ssize_t create(const char *name, mode_t perms, const char *string, size_t size); // Sets the initial contents to "string" of size "size". // Returns the number of bytes written or -1 on error. ssize_t create(const char *name, mode_t perms, const void *data, size_t size); // Sets the initial contents to "data" of size "size". // Returns the number of bytes written or -1 on error. // These methods read the contents of the file into a buffer. char *getContents(); // Allocates a string large enough to accommodate the // contents of the currently opened file, reads the // contents of the file into the string and returns the // string. The string must be freed by the calling // program. // // If the file contains no data, then a string of length // zero is returned. If an error occurs then a NULL // is returned. ssize_t getContents(unsigned char *buffer, size_t buffersize); // Reads the contents of the currently open file into // "buffer" of length "buffersize". If the file is // larger than "buffersize" then only "buffersize" bytes // of the file will be read into "buffer". // // Returns the number of bytes copied into "buffer" or // -1 on error. // These methods truncate the file. // They return true on success and false on failure. bool truncate() const; // Truncates all data in the file, resulting in // a file of zero length. bool truncate(off64_t length) const; // Truncates all data beyond the first "length" // bytes, resulting in a file of "length" bytes. // These methods allow you to get or set the position at which // the next read or write will occur. Each returns the position // relative to the beginning of the file on success or -1 on // failure. off64_t getCurrentPosition() const; // Returns the position at which the next read or // write will occur. off64_t setPositionRelativeToBeginning(off64_t offset) const; // Sets the position to the beginning of the // file + "offset" bytes. off64_t setPositionRelativeToCurrent(off64_t offset) const; // Sets the position to the current // position + "offset" bytes. off64_t setPositionRelativeToEnd(off64_t offset) const; // Sets the position to the end of the // file + "offset" bytes. // The following methods allow you to lock files or regions // of files. // // The tryLock() methods attempt to lock and return success if // the lock can be established immediately or false otherwise. // // The lock() methods block until a lock is established and // return true on success or false if an error occurs. // // The checkLock() methods check to see if a lock can be // established but do not actually lock anything. If a lock // can be established, they return true. Otherwise they return // false and populate the fields in the supplied flock struct // with information about one of the conflicting locks. // // The unlock() methods attempt to release a previosly // established lock and return true on success or false on // error. // These methods allow you to lock the entire file. bool tryLockFile(short type) const; bool lockFile(short type) const; bool checkLockFile(short type, struct flock *lck) const; bool unlockFile() const; // These methods allow you to lock an arbitrary // region of the file. bool tryLockRegion(short type, off64_t start, off64_t len) const; bool lockRegion(short type, off64_t start, off64_t len) const; bool checkLockRegion(short type, off64_t start, off64_t len, struct flock *lck) const; bool unlockRegion(off64_t start, off64_t len) const; // These methods allow you to lock an arbitrary region of the // file relative to the current position. bool tryLockFromCurrent(short type, off64_t len) const; bool tryLockFromCurrent(short type, off64_t start, off64_t len) const; bool lockFromCurrent(short type, off64_t len) const; bool lockFromCurrent(short type, off64_t start, off64_t len) const; bool checkLockFromCurrent(short type, off64_t len, struct flock *lck) const; bool checkLockFromCurrent(short type, off64_t start, off64_t len, struct flock *lck) const; bool unlockFromCurrent(off64_t len) const; bool unlockFromCurrent(off64_t start, off64_t len) const; // These methods allow you to lock an arbitrary region of the // file relative to the end of the file. bool tryLockFromEnd(short type, off64_t len) const; bool tryLockFromEnd(short type, off64_t start, off64_t len) const; bool lockFromEnd(short type, off64_t len) const; bool lockFromEnd(short type, off64_t start, off64_t len) const; bool checkLockFromEnd(short type, off64_t len, struct flock *lck) const; bool checkLockFromEnd(short type, off64_t start, off64_t len, struct flock *lck) const; bool unlockFromEnd(off64_t len) const; bool unlockFromEnd(off64_t start, off64_t len) const; // These methods allow you to lock "the remainder" of a file // starting at a given offset. bool tryLockRemainder(short type, off64_t start) const; bool lockRemainder(short type, off64_t start) const; bool checkLockRemainder(short type, off64_t start, struct flock *lck) const; bool unlockRemainder(off64_t start) const; // These methods allow you to lock "the remainder" of a file // relative to the current position. bool tryLockRemainderFromCurrent(short type) const; bool tryLockRemainderFromCurrent(short type, off64_t start) const; bool lockRemainderFromCurrent(short type) const; bool lockRemainderFromCurrent(short type, off64_t start) const; bool checkLockRemainderFromCurrent(short type, struct flock *lck) const; bool checkLockRemainderFromCurrent(short type, off64_t start, struct flock *lck) const; bool unlockRemainderFromCurrent() const; bool unlockRemainderFromCurrent(off64_t start) const; // These methods allow you to lock "the remainder" of a file // relative to the end of the file. bool tryLockRemainderFromEnd(short type) const; bool tryLockRemainderFromEnd(short type, off64_t start) const; bool lockRemainderFromEnd(short type) const; bool lockRemainderFromEnd(short type, off64_t start) const; bool checkLockRemainderFromEnd(short type, struct flock *lck) const; bool checkLockRemainderFromEnd(short type, off64_t start, struct flock *lck) const; bool unlockRemainderFromEnd() const; bool unlockRemainderFromEnd(off64_t start) const; // These methods allow you to advise the kernel that you are // going to access a region of a file in a particular manner. // The kernel can then perform some optimisations. // // In these methods, the region of the file begins at "start" // and continues for "len" bytes. // // These methods return true on success and false on failure. // // On operating systems don't support these methods, they // return true but don't actually do anything. bool sequentialAccess(off64_t start, size_t len) const; // The region will be accessed in sequential order. bool randomAccess(off64_t start, size_t len) const; // The region will be accessed in random order. bool onlyOnce(off64_t start, size_t len) const; // The region will be only be accessed once. bool willNeed(off64_t start, size_t len) const; // The region will be accessed in the near future. bool wontNeed(off64_t start, size_t len) const; // The region will not be accessed in the near future. bool normalAccess(off64_t start, size_t len) const; // Removes any advice that has previously been applied // to the region. bool reserve(off64_t start, size_t len) const; // Reserves space on the storage medium such that a // write to the region starting at "start" and // continuing for "len" bytes will not fail due to // lack of storage space. // // Returns true if the region can be reserved and // false otherwise. // Changes to files are often cached in system ram, these // methods makes sure that those changes are copied // to the storage medium that the file resides on. // // Returns true on success and false on failure. // // Note that if a hard disk has on-board write cache // enabled, this method only assures that the changes // has been copied into the disk's write cache, not // necessarily to the disk itself. bool sync() const ; bool dataSync() const ; // Similar to sync() but does not wait for the file's // last-access or last-modification times to be copied. // By default, the open() and create() methods call // getCurrentProperties() so the other methods of this class // will return valid data about the file immediately. These // methods alter that behaviour. void getCurrentPropertiesOnOpen(); void dontGetCurrentPropertiesOnOpen(); bool getCurrentProperties(); // Get the current file properties. // // Returns true on success and false on failure. // These methods return various file properties. mode_t getPermissions() const; // returns the permissions uid_t getOwnerUserId() const; // returns the user id of the file's owner gid_t getOwnerGroupId() const; // returns the group id of the file's owner off64_t getSize() const; // returns the number of bytes in the file blksize_t getBlockSize() const; // returns the blocksize to use for most // efficient I/O with the file or -1 for // systems don't support this blkcnt_t getBlockCount() const; // returns the number of blocks allocated for // the file or -1 for systems don't support this int isSocket() const; // returns 1 if the file is a socket, // 0 if it's not or -1 on error. int isSymbolicLink() const; // returns 1 if the file is a symbolic link, // 0 if it's not or -1 on error. int isRegularFile() const; // returns 1 if the file is a regular file, // 0 if it's not or -1 on error. int isBlockDevice() const; // returns 1 if the file is a block device, // 0 if it's not or -1 on error. int isDirectory() const; // returns 1 if the file is a directory, // 0 if it's not or -1 on error. int isCharacterDevice() const; // returns 1 if the file is a character device, // 0 if it's not or -1 on error. int isFifo() const; // returns 1 if the file is a fifo, // 0 if it's not or -1 on error. time_t getLastAccessTime() const; // returns the time of last access time_t getLastModificationTime() const; // returns the time of last modification // // Modification time IS NOT affected by chmod, // chown, or creating links. time_t getLastChangeTime() const; // returns the time of last change // // Change time IS affected by chmod, chown and // creating links. dev_t getDevice() const; // return the device of the file dev_t getDeviceType() const; // return the device type of the file ino_t getInode() const; // return the inode of the file nlink_t getNumberOfHardLinks() const; // return the number of hard links to the file // These methods change the user and/or group // that owns the file. // // They return true on success and false on failure. bool changeOwner(const char *newuser, const char *newgroup) const; bool changeOwner(uid_t uid, gid_t gid) const; bool changeOwnerUserId(const char *newuser) const; bool changeOwnerUserId(uid_t uid) const; bool changeOwnerGroupId(const char *newgroup) const; bool changeOwnerGroupId(gid_t gid) const; bool canChangeOwner() const; // Returns true if any of the changeOwner() // methods are allowed on "filename" and // false otherwise. long maxLinks() const; // Returns the maximum number of links that can be // created to "filename". // Some filesystems support extended file attributes. These // methods provide an interface for getting and setting those // attributes. const char * const *listAttributes() const; // Returns a NULL terminated array of attributes or // NULL if an error occurred. // These methods reads the value of the named attribute into // the supplied (preallocated) buffer. // They return true on success and false on failure. bool getAttribute(const char *name, unsigned short *number) const; bool getAttribute(const char *name, unsigned long *number) const; bool getAttribute(const char *name, short *number) const; bool getAttribute(const char *name, long *number) const; bool getAttribute(const char *name, float *number) const; bool getAttribute(const char *name, double *number) const; bool getAttribute(const char *name, unsigned char *character) const; bool getAttribute(const char *name, char *character) const; bool getAttribute(const char *name, bool *value) const; // These methods allocate a buffer, read the value into it // and return the allocated buffer. Some of these methods also // return the size of the buffer. // They return true on success and false on failure. bool getAttribute(const char *name, unsigned char **string) const; bool getAttribute(const char *name, char **string) const; bool getAttribute(const char *name, unsigned char **string, size_t *size) const; bool getAttribute(const char *name, char **string, size_t *size) const; bool getAttribute(const char *name, void **buffer, size_t *size) const; // These methods create a new attribute. // They return true on success and false on failure and will // fail if the attribute already exists. bool createAttribute(const char *name, unsigned short number) const; bool createAttribute(const char *name, unsigned long number) const; bool createAttribute(const char *name, short number) const; bool createAttribute(const char *name, long number) const; bool createAttribute(const char *name, float number) const; bool createAttribute(const char *name, double number) const; bool createAttribute(const char *name, unsigned char character) const; bool createAttribute(const char *name, char character) const; bool createAttribute(const char *name, bool value) const; bool createAttribute(const char *name, const unsigned char *string) const; bool createAttribute(const char *name, const char *string) const; bool createAttribute(const char *name, const unsigned char *string, size_t size) const; bool createAttribute(const char *name, const char *string, size_t size) const; bool createAttribute(const char *name, const void *buffer, size_t size) const; // These method replace an existing attribute. // They return true on success and false on failure and will // fail if the attribute doesn't already exist. bool replaceAttribute(const char *name, unsigned short number) const; bool replaceAttribute(const char *name, unsigned long number) const; bool replaceAttribute(const char *name, short number) const; bool replaceAttribute(const char *name, long number) const; bool replaceAttribute(const char *name, float number) const; bool replaceAttribute(const char *name, double number) const; bool replaceAttribute(const char *name, unsigned char character) const; bool replaceAttribute(const char *name, char character) const; bool replaceAttribute(const char *name, bool value) const; bool replaceAttribute(const char *name, const unsigned char *string) const; bool replaceAttribute(const char *name, const char *string) const; bool replaceAttribute(const char *name, const unsigned char *string, size_t size) const; bool replaceAttribute(const char *name, const char *string, size_t size) const; bool replaceAttribute(const char *name, const void *buffer, size_t size) const; // These methods create new attributes or replace existing // attributes. They returns true on success and false on // failure. bool setAttribute(const char *name, unsigned short number) const; bool setAttribute(const char *name, unsigned long number) const; bool setAttribute(const char *name, short number) const; bool setAttribute(const char *name, long number) const; bool setAttribute(const char *name, float number) const; bool setAttribute(const char *name, double number) const; bool setAttribute(const char *name, unsigned char character) const; bool setAttribute(const char *name, char character) const; bool setAttribute(const char *name, bool value) const; bool setAttribute(const char *name, const unsigned char *string) const; bool setAttribute(const char *name, const char *string) const; bool setAttribute(const char *name, const unsigned char *string, size_t size) const; bool setAttribute(const char *name, const char *string, size_t size) const; bool setAttribute(const char *name, const void *buffer, size_t size) const; bool removeAttribute(const char *name) const; // Removes attribute "name". // Returns true on success and false on failure. struct stat *getStat(); // Returns a pointer to the "stat" struct // used internally. // These methods creates the file "name" with permissions // "perms". If the file already exists, it will be truncated. static bool createFile(const char *name, mode_t perms); // Returns true on success and false on failure. static ssize_t createFile(const char *name, mode_t perms, unsigned short number); // Sets the initial contents to "number". // Returns the number of bytes written or -1 on error. static ssize_t createFile(const char *name, mode_t perms, unsigned long number); // Sets the initial contents to "number". // Returns the number of bytes written or -1 on error. static ssize_t createFile(const char *name, mode_t perms, float number); // Sets the initial contents to "number". // Returns the number of bytes written or -1 on error. static ssize_t createFile(const char *name, mode_t perms, double number); // Sets the initial contents to "number". // Returns the number of bytes written or -1 on error. static ssize_t createFile(const char *name, mode_t perms, char number); // Sets the initial contents to "number". // Returns the number of bytes written or -1 on error. static ssize_t createFile(const char *name, mode_t perms, const char *string); // Sets the initial contents to "string". // Returns the number of bytes written or -1 on error. static ssize_t createFile(const char *name, mode_t perms, const char *string, size_t size); // Sets the initial contents to "string" of size "size". // Returns the number of bytes written or -1 on error. static ssize_t createFile(const char *name, mode_t perms, const void *data, size_t size); // Sets the initial contents to "data" of size "size". // Returns the number of bytes written or -1 on error. // These methods allow you to create special kinds of files. static bool createFifo(const char *filename, mode_t perms); // Creates a fifo called "filename" with permissions // "perms". // // Returns true on success and false on failure. static int createTemporaryFile(char *templatefilename); // Creates a temporary file using "templatefilename" // as a template. The last 6 characters of // "templatefilename" must be XXXXXX and // "templatefilename" will be modified to contain the // name of the file that was actually created. // // Opens and returns the file descriptor handle of the // file on success and -1 on failure. static bool createHardLink(const char *oldpath, const char *newpath); // Creates a hard link between "oldpath" and "newpath". // Returns true on success and false on failure. static bool createSymbolicLink(const char *oldpath, const char *newpath); // Creates a symbolic link between "oldpath" and // "newpath". Returns true on success and false on // failure. static char *resolveSymbolicLink(const char *filename); // Returns the pathname of the file that the symbolic // link "filename" points to. Returns NULL on failure. // // Note that this method allocates a buffer for the // path internally and returns it. The calling program // must deallocate this buffer. static bool rename(const char *oldpath, const char *newpath); // Renames "oldpath" to "newpath". Returns true on // success and false on failure. static bool remove(const char *filename); // Removes file "filename". Returns true on success // and false on failure. (Will not remove a directory). // These methods truncate the file. // They return true on success and false on failure. static bool truncate(const char *filename); static bool truncate(const char *filename, off64_t length); // These methods read the contents of the file into a buffer. static char *getContents(const char *name); // Allocates a string large enough to accommodate the // contents of the file "name" , reads the contents of // the file into the string, terminates it with a NULL // and returns the string. // The string must be freed by the calling program. // // If the file contains no data, then a string of length // zero is returned. If an error occurs then a NULL // is returned. static ssize_t getContents(const char *name, unsigned char *buffer, size_t buffersize); // Reads the contents of the file "name" into // "buffer" of length "buffersize". If the file is // larger than "buffersize" then only "buffersize" bytes // of the file will be read into "buffer". // // Returns the number of bytes copied into "buffer" or // -1 on error. // These methods allow you to check various access statuses. static bool exists(const char *filename); // Returns true if the file exists and false otherwise. static bool readable(const char *filename); // Returns true if "filename" is readable by the user // or false otherwise. static bool writeable(const char *filename); // Returns true if "filename" is writeable by the user // or false otherwise. static bool executable(const char *filename); // Returns true if "filename" is executable by the user // or false otherwise. static bool accessible(const char *filename, int mode); // Checks to see if "filename" exists, is readable, // is writeable and/or is executable by the user, based // on the value of "mode". Mode should be an or'ed // combination of F_OK (exists), R_OK (readable), // W_OK (writable) and X_OK (executable) flags. // // Returns true if the file meets the conditions set // by the mode and false otherwise. // These methods return various file properties into the // supplied buffers. // They return true on success and false on failure. static bool getPermissions(const char *filename, mode_t *perms); static bool getOwnerUserId(const char *filename, uid_t *uid); static bool getOwnerGroupId(const char *filename, gid_t *gid); static bool getSize(const char *filename, off64_t *size); static bool getBlockSize(const char *filename, blksize_t *size); static bool getBlockCount(const char *filename, blkcnt_t *blocks); static int isSocket(const char *filename); static int isSymbolicLink(const char *filename); static int isRegularFile(const char *filename); static int isBlockDevice(const char *filename); static int isDirectory(const char *filename); static int isCharacterDevice(const char *filename); static int isFifo(const char *filename); static bool getLastAccessTime(const char *filename, time_t *atime); static bool getLastModificationTime(const char *filename, time_t *mtime); static bool getLastChangeTime(const char *filename, time_t *ctime); static bool getDevice(const char *filename, dev_t *dev); static bool getDeviceType(const char *filename, dev_t *devtype); static bool getInode(const char *filename, ino_t *inode); static bool getNumberOfHardLinks(const char *filename, nlink_t *nlink); static bool changeOwner(const char *filename, const char *newuser, const char *newgroup); static bool changeOwner(const char *filename, uid_t uid, gid_t gid); static bool changeOwnerUserId(const char *filename, const char *newuser); static bool changeOwnerUserId(const char *filename, uid_t uid); static bool changeOwnerGroupId(const char *filename, const char *newgroup); static bool changeOwnerGroupId(const char *filename, gid_t gid); static bool canChangeOwner(const char *filename); // Returns true if any of the changeOwner() // methods are allowed on "filename" and // false otherwise. // These methods allow you to override the last access and/or // modification time of a file. // They return true on success and false on failure. static bool setLastAccessTime(const char *filename, time_t lastaccesstime); static bool setLastModificationTime(const char *filename, time_t lastmodtime); static bool setLastAccessAndModificationTimes( const char *filename, time_t lastaccesstime, time_t lastmodtime); static bool setLastAccessAndModificationTimes( const char *filename); // Sets the last access and modification times of // "filename" to now. static char *dirname(const char *filename); // Returns the directory portion of "filename". // This method allocates a buffer internally // and returns it. The calling program must // deallocate the buffer. static char *basename(const char *filename); // Returns the non-directory portion of // "filename". // This method allocates a buffer internally // and returns it. The calling program must // deallocate the buffer. static char *basename(const char *filename, const char *suffix); // Returns the non-directory portion of // "filename", truncating "suffix". // This method allocates a buffer internally // and returns it. The calling program must // deallocate the buffer. static key_t generateKey(const char *filename, int id); // Generates a key based on "filename" and the // least signifigant 8 bits of id (which must // be non-zero) suitable for use with // semaphores, shared memory segments and // message queues. static long maxLinks(const char *filename); // Returns the maximum number of links that // can be created to "filename". #include <rudiments/private/file.h> }; #ifdef RUDIMENTS_NAMESPACE } #endif #endif