remove space in the end of line
2 files added
11 files modified
| | |
| | | * |
| | | * Filename: cp_comport.c |
| | | * Description: It's the comport operate library. |
| | | * |
| | | * |
| | | * Version: 2.0.0(10/17/2018~) |
| | | * Author: Guo Wenxue <guowenxue@gmail.com> |
| | | * ChangeLog: 1, Release initial version on "10/17/2018 03:33:25 PM" |
| | | * |
| | | * |
| | | ********************************************************************************/ |
| | | |
| | | #include "comport.h" |
| | |
| | | |
| | | |
| | | |
| | | /* |
| | | /* |
| | | * description: Open the serial port |
| | | * |
| | | * input args: $comport: corresponding comport point |
| | | * input args: $comport: corresponding comport point |
| | | * $dev_name: The comport device name path, such as '/dev/ttyS3' |
| | | * $baudrate: The baudrate, such as 115200 |
| | | * $settings: The databit,parity,stopbit,flowctrl settings, such as '8N1N' |
| | |
| | | goto CleanUp; |
| | | } |
| | | } |
| | | else |
| | | else |
| | | { |
| | | rv = -5; |
| | | goto CleanUp; |
| | |
| | | |
| | | if (0 != tcgetattr(comport->fd, &old_cfg)) |
| | | { |
| | | rv = -6; // Failed to get Com settings |
| | | rv = -6; // Failed to get Com settings |
| | | goto CleanUp; |
| | | } |
| | | |
| | |
| | | /* Set the parity */ |
| | | switch (comport->parity) |
| | | { |
| | | case 0x01: // Odd |
| | | case 0x01: // Odd |
| | | new_cfg.c_cflag |= (PARENB | PARODD); |
| | | new_cfg.c_cflag |= (INPCK | ISTRIP); |
| | | break; |
| | | case 0x02: // Even |
| | | case 0x02: // Even |
| | | new_cfg.c_cflag |= PARENB; |
| | | new_cfg.c_cflag &= ~PARODD;; |
| | | new_cfg.c_cflag |= (INPCK | ISTRIP); |
| | |
| | | /* Set flow control */ |
| | | switch (comport->flowctrl) |
| | | { |
| | | case 1: // Software control |
| | | case 1: // Software control |
| | | case 3: |
| | | new_cfg.c_cflag &= ~(CRTSCTS); |
| | | new_cfg.c_iflag |= (IXON | IXOFF); |
| | |
| | | tcflush(comport->fd, TCIFLUSH); |
| | | if (0 != tcsetattr(comport->fd, TCSANOW, &new_cfg)) |
| | | { |
| | | rv = -7; // Failed to set device com port settings |
| | | rv = -7; // Failed to set device com port settings |
| | | goto CleanUp; |
| | | } |
| | | |
| | |
| | | |
| | | |
| | | /* |
| | | * description: close comport |
| | | * input args: $comport: corresponding comport point |
| | | * description: close comport |
| | | * input args: $comport: corresponding comport point |
| | | */ |
| | | |
| | | void comport_close(comport_t *comport) |
| | |
| | | { |
| | | rv = -4; |
| | | goto CleanUp; |
| | | } |
| | | } |
| | | |
| | | left_bytes -= rv; |
| | | ptr += rv; |
| | | left_bytes -= rv; |
| | | ptr += rv; |
| | | } |
| | | |
| | | rv = 0; |
| | |
| | | iRet = select(comport->fd + 1, &rdfds, 0, &exfds, &stTime); |
| | | if (0 == iRet) |
| | | { |
| | | rv = 0; |
| | | rv = 0; |
| | | goto CleanUp; |
| | | } |
| | | else if (0 < iRet) |
| | | { |
| | | if (0 != FD_ISSET(comport->fd, &exfds)) |
| | | { |
| | | rv = -6; |
| | | rv = -6; |
| | | COM_PRINT("Error checking recv status.\n"); |
| | | goto CleanUp; |
| | | } |
| | | |
| | | if (0 == FD_ISSET(comport->fd, &rdfds)) |
| | | { |
| | | rv = 0; |
| | | rv = 0; |
| | | COM_PRINT("No incoming data.\n"); |
| | | goto CleanUp; |
| | | } |
| | |
| | | if (EINTR == errno) |
| | | { |
| | | COM_PRINT("catch interrupt signal.\n"); |
| | | rv = 0; |
| | | rv = 0; |
| | | } |
| | | else |
| | | { |
| | | COM_PRINT("Check recv status failure.\n"); |
| | | rv = -7; |
| | | rv = -7; |
| | | } |
| | | |
| | | goto CleanUp; |
| | |
| | | /************************************************************************************** |
| | | * Description: Set the comport databit,parity,stopbit,flowctrl into the comport structure |
| | | * Input Args: comport: the comport_t pointer |
| | | * settings: The databit/parity/stopbit/flowctrl settings as like "8N1N" |
| | | * settings: The databit/parity/stopbit/flowctrl settings as like "8N1N" |
| | | * Output Args: NONE |
| | | * Return Value: NONE |
| | | *************************************************************************************/ |
| | |
| | | * All rights reserved. |
| | | * |
| | | * Filename: comport.h |
| | | * Description: This head file is for the common TTY/Serial port operator library |
| | | * |
| | | * Description: This head file is for the common TTY/Serial port operator library |
| | | * |
| | | * Version: 1.0.0(10/17/2018~) |
| | | * Author: Guo Wenxue <guowenxue@gmail.com> |
| | | * ChangeLog: 1, Release initial version on "10/17/2018 03:33:25 PM" |
| | | * |
| | | * |
| | | ********************************************************************************/ |
| | | #ifndef __COMPORT_H_ |
| | | #define __COMPORT_H_ |
| | |
| | | } comport_t; |
| | | |
| | | |
| | | /* |
| | | /* |
| | | * description: Open the comport specified by $comport |
| | | * |
| | | * input args: $comport: corresponding comport point |
| | | * input args: $comport: corresponding comport point |
| | | * $devname: The comport device name path, such as '/dev/ttyS3' |
| | | * $baudrate: The baudrate, such as 115200 |
| | | * $settings: The databit,parity,stopbit,flowctrl settings, such as '8N1N' |
| | |
| | | extern int comport_open(comport_t *comport, const char *devname, long baudrate, const char *settings); |
| | | |
| | | /* |
| | | * description: close comport |
| | | * input args: $comport: corresponding comport point |
| | | * description: close comport |
| | | * input args: $comport: corresponding comport point |
| | | */ |
| | | extern void comport_close(comport_t *comport); |
| | | |
| | |
| | | |
| | | /*-------------------------------------------------------------------------*/ |
| | | /** |
| | | @file iniparser.c v4.1 |
| | | @file iniparser.c v4.1 |
| | | @author N. Devillard |
| | | @url https://github.com/ndevilla/iniparser |
| | | @brief Parser for ini files. |
| | |
| | | * |
| | | * Filename: linux_list.h |
| | | * Description: This file is copied from Linux kernel, which provide link list API. |
| | | * |
| | | * |
| | | * Version: 1.0.0(08/09/2020) |
| | | * Author: Guo Wenxue <guowenxue@gmail.com> |
| | | * ChangeLog: 1, Release initial version on "08/09/2020 02:24:34 AM" |
| | | * |
| | | * |
| | | ********************************************************************************/ |
| | | |
| | | #ifndef _LINUX_LIST_H |
| | |
| | | * |
| | | * Filename: logger.c |
| | | * Description: This file is the linux infrastructural logger system library |
| | | * |
| | | * |
| | | * Version: 1.0.0(08/08/2020~) |
| | | * Author: Guo Wenxue <guowenxue@gmail.com> |
| | | * ChangeLog: 1, Release initial version on "08/08/2020 04:24:01 PM" |
| | | * |
| | | * |
| | | ********************************************************************************/ |
| | | |
| | | #include "logger.h" |
| | |
| | | |
| | | |
| | | /* use standard error as output */ |
| | | if( !log_file || log_file[0]=='\0' || !strcmp(log_file, LOG_STDERR)) |
| | | if( !log_file || log_file[0]=='\0' || !strcmp(log_file, LOG_STDERR)) |
| | | { |
| | | strncpy(logger->file, LOG_STDERR, FILENAME_LEN); |
| | | strncpy(logger->file, LOG_STDERR, FILENAME_LEN); |
| | | logger->flag |= FLAG_LOGGER_CONSOLE; |
| | | logger->level = level; |
| | | logger->fp = stderr; |
| | |
| | | goto OUT; |
| | | } |
| | | |
| | | strncpy(logger->file, log_file, FILENAME_LEN); |
| | | strncpy(logger->file, log_file, FILENAME_LEN); |
| | | logger->flag |= FLAG_LOGGER_FILE; |
| | | logger->level = level; |
| | | logger->size = log_size; |
| | | logger->size = log_size; |
| | | |
| | | log_rollback_size = log_size <= 0 ? LOG_ROLLBACK_NONE : log_size*1024; /* Unit KiB */ |
| | | |
| | | |
| | | filemode = (log_rollback_size==LOG_ROLLBACK_NONE) ? "a+" : "w+"; |
| | | |
| | | logger->fp = fopen(logger->file, filemode); |
| | |
| | | { |
| | | log_close(); |
| | | filemode = log_rollback_size==LOG_ROLLBACK_NONE ? "a+" : "w+"; |
| | | logger->fp = fopen(logger->file, filemode); |
| | | |
| | | logger->fp = fopen(logger->file, filemode); |
| | | |
| | | if (logger->fp == NULL) |
| | | rc = -2; |
| | | } |
| | |
| | | " " |
| | | " " |
| | | " ???????????????" |
| | | "????????????????" |
| | | "????????????????" |
| | | "????????????????" |
| | | "????????????????" |
| | | "????????????????" |
| | | "????????????????" |
| | | "????????????????" |
| | | "????????????????" |
| | | "????????????????"; |
| | | |
| | | void logger_dump(int level, char *buf, int len) |
| | |
| | | * Version: 1.0.0(08/08/2020~) |
| | | * Author: Guo Wenxue <guowenxue@gmail.com> |
| | | * ChangeLog: 1, Release initial version on "08/08/2020 05:16:56 PM" |
| | | * |
| | | * |
| | | ********************************************************************************/ |
| | | |
| | | #ifndef _LOGGER_H_ |
| | |
| | | #define FILENAME_LEN 64 |
| | | #endif |
| | | |
| | | #define LOG_STDERR "stderr" /* Debug mode log file is console */ |
| | | #define LOG_STDERR "stderr" /* Debug mode log file is console */ |
| | | |
| | | #define LOG_ROLLBACK_SIZE 512 /* Default rollback log size */ |
| | | #define LOG_ROLLBACK_NONE 0 /* Set rollback size to 0 will not rollback */ |
New file |
| | |
| | | /******************************************************************************** |
| | | * Copyright: (C) 2021 LingYun IoT System Studio |
| | | * All rights reserved. |
| | | * |
| | | * Filename: ringbuf.h |
| | | * Description: This head file |
| | | * |
| | | * Version: 1.0.0(2021年04月29日) |
| | | * Author: Guo Wenxue <guowenxue@gmail.com> |
| | | * ChangeLog: 1, Release initial version on "2021年04月29日 12时18分32秒" |
| | | * |
| | | ********************************************************************************/ |
| | | #include <string.h> |
| | | #include <assert.h> |
| | | #include "ringbuf.h" |
| | | |
| | | void rb_init (struct ring_buffer *ring, unsigned char* buff, int size) |
| | | { |
| | | memset (ring, 0, sizeof (struct ring_buffer)); |
| | | ring->rd_pointer = 0; |
| | | ring->wr_pointer = 0; |
| | | ring->buffer= buff; |
| | | ring->size = size; |
| | | } |
| | | |
| | | |
| | | int rb_write (struct ring_buffer *rb, unsigned char * buf, int len) |
| | | { |
| | | int total; |
| | | int i; |
| | | |
| | | /* total = len = min(space, len) */ |
| | | total = rb_free_size(rb); |
| | | if(len > total) |
| | | len = total; |
| | | else |
| | | total = len; |
| | | |
| | | i = rb->wr_pointer; |
| | | if(i + len > rb->size) |
| | | { |
| | | memcpy(rb->buffer + i, buf, rb->size - i); |
| | | buf += rb->size - i; |
| | | len -= rb->size - i; |
| | | i = 0; |
| | | } |
| | | |
| | | memcpy(rb->buffer + i, buf, len); |
| | | rb->wr_pointer = i + len; |
| | | return total; |
| | | } |
| | | |
| | | |
| | | int rb_free_size (struct ring_buffer *rb) |
| | | { |
| | | return (rb->size - 1 - rb_data_size(rb)); |
| | | } |
| | | |
| | | |
| | | int rb_read (struct ring_buffer *rb, unsigned char * buf, int max) |
| | | { |
| | | int total; |
| | | int i; |
| | | |
| | | /* total = len = min(used, len) */ |
| | | total = rb_data_size(rb); |
| | | |
| | | if(max > total) |
| | | max = total; |
| | | else |
| | | total = max; |
| | | |
| | | |
| | | i = rb->rd_pointer; |
| | | if(i + max > rb->size) |
| | | { |
| | | memcpy(buf, rb->buffer + i, rb->size - i); |
| | | buf += rb->size - i; |
| | | max -= rb->size - i; |
| | | i = 0; |
| | | } |
| | | |
| | | memcpy(buf, rb->buffer + i, max); |
| | | rb->rd_pointer = i + max; |
| | | |
| | | return total; |
| | | } |
| | | |
| | | int rb_data_size (struct ring_buffer *rb) |
| | | { |
| | | return ((rb->wr_pointer - rb->rd_pointer) & (rb->size-1)); |
| | | } |
| | | |
| | | void rb_clear (struct ring_buffer *rb) |
| | | { |
| | | memset(rb->buffer,0,rb->size); |
| | | rb->rd_pointer=0; |
| | | rb->wr_pointer=0; |
| | | } |
| | | |
| | | unsigned char rb_peek(struct ring_buffer* rb, int index) |
| | | { |
| | | assert(index < rb_data_size(rb)); |
| | | |
| | | return rb->buffer[((rb->rd_pointer + index) % rb->size)]; |
| | | } |
New file |
| | |
| | | /******************************************************************************** |
| | | * Copyright: (C) 2021 LingYun IoT System Studio |
| | | * All rights reserved. |
| | | * |
| | | * Filename: ringbuf.h |
| | | * Description: This head file |
| | | * |
| | | * Version: 1.0.0(2021年04月29日) |
| | | * Author: Guo Wenxue <guowenxue@gmail.com> |
| | | * ChangeLog: 1, Release initial version on "2021年04月29日 12时18分32秒" |
| | | * |
| | | ********************************************************************************/ |
| | | |
| | | #ifndef _RINGBUF_H_ |
| | | #define _RINGBUF_H_ |
| | | |
| | | struct ring_buffer |
| | | { |
| | | unsigned char *buffer; |
| | | int wr_pointer; |
| | | int rd_pointer; |
| | | int size; |
| | | }; |
| | | |
| | | |
| | | /* Initial the ring buffer */ |
| | | void rb_init (struct ring_buffer *ring, unsigned char *buff, int size) ; |
| | | |
| | | |
| | | /* Description: Write $len bytes data in $buf into ring buffer $rb |
| | | * Return Value: The actual written into ring buffer data size, if ring buffer |
| | | * left space size small than $len, then only part of the data be written into. |
| | | */ |
| | | int rb_write (struct ring_buffer *rb, unsigned char *buf, int len) ; |
| | | |
| | | |
| | | /* Get ring buffer left free size */ |
| | | int rb_free_size (struct ring_buffer *rb); |
| | | |
| | | |
| | | /* Read $max bytes data from ring buffer $rb to $buf */ |
| | | int rb_read (struct ring_buffer *rb, unsigned char *buf, int max); |
| | | |
| | | |
| | | /* Read a specify $index byte data in ring buffer $rb */ |
| | | unsigned char rb_peek(struct ring_buffer *rb, int index); |
| | | |
| | | |
| | | /* Get data size in the ring buffer */ |
| | | int rb_data_size (struct ring_buffer *rb); |
| | | |
| | | |
| | | /* Clear the ring buffer data */ |
| | | void rb_clear (struct ring_buffer *rb) ; |
| | | |
| | | #endif /* ----- #ifndef _RINGBUF_H_ ----- */ |
| | | |
| | |
| | | /********************************************************************************* |
| | | * Copyright: (C) 2021 Guo Wenxue <guowenxue@gmail.com> |
| | | * Copyright: (C) 2021 Guo Wenxue <guowenxue@gmail.com> |
| | | * All rights reserved. |
| | | * |
| | | * Filename: comport.c |
| | | * Description: This file used to do ioctl() on common device or communicate |
| | | * Description: This file used to do ioctl() on common device or communicate |
| | | * with serial port/TTY device. |
| | | * |
| | | * |
| | | * Version: 1.0.0(5/1/2021~) |
| | | * Author: Guo Wenxue <guowenxue@gmail.com> |
| | | * ChangeLog: 1, Release initial version on "5/1/2021 10:08:05 AM" |
| | | * |
| | | * |
| | | ********************************************************************************/ |
| | | #include <getopt.h> |
| | | #include <libgen.h> |
| | |
| | | case 'd': |
| | | dev_name = optarg; |
| | | break; |
| | | |
| | | |
| | | case 'b': |
| | | baudrate = atoi(optarg); |
| | | break; |
| | |
| | | void stdin_nonblock(void) |
| | | { |
| | | struct termios ttystate; |
| | | |
| | | |
| | | //get the terminal state |
| | | tcgetattr(STDIN_FILENO, &ttystate); |
| | | |
| | |
| | | ttystate.c_lflag &= ~ICANON; |
| | | //minimum of number input read. |
| | | ttystate.c_cc[VMIN] = 1; |
| | | |
| | | |
| | | //set the terminal attributes. |
| | | tcsetattr(STDIN_FILENO, TCSANOW, &ttystate); |
| | | } |
| | | |
| | | } |
| | | |
| | | int kbhit(void) |
| | | { |
| | | { |
| | | struct timeval tv; |
| | | fd_set fds; |
| | | tv.tv_sec = 0; |
| | | tv.tv_usec = 0; |
| | | tv.tv_sec = 0; |
| | | tv.tv_usec = 0; |
| | | FD_ZERO(&fds); |
| | | FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0 |
| | | select(STDIN_FILENO + 1, &fds, NULL, NULL, &tv); |
| | | return FD_ISSET(STDIN_FILENO, &fds); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | * |
| | | * Filename: logger.c |
| | | * Description: This file is logger system sample code. |
| | | * |
| | | * |
| | | * Version: 1.0.0(17/07/21) |
| | | * Author: Guo Wenxue <guowenxue@gmail.com> |
| | | * ChangeLog: 1, Release initial version on "17/07/21 15:51:04" |
| | | * |
| | | * |
| | | ********************************************************************************/ |
| | | #include "logger.h" |
| | | |
| | |
| | | log_close(); |
| | | |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | |
| | | * |
| | | * 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> |
| | |
| | | case SIGPIPE: |
| | | log_warn("SIGPIPE - warnning\n"); |
| | | break; |
| | | |
| | | |
| | | default: |
| | | break; |
| | | } |
| | |
| | | sigaction(SIGPIPE, &sigact, 0); /* catch broken pipe */ |
| | | #if 0 |
| | | sigaction(SIGCHLD, &sigact, 0); /* catch child process return */ |
| | | sigaction(SIGUSR2, &sigact, 0); /* catch USER signal */ |
| | | sigaction(SIGUSR2, &sigact, 0); /* catch USER signal */ |
| | | #endif |
| | | } |
| | | |
| | |
| | | * Return : NONE |
| | | * *****************************************************************************/ |
| | | void daemonize(int nochdir, int noclose) |
| | | { |
| | | int rv, fd; |
| | | int i; |
| | | |
| | | /* already a daemon */ |
| | | if (1 == getppid()) |
| | | return; |
| | | |
| | | { |
| | | int rv, fd; |
| | | int i; |
| | | |
| | | /* already a daemon */ |
| | | if (1 == getppid()) |
| | | return; |
| | | |
| | | /* fork error */ |
| | | rv = fork(); |
| | | if (rv < 0) exit(1); |
| | | |
| | | rv = fork(); |
| | | if (rv < 0) exit(1); |
| | | |
| | | /* parent process exit */ |
| | | if (rv > 0) |
| | | exit(0); |
| | | |
| | | exit(0); |
| | | |
| | | /* obtain a new process session group */ |
| | | setsid(); |
| | | |
| | | setsid(); |
| | | |
| | | if (!noclose) |
| | | { |
| | | /* close all descriptors */ |
| | |
| | | { |
| | | //if (i != g_logPtr->fd) |
| | | close(i); |
| | | } |
| | | } |
| | | |
| | | /* Redirect Standard input [0] to /dev/null */ |
| | | fd = open("/dev/null", O_RDWR); |
| | | fd = open("/dev/null", O_RDWR); |
| | | |
| | | /* Redirect Standard output [1] to /dev/null */ |
| | | dup(fd); |
| | | dup(fd); |
| | | |
| | | /* Redirect Standard error [2] to /dev/null */ |
| | | dup(fd); |
| | | } |
| | | |
| | | umask(0); |
| | | |
| | | dup(fd); |
| | | } |
| | | |
| | | umask(0); |
| | | |
| | | if (!nochdir) |
| | | chdir("/"); |
| | | |
| | | chdir("/"); |
| | | |
| | | return; |
| | | } |
| | | |
| | | /* **************************************************************************** |
| | | * FunctionName: check_set_program_running |
| | | * Description : check program already running or not, if not then run it and |
| | | * 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 |
| | |
| | | if( !pidfile ) |
| | | return 0; |
| | | |
| | | if( check_daemon_running(pidfile) ) |
| | | if( check_daemon_running(pidfile) ) |
| | | { |
| | | log_err("Program already running, process exit now"); |
| | | return -1; |
| | | } |
| | | |
| | | if( daemon ) |
| | | if( daemon ) |
| | | { |
| | | if( set_daemon_running(pidfile) < 0 ) |
| | | { |
| | |
| | | * Return : 0: Record successfully Else: Failure |
| | | * *****************************************************************************/ |
| | | int record_daemon_pid(const char *pid_file) |
| | | { |
| | | struct stat fStatBuf; |
| | | int fd = -1; |
| | | { |
| | | 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); |
| | | char ipc_dir[64] = { 0 }; |
| | | |
| | | /* dirname() will modify ipc_dir and save the result */ |
| | | dirname(ipc_dir); |
| | | |
| | | 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_err("cannot create %s: %s\n", ipc_dir, strerror(errno)); |
| | | return -1; |
| | | } |
| | | |
| | | (void)chmod(ipc_dir, mode); |
| | | } |
| | | |
| | | /* Create the process running PID file */ |
| | | if (stat(ipc_dir, &fStatBuf) < 0) |
| | | { |
| | | if (mkdir(ipc_dir, mode) < 0) |
| | | { |
| | | log_err("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); |
| | | char pid[PID_ASCII_SIZE]; |
| | | snprintf(pid, sizeof(pid), "%u\n", (unsigned)getpid()); |
| | | write(fd, pid, strlen(pid)); |
| | | close(fd); |
| | | |
| | | log_dbg("Record PID<%u> to file %s.\n", getpid(), pid_file); |
| | | } |
| | | else |
| | | } |
| | | else |
| | | { |
| | | log_err("cannot create %s: %s\n", pid_file, strerror(errno)); |
| | | return -1; |
| | |
| | | * Return : pid_t: The daemon process PID number |
| | | * *****************************************************************************/ |
| | | pid_t get_daemon_pid(const char *pid_file) |
| | | { |
| | | FILE *f; |
| | | pid_t pid; |
| | | |
| | | { |
| | | 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); |
| | | } |
| | | { |
| | | char pid_ascii[PID_ASCII_SIZE]; |
| | | (void)fgets(pid_ascii, PID_ASCII_SIZE, f); |
| | | (void)fclose(f); |
| | | pid = atoi(pid_ascii); |
| | | } |
| | | else |
| | | { |
| | | log_err("Can't open PID record file %s: %s\n", pid_file, strerror(errno)); |
| | | return -1; |
| | | } |
| | | } |
| | | return pid; |
| | | } |
| | | } |
| | | |
| | | /* **************************************************************************** |
| | | * FunctionName: check_daemon_running |
| | |
| | | * *****************************************************************************/ |
| | | int check_daemon_running(const char *pid_file) |
| | | { |
| | | int rv = -1; |
| | | int rv = -1; |
| | | struct stat fStatBuf; |
| | | |
| | | rv = stat(pid_file, &fStatBuf); |
| | | if (0 == rv) |
| | | { |
| | | pid_t pid = -1; |
| | | 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; |
| | | } |
| | | { |
| | | 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; |
| | | } |
| | | } |
| | | |
| | | { |
| | | printf("Read record file \"%s\" failure, maybe program still running.\n", pid_file); |
| | | return 1; |
| | | } |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | |
| | |
| | | * *****************************************************************************/ |
| | | int stop_daemon_running(const char *pid_file) |
| | | { |
| | | pid_t pid = -1; |
| | | pid_t pid = -1; |
| | | struct stat fStatBuf; |
| | | |
| | | if ( stat(pid_file, &fStatBuf) < 0) |
| | | return 0; |
| | | |
| | | printf("PID record file \"%s\" exist.\n", pid_file); |
| | | 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) |
| | | { |
| | | { |
| | | while ( (kill(pid, 0) ) == 0) |
| | | { |
| | | kill(pid, SIGTERM); |
| | | sleep(1); |
| | | } |
| | | |
| | | remove(pid_file); |
| | | } |
| | | |
| | | } |
| | | |
| | | remove(pid_file); |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | |
| | |
| | | |
| | | /* **************************************************************************** |
| | | * FunctionName: set_daemon_running |
| | | * Description : Set the programe running as daemon if it's not running and record |
| | | * 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_nrml("Program running as daemon [PID:%d].\n", getpid()); |
| | | |
| | | if (record_daemon_pid(pid_file) < 0) |
| | | { |
| | | log_err("Record PID to file \"%s\" failure.\n", pid_file); |
| | | { |
| | | daemonize(0, 1); |
| | | log_nrml("Program running as daemon [PID:%d].\n", getpid()); |
| | | |
| | | if (record_daemon_pid(pid_file) < 0) |
| | | { |
| | | log_err("Record PID to file \"%s\" failure.\n", pid_file); |
| | | return -2; |
| | | } |
| | | |
| | |
| | | int rv = 0; |
| | | pthread_t tid; |
| | | |
| | | pthread_attr_t thread_attr; |
| | | pthread_attr_t thread_attr; |
| | | |
| | | /* Initialize the thread attribute */ |
| | | rv = pthread_attr_init(&thread_attr); |
| | | 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); |
| | | 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); |
| | | 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) |
| | |
| | | } |
| | | |
| | | /* Destroy the attributes of thread */ |
| | | pthread_attr_destroy(&thread_attr); |
| | | pthread_attr_destroy(&thread_attr); |
| | | return rv; |
| | | } |
| | | |
| | |
| | | { |
| | | char cmd[256]; |
| | | va_list args; |
| | | |
| | | memset(cmd, 0, sizeof(cmd)); |
| | | |
| | | va_start(args, format); |
| | | |
| | | memset(cmd, 0, sizeof(cmd)); |
| | | |
| | | va_start(args, format); |
| | | vsnprintf(cmd, sizeof(cmd), format, args); |
| | | va_end(args); |
| | | |
| | | va_end(args); |
| | | |
| | | system(cmd); |
| | | } |
| | | |
| | |
| | | * Version: 1.0.0(7/06/2012~) |
| | | * Author: Guo Wenxue <guowenxue@gmail.com> |
| | | * ChangeLog: 1, Release initial version on "7/06/2012 09:21:33 PM" |
| | | * |
| | | * |
| | | ********************************************************************************/ |
| | | |
| | | #ifndef __UTIL_PROC_H_ |
| | |
| | | * Version: 1.0.0(07/23/2020) |
| | | * Author: Guo Wenxue <guowenxue@gmail.com> |
| | | * ChangeLog: 1, Release initial version on "07/23/2020 07:46:37 AM" |
| | | * |
| | | * |
| | | ********************************************************************************/ |
| | | #ifndef __UTIL_TIME_H_ |
| | | #define __UTIL_TIME_H_ |
| | |
| | | int year; |
| | | int month; |
| | | int day; |
| | | int hour; |
| | | int hour; |
| | | int minute; |
| | | int second; |
| | | int dayofweek; |
| | |
| | | /* sleep for micro second */ |
| | | static inline void msleep(unsigned long ms) |
| | | { |
| | | struct timespec timeout; |
| | | struct timespec timeout; |
| | | unsigned long tmp; |
| | | |
| | | timeout.tv_sec = ms / 1000; |
| | |
| | | else |
| | | { |
| | | timeout.tv_nsec = 0; |
| | | } |
| | | |
| | | } |
| | | |
| | | nanosleep(&timeout, 0); |
| | | } |
| | | |
| | | /* call gettimeofday() to get current micro second */ |
| | | static inline unsigned long time_now() |
| | | { |
| | | struct timeval now; |
| | | struct timeval now; |
| | | |
| | | gettimeofday(&now, 0); |
| | | |
| | |
| | | /* timep has elapsed since $start, unit as micro second*/ |
| | | static inline uint32_t time_elapsed(uint32_t start) |
| | | { |
| | | uint32_t current = time_now(); |
| | | uint32_t current = time_now(); |
| | | |
| | | if(current >= start) |
| | | return current-start; |
| | | else |
| | | else |
| | | return current+0xFFFFFFFF-start; |
| | | } |
| | | |
| | | /* call gettimeofday() to get current micro second */ |
| | | static inline unsigned long time_second() |
| | | { |
| | | struct timeval now; |
| | | struct timeval now; |
| | | |
| | | gettimeofday(&now, 0); |
| | | return now.tv_sec; |
| | |
| | | /* timep has elapsed since $start, unit as micro second*/ |
| | | static inline uint32_t seconds_elapsed(uint32_t start) |
| | | { |
| | | uint32_t current = time_second(); |
| | | uint32_t current = time_second(); |
| | | |
| | | if(current >= start) |
| | | return current-start; |
| | | else |
| | | else |
| | | return current+0xFFFFFFFF-start; |
| | | } |
| | | |
| | |
| | | #define time_after(a,b) \ |
| | | (typecheck(unsigned long, a) && typecheck(unsigned long, b) && ((long)(b) - (long)(a) < 0)) |
| | | #define time_before(a,b) time_after(b,a) |
| | | |
| | | |
| | | #define time_after_eq(a,b) \ |
| | | (typecheck(unsigned long, a) && typecheck(unsigned long, b) && ((long)(a) - (long)(b) >= 0)) |
| | | #define time_before_eq(a,b) time_after_eq(b,a) |
| | |
| | | #define time_after64(a,b) \ |
| | | (typecheck(__u64, a) && typecheck(__u64, b) && ((__s64)(b) - (__s64)(a) < 0)) |
| | | #define time_before64(a,b) time_after64(b,a) |
| | | |
| | | |
| | | #define time_after_eq64(a,b) \ |
| | | (typecheck(__u64, a) && typecheck(__u64, b) && ((__s64)(a) - (__s64)(b) >= 0)) |
| | | #define time_before_eq64(a,b) time_after_eq64(b,a) |
| | | |
| | | |
| | | |
| | | static inline void get_sys_time(date_time_t *date) |
| | | { |
| | | time_t now = time(NULL); |
| | | struct tm *tnow = localtime(&now); |
| | | |
| | | memset(date, 0, sizeof(*date)); |
| | | struct tm *tnow = localtime(&now); |
| | | |
| | | memset(date, 0, sizeof(*date)); |
| | | date->year = 1900 + tnow->tm_year; |
| | | date->month = 1 + tnow->tm_mon; |
| | | date->day = tnow->tm_mday; |
| | | |
| | | date->hour = tnow->tm_hour; |
| | | date->minute = tnow->tm_min; |
| | | date->second = tnow->tm_sec; |
| | | date->dayofweek = tnow->tm_wday; |
| | | date->second = tnow->tm_sec; |
| | | date->dayofweek = tnow->tm_wday; |
| | | return; |
| | | } |
| | | |
| | | static inline int get_rtc_time(date_time_t *date) |
| | | { |
| | | int rv, fd = -1; |
| | | struct rtc_time rtc_tm; |
| | | struct rtc_time rtc_tm; |
| | | |
| | | memset(date, 0, sizeof(*date)); |
| | | |