Add socketd example project
Signed-off-by: guowenxue <guowenxue@gmail.com>
New file |
| | |
| | | /********************************************************************************* |
| | | * Copyright: (C) 2023 LingYun IoT System Studio |
| | | * All rights reserved. |
| | | * |
| | | * Filename: ds18b20.c |
| | | * Description: This file is temperature sensor DS18B20 code |
| | | * |
| | | * Version: 1.0.0(2023/8/10) |
| | | * Author: Guo Wenxue <guowenxue@gmail.com> |
| | | * ChangeLog: 1, Release initial version on "2023/8/10 12:13:26" |
| | | * |
| | | * Pin connection: |
| | | * |
| | | * DS18B20 Module Raspberry Pi Board |
| | | * VCC <-----> #Pin1(3.3V) |
| | | * DQ <-----> #Pin7(BCM GPIO4) |
| | | * GND <-----> GND |
| | | * |
| | | * /boot/config.txt: |
| | | * |
| | | * dtoverlay=w1-gpio-pullup,gpiopin=4 |
| | | * |
| | | ********************************************************************************/ |
| | | |
| | | |
| | | #include <stdio.h> |
| | | #include <stdlib.h> |
| | | #include <unistd.h> |
| | | #include <fcntl.h> |
| | | #include <dirent.h> |
| | | #include <string.h> |
| | | #include <time.h> |
| | | #include <errno.h> |
| | | |
| | | #include "logger.h" |
| | | |
| | | /* File Content: |
| | | pi@raspberrypi:~/guowenxue $ cat /sys/bus/w1/devices/28-041731f7c0ff/w1_slave |
| | | 3a 01 4b 46 7f ff 0c 10 a5 : crc=a5 YES |
| | | 3a 01 4b 46 7f ff 0c 10 a5 t=19625 |
| | | */ |
| | | |
| | | int ds18b20_get_temperature(float *temp) |
| | | { |
| | | char w1_path[50] = "/sys/bus/w1/devices/"; |
| | | char chip[20]; |
| | | char buf[128]; |
| | | DIR *dirp; |
| | | struct dirent *direntp; |
| | | int fd =-1; |
| | | char *ptr; |
| | | float value; |
| | | int found = 0; |
| | | |
| | | if( !temp ) |
| | | { |
| | | return -1; |
| | | } |
| | | |
| | | /*+-------------------------------------------------------------------+ |
| | | *| open dierectory /sys/bus/w1/devices to get chipset Serial Number | |
| | | *+-------------------------------------------------------------------+*/ |
| | | if((dirp = opendir(w1_path)) == NULL) |
| | | { |
| | | log_error("opendir error: %s\n", strerror(errno)); |
| | | return -2; |
| | | } |
| | | |
| | | while((direntp = readdir(dirp)) != NULL) |
| | | { |
| | | if(strstr(direntp->d_name,"28-")) |
| | | { |
| | | /* find and get the chipset SN filename */ |
| | | strcpy(chip,direntp->d_name); |
| | | found = 1; |
| | | break; |
| | | } |
| | | } |
| | | closedir(dirp); |
| | | |
| | | if( !found ) |
| | | { |
| | | log_error("Can not find ds18b20 in %s\n", w1_path); |
| | | return -3; |
| | | } |
| | | |
| | | /* get DS18B20 sample file full path: /sys/bus/w1/devices/28-xxxx/w1_slave */ |
| | | strncat(w1_path, chip, sizeof(w1_path)-strlen(w1_path)); |
| | | strncat(w1_path, "/w1_slave", sizeof(w1_path)-strlen(w1_path)); |
| | | |
| | | /* open file /sys/bus/w1/devices/28-xxxx/w1_slave to get temperature */ |
| | | if( (fd=open(w1_path, O_RDONLY)) < 0 ) |
| | | { |
| | | log_error("open %s error: %s\n", w1_path, strerror(errno)); |
| | | return -4; |
| | | } |
| | | |
| | | if(read(fd, buf, sizeof(buf)) < 0) |
| | | { |
| | | log_error("read %s error: %s\n", w1_path, strerror(errno)); |
| | | return -5; |
| | | } |
| | | |
| | | ptr = strstr(buf, "t="); |
| | | if( !ptr ) |
| | | { |
| | | log_error("ERROR: Can not get temperature\n"); |
| | | return -6; |
| | | } |
| | | |
| | | ptr+=2; |
| | | |
| | | /* convert string value to float value */ |
| | | *temp = atof(ptr)/1000; |
| | | |
| | | close(fd); |
| | | |
| | | return 0; |
| | | } |
New file |
| | |
| | | /********************************************************************************* |
| | | * Copyright: (C) 2023 LingYun IoT System Studio |
| | | * All rights reserved. |
| | | * |
| | | * Filename: ds18b20.h |
| | | * Description: This file is temperature sensor DS18B20 code |
| | | * |
| | | * Version: 1.0.0(2023/8/10) |
| | | * Author: Guo Wenxue <guowenxue@gmail.com> |
| | | * ChangeLog: 1, Release initial version on "2023/8/10 12:13:26" |
| | | * |
| | | * Pin connection: |
| | | * |
| | | * DS18B20 Module Raspberry Pi Board |
| | | * VCC <-----> #Pin1(3.3V) |
| | | * DQ <-----> #Pin7(BCM GPIO4) |
| | | * GND <-----> GND |
| | | * |
| | | * /boot/config.txt: |
| | | * |
| | | * dtoverlay=w1-gpio-pullup,gpiopin=4 |
| | | * |
| | | ********************************************************************************/ |
| | | |
| | | #ifndef _DS18B20_H_ |
| | | #define _DS18B20_H_ |
| | | |
| | | extern int ds18b20_get_temperature(float *temp); |
| | | |
| | | #endif /* ----- #ifndef _DS18B20_H_ ----- */ |
| | | |
New file |
| | |
| | | /********************************************************************************* |
| | | * Copyright: (C) 2023 LingYun IoT System Studio. |
| | | * All rights reserved. |
| | | * |
| | | * Filename: logger.c |
| | | * Description: This file is common logger API functions |
| | | * |
| | | * Version: 1.0.0(11/08/23) |
| | | * Author: Guo Wenxue <guowenxue@gmail.com> |
| | | * ChangeLog: 1, Release initial version on "11/08/23 16:18:43" |
| | | * |
| | | ********************************************************************************/ |
| | | |
| | | #include <stdio.h> |
| | | #include <errno.h> |
| | | #include <stdlib.h> |
| | | #include <stdarg.h> |
| | | #include <string.h> |
| | | #include <time.h> |
| | | #include <unistd.h> |
| | | #include <sys/types.h> |
| | | #include <sys/time.h> |
| | | #include <pthread.h> |
| | | |
| | | #include "logger.h" |
| | | |
| | | typedef void (*log_LockFn)(void *udata, int lock); |
| | | |
| | | static struct { |
| | | char file[32]; /* logger file name */ |
| | | FILE *fp; /* logger file pointer */ |
| | | long size; /* logger file max size */ |
| | | int level; /* logger level */ |
| | | log_LockFn lockfn; /* lock function */ |
| | | void *udata; /* lock data */ |
| | | } L; |
| | | |
| | | static const char *level_names[] = { |
| | | "ERROR", |
| | | "WARN", |
| | | "INFO", |
| | | "DEBUG", |
| | | "TRACE" |
| | | }; |
| | | |
| | | static const char *level_colors[] = { |
| | | "\x1b[31m", |
| | | "\x1b[33m", |
| | | "\x1b[32m", |
| | | "\x1b[36m", |
| | | "\x1b[94m" |
| | | }; |
| | | |
| | | static inline void time_to_str(char *buf) |
| | | { |
| | | struct timeval tv; |
| | | struct tm *tm; |
| | | int len; |
| | | |
| | | gettimeofday(&tv, NULL); |
| | | tm = localtime(&tv.tv_sec); |
| | | |
| | | len = sprintf(buf, "%04d-%02d-%02d %02d:%02d:%02d.%06d ", |
| | | tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, |
| | | tm->tm_hour, tm->tm_min, tm->tm_sec, (int)tv.tv_usec); |
| | | |
| | | buf[len] = '\0'; |
| | | } |
| | | |
| | | static void mutex_lock(void *udata, int lock) |
| | | { |
| | | int err; |
| | | pthread_mutex_t *l = (pthread_mutex_t *) udata; |
| | | |
| | | if (lock) |
| | | { |
| | | if ( (err = pthread_mutex_lock(l)) != 0 ) |
| | | log_error("Unable to lock log lock: %s", strerror(err)); |
| | | } |
| | | else |
| | | { |
| | | if ( (err = pthread_mutex_unlock(l) != 0) ) |
| | | log_error("Unable to unlock log lock: %s", strerror(err)); |
| | | } |
| | | } |
| | | |
| | | int log_open(char *fname, int level, int size, int lock) |
| | | { |
| | | FILE *fp; |
| | | |
| | | L.level = level; |
| | | L.size = size*1024; |
| | | |
| | | if( !fname || !strcmp(fname, "console") || !strcmp(fname, "stderr") ) |
| | | { |
| | | strcpy(L.file, "console"); |
| | | L.fp = stderr; |
| | | L.size = 0; /* console don't need rollback */ |
| | | } |
| | | else |
| | | { |
| | | if ( !(fp = fopen(fname, "a+")) ) |
| | | { |
| | | fprintf(stderr, "%s() failed: %s\n", __func__, strerror(errno)); |
| | | return -2; |
| | | } |
| | | L.fp = fp; |
| | | strncpy(L.file, fname, sizeof(L.file)); |
| | | } |
| | | |
| | | |
| | | if( lock ) |
| | | { |
| | | static pthread_mutex_t log_lock; |
| | | |
| | | pthread_mutex_init(&log_lock, NULL); |
| | | L.udata = (void *)&log_lock; |
| | | L.lockfn = mutex_lock; |
| | | } |
| | | |
| | | fprintf(L.fp, "\n"); |
| | | log_info("logger system(%s) start: file:\"%s\", level:%s, maxsize:%luKiB\n\n", |
| | | LOG_VERSION, L.file, level_names[level], size); |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | void log_close(void) |
| | | { |
| | | if( L.fp && L.fp!=stderr ) |
| | | fclose(L.fp); |
| | | |
| | | if (L.udata ) |
| | | pthread_mutex_destroy( L.udata); |
| | | } |
| | | |
| | | static void log_rollback(void) |
| | | { |
| | | char cmd[128]={0}; |
| | | long fsize; |
| | | |
| | | /* don't need rollback */ |
| | | if(L.size <= 0 ) |
| | | return ; |
| | | |
| | | fsize = ftell(L.fp); |
| | | if( fsize < L.size ) |
| | | return ; |
| | | |
| | | /* backup current log file */ |
| | | snprintf(cmd, sizeof(cmd), "cp %s %s.bak", L.file, L.file); |
| | | system(cmd); |
| | | |
| | | /* rollback file */ |
| | | fseek(L.fp, 0, SEEK_SET); |
| | | truncate(L.file, 0); |
| | | |
| | | fprintf(L.fp, "\n"); |
| | | log_info("logger system(%s) rollback: file:\"%s\", level:%s, maxsize:%luKiB\n\n", |
| | | LOG_VERSION, L.file, level_names[L.level], L.size/1024); |
| | | |
| | | return ; |
| | | } |
| | | |
| | | void _log_write(int level, const char *file, int line, const char *fmt, ...) |
| | | { |
| | | va_list args; |
| | | char time_string[100]; |
| | | |
| | | if ( !L.fp || level>L.level ) |
| | | return; |
| | | |
| | | /* Acquire lock */ |
| | | if ( L.lockfn ) |
| | | L.lockfn(L.udata, 1); |
| | | |
| | | log_rollback(); |
| | | |
| | | /* check and rollback file */ |
| | | time_to_str(time_string); |
| | | |
| | | /* Log to stderr */ |
| | | if ( L.fp == stderr ) |
| | | { |
| | | fprintf(L.fp, "%s %s %-5s\x1b[0m \x1b[90m%s:%03d:\x1b[0m ", |
| | | time_string, level_colors[level], level_names[level], file, line); |
| | | } |
| | | else /* Log to file */ |
| | | { |
| | | fprintf(L.fp, "%s %-5s %s:%03d: ", time_string, level_names[level], file, line); |
| | | } |
| | | |
| | | va_start(args, fmt); |
| | | vfprintf(L.fp, fmt, args); |
| | | va_end(args); |
| | | |
| | | fflush(L.fp); |
| | | |
| | | /* Release lock */ |
| | | if ( L.lockfn ) |
| | | L.lockfn(L.udata, 0); |
| | | } |
| | | |
| | | #define LINELEN 81 |
| | | #define CHARS_PER_LINE 16 |
| | | static char *print_char = |
| | | " " |
| | | " " |
| | | " !\"#$%&'()*+,-./" |
| | | "0123456789:;<=>?" |
| | | "@ABCDEFGHIJKLMNO" |
| | | "PQRSTUVWXYZ[\\]^_" |
| | | "`abcdefghijklmno" |
| | | "pqrstuvwxyz{|}~ " |
| | | " " |
| | | " " |
| | | " ???????????????" |
| | | "????????????????" |
| | | "????????????????" |
| | | "????????????????" |
| | | "????????????????" |
| | | "????????????????"; |
| | | |
| | | void log_dump(int level, const char *prompt, char *buf, size_t len) |
| | | { |
| | | int rc; |
| | | int idx; |
| | | char prn[LINELEN]; |
| | | char lit[CHARS_PER_LINE + 2]; |
| | | char hc[4]; |
| | | short line_done = 1; |
| | | |
| | | if (!L.fp || level>L.level) |
| | | return; |
| | | |
| | | if( prompt ) |
| | | _log_write(level, __FILE__, __LINE__, "%s", prompt); |
| | | |
| | | rc = len; |
| | | idx = 0; |
| | | lit[CHARS_PER_LINE] = '\0'; |
| | | |
| | | while (rc > 0) |
| | | { |
| | | if (line_done) |
| | | snprintf(prn, LINELEN, "%08X: ", idx); |
| | | |
| | | do |
| | | { |
| | | unsigned char c = buf[idx]; |
| | | snprintf(hc, 4, "%02X ", c); |
| | | strncat(prn, hc, LINELEN); |
| | | |
| | | lit[idx % CHARS_PER_LINE] = print_char[c]; |
| | | } |
| | | while (--rc > 0 && (++idx % CHARS_PER_LINE != 0)); |
| | | |
| | | line_done = (idx % CHARS_PER_LINE) == 0; |
| | | if (line_done) |
| | | { |
| | | if (L.fp) |
| | | fprintf(L.fp, "%s %s\n", prn, lit); |
| | | } |
| | | } |
| | | |
| | | if (!line_done) |
| | | { |
| | | int ldx = idx % CHARS_PER_LINE; |
| | | lit[ldx++] = print_char[(int)buf[idx]]; |
| | | lit[ldx] = '\0'; |
| | | |
| | | while ((++idx % CHARS_PER_LINE) != 0) |
| | | strncat(prn, " ", sizeof(prn)-strlen(prn)); |
| | | |
| | | if (L.fp) |
| | | fprintf(L.fp, "%s %s\n", prn, lit); |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | /********************************************************************************* |
| | | * Copyright: (C) 2023 LingYun IoT System Studio. |
| | | * All rights reserved. |
| | | * |
| | | * Filename: logger.h |
| | | * Description: This file is common logger API functions |
| | | * |
| | | * Version: 1.0.0(11/08/23) |
| | | * Author: Guo Wenxue <guowenxue@gmail.com> |
| | | * ChangeLog: 1, Release initial version on "11/08/23 16:18:43" |
| | | * |
| | | ********************************************************************************/ |
| | | |
| | | #ifndef _LOGGER_H_ |
| | | #define _LOGGER_H_ |
| | | |
| | | #include <stdio.h> |
| | | #include <stdarg.h> |
| | | |
| | | #define LOG_VERSION "v0.1" |
| | | |
| | | /* log level */ |
| | | enum { |
| | | LOG_LEVEL_ERROR, |
| | | LOG_LEVEL_WARN, |
| | | LOG_LEVEL_INFO, |
| | | LOG_LEVEL_DEBUG, |
| | | LOG_LEVEL_TRACE, |
| | | LOG_LEVEL_MAX |
| | | }; |
| | | |
| | | enum { |
| | | LOG_LOCK_DISABLE, /* disable lock */ |
| | | LOG_LOCK_ENABLE, /* enable lock */ |
| | | }; |
| | | |
| | | #define ROLLBACK_NONE 0 |
| | | |
| | | /* description: Initial the logger system |
| | | * arguments : |
| | | * $fname: logger file name, NULL/"console"/"stderr" will log to console |
| | | * $level: logger level above; |
| | | * $size : logger file max size in KiB |
| | | * $lock : thread lock enable or not |
| | | * return : <0: Failed ==0: Sucessfully |
| | | */ |
| | | #define THREAD_LOCK_NONE 0 |
| | | #define THREAD_LOCK_EN 1 |
| | | int log_open(char *fname, int level, int size, int lock); |
| | | |
| | | |
| | | /* description: Terminate the logger system */ |
| | | void log_close(void); |
| | | |
| | | |
| | | /* description: log message into log file. Don't call this function directly. */ |
| | | void _log_write(int level, const char *file, int line, const char *fmt, ...); |
| | | |
| | | |
| | | /* description: dump a buffer in hex to logger file */ |
| | | void log_dump(int level, const char *prompt, char *buf, size_t len); |
| | | |
| | | /* function: log message into logger file with different log level */ |
| | | #define log_trace(...) _log_write(LOG_LEVEL_TRACE, __FILE__, __LINE__, __VA_ARGS__) |
| | | #define log_debug(...) _log_write(LOG_LEVEL_DEBUG, __FILE__, __LINE__, __VA_ARGS__) |
| | | #define log_info(...) _log_write(LOG_LEVEL_INFO, __FILE__, __LINE__, __VA_ARGS__) |
| | | #define log_warn(...) _log_write(LOG_LEVEL_WARN, __FILE__, __LINE__, __VA_ARGS__) |
| | | #define log_error(...) _log_write(LOG_LEVEL_ERROR, __FILE__, __LINE__, __VA_ARGS__) |
| | | |
| | | #endif |
New file |
| | |
| | | #******************************************************************************** |
| | | # Copyright: (C) 2023 LingYun IoT System Studio |
| | | # All rights reserved. |
| | | # |
| | | # Filename: Makefile |
| | | # Description: This file used compile all the source code to static library |
| | | # |
| | | # Version: 1.0.0(11/08/23) |
| | | # Author: Guo Wenxue <guowenxue@gmail.com> |
| | | # ChangeLog: 1, Release initial version on "11/08/23 16:18:43" |
| | | # |
| | | #******************************************************************************* |
| | | |
| | | PWD=$(shell pwd ) |
| | | |
| | | BUILD_ARCH=$(shell uname -m) |
| | | ifneq ($(findstring $(BUILD_ARCH), "x86_64" "i386"),) |
| | | CROSS_COMPILE?=arm-linux-gnueabihf- |
| | | endif |
| | | |
| | | LIBNAME=$(shell basename ${PWD} ) |
| | | TOPDIR=$(shell dirname ${PWD} ) |
| | | CFLAGS+=-D_GNU_SOURCE |
| | | |
| | | all: clean |
| | | @rm -f *.o |
| | | @${CROSS_COMPILE}gcc ${CFLAGS} -I${TOPDIR} -c *.c |
| | | ${CROSS_COMPILE}ar -rcs lib${LIBNAME}.a *.o |
| | | |
| | | clean: |
| | | @rm -f *.o |
| | | @rm -f *.a |
| | | |
| | | distclean: |
| | | @make clean |
New file |
| | |
| | | /********************************************************************************* |
| | | * Copyright: (C) 2020 LingYun IoT System Studio |
| | | * All rights reserved. |
| | | * |
| | | * Filename: 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 "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); |
| | | } |
| | | |
| | | |
New file |
| | |
| | | /******************************************************************************** |
| | | * Copyright: (C) 2020 LingYun IoT System Studio |
| | | * All rights reserved. |
| | | * |
| | | * Filename: proc.h |
| | | * Description: This head file is for Linux process/thread API |
| | | * |
| | | * 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 __PROC_H_ |
| | | #define __PROC_H_ |
| | | |
| | | #include <signal.h> |
| | | #include <time.h> |
| | | |
| | | #define PID_ASCII_SIZE 11 |
| | | |
| | | typedef struct proc_signal_s |
| | | { |
| | | int signal; |
| | | unsigned stop; /* 0: Not term 1: Stop */ |
| | | } proc_signal_t; |
| | | |
| | | typedef void *(* thread_body_t) (void *thread_arg); |
| | | |
| | | extern proc_signal_t g_signal; |
| | | |
| | | /* install default signal process functions */ |
| | | extern void install_default_signal(void); |
| | | |
| | | /* excute a linux command by system() */ |
| | | extern void exec_system_cmd(const char *format, ...); |
| | | |
| | | /* check program already running or not, if not then run it and record pid into $pidfile */ |
| | | extern int check_set_program_running(int daemon, char *pidfile); |
| | | |
| | | /* check program already running or not from $pid_file */ |
| | | extern int check_daemon_running(const char *pid_file); |
| | | |
| | | /* set program daemon running and record pid in $pid_file */ |
| | | extern int set_daemon_running(const char *pid_file); |
| | | |
| | | /* record proces ID into $pid_file */ |
| | | extern int record_daemon_pid(const char *pid_file); |
| | | |
| | | /* stop program running from $pid_file */ |
| | | extern int stop_daemon_running(const char *pid_file); |
| | | |
| | | /* my implementation for set program running in daemon */ |
| | | extern void daemonize(int nochdir, int noclose); |
| | | |
| | | /* start a new thread to run $thread_workbody point function */ |
| | | extern int thread_start(pthread_t *thread_id, thread_body_t thread_workbody, void *thread_arg); |
| | | |
| | | /* +---------------------+ |
| | | * | Low level API | |
| | | * +---------------------+*/ |
| | | |
| | | /* get daemon process ID from $pid_file */ |
| | | extern pid_t get_daemon_pid(const char *pid_file); |
| | | |
| | | /* +------------------------+ |
| | | * | inline functions API | |
| | | * +------------------------+*/ |
| | | static inline void msleep(unsigned long ms) |
| | | { |
| | | struct timespec cSleep; |
| | | unsigned long ulTmp; |
| | | |
| | | cSleep.tv_sec = ms / 1000; |
| | | if (cSleep.tv_sec == 0) |
| | | { |
| | | ulTmp = ms * 10000; |
| | | cSleep.tv_nsec = ulTmp * 100; |
| | | } |
| | | else |
| | | { |
| | | cSleep.tv_nsec = 0; |
| | | } |
| | | |
| | | nanosleep(&cSleep, 0); |
| | | return ; |
| | | } |
| | | |
| | | #endif |
New file |
| | |
| | | /********************************************************************************* |
| | | * Copyright: (C) 2019 LingYun IoT System Studio |
| | | * All rights reserved. |
| | | * |
| | | * Filename: main.c |
| | | * Description: This file |
| | | * |
| | | * Version: 1.0.0(29/01/19) |
| | | * Author: Guo Wenxue <guowenxue@gmail.com> |
| | | * ChangeLog: 1, Release initial version on "29/01/19 15:34:41" |
| | | * |
| | | ********************************************************************************/ |
| | | #include <stdio.h> |
| | | #include <stdlib.h> |
| | | #include <unistd.h> |
| | | #include <time.h> |
| | | #include <getopt.h> |
| | | #include <libgen.h> |
| | | #include <string.h> |
| | | #include <errno.h> |
| | | |
| | | #include "logger.h" |
| | | #include "ds18b20.h" |
| | | #include "proc.h" |
| | | |
| | | #define PROG_VERSION "v1.0.0" |
| | | #define DAEMON_PIDFILE "/tmp/.socketd.pid" |
| | | |
| | | static void program_usage(char *progname) |
| | | { |
| | | |
| | | printf("Usage: %s [OPTION]...\n", progname); |
| | | printf(" %s is LingYun studio temperature socket client program running on RaspberryPi\n", progname); |
| | | |
| | | printf("\nMandatory arguments to long options are mandatory for short options too:\n"); |
| | | printf(" -d[debug ] Running in debug mode\n"); |
| | | printf(" -h[help ] Display this help information\n"); |
| | | printf(" -v[version ] Display the program version\n"); |
| | | |
| | | printf("\n%s version %s\n", progname, PROG_VERSION); |
| | | return; |
| | | } |
| | | |
| | | int main (int argc, char **argv) |
| | | { |
| | | int daemon = 1; |
| | | int opt; |
| | | char *progname=NULL; |
| | | char *logfile="client.log"; |
| | | int loglevel=LOG_LEVEL_INFO; |
| | | int logsize=10; /* logfile size max to 10K */ |
| | | |
| | | struct option long_options[] = { |
| | | {"debug", no_argument, NULL, 'd'}, |
| | | {"version", no_argument, NULL, 'v'}, |
| | | {"help", no_argument, NULL, 'h'}, |
| | | {NULL, 0, NULL, 0} |
| | | }; |
| | | |
| | | progname = (char *)basename(argv[0]); |
| | | |
| | | /* Parser the command line parameters */ |
| | | while ((opt = getopt_long(argc, argv, "dvh", long_options, NULL)) != -1) |
| | | { |
| | | switch (opt) |
| | | { |
| | | case 'd': /* Set debug running */ |
| | | daemon = 0; |
| | | logfile="console"; |
| | | loglevel=LOG_LEVEL_DEBUG; |
| | | break; |
| | | |
| | | case 'v': /* Get software version */ |
| | | printf("%s version %s\n", progname, PROG_VERSION); |
| | | return 0; |
| | | |
| | | case 'h': /* Get help information */ |
| | | program_usage(progname); |
| | | return 0; |
| | | |
| | | default: |
| | | break; |
| | | } |
| | | |
| | | } |
| | | |
| | | if( log_open(logfile, loglevel, logsize, THREAD_LOCK_NONE) < 0 ) |
| | | { |
| | | fprintf(stderr, "Initial log system failed\n"); |
| | | return 1; |
| | | } |
| | | |
| | | install_default_signal(); |
| | | |
| | | if( check_set_program_running(daemon, DAEMON_PIDFILE) < 0 ) |
| | | goto cleanup; |
| | | |
| | | while( ! g_signal.stop ) |
| | | { |
| | | msleep(1000); |
| | | } |
| | | |
| | | cleanup: |
| | | log_close(); |
| | | |
| | | return 0; |
| | | } |
New file |
| | |
| | | #******************************************************************************** |
| | | # Copyright: (C) 2023 LingYun IoT System Studio |
| | | # All rights reserved. |
| | | # |
| | | # Filename: Makefile |
| | | # Description: This file is the project top Makefie |
| | | # |
| | | # Version: 1.0.0(11/08/23) |
| | | # Author: Guo Wenxue <guowenxue@gmail.com> |
| | | # ChangeLog: 1, Release initial version on "11/08/23 16:18:43" |
| | | # |
| | | #******************************************************************************* |
| | | |
| | | PRJ_PATH=$(shell pwd) |
| | | APP_NAME = client |
| | | |
| | | BUILD_ARCH=$(shell uname -m) |
| | | ifneq ($(findstring $(BUILD_ARCH), "x86_64" "i386"),) |
| | | CROSS_COMPILE=arm-linux-gnueabihf- |
| | | endif |
| | | |
| | | # C source files in top-level directory |
| | | SRCFILES = $(wildcard *.c) |
| | | |
| | | # common CFLAGS for our source code |
| | | CFLAGS = -Wall -Wshadow -Wundef -Wmaybe-uninitialized -D_GNU_SOURCE |
| | | |
| | | # sub-directory need to entry and compile |
| | | SUBDIR=booster sqlite |
| | | |
| | | # sub-directory compiled to a library and need to link |
| | | SRCS=booster |
| | | SRCS_PATH=$(patsubst %,${PRJ_PATH}/%,$(SRCS)) |
| | | CFLAGS+=$(patsubst %,-I%,$(SRCS_PATH)) |
| | | LDFLAGS+=$(patsubst %,-L%,$(SRCS_PATH)) |
| | | LIBS=$(patsubst %,-l%,$(SRCS)) |
| | | LDFLAGS+=${LIBS} |
| | | |
| | | # Open source libraries |
| | | CFLAGS+=-I ${PRJ_PATH}/sqlite/install/include |
| | | LDFLAGS+=-L ${PRJ_PATH}/sqlite/install/lib |
| | | LDFLAGS+=-lsqlite3 |
| | | |
| | | LDFLAGS+=-lpthread |
| | | |
| | | all: entry subdir |
| | | ${CROSS_COMPILE}gcc ${CFLAGS} client.c -o client ${LDFLAGS} |
| | | |
| | | entry: |
| | | @echo "Building ${APP_NAME} on ${BUILD_ARCH}" |
| | | |
| | | subdir: |
| | | @for dir in ${SUBDIR} ; do if [ ! -e $${dir} ] ; then ln -s ../$${dir}; fi; done |
| | | @for dir in ${SUBDIR} ; do make -C $${dir} ; done |
| | | |
| | | install: |
| | | cp ${APP_NAME} /tftp |
| | | |
| | | clean: |
| | | @for dir in ${SRCS} ; do if [ -e $${dir} ] ; then make clean -C $${dir}; fi; done |
| | | @rm -f ${APP_NAME} |
| | | |
| | | distclean: |
| | | @for dir in ${SUBDIR} ; do if [ -e $${dir} ] ; then make clean -C $${dir}; fi; done |
| | | @rm -f ${APP_NAME} |
| | | @rm -f cscope.* tags |
| | | |
New file |
| | |
| | | #!/bin/bash |
| | | |
| | | # library name and version |
| | | # Official: https://www.sqlite.org/index.html |
| | | LIB_NAME=sqlite-autoconf-3430000 |
| | | PACK_SUFIX=tar.gz |
| | | |
| | | # LingYun source code FTP server |
| | | LY_FTP=http://main.iot-yun.club:2211/src/ |
| | | |
| | | # library download URL address |
| | | LIB_URL=$LY_FTP |
| | | |
| | | # Cross compiler for cross compile on Linux server |
| | | CROSS_COMPILE=arm-linux-gnueabihf- |
| | | |
| | | # compile jobs |
| | | JOBS=`cat /proc/cpuinfo |grep "processor"|wc -l` |
| | | |
| | | # this project absolute path |
| | | PRJ_PATH=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd) |
| | | |
| | | # top project absolute path |
| | | TOP_PATH=$(realpath $PRJ_PATH/..) |
| | | |
| | | # binaries install path |
| | | PREFIX_PATH=$PRJ_PATH/install |
| | | BIN_PATH=$PREFIX_PATH/bin |
| | | LIB_PATH=$PREFIX_PATH/lib |
| | | INC_PATH=$PREFIX_PATH/include |
| | | |
| | | # check installed or not file |
| | | INST_FILE=$PREFIX_PATH/bin/sqlite3 |
| | | |
| | | # shell script will exit once get command error |
| | | set -e |
| | | |
| | | #+-------------------------+ |
| | | #| Shell script functions | |
| | | #+-------------------------+ |
| | | |
| | | function pr_error() { |
| | | echo -e "\033[40;31m $1 \033[0m" |
| | | } |
| | | |
| | | function pr_warn() { |
| | | echo -e "\033[40;33m $1 \033[0m" |
| | | } |
| | | |
| | | function pr_info() { |
| | | echo -e "\033[40;32m $1 \033[0m" |
| | | } |
| | | |
| | | function check_result() |
| | | { |
| | | if [ $? != 0 ] ; then |
| | | pr_error $1 |
| | | fi |
| | | } |
| | | # decompress a packet to destination path |
| | | function do_unpack() |
| | | { |
| | | tarball=$1 |
| | | dstpath=`pwd` |
| | | |
| | | if [[ $# == 2 ]] ; then |
| | | dstpath=$2 |
| | | fi |
| | | |
| | | pr_info "decompress $tarball => $dstpath" |
| | | |
| | | mkdir -p $dstpath |
| | | case $tarball in |
| | | *.tar.gz) |
| | | tar -xzf $tarball -C $dstpath |
| | | ;; |
| | | |
| | | *.tar.bz2) |
| | | tar -xjf $tarball -C $dstpath |
| | | ;; |
| | | |
| | | *.tar.xz) |
| | | tar -xJf $tarball -C $dstpath |
| | | ;; |
| | | |
| | | *.tar.zst) |
| | | tar -I zstd -xf $tarball -C $dstpath |
| | | ;; |
| | | |
| | | *.tar) |
| | | tar -xf $tarball -C $dstpath |
| | | ;; |
| | | |
| | | *.zip) |
| | | unzip -qo $tarball -d $dstpath |
| | | ;; |
| | | |
| | | *) |
| | | pr_error "decompress Unsupport packet: $tarball" |
| | | return 1; |
| | | ;; |
| | | esac |
| | | } |
| | | |
| | | function do_export() |
| | | { |
| | | BUILD_ARCH=$(uname -m) |
| | | if [[ $BUILD_ARCH =~ "arm" ]] ; then |
| | | pr_warn "local($BUILD_ARCH) compile $LIB_NAME" |
| | | return ; |
| | | fi |
| | | |
| | | pr_warn "cross(${CROSS_COMPILE}) compile $LIB_NAME" |
| | | |
| | | # export cross toolchain |
| | | export CC=${CROSS_COMPILE}gcc |
| | | export CXX=${CROSS_COMPILE}g++ |
| | | export AS=${CROSS_COMPILE}as |
| | | export AR=${CROSS_COMPILE}ar |
| | | export LD=${CROSS_COMPILE}ld |
| | | export NM=${CROSS_COMPILE}nm |
| | | export RANLIB=${CROSS_COMPILE}ranlib |
| | | export OBJDUMP=${CROSS_COMPILE}objdump |
| | | export STRIP=${CROSS_COMPILE}strip |
| | | |
| | | # export cross configure |
| | | export CONFIG_CROSS=" --build=i686-pc-linux --host=arm-linux " |
| | | |
| | | # Clear LDFLAGS and CFLAGS |
| | | export LDFLAGS= |
| | | export CFLAGS= |
| | | } |
| | | |
| | | function do_fetch() |
| | | { |
| | | if [ -e ${INST_FILE} ] ; then |
| | | pr_warn "$LIB_NAME compile and installed alredy" |
| | | exit ; |
| | | fi |
| | | |
| | | if [ -d $LIB_NAME ] ; then |
| | | pr_warn "$LIB_NAME fetch already" |
| | | return ; |
| | | fi |
| | | |
| | | if [ ! -f ${LIB_NAME}.${PACK_SUFIX} ] ; then |
| | | wget ${LIB_URL}/${LIB_NAME}.${PACK_SUFIX} |
| | | check_result "ERROR: download ${LIB_NAME} failure" |
| | | fi |
| | | |
| | | do_unpack ${LIB_NAME}.${PACK_SUFIX} |
| | | } |
| | | |
| | | function do_build() |
| | | { |
| | | cd $LIB_NAME |
| | | |
| | | do_export |
| | | |
| | | ./configure --prefix=${PREFIX_PATH} ${CONFIG_CROSS} --enable-static --enable-static-shell |
| | | check_result "ERROR: configure ${LIB_NAME} failure" |
| | | |
| | | make && make install |
| | | check_result "ERROR: compile ${LIB_NAME} failure" |
| | | } |
| | | |
| | | function do_clean() |
| | | { |
| | | rm -rf *${LIB_NAME}* |
| | | } |
| | | |
| | | if [[ $# == 1 && $1 == -c ]] ;then |
| | | pr_warn "start clean ${LIB_NAME}" |
| | | do_clean |
| | | exit; |
| | | fi |
| | | |
| | | do_fetch |
| | | |
| | | do_build |
| | | |
New file |
| | |
| | | |
| | | all: |
| | | ./build.sh |
| | | |
| | | clean: |
| | | rm -rf install |
| | | ./build.sh -c |