2 * Copyright (C) 1996-2020 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
9 #ifndef SQUID_BASE_FILE_H
10 #define SQUID_BASE_FILE_H
12 #include "sbuf/SBuf.h"
18 /// How should a file be opened/created? Should it be locked?
19 class FileOpeningConfig
22 static FileOpeningConfig
ReadOnly(); // shared reading
23 static FileOpeningConfig
ReadWrite(); // exclusive creation and/or reading/writing
25 /* adjustment methods; named to work well with the File::Be::X shorthand */
27 /// protect concurrent accesses by attempting to obtain an appropriate lock
28 FileOpeningConfig
&locked(unsigned int attempts
= 5);
30 /// when opening a file for writing, create it if it does not exist
31 FileOpeningConfig
&createdIfMissing();
33 /// enter_suid() to open the file; leaves suid ASAP after that
34 FileOpeningConfig
&openedByRoot() { openByRoot
= true; return *this; }
36 /* add more mode adjustment methods as needed */
41 /* file opening parameters */
43 DWORD desiredAccess
= 0; ///< 2nd CreateFile() parameter
44 DWORD shareMode
= 0; ///< 3rd CreateFile() parameter
45 DWORD creationDisposition
= OPEN_EXISTING
; ///< 5th CreateFile() parameter
47 mode_t creationMask
= 0; ///< umask() parameter; the default is S_IWGRP|S_IWOTH
48 int openFlags
= 0; ///< opening flags; 2nd open(2) parameter
49 mode_t openMode
= 0644; ///< access mode; 3rd open(2) parameter
52 /* file locking (disabled unless lock(n) sets positive lockAttempts) */
54 DWORD lockFlags
= 0; ///< 2nd LockFileEx() parameter
56 int lockType
= F_UNLCK
; ///< flock::type member for fcntl(F_SETLK)
58 int flockMode
= LOCK_UN
; ///< 2nd flock(2) parameter
60 static const unsigned int RetryGapUsec
= 500000; /// pause before each lock retry
61 unsigned int lockAttempts
= 0; ///< how many times to try locking
62 bool openByRoot
= false;
65 /// a portable locking-aware exception-friendly file (with RAII API)
69 typedef FileOpeningConfig Be
; ///< convenient shorthand for File() callers
71 /// \returns nil if File() throws or a new File object (otherwise)
72 static File
*Optional(const SBuf
&aName
, const FileOpeningConfig
&cfg
);
74 File(const SBuf
&aFilename
, const FileOpeningConfig
&cfg
); ///< opens
77 /* can move but cannot copy */
78 File(const File
&) = delete;
79 File
&operator = (const File
&) = delete;
81 File
&operator = (File
&&other
);
83 const SBuf
&name() const { return name_
; }
85 /* system call wrappers */
87 /// makes the file size (and the current I/O offset) zero
89 SBuf
readSmall(SBuf::size_type minBytes
, SBuf::size_type maxBytes
); ///< read(2) for small files
90 void writeAll(const SBuf
&data
); ///< write(2) with a "wrote everything" check
91 void synchronize(); ///< fsync(2)
96 return fd_
!= InvalidHandle
;
102 void open(const FileOpeningConfig
&cfg
);
103 void lock(const FileOpeningConfig
&cfg
);
104 void lockOnce(const FileOpeningConfig
&cfg
);
107 /// \returns a description a system call-related failure
108 SBuf
sysCallFailure(const char *callName
, const SBuf
&error
) const;
109 /// \returns a description of an errno-based system call failure
110 SBuf
sysCallError(const char *callName
, const int savedErrno
) const;
113 SBuf name_
; ///< location on disk
115 // Windows-specific HANDLE is needed because LockFileEx() does not take POSIX FDs.
117 typedef HANDLE Handle
;
118 static const Handle InvalidHandle
;
121 static const Handle InvalidHandle
= -1;
123 Handle fd_
= InvalidHandle
; ///< OS-specific file handle