MPD  0.20.18
PidFile.hxx
Go to the documentation of this file.
1 /*
2  * Copyright 2003-2017 The Music Player Daemon Project
3  * http://www.musicpd.org
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #ifndef MPD_PID_FILE_HXX
21 #define MPD_PID_FILE_HXX
22 
23 #include "fs/FileSystem.hxx"
24 #include "fs/AllocatedPath.hxx"
25 #include "Log.hxx"
26 
27 #include <assert.h>
28 #include <string.h>
29 #include <unistd.h>
30 #include <stdlib.h>
31 #include <fcntl.h>
32 
33 class PidFile {
34  int fd;
35 
36 public:
37  PidFile(const AllocatedPath &path):fd(-1) {
38  if (path.IsNull())
39  return;
40 
41  fd = OpenFile(path, O_WRONLY|O_CREAT|O_TRUNC, 0666);
42  if (fd < 0) {
43  const std::string utf8 = path.ToUTF8();
44  FormatFatalSystemError("Failed to create pid file \"%s\"",
45  utf8.c_str());
46  }
47  }
48 
49  PidFile(const PidFile &) = delete;
50 
51  void Close() {
52  if (fd < 0)
53  return;
54 
55  close(fd);
56  }
57 
58  void Delete(const AllocatedPath &path) {
59  if (fd < 0) {
60  assert(path.IsNull());
61  return;
62  }
63 
64  assert(!path.IsNull());
65 
66  close(fd);
67  unlink(path.c_str());
68  }
69 
70  void Write(pid_t pid) {
71  if (fd < 0)
72  return;
73 
74  char buffer[64];
75  sprintf(buffer, "%lu\n", (unsigned long)pid);
76 
77  write(fd, buffer, strlen(buffer));
78  close(fd);
79  }
80 
81  void Write() {
82  if (fd < 0)
83  return;
84 
85  Write(getpid());
86  }
87 };
88 
90 static inline pid_t
91 ReadPidFile(Path path) noexcept
92 {
93  int fd = OpenFile(path, O_RDONLY, 0);
94  if (fd < 0)
95  return -1;
96 
97  pid_t pid = -1;
98 
99  char buffer[32];
100  auto nbytes = read(fd, buffer, sizeof(buffer) - 1);
101  if (nbytes > 0) {
102  buffer[nbytes] = 0;
103 
104  char *endptr;
105  auto value = strtoul(buffer, &endptr, 10);
106  if (endptr > buffer)
107  pid = value;
108  }
109 
110  close(fd);
111  return pid;
112 }
113 
114 #endif
static gcc_pure pid_t ReadPidFile(Path path) noexcept
Definition: PidFile.hxx:91
gcc_pure const_pointer_type c_str() const noexcept
Returns the value as a const C string.
PidFile(const AllocatedPath &path)
Definition: PidFile.hxx:37
A path name in the native file system character set.
gcc_pure std::string ToUTF8() const noexcept
Convert the path to UTF-8.
bool IsNull() const noexcept
Check if this is a "nulled" instance.
void Write(pid_t pid)
Definition: PidFile.hxx:70
void Delete(const AllocatedPath &path)
Definition: PidFile.hxx:58
A path name in the native file system character set.
Definition: Path.hxx:39
void Close()
Definition: PidFile.hxx:51
gcc_noreturn void FormatFatalSystemError(const char *fmt,...)
#define gcc_pure
Definition: Compiler.h:116
void Write()
Definition: PidFile.hxx:81
static int OpenFile(Path file, int flags, int mode)
Wrapper for open_cloexec() that uses Path names.
Definition: FileSystem.hxx:57