From c13c9806f957ebc675462737f4b328d3ab89e028 Mon Sep 17 00:00:00 2001
From: guowenxue <guowenxue@gmail.com>
Date: Mon, 10 Jul 2023 17:29:22 +0800
Subject: [PATCH] update gpsd.c
---
gpsd/booster/util_proc.c | 432 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 432 insertions(+), 0 deletions(-)
diff --git a/gpsd/booster/util_proc.c b/gpsd/booster/util_proc.c
new file mode 100644
index 0000000..dfdabae
--- /dev/null
+++ b/gpsd/booster/util_proc.c
@@ -0,0 +1,432 @@
+/*********************************************************************************
+ * Copyright: (C) 2020 LingYun IoT System Studio
+ * All rights reserved.
+ *
+ * Filename: util_proc.c
+ * Description: This file is the process API
+ *
+ * Version: 1.0.0(7/06/2020)
+ * Author: Guo Wenxue <guowenxue@gmail.com>
+ * ChangeLog: 1, Release initial version on "7/06/2020 09:19:02 PM"
+ *
+ ********************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "util_proc.h"
+#include "logger.h"
+
+proc_signal_t g_signal={0};
+
+void proc_default_sighandler(int sig)
+{
+ switch(sig)
+ {
+ case SIGINT:
+ log_warn("SIGINT - stopping\n");
+ g_signal.stop = 1;
+ break;
+
+ case SIGTERM:
+ log_warn("SIGTERM - stopping\n");
+ g_signal.stop = 1;
+ break;
+
+ case SIGSEGV:
+ log_warn("SIGSEGV - stopping\n");
+#if 0
+ if(g_signal.stop)
+ exit(0);
+
+ g_signal.stop = 1;
+#endif
+ break;
+
+ case SIGPIPE:
+ log_warn("SIGPIPE - warnning\n");
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+/* install default signal process functions */
+void install_default_signal(void)
+{
+ struct sigaction sigact, sigign;
+
+ log_info("Install default signal handler.\n");
+
+ /* Initialize the catch signal structure. */
+ sigemptyset(&sigact.sa_mask);
+ sigact.sa_flags = 0;
+ sigact.sa_handler = proc_default_sighandler;
+
+ /* Setup the ignore signal. */
+ sigemptyset(&sigign.sa_mask);
+ sigign.sa_flags = 0;
+ sigign.sa_handler = SIG_IGN;
+
+ sigaction(SIGTERM, &sigact, 0); /* catch terminate signal "kill" command */
+ sigaction(SIGINT, &sigact, 0); /* catch interrupt signal CTRL+C */
+ //sigaction(SIGSEGV, &sigact, 0); /* catch segmentation faults */
+ sigaction(SIGPIPE, &sigact, 0); /* catch broken pipe */
+#if 0
+ sigaction(SIGCHLD, &sigact, 0); /* catch child process return */
+ sigaction(SIGUSR2, &sigact, 0); /* catch USER signal */
+#endif
+}
+
+
+/* ****************************************************************************
+ * FunctionName: daemonize
+ * Description : Set the programe runs as daemon in background
+ * Inputs : nodir: DON'T change the work directory to / : 1:NoChange 0:Change
+ * noclose: close the opened file descrtipion or not 1:Noclose 0:Close
+ * Output : NONE
+ * Return : NONE
+ * *****************************************************************************/
+void daemonize(int nochdir, int noclose)
+{
+ int rv, fd;
+ int i;
+
+ /* already a daemon */
+ if (1 == getppid())
+ return;
+
+ /* fork error */
+ rv = fork();
+ if (rv < 0) exit(1);
+
+ /* parent process exit */
+ if (rv > 0)
+ exit(0);
+
+ /* obtain a new process session group */
+ setsid();
+
+ if (!noclose)
+ {
+ /* close all descriptors */
+ for (i = getdtablesize(); i >= 0; --i)
+ {
+ //if (i != g_logPtr->fd)
+ close(i);
+ }
+
+ /* Redirect Standard input [0] to /dev/null */
+ fd = open("/dev/null", O_RDWR);
+
+ /* Redirect Standard output [1] to /dev/null */
+ dup(fd);
+
+ /* Redirect Standard error [2] to /dev/null */
+ dup(fd);
+ }
+
+ umask(0);
+
+ if (!nochdir)
+ chdir("/");
+
+ return;
+}
+
+/* ****************************************************************************
+ * FunctionName: check_set_program_running
+ * Description : check program already running or not, if not then run it and
+ * record pid into $pidfile
+ * Inputs : daemon: set program running in daemon or not
+ * pid_file:The record PID file path
+ * Output : NONE
+ * Return : 0: Record successfully Else: Failure
+ * *****************************************************************************/
+
+int check_set_program_running(int daemon, char *pidfile)
+{
+ if( !pidfile )
+ return 0;
+
+ if( check_daemon_running(pidfile) )
+ {
+ log_error("Program already running, process exit now");
+ return -1;
+ }
+
+ if( daemon )
+ {
+ if( set_daemon_running(pidfile) < 0 )
+ {
+ log_error("set program running as daemon failure\n");
+ return -2;
+ }
+ }
+ else
+ {
+ if( record_daemon_pid(pidfile) < 0 )
+ {
+ log_error("record program running PID failure\n");
+ return -3;
+ }
+ }
+
+ return 0;
+}
+
+
+
+/* ****************************************************************************
+ * FunctionName: record_daemon_pid
+ * Description : Record the running daemon program PID to the file "pid_file"
+ * Inputs : pid_file:The record PID file path
+ * Output : NONE
+ * Return : 0: Record successfully Else: Failure
+ * *****************************************************************************/
+int record_daemon_pid(const char *pid_file)
+{
+ struct stat fStatBuf;
+ int fd = -1;
+ int mode = S_IROTH | S_IXOTH | S_IRGRP | S_IXGRP | S_IRWXU;
+ char ipc_dir[64] = { 0 };
+
+ strncpy(ipc_dir, pid_file, 64);
+
+ /* dirname() will modify ipc_dir and save the result */
+ dirname(ipc_dir);
+
+ /* If folder pid_file PATH doesnot exist, then we will create it" */
+ if (stat(ipc_dir, &fStatBuf) < 0)
+ {
+ if (mkdir(ipc_dir, mode) < 0)
+ {
+ log_error("cannot create %s: %s\n", ipc_dir, strerror(errno));
+ return -1;
+ }
+
+ (void)chmod(ipc_dir, mode);
+ }
+
+ /* Create the process running PID file */
+ mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+ if ((fd = open(pid_file, O_RDWR | O_CREAT | O_TRUNC, mode)) >= 0)
+ {
+ char pid[PID_ASCII_SIZE];
+ snprintf(pid, sizeof(pid), "%u\n", (unsigned)getpid());
+ write(fd, pid, strlen(pid));
+ close(fd);
+
+ log_debug("Record PID<%u> to file %s.\n", getpid(), pid_file);
+ }
+ else
+ {
+ log_error("cannot create %s: %s\n", pid_file, strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
+
+/* ****************************************************************************
+ * FunctionName: get_daemon_pid
+ * Description : Get the daemon process PID from the PID record file "pid_file"
+ * Inputs : pid_file: the PID record file
+ * Output : NONE
+ * Return : pid_t: The daemon process PID number
+ * *****************************************************************************/
+pid_t get_daemon_pid(const char *pid_file)
+{
+ FILE *f;
+ pid_t pid;
+
+ if ((f = fopen(pid_file, "rb")) != NULL)
+ {
+ char pid_ascii[PID_ASCII_SIZE];
+ (void)fgets(pid_ascii, PID_ASCII_SIZE, f);
+ (void)fclose(f);
+ pid = atoi(pid_ascii);
+ }
+ else
+ {
+ log_error("Can't open PID record file %s: %s\n", pid_file, strerror(errno));
+ return -1;
+ }
+ return pid;
+}
+
+/* ****************************************************************************
+ * FunctionName: check_daemon_running
+ * Description : Check the daemon program already running or not
+ * Inputs : pid_file: The record running daemon program PID
+ * Output : NONE
+ * Return : 1: The daemon program alread running 0: Not running
+ * *****************************************************************************/
+int check_daemon_running(const char *pid_file)
+{
+ int rv = -1;
+ struct stat fStatBuf;
+
+ rv = stat(pid_file, &fStatBuf);
+ if (0 == rv)
+ {
+ pid_t pid = -1;
+ printf("PID record file \"%s\" exist.\n", pid_file);
+
+ pid = get_daemon_pid(pid_file);
+ if (pid > 0) /* Process pid exist */
+ {
+ if ((rv = kill(pid, 0)) == 0)
+ {
+ printf("Program with PID[%d] seems running.\n", pid);
+ return 1;
+ }
+ else /* Send signal to the old process get no reply. */
+ {
+ printf("Program with PID[%d] seems exit.\n", pid);
+ remove(pid_file);
+ return 0;
+ }
+ }
+ else if (0 == pid)
+ {
+ printf("Can not read program PID form record file.\n");
+ remove(pid_file);
+ return 0;
+ }
+ else /* Read pid from file "pid_file" failure */
+ {
+ printf("Read record file \"%s\" failure, maybe program still running.\n", pid_file);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/* ****************************************************************************
+ * FunctionName: stop_daemon_running
+ * Description : Stop the daemon program running
+ * Inputs : pid_file: The record running daemon program PID
+ * Output : NONE
+ * Return : 1: The daemon program alread running 0: Not running
+ * *****************************************************************************/
+int stop_daemon_running(const char *pid_file)
+{
+ pid_t pid = -1;
+ struct stat fStatBuf;
+
+ if ( stat(pid_file, &fStatBuf) < 0)
+ return 0;
+
+ printf("PID record file \"%s\" exist.\n", pid_file);
+ pid = get_daemon_pid(pid_file);
+ if (pid > 0) /* Process pid exist */
+ {
+ while ( (kill(pid, 0) ) == 0)
+ {
+ kill(pid, SIGTERM);
+ sleep(1);
+ }
+
+ remove(pid_file);
+ }
+
+ return 0;
+}
+
+
+
+/* ****************************************************************************
+ * FunctionName: set_daemon_running
+ * Description : Set the programe running as daemon if it's not running and record
+ * its PID to the pid_file.
+ * Inputs : pid_file: The record running daemon program PID
+ * Output : NONE
+ * Return : 0: Successfully. 1: Failure
+ * *****************************************************************************/
+int set_daemon_running(const char *pid_file)
+{
+ daemonize(0, 1);
+ log_info("Program running as daemon [PID:%d].\n", getpid());
+
+ if (record_daemon_pid(pid_file) < 0)
+ {
+ log_error("Record PID to file \"%s\" failure.\n", pid_file);
+ return -2;
+ }
+
+ return 0;
+}
+
+/* start a new thread to run $thread_workbody point function */
+int thread_start(pthread_t *thread_id, thread_body_t thread_workbody, void *thread_arg)
+{
+ int rv = 0;
+ pthread_t tid;
+
+ pthread_attr_t thread_attr;
+
+ /* Initialize the thread attribute */
+ rv = pthread_attr_init(&thread_attr);
+ if(rv)
+ return -1;
+
+ /* Set the stack size of the thread */
+ rv = pthread_attr_setstacksize(&thread_attr, 120 * 1024);
+ if(rv)
+ goto CleanUp;
+
+ /* Set thread to detached state:Don`t need pthread_join */
+ rv = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
+ if(rv)
+ goto CleanUp;
+
+ /* Create the thread */
+ rv = pthread_create(&tid, &thread_attr, thread_workbody, thread_arg);
+ if(rv)
+ goto CleanUp;
+
+CleanUp:
+
+
+ if( thread_id )
+ {
+ if( rv )
+ *thread_id = 0;
+ else
+ *thread_id = tid;
+ }
+
+ /* Destroy the attributes of thread */
+ pthread_attr_destroy(&thread_attr);
+ return rv;
+}
+
+
+/* excute a linux command by system() */
+void exec_system_cmd(const char *format, ...)
+{
+ char cmd[256];
+ va_list args;
+
+ memset(cmd, 0, sizeof(cmd));
+
+ va_start(args, format);
+ vsnprintf(cmd, sizeof(cmd), format, args);
+ va_end(args);
+
+ system(cmd);
+}
+
+
--
Gitblit v1.9.1