]> git.ipfire.org Git - thirdparty/squid.git/blob - src/base/File.h
Docs: Copyright updates for 2018 (#114)
[thirdparty/squid.git] / src / base / File.h
1 /*
2 * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
3 *
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.
7 */
8
9 #ifndef SQUID_BASE_FILE_H
10 #define SQUID_BASE_FILE_H
11
12 #include "sbuf/SBuf.h"
13
14 #if HAVE_SYS_FILE_H
15 #include <sys/file.h>
16 #endif
17
18 /// How should a file be opened/created? Should it be locked?
19 class FileOpeningConfig
20 {
21 public:
22 static FileOpeningConfig ReadOnly(); // shared reading
23 static FileOpeningConfig ReadWrite(); // exclusive creation and/or reading/writing
24
25 /* adjustment methods; named to work well with the File::Be::X shorthand */
26
27 /// protect concurrent accesses by attempting to obtain an appropriate lock
28 FileOpeningConfig &locked(unsigned int attempts = 5);
29
30 /// when opening a file for writing, create it if it does not exist
31 FileOpeningConfig &createdIfMissing();
32
33 /// enter_suid() to open the file; leaves suid ASAP after that
34 FileOpeningConfig &openedByRoot() { openByRoot = true; return *this; }
35
36 /* add more mode adjustment methods as needed */
37
38 private:
39 friend class File;
40
41 /* file opening parameters */
42 #if _SQUID_WINDOWS_
43 DWORD desiredAccess = 0; ///< 2nd CreateFile() parameter
44 DWORD shareMode = 0; ///< 3rd CreateFile() parameter
45 DWORD creationDisposition = OPEN_EXISTING; ///< 5th CreateFile() parameter
46 #else
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
50 #endif
51
52 /* file locking (disabled unless lock(n) sets positive lockAttempts) */
53 #if _SQUID_WINDOWS_
54 DWORD lockFlags = 0; ///< 2nd LockFileEx() parameter
55 #elif _SQUID_SOLARIS_
56 int lockType = F_UNLCK; ///< flock::type member for fcntl(F_SETLK)
57 #else
58 int flockMode = LOCK_UN; ///< 2nd flock(2) parameter
59 #endif
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;
63 };
64
65 /// a portable locking-aware exception-friendly file (with RAII API)
66 class File
67 {
68 public:
69 typedef FileOpeningConfig Be; ///< convenient shorthand for File() callers
70
71 /// \returns nil if File() throws or a new File object (otherwise)
72 static File *Optional(const SBuf &aName, const FileOpeningConfig &cfg);
73
74 File(const SBuf &aFilename, const FileOpeningConfig &cfg); ///< opens
75 ~File(); ///< closes
76
77 /* can move but cannot copy */
78 File(const File &) = delete;
79 File &operator = (const File &) = delete;
80 File(File &&other);
81 File &operator = (File &&other);
82
83 const SBuf &name() const { return name_; }
84
85 /* system call wrappers */
86
87 /// makes the file size (and the current I/O offset) zero
88 void truncate();
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)
92
93 protected:
94 bool isOpen() const {
95 #if _SQUID_WINDOWS_
96 return fd_ != InvalidHandle;
97 #else
98 return fd_ >= 0;
99 #endif
100 }
101
102 void open(const FileOpeningConfig &cfg);
103 void lock(const FileOpeningConfig &cfg);
104 void lockOnce(const FileOpeningConfig &cfg);
105 void close();
106
107 /// \returns a description a system call-related failure
108 SBuf sysCallFailure(const char *callName, const char *error) const;
109 /// \returns a description of an errno-based system call failure
110 SBuf sysCallError(const char *callName, const int savedErrno) const;
111
112 private:
113 SBuf name_; ///< location on disk
114
115 // Windows-specific HANDLE is needed because LockFileEx() does not take POSIX FDs.
116 #if _SQUID_WINDOWS_
117 typedef HANDLE Handle;
118 static const Handle InvalidHandle = INVALID_HANDLE_VALUE;
119 #else
120 typedef int Handle;
121 static const Handle InvalidHandle = -1;
122 #endif
123 Handle fd_ = InvalidHandle; ///< OS-specific file handle
124 };
125
126 #endif
127