int createPidFile(const char *progName, const char *pidFile, int flags) { int fd; char buf[BUF_SIZE]; fd = open(pidFile, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); if (fd == -1) { errnoMsg(LOG_ERR, "Could not open PID file %s", pidFile); return -1; } if (flags & CPF_CLOEXEC) { /* Set the close-on-exec file descriptor flag */ /* Instead of the following steps, we could (on Linux) have opened the file with O_CLOEXEC flag. However, not all systems support open() O_CLOEXEC (which was only standardized in SUSv4), so instead we use fcntl() to set the close-on-exec flag after opening the file */ flags = fcntl(fd, F_GETFD); /* Fetch flags */ if (flags == -1) errnoMsg(LOG_ERR, "Could not get flags for PID file %s", pidFile); flags |= FD_CLOEXEC; /* Turn on FD_CLOEXEC */ if (fcntl(fd, F_SETFD, flags) == -1) { /* Update flags */ errnoMsg(LOG_ERR, "Could not set flags for PID file %s", pidFile); return -1; } } if (lockRegion(fd, F_WRLCK, SEEK_SET, 0, 0) == -1) { if (errno == EAGAIN || errno == EACCES) errMsg(LOG_ERR, "PID file '%s' is locked; probably " "'%s' is already running", pidFile, progName); else errMsg(LOG_ERR, "Unable to lock PID file '%s'", pidFile); return -1; } if (ftruncate(fd, 0) == -1) { errnoMsg(LOG_ERR, "Could not truncate PID file '%s'", pidFile); return -1; } snprintf(buf, BUF_SIZE, "%ld\n", (long) getpid()); if (write(fd, buf, strlen(buf)) != strlen(buf)) { errnoMsg(LOG_ERR, "Could not write to PID file '%s'", pidFile); return -1; } return fd; }
int createPidFile(const char *progName, const char *pidFile, int flags) { int fd; char buf[BUF_SIZE]; fd = open(pidFile, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); if (fd == -1) errExit("Could not open PID file %s", pidFile); if (flags & CPF_CLOEXEC) { /* Set the close-on-exec file descriptor flag */ flags = fcntl(fd, F_GETFD); /* Fetch flags */ if (flags == -1) errExit("Could not get flags for PID file %s", pidFile); flags |= FD_CLOEXEC; /* Turn on FD_CLOEXEC */ if (fcntl(fd, F_SETFD, flags) == -1) /* Update flags */ errExit("Could not set flags for PID file %s", pidFile); } if (lockRegion(fd, F_WRLCK, SEEK_SET, 0, 0) == -1) { if (errno == EAGAIN || errno == EACCES) fatal("PID file '%s' is locked; probably " "'%s' is already running", pidFile, progName); else errExit("Unable to lock PID file '%s'", pidFile); } if (ftruncate(fd, 0) == -1) errExit("Could not truncate PID file '%s'", pidFile); snprintf(buf, BUF_SIZE, "%ld\n", (long) getpid()); if (write(fd, buf, strlen(buf)) != strlen(buf)) fatal("Writing to PID file '%s'", pidFile); return fd; }