1. 程式人生 > >Linux C啟動時創建pid文件

Linux C啟動時創建pid文件

byte 寫入文件 errno.h mon nis npr tpi lin pen

程序在啟動時將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!

Linux C啟動時創建pid文件