Linux C启动时创建pid文件

程序在启动时将pid写入文件,当程序再次启动时会进行检测,避免启动多个实例。

util-pidfile.h文件

1 #ifndef __UTIL_PID_H__
2 #define __UTIL_PID_H__
3 
4 int PidfileCreate(const char *);
5 void PidfileRemove(const char *);
6 int PidfileTestRunning(const char *pid_filename);
7 
8 #endif /* __UTIL_PID_H__ */

 util-pidfile.c文件

  1 #include <stdio.h>
  2 #include <inttypes.h>   // PRIuMAX
  3 #include <errno.h>      // errno
  4 #include <string.h>     // strerror
  5 
  6 #include <sys/types.h>
  7 #include <sys/stat.h>
  8 #include <fcntl.h>
  9 #include <unistd.h> // getpid
 10 #include <signal.h> // kill
 11 
 12 #include "util-debug.h"
 13 #include "util-pidfile.h"
 14 
 15 /**
 16  * \brief Write a pid file (used at the startup)
 17  *        This commonly needed by the init scripts
 18  *
 19  * \param pointer to the name of the pid file to write (optarg)
 20  *
 21  * \retval 0 if succes
 22  * \retval -1 on failure
 23  */
 24 int PidfileCreate(const char *pidfile)
 25 {
 26     int pidfd = 0;
 27     char val[16];
 28 
 29     int len = snprintf(val, sizeof(val), "%"PRIuMAX"\n", (uintmax_t)getpid());
 30     if (len <= 0) {
 31         LogError("Pid error (%s)", strerror(errno));
 32         return(-1);
 33     }
 34 
 35     pidfd = open(pidfile, O_CREAT | O_TRUNC | O_NOFOLLOW | O_WRONLY, 0644);
 36     if (pidfd < 0) {
 37         LogError("unable to set pidfile '%s': %s",
 38                    pidfile,
 39                    strerror(errno));
 40         return(-1);
 41     }
 42 
 43     ssize_t r = write(pidfd, val, (unsigned int)len);
 44     if (r == -1) {
 45         LogError("unable to write pidfile: %s", strerror(errno));
 46         close(pidfd);
 47         return(-1);
 48     } else if ((size_t)r != len) {
 49         LogError("unable to write pidfile: wrote"
 50                 " %"PRIdMAX" of %"PRIuMAX" bytes.", (intmax_t)r, (uintmax_t)len);
 51         close(pidfd);
 52         return(-1);
 53     }
 54 
 55     close(pidfd);
 56     return(0);
 57 }
 58 
 59 /**
 60  * \brief Remove the pid file (used at the startup)
 61  *
 62  * \param pointer to the name of the pid file to write (optarg)
 63  */
 64 void PidfileRemove(const char *pid_filename)
 65 {
 66     if (pid_filename != NULL) {
 67         /* we ignore the result, the user may have removed the file already. */
 68         (void)unlink(pid_filename);
 69     }
 70 }
 71 
 72 /**
 73  * \brief Check a pid file (used at the startup)
 74  *        This commonly needed by the init scripts
 75  *
 76  * \param pointer to the name of the pid file to write (optarg)
 77  *
 78  * \retval 0 if succes
 79  * \retval -1 on failure
 80  */
 81 int PidfileTestRunning(const char *pid_filename)
 82 {
 83     if (access(pid_filename, F_OK) == 0) {
 84         /* Check if the existing process is still alive. */
 85         pid_t pidv;
 86         FILE *pf;
 87 
 88         pf = fopen(pid_filename, "r");
 89         if (pf == NULL) {
 90             LogError("pid file '%s' exists and can not be read. Aborting!",
 91                     pid_filename);
 92             return -1;
 93         }
 94 
 95         if (fscanf(pf, "%d", &pidv) == 1 && kill(pidv, 0) == 0) {
 96             fclose(pf);
 97             LogError("pid file '%s' exists. Is program already running? Aborting!",
 98                     pid_filename);
 99             return -1;
100         }
101 
102         fclose(pf);
103     }
104     return 0;
105 }

util-debug.h日志打印(主要是为了方便以后使用其他打印接口,就不用再修改util-pidfile.c文件了)

 1 #ifndef __UTIL_DEBUG_H__
 2 #define __UTIL_DEBUG_H__
 3 
 4 #ifndef LOG_PRINT
 5 #define LOG_MAX_LOG_MSG_LEN 2048
 6 #define Log(x, file, func, line, ...)                           \
 7     do {                                                        \
 8         char _log_msg[LOG_MAX_LOG_MSG_LEN];                     \
 9         snprintf(_log_msg, LOG_MAX_LOG_MSG_LEN, __VA_ARGS__);   \
10         fprintf(stdout, "<%s> %s\n", x, _log_msg);              \
11     } while(0)
12 
13 #define LogError(...) Log("ERROR", \
14         __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
15 
16 #define LogWarning(...) Log("WARNING", \
17         __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
18 
19 #define LogInfo(...) Log("INFO", \
20         __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
21 
22 #define LogDebug(...) Log("DEBUG", \
23         __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
24 
25 #define FatalError(...) do {                                           \
26     LogError(__VA_ARGS__);                                             \
27     exit(EXIT_FAILURE);                                                \
28 } while(0)
29 #endif
30 
31 
32 #endif //__UTIL_DEBUG_H__

main.c文件

 1 #include <stdio.h>
 2 #include <unistd.h>
 3 
 4 #include "util-pidfile.h"
 5 
 6 
 7 int main()
 8 {
 9     int result = 0;
10 
11     const char *pidfile = "/var/run/test_pid01.pid";
12 
13     if (PidfileTestRunning(pidfile) != 0)
14         return -1;
15 
16     PidfileCreate(pidfile);
17 
18     while (1){
19         sleep(1);
20     }
21 
22     PidfileRemove(pidfile);
23     return 0;
24 }

编译完成后运行该程序,然后再启动一个终端,再次运行这个程序的时候就会打印程序已运行并退出。

 <ERROR> pid file '/var/run/test_pid01.pid' exists. Is program already running? Aborting!

猜你喜欢

转载自www.cnblogs.com/yanhai307/p/10511816.html