unix/PidFile: use raw file descriptor instead of stdio

This commit is contained in:
Max Kellermann 2015-08-15 16:42:07 +02:00
parent 567bf445bf
commit 4f29034f11
1 changed files with 29 additions and 20 deletions

View File

@ -25,20 +25,19 @@
#include "Log.hxx"
#include <assert.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
class PidFile {
FILE *file;
int fd;
public:
PidFile(const AllocatedPath &path):file(nullptr) {
PidFile(const AllocatedPath &path):fd(-1) {
if (path.IsNull())
return;
file = FOpen(path, FOpenMode::WriteText);
if (file == nullptr) {
fd = OpenFile(path, O_WRONLY|O_CREAT|O_TRUNC, 0666);
if (fd < 0) {
const std::string utf8 = path.ToUTF8();
FormatFatalSystemError("Failed to create pid file \"%s\"",
utf8.c_str());
@ -48,34 +47,35 @@ public:
PidFile(const PidFile &) = delete;
void Close() {
if (file == nullptr)
if (fd < 0)
return;
fclose(file);
close(fd);
}
void Delete(const AllocatedPath &path) {
if (file == nullptr) {
if (fd < 0) {
assert(path.IsNull());
return;
}
assert(!path.IsNull());
fclose(file);
close(fd);
RemoveFile(path);
}
void Write(pid_t pid) {
if (file == nullptr)
if (fd < 0)
return;
fprintf(file, "%lu\n", (unsigned long)pid);
fclose(file);
char buffer[64];
sprintf(buffer, "%lu\n", (unsigned long)pid);
close(fd);
}
void Write() {
if (file == nullptr)
if (fd < 0)
return;
Write(getpid());
@ -86,15 +86,24 @@ gcc_pure
static inline pid_t
ReadPidFile(Path path)
{
FILE *fp = FOpen(path, PATH_LITERAL("r"));
if (fp == nullptr)
int fd = OpenFile(path, O_RDONLY, 0);
if (fd < 0)
return -1;
int pid;
if (fscanf(fp, "%i", &pid) != 1)
pid = -1;
pid_t pid = -1;
fclose(fp);
char buffer[32];
auto nbytes = read(fd, buffer, sizeof(buffer) - 1);
if (nbytes > 0) {
buffer[nbytes] = 0;
char *endptr;
auto value = strtoul(buffer, &endptr, 10);
if (endptr > buffer)
pid = value;
}
close(fd);
return pid;
}