]> git.ipfire.org Git - thirdparty/squid.git/blame - src/base/File.h
Source Format Enforcement (#532)
[thirdparty/squid.git] / src / base / File.h
CommitLineData
e99fa721 1/*
77b1029d 2 * Copyright (C) 1996-2020 The Squid Software Foundation and contributors
e99fa721
EB
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
588512b3
AJ
14#if HAVE_SYS_FILE_H
15#include <sys/file.h>
16#endif
17
e99fa721
EB
18/// How should a file be opened/created? Should it be locked?
19class FileOpeningConfig
20{
21public:
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
38private:
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)
66class File
67{
68public:
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
93protected:
886e99cd
AR
94 bool isOpen() const {
95#if _SQUID_WINDOWS_
96 return fd_ != InvalidHandle;
97#else
98 return fd_ >= 0;
99#endif
100 }
e99fa721
EB
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
6c1219b9 108 SBuf sysCallFailure(const char *callName, const SBuf &error) const;
e99fa721
EB
109 /// \returns a description of an errno-based system call failure
110 SBuf sysCallError(const char *callName, const int savedErrno) const;
111
112private:
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;
ee244464 118 static const Handle InvalidHandle;
e99fa721
EB
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