Coverage Report

Created: 2026-07-14 08:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/kea/src/lib/util/pid_file.h
Line
Count
Source
1
// Copyright (C) 2015-2025 Internet Systems Consortium, Inc. ("ISC")
2
//
3
// This Source Code Form is subject to the terms of the Mozilla Public
4
// License, v. 2.0. If a copy of the MPL was not distributed with this
5
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7
#ifndef PID_FILE_H
8
#define PID_FILE_H
9
10
#include <exceptions/exceptions.h>
11
#include <boost/shared_ptr.hpp>
12
#include <fstream>
13
#include <ostream>
14
#include <string>
15
16
namespace isc {
17
namespace util {
18
19
/// @brief Exception thrown when an error occurs during PID file processing.
20
class PIDFileError : public Exception {
21
public:
22
    PIDFileError(const char* file, size_t line, const char* what) :
23
0
        isc::Exception(file, line, what) { }
24
};
25
26
/// @brief Exception thrown when an error occurs trying to read a PID
27
/// from an opened file.
28
class PIDCantReadPID : public Exception {
29
public:
30
    PIDCantReadPID(const char* file, size_t line, const char* what) :
31
0
        isc::Exception(file, line, what) { }
32
};
33
34
/// @brief Class to help with processing PID files
35
///
36
/// This is a utility class to manipulate PID file. It provides
37
/// functions for writing and deleting a file containing a PID as
38
/// well as for extracting a PID from a file and checking if the
39
/// process is still running.
40
class PIDFile {
41
public:
42
    /// @brief Constructor
43
    ///
44
    /// @param filename PID filename.
45
    PIDFile(const std::string& filename)
46
12.3k
        : filename_(filename) {
47
12.3k
    }
48
49
    /// @brief Destructor
50
12.3k
    virtual ~PIDFile() = default;
51
52
    /// @brief Read the PID in from the file and check it.
53
    ///
54
    /// Read the PID in from the file then use it to see if
55
    /// a process with that PID exists. If the file doesn't
56
    /// exist treat it as the process not being there.
57
    /// If the file exists but can't be read or it doesn't have
58
    /// the proper format treat it as the process existing.
59
    ///
60
    /// The PID file should be locked to avoid a race condition.
61
    ///
62
    /// @return returns the PID if it is in, 0 otherwise.
63
    ///
64
    /// @throw throws PIDCantReadPID if it was able to open the file
65
    /// but was unable to read the PID from it.
66
    int check() const;
67
68
    /// @brief Write the PID to the file.
69
    ///
70
    /// The PID file must be locked to avoid a race condition.
71
    ///
72
    /// @param pid the pid to write to the file.
73
    ///
74
    /// @throw throws PIDFileError if it can't open or write to the PID file.
75
    void write(int) const;
76
77
    /// @brief Get PID of the current process and write it to the file.
78
    ///
79
    /// The PID file must be locked to avoid a race condition.
80
    ///
81
    /// @throw throws PIDFileError if it can't open or write to the PID file.
82
    void write() const;
83
84
    /// @brief Delete the PID file.
85
    ///
86
    /// This is an atomic operation not subject to a race condition.
87
    ///
88
    /// @throw throws PIDFileError if it can't delete the PID file
89
    void deleteFile() const;
90
91
    /// @brief Returns the path to the PID file.
92
0
    std::string getFilename() const {
93
0
        return (filename_);
94
0
    }
95
96
    /// @brief  Returns the path to the lock file.
97
12.3k
    std::string getLockname() const {
98
12.3k
        return (filename_ + ".lock");
99
12.3k
    }
100
101
private:
102
    /// @brief PID filename
103
    std::string filename_;
104
};
105
106
/// @brief Defines a shared pointer to a PIDFile
107
typedef boost::shared_ptr<PIDFile> PIDFilePtr;
108
109
/// @brief RAII device to handle a lock file to avoid race conditions.
110
/// @note If there is a missing component in the path and the lock is
111
/// not blocking the lock is considered as being acquired: this does not
112
/// change the behavior of PIDFile methods (check() will succeed and
113
/// write() throw) and does not require unit test updates as if the
114
/// constructor throws.
115
class PIDLock {
116
public:
117
    /// @brief Constructor
118
    ///
119
    /// Try to get a lock.
120
    ///
121
    /// @param lockname Lock filename.
122
    /// @param blocking If true (default is false) block when already locked.
123
    PIDLock(const std::string& lockname, bool blocking = false);
124
125
    /// @brief Destructor
126
    ///
127
    /// Release the lock when taken and delete the lock file.
128
    ~PIDLock();
129
130
    /// @brief Return the lock status.
131
12.3k
    bool isLocked() {
132
12.3k
        return (locked_);
133
12.3k
    }
134
135
private:
136
    /// @brief Name of the lock file.
137
    std::string lockname_;
138
139
    /// @brief File descriptor to the lock file.
140
    int fd_;
141
142
    /// @brief Lock status.
143
    bool locked_;
144
};
145
146
} // namespace isc::util
147
} // namespace isc
148
149
#endif // PID_FILE_H