#include <talloc.h>
#include "lib/util/blocking.h"
+#include "lib/util/pidfile.h"
#include "common/pidfile.h"
static int pidfile_context_destructor(struct pidfile_context *pid_ctx);
-int pidfile_create(TALLOC_CTX *mem_ctx, const char *pidfile,
- struct pidfile_context **result)
+int pidfile_context_create(TALLOC_CTX *mem_ctx, const char *pidfile,
+ struct pidfile_context **result)
{
struct pidfile_context *pid_ctx;
- struct flock lck;
- char tmp[64];
int fd, ret = 0;
- int len;
- ssize_t nwritten;
pid_ctx = talloc_zero(mem_ctx, struct pidfile_context);
if (pid_ctx == NULL) {
pid_ctx->pid = getpid();
- fd = open(pidfile, O_CREAT|O_WRONLY|O_NONBLOCK, 0644);
- if (fd == -1) {
- ret = errno;
- goto fail;
- }
-
- if (! set_close_on_exec(fd)) {
- close(fd);
- ret = EIO;
- goto fail;
- }
-
- pid_ctx->fd = fd;
-
- lck = (struct flock) {
- .l_type = F_WRLCK,
- .l_whence = SEEK_SET,
- };
-
- do {
- ret = fcntl(fd, F_SETLK, &lck);
- } while ((ret == -1) && (errno == EINTR));
-
+ ret = pidfile_path_create(pid_ctx->pidfile, &fd);
if (ret != 0) {
- ret = errno;
- goto fail;
+ return ret;
}
- do {
- ret = ftruncate(fd, 0);
- } while ((ret == -1) && (errno == EINTR));
-
- if (ret == -1) {
- ret = EIO;
- goto fail_unlink;
- }
-
- len = snprintf(tmp, sizeof(tmp), "%u\n", pid_ctx->pid);
- if (len < 0) {
- ret = EIO;
- goto fail_unlink;
- }
-
- do {
- nwritten = write(fd, tmp, len);
- } while ((nwritten == -1) && (errno == EINTR));
-
- if ((nwritten == -1) || (nwritten != len)) {
- ret = EIO;
- goto fail_unlink;
- }
+ pid_ctx->fd = fd;
talloc_set_destructor(pid_ctx, pidfile_context_destructor);
*result = pid_ctx;
return 0;
-fail_unlink:
- unlink(pidfile);
- close(fd);
-
fail:
talloc_free(pid_ctx);
return ret;
static int pidfile_context_destructor(struct pidfile_context *pid_ctx)
{
- struct flock lck;
- int ret;
-
if (getpid() != pid_ctx->pid) {
return 0;
}
- lck = (struct flock) {
- .l_type = F_UNLCK,
- .l_whence = SEEK_SET,
- };
-
(void) unlink(pid_ctx->pidfile);
- do {
- ret = fcntl(pid_ctx->fd, F_SETLK, &lck);
- } while ((ret == -1) && (errno == EINTR));
-
- do {
- ret = close(pid_ctx->fd);
- } while ((ret == -1) && (errno == EINTR));
+ pidfile_fd_close(pid_ctx->fd);
return 0;
}