libmultipath: use vector for for pp->hwe and mp->hwe
[multipath-tools/.git] / multipathd / pidfile.c
1 #include <sys/types.h> /* for pid_t */
2 #include <sys/stat.h>  /* for open */
3 #include <errno.h>     /* for EACCESS and EAGAIN */
4 #include <stdio.h>     /* for snprintf() */
5 #include <string.h>    /* for memset() */
6 #include <unistd.h>    /* for ftruncate() */
7 #include <fcntl.h>     /* for fcntl() */
8
9 #include "debug.h"
10
11 #include "pidfile.h"
12
13 int pidfile_create(const char *pidFile, pid_t pid)
14 {
15         char buf[20];
16         struct flock lock;
17         int fd, value;
18
19         if((fd = open(pidFile, O_WRONLY | O_CREAT,
20                        (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) < 0) {
21                 condlog(0, "Cannot open pidfile [%s], error was [%s]",
22                         pidFile, strerror(errno));
23                 return -errno;
24         }
25         lock.l_type = F_WRLCK;
26         lock.l_start = 0;
27         lock.l_whence = SEEK_SET;
28         lock.l_len = 0;
29
30         if (fcntl(fd, F_SETLK, &lock) < 0) {
31                 if (errno != EACCES && errno != EAGAIN)
32                         condlog(0, "Cannot lock pidfile [%s], error was [%s]",
33                                 pidFile, strerror(errno));
34                 else
35                         condlog(0, "process is already running");
36                 goto fail;
37         }
38         if (ftruncate(fd, 0) < 0) {
39                 condlog(0, "Cannot truncate pidfile [%s], error was [%s]",
40                         pidFile, strerror(errno));
41                 goto fail;
42         }
43         memset(buf, 0, sizeof(buf));
44         snprintf(buf, sizeof(buf)-1, "%u", pid);
45         if (write(fd, buf, strlen(buf)) != strlen(buf)) {
46                 condlog(0, "Cannot write pid to pidfile [%s], error was [%s]",
47                         pidFile, strerror(errno));
48                 goto fail;
49         }
50         if ((value = fcntl(fd, F_GETFD, 0)) < 0) {
51                 condlog(0, "Cannot get close-on-exec flag from pidfile [%s], "
52                         "error was [%s]", pidFile, strerror(errno));
53                 goto fail;
54         }
55         value |= FD_CLOEXEC;
56         if (fcntl(fd, F_SETFD, value) < 0) {
57                 condlog(0, "Cannot set close-on-exec flag from pidfile [%s], "
58                         "error was [%s]", pidFile, strerror(errno));
59                 goto fail;
60         }
61         return fd;
62 fail:
63         close(fd);
64         return -errno;
65 }