Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f2ff934f9 | ||
|
|
c6cc5009dc | ||
|
|
05dbd9577c | ||
|
|
2622ccaafc | ||
|
|
664f458da6 | ||
|
|
a0760bde96 | ||
|
|
499a738901 | ||
|
|
34fe72877e | ||
|
|
6ff6a58132 | ||
|
|
f40406bd0d | ||
|
|
5cecf3b5ba | ||
|
|
6e9efcbfcc | ||
|
|
c6a798458b | ||
|
|
8c5dd9ca47 |
207
.gitignore
vendored
207
.gitignore
vendored
@ -1,205 +1,2 @@
|
|||||||
# ---> C
|
/cmake-build-debug
|
||||||
# Prerequisites
|
/build
|
||||||
*.d
|
|
||||||
|
|
||||||
# Object files
|
|
||||||
*.o
|
|
||||||
*.ko
|
|
||||||
*.obj
|
|
||||||
*.elf
|
|
||||||
|
|
||||||
# Linker output
|
|
||||||
*.ilk
|
|
||||||
*.map
|
|
||||||
*.exp
|
|
||||||
|
|
||||||
# Precompiled Headers
|
|
||||||
*.gch
|
|
||||||
*.pch
|
|
||||||
|
|
||||||
# Libraries
|
|
||||||
*.lib
|
|
||||||
*.a
|
|
||||||
*.la
|
|
||||||
*.lo
|
|
||||||
|
|
||||||
# Shared objects (inc. Windows DLLs)
|
|
||||||
*.dll
|
|
||||||
*.so
|
|
||||||
*.so.*
|
|
||||||
*.dylib
|
|
||||||
|
|
||||||
# Executables
|
|
||||||
*.exe
|
|
||||||
*.out
|
|
||||||
*.app
|
|
||||||
*.i*86
|
|
||||||
*.x86_64
|
|
||||||
*.hex
|
|
||||||
|
|
||||||
# Debug files
|
|
||||||
*.dSYM/
|
|
||||||
*.su
|
|
||||||
*.idb
|
|
||||||
*.pdb
|
|
||||||
|
|
||||||
# Kernel Module Compile Results
|
|
||||||
*.mod*
|
|
||||||
*.cmd
|
|
||||||
.tmp_versions/
|
|
||||||
modules.order
|
|
||||||
Module.symvers
|
|
||||||
Mkfile.old
|
|
||||||
dkms.conf
|
|
||||||
|
|
||||||
# ---> C++
|
|
||||||
# Prerequisites
|
|
||||||
*.d
|
|
||||||
|
|
||||||
# Compiled Object files
|
|
||||||
*.slo
|
|
||||||
*.lo
|
|
||||||
*.o
|
|
||||||
*.obj
|
|
||||||
|
|
||||||
# Precompiled Headers
|
|
||||||
*.gch
|
|
||||||
*.pch
|
|
||||||
|
|
||||||
# Compiled Dynamic libraries
|
|
||||||
*.so
|
|
||||||
*.dylib
|
|
||||||
*.dll
|
|
||||||
|
|
||||||
# Fortran module files
|
|
||||||
*.mod
|
|
||||||
*.smod
|
|
||||||
|
|
||||||
# Compiled Static libraries
|
|
||||||
*.lai
|
|
||||||
*.la
|
|
||||||
*.a
|
|
||||||
*.lib
|
|
||||||
|
|
||||||
# Executables
|
|
||||||
*.exe
|
|
||||||
*.out
|
|
||||||
*.app
|
|
||||||
|
|
||||||
# ---> CMake
|
|
||||||
CMakeLists.txt.user
|
|
||||||
CMakeCache.txt
|
|
||||||
CMakeFiles
|
|
||||||
CMakeScripts
|
|
||||||
Testing
|
|
||||||
Makefile
|
|
||||||
cmake_install.cmake
|
|
||||||
install_manifest.txt
|
|
||||||
compile_commands.json
|
|
||||||
CTestTestfile.cmake
|
|
||||||
_deps
|
|
||||||
|
|
||||||
# ---> VisualStudioCode
|
|
||||||
.vscode/*
|
|
||||||
!.vscode/settings.json
|
|
||||||
!.vscode/tasks.json
|
|
||||||
!.vscode/launch.json
|
|
||||||
!.vscode/extensions.json
|
|
||||||
*.code-workspace
|
|
||||||
|
|
||||||
# ---> Vim
|
|
||||||
# Swap
|
|
||||||
[._]*.s[a-v][a-z]
|
|
||||||
!*.svg # comment out if you don't need vector files
|
|
||||||
[._]*.sw[a-p]
|
|
||||||
[._]s[a-rt-v][a-z]
|
|
||||||
[._]ss[a-gi-z]
|
|
||||||
[._]sw[a-p]
|
|
||||||
|
|
||||||
# Session
|
|
||||||
Session.vim
|
|
||||||
Sessionx.vim
|
|
||||||
|
|
||||||
# Temporary
|
|
||||||
.netrwhist
|
|
||||||
*~
|
|
||||||
# Auto-generated tag files
|
|
||||||
tags
|
|
||||||
# Persistent undo
|
|
||||||
[._]*.un~
|
|
||||||
|
|
||||||
# ---> JetBrains
|
|
||||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
|
|
||||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
|
||||||
|
|
||||||
# User-specific stuff
|
|
||||||
.idea/**/workspace.xml
|
|
||||||
.idea/**/tasks.xml
|
|
||||||
.idea/**/usage.statistics.xml
|
|
||||||
.idea/**/dictionaries
|
|
||||||
.idea/**/shelf
|
|
||||||
|
|
||||||
# Generated files
|
|
||||||
.idea/**/contentModel.xml
|
|
||||||
|
|
||||||
# Sensitive or high-churn files
|
|
||||||
.idea/**/dataSources/
|
|
||||||
.idea/**/dataSources.ids
|
|
||||||
.idea/**/dataSources.local.xml
|
|
||||||
.idea/**/sqlDataSources.xml
|
|
||||||
.idea/**/dynamic.xml
|
|
||||||
.idea/**/uiDesigner.xml
|
|
||||||
.idea/**/dbnavigator.xml
|
|
||||||
|
|
||||||
# Gradle
|
|
||||||
.idea/**/gradle.xml
|
|
||||||
.idea/**/libraries
|
|
||||||
|
|
||||||
# Gradle and Maven with auto-import
|
|
||||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
|
||||||
# since they will be recreated, and may cause churn. Uncomment if using
|
|
||||||
# auto-import.
|
|
||||||
# .idea/artifacts
|
|
||||||
# .idea/compiler.xml
|
|
||||||
# .idea/jarRepositories.xml
|
|
||||||
# .idea/modules.xml
|
|
||||||
# .idea/*.iml
|
|
||||||
# .idea/modules
|
|
||||||
# *.iml
|
|
||||||
# *.ipr
|
|
||||||
|
|
||||||
# CMake
|
|
||||||
cmake-build-*/
|
|
||||||
|
|
||||||
# Mongo Explorer plugin
|
|
||||||
.idea/**/mongoSettings.xml
|
|
||||||
|
|
||||||
# File-based project format
|
|
||||||
*.iws
|
|
||||||
|
|
||||||
# IntelliJ
|
|
||||||
out/
|
|
||||||
|
|
||||||
# mpeltonen/sbt-idea plugin
|
|
||||||
.idea_modules/
|
|
||||||
|
|
||||||
# JIRA plugin
|
|
||||||
atlassian-ide-plugin.xml
|
|
||||||
|
|
||||||
# Cursive Clojure plugin
|
|
||||||
.idea/replstate.xml
|
|
||||||
|
|
||||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
|
||||||
com_crashlytics_export_strings.xml
|
|
||||||
crashlytics.properties
|
|
||||||
crashlytics-build.properties
|
|
||||||
fabric.properties
|
|
||||||
|
|
||||||
# Editor-based Rest Client
|
|
||||||
.idea/httpRequests
|
|
||||||
|
|
||||||
# Android studio 3.1+ serialized cache file
|
|
||||||
.idea/caches/build_file_checksums.ser
|
|
||||||
|
|
||||||
vperf
|
|
||||||
test/
|
|
||||||
|
|||||||
@ -1,16 +1,25 @@
|
|||||||
cmake_minimum_required (VERSION 2.8)
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
project(vperf C)
|
||||||
|
|
||||||
# veypi
|
set(CMAKE_C_STANDARD 11)
|
||||||
# projectname is the same as the main-executable
|
|
||||||
project(vperf)
|
|
||||||
|
|
||||||
add_definitions('-g')
|
set(SOURCES_CODE
|
||||||
add_definitions('-Wall')
|
main
|
||||||
#add_definitions('-std=c++11')
|
src/filter.c
|
||||||
|
src/filter.h
|
||||||
|
src/SystemInfo.c
|
||||||
|
src/SystemInfo.h
|
||||||
|
src/ProcessInfo.c
|
||||||
|
src/ProcessInfo.h
|
||||||
|
src/list.c
|
||||||
|
src/list.h
|
||||||
|
src/list_iterator.c
|
||||||
|
src/list_node.c
|
||||||
|
src/server.c
|
||||||
|
src/server.h
|
||||||
|
include/cJSON.c
|
||||||
|
include/cJSON.h)
|
||||||
|
|
||||||
|
find_package (Threads)
|
||||||
add_executable(${PROJECT_NAME} main.c test.c)
|
add_executable(vperf ${SOURCES_CODE})
|
||||||
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/build/)
|
target_link_libraries (vperf ${CMAKE_THREAD_LIBS_INIT})
|
||||||
|
|
||||||
#add_custom_target(${PROJECT_NAME}-symlink ALL ln --force -s ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME} ${CMAKE_SOURCE_DIR}/${PROJECT_NAME} DEPENDS ${PROJECT_NAME})
|
|
||||||
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ${CMAKE_SOURCE_DIR}/${PROJECT_NAME})
|
|
||||||
5
CrossCompile.cmake
Normal file
5
CrossCompile.cmake
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
set(CMAKE_SYSTEM_NAME Linux)
|
||||||
|
set(CMAKE_SYSTEM_PROCESSOR arm)
|
||||||
|
|
||||||
|
#cmake -DCMAKE_TOOLCHAIN_FILE=../CrossCompile.cmake ..
|
||||||
|
set(CMAKE_C_COMPILER,"/usr/bin/arm-linux-gnuedbihf-gcc")
|
||||||
@ -1,47 +0,0 @@
|
|||||||
MemTotal: 4169396 kB
|
|
||||||
MemFree: 3468580 kB
|
|
||||||
MemAvailable: 3660912 kB
|
|
||||||
Buffers: 3268 kB
|
|
||||||
Cached: 378088 kB
|
|
||||||
SwapCached: 0 kB
|
|
||||||
Active: 261560 kB
|
|
||||||
Inactive: 257688 kB
|
|
||||||
Active(anon): 133856 kB
|
|
||||||
Inactive(anon): 8456 kB
|
|
||||||
Active(file): 127704 kB
|
|
||||||
Inactive(file): 249232 kB
|
|
||||||
Unevictable: 0 kB
|
|
||||||
Mlocked: 0 kB
|
|
||||||
SwapTotal: 2097148 kB
|
|
||||||
SwapFree: 2097148 kB
|
|
||||||
Dirty: 4 kB
|
|
||||||
Writeback: 0 kB
|
|
||||||
AnonPages: 136036 kB
|
|
||||||
Mapped: 143540 kB
|
|
||||||
Shmem: 8676 kB
|
|
||||||
KReclaimable: 39372 kB
|
|
||||||
Slab: 106852 kB
|
|
||||||
SReclaimable: 39372 kB
|
|
||||||
SUnreclaim: 67480 kB
|
|
||||||
KernelStack: 2832 kB
|
|
||||||
PageTables: 6408 kB
|
|
||||||
NFS_Unstable: 0 kB
|
|
||||||
Bounce: 0 kB
|
|
||||||
WritebackTmp: 0 kB
|
|
||||||
CommitLimit: 4181844 kB
|
|
||||||
Committed_AS: 784436 kB
|
|
||||||
VmallocTotal: 34359738367 kB
|
|
||||||
VmallocUsed: 0 kB
|
|
||||||
VmallocChunk: 0 kB
|
|
||||||
HardwareCorrupted: 0 kB
|
|
||||||
AnonHugePages: 30720 kB
|
|
||||||
ShmemHugePages: 0 kB
|
|
||||||
ShmemPmdMapped: 0 kB
|
|
||||||
HugePages_Total: 0
|
|
||||||
HugePages_Free: 0
|
|
||||||
HugePages_Rsvd: 0
|
|
||||||
HugePages_Surp: 0
|
|
||||||
Hugepagesize: 2048 kB
|
|
||||||
Hugetlb: 0 kB
|
|
||||||
DirectMap4k: 138176 kB
|
|
||||||
DirectMap2M: 4360192 kB
|
|
||||||
3110
include/cJSON.c
Normal file
3110
include/cJSON.c
Normal file
File diff suppressed because it is too large
Load Diff
293
include/cJSON.h
Normal file
293
include/cJSON.h
Normal file
@ -0,0 +1,293 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef cJSON__h
|
||||||
|
#define cJSON__h
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
|
||||||
|
#define __WINDOWS__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
|
||||||
|
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options:
|
||||||
|
|
||||||
|
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
|
||||||
|
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
|
||||||
|
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
|
||||||
|
|
||||||
|
For *nix builds that support visibility attribute, you can define similar behavior by
|
||||||
|
|
||||||
|
setting default visibility to hidden by adding
|
||||||
|
-fvisibility=hidden (for gcc)
|
||||||
|
or
|
||||||
|
-xldscope=hidden (for sun cc)
|
||||||
|
to CFLAGS
|
||||||
|
|
||||||
|
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CJSON_CDECL __cdecl
|
||||||
|
#define CJSON_STDCALL __stdcall
|
||||||
|
|
||||||
|
/* export symbols by default, this is necessary for copy pasting the C and header file */
|
||||||
|
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
|
||||||
|
#define CJSON_EXPORT_SYMBOLS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CJSON_HIDE_SYMBOLS)
|
||||||
|
#define CJSON_PUBLIC(type) type CJSON_STDCALL
|
||||||
|
#elif defined(CJSON_EXPORT_SYMBOLS)
|
||||||
|
#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL
|
||||||
|
#elif defined(CJSON_IMPORT_SYMBOLS)
|
||||||
|
#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL
|
||||||
|
#endif
|
||||||
|
#else /* !__WINDOWS__ */
|
||||||
|
#define CJSON_CDECL
|
||||||
|
#define CJSON_STDCALL
|
||||||
|
|
||||||
|
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
|
||||||
|
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
|
||||||
|
#else
|
||||||
|
#define CJSON_PUBLIC(type) type
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* project version */
|
||||||
|
#define CJSON_VERSION_MAJOR 1
|
||||||
|
#define CJSON_VERSION_MINOR 7
|
||||||
|
#define CJSON_VERSION_PATCH 14
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/* cJSON Types: */
|
||||||
|
#define cJSON_Invalid (0)
|
||||||
|
#define cJSON_False (1 << 0)
|
||||||
|
#define cJSON_True (1 << 1)
|
||||||
|
#define cJSON_NULL (1 << 2)
|
||||||
|
#define cJSON_Number (1 << 3)
|
||||||
|
#define cJSON_String (1 << 4)
|
||||||
|
#define cJSON_Array (1 << 5)
|
||||||
|
#define cJSON_Object (1 << 6)
|
||||||
|
#define cJSON_Raw (1 << 7) /* raw json */
|
||||||
|
|
||||||
|
#define cJSON_IsReference 256
|
||||||
|
#define cJSON_StringIsConst 512
|
||||||
|
|
||||||
|
/* The cJSON structure: */
|
||||||
|
typedef struct cJSON
|
||||||
|
{
|
||||||
|
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
|
||||||
|
struct cJSON *next;
|
||||||
|
struct cJSON *prev;
|
||||||
|
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
|
||||||
|
struct cJSON *child;
|
||||||
|
|
||||||
|
/* The type of the item, as above. */
|
||||||
|
int type;
|
||||||
|
|
||||||
|
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
|
||||||
|
char *valuestring;
|
||||||
|
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
|
||||||
|
int valueint;
|
||||||
|
/* The item's number, if type==cJSON_Number */
|
||||||
|
double valuedouble;
|
||||||
|
|
||||||
|
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
|
||||||
|
char *string;
|
||||||
|
} cJSON;
|
||||||
|
|
||||||
|
typedef struct cJSON_Hooks
|
||||||
|
{
|
||||||
|
/* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
|
||||||
|
void *(CJSON_CDECL *malloc_fn)(size_t sz);
|
||||||
|
void (CJSON_CDECL *free_fn)(void *ptr);
|
||||||
|
} cJSON_Hooks;
|
||||||
|
|
||||||
|
typedef int cJSON_bool;
|
||||||
|
|
||||||
|
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
|
||||||
|
* This is to prevent stack overflows. */
|
||||||
|
#ifndef CJSON_NESTING_LIMIT
|
||||||
|
#define CJSON_NESTING_LIMIT 1000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* returns the version of cJSON as a string */
|
||||||
|
CJSON_PUBLIC(const char*) cJSON_Version(void);
|
||||||
|
|
||||||
|
/* Supply malloc, realloc and free functions to cJSON */
|
||||||
|
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
|
||||||
|
|
||||||
|
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
|
||||||
|
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length);
|
||||||
|
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
|
||||||
|
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated);
|
||||||
|
|
||||||
|
/* Render a cJSON entity to text for transfer/storage. */
|
||||||
|
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
|
||||||
|
/* Render a cJSON entity to text for transfer/storage without any formatting. */
|
||||||
|
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
|
||||||
|
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
|
||||||
|
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
|
||||||
|
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
|
||||||
|
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
|
||||||
|
/* Delete a cJSON entity and all subentities. */
|
||||||
|
CJSON_PUBLIC(void) cJSON_Delete(cJSON *item);
|
||||||
|
|
||||||
|
/* Returns the number of items in an array (or object). */
|
||||||
|
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
|
||||||
|
/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
|
||||||
|
/* Get item "string" from object. Case insensitive. */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
|
||||||
|
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
||||||
|
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
|
||||||
|
|
||||||
|
/* Check item type and return its value */
|
||||||
|
CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item);
|
||||||
|
|
||||||
|
/* These functions check the type of an item */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
|
||||||
|
|
||||||
|
/* These calls create a cJSON item of the appropriate type. */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
|
||||||
|
/* raw json */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
|
||||||
|
|
||||||
|
/* Create a string where valuestring references a string so
|
||||||
|
* it will not be freed by cJSON_Delete */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
|
||||||
|
/* Create an object/array that only references it's elements so
|
||||||
|
* they will not be freed by cJSON_Delete */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
|
||||||
|
|
||||||
|
/* These utilities create an Array of count items.
|
||||||
|
* The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count);
|
||||||
|
|
||||||
|
/* Append item to the specified array/object. */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
|
||||||
|
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
|
||||||
|
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
|
||||||
|
* writing to `item->string` */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
|
||||||
|
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
|
||||||
|
|
||||||
|
/* Remove/Detach items from Arrays/Objects. */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
|
||||||
|
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||||
|
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
|
||||||
|
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||||
|
|
||||||
|
/* Update array items. */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
|
||||||
|
|
||||||
|
/* Duplicate a cJSON item */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
|
||||||
|
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
|
||||||
|
* need to be released. With recurse!=0, it will duplicate any children connected to the item.
|
||||||
|
* The item->next and ->prev pointers are always zero on return from Duplicate. */
|
||||||
|
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
|
||||||
|
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
|
||||||
|
|
||||||
|
/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings.
|
||||||
|
* The input pointer json cannot point to a read-only address area, such as a string constant,
|
||||||
|
* but should point to a readable and writable adress area. */
|
||||||
|
CJSON_PUBLIC(void) cJSON_Minify(char *json);
|
||||||
|
|
||||||
|
/* Helper functions for creating and adding items to an object at the same time.
|
||||||
|
* They return the added item or NULL on failure. */
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
|
||||||
|
|
||||||
|
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
|
||||||
|
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
|
||||||
|
/* helper for the cJSON_SetNumberValue macro */
|
||||||
|
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
|
||||||
|
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
|
||||||
|
/* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */
|
||||||
|
CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring);
|
||||||
|
|
||||||
|
/* Macro for iterating over an array or object */
|
||||||
|
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
|
||||||
|
|
||||||
|
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
|
||||||
|
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
|
||||||
|
CJSON_PUBLIC(void) cJSON_free(void *object);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -1,18 +0,0 @@
|
|||||||
/*
|
|
||||||
* test.h
|
|
||||||
* Copyright (C) 2021 light <light@lightdeMBP>
|
|
||||||
*
|
|
||||||
* Distributed under terms of the MIT license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef TEST_H
|
|
||||||
#define TEST_H
|
|
||||||
|
|
||||||
|
|
||||||
#include<math.h>
|
|
||||||
|
|
||||||
double get_sqrt(double var1);
|
|
||||||
|
|
||||||
void updateMem(unsigned int *all, unsigned int *fre, float *useage);
|
|
||||||
|
|
||||||
#endif /* !TEST_H */
|
|
||||||
66
main.c
66
main.c
@ -1,36 +1,42 @@
|
|||||||
/*
|
#include "src/filter.h"
|
||||||
* main.c
|
#include "src/server.h"
|
||||||
* Copyright (C) 2021 light <light@lightdeMBP>
|
#include "src/ProcessInfo.h"
|
||||||
*
|
#include "src/SystemInfo.h"
|
||||||
* Distributed under terms of the MIT license.
|
#include <stdio.h>
|
||||||
*/
|
#include <sys/unistd.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#include<stdio.h>
|
#define DEBUG
|
||||||
#include"./include/test.h"
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#define MAX_LINE 1024
|
|
||||||
struct memGlobal {
|
|
||||||
unsigned int All;
|
|
||||||
float Useage;
|
|
||||||
unsigned int Free;
|
|
||||||
} memG;
|
|
||||||
|
|
||||||
struct cpuGlobal {
|
int main() {
|
||||||
float Useage;
|
int rc;
|
||||||
} cpuG;
|
pthread_t unix_domain_server;
|
||||||
|
|
||||||
struct process {
|
initProcList();
|
||||||
char Name[128];
|
|
||||||
unsigned id;
|
|
||||||
float cpu;
|
|
||||||
float mem;
|
|
||||||
} pList[1024];
|
|
||||||
|
|
||||||
int main()
|
//init
|
||||||
{
|
//get /data/data/dir
|
||||||
updateMem(&memG.All, &memG.Free, &memG.Useage);
|
//get whitelist
|
||||||
printf("mem: all %u free: %u usage: %f\n", memG.All, memG.Free, memG.Useage);
|
//init Proc_List
|
||||||
|
//init Global_Info
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
i++;
|
||||||
|
printf("\nloop:%d\n", i);
|
||||||
|
usleep(60000000 / UPDATE_FREQUENCY * 0.98);
|
||||||
|
//monitor Global_Info and decicde to kill some process
|
||||||
|
updateSystemInfo();
|
||||||
|
//monitor Proc_List
|
||||||
|
updateProcList();
|
||||||
|
}
|
||||||
|
|
||||||
|
//server
|
||||||
|
// rc = pthread_create(&unix_domain_server, NULL, (void *)&server, NULL);
|
||||||
|
// if (rc != 0) {
|
||||||
|
// perror("unix_domain_server thread fail");
|
||||||
|
// }
|
||||||
|
|
||||||
|
sleep(100);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
266
src/ProcessInfo.c
Normal file
266
src/ProcessInfo.c
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
//
|
||||||
|
// Created by Iain on 2021/7/17.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "ProcessInfo.h"
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define LOG
|
||||||
|
#define BUFFER_SIZE_PROC_STAT 1024
|
||||||
|
#define BUFFER_SIZE_PROC_STATUS 128
|
||||||
|
#define STAT_UTIME 13
|
||||||
|
#define STAT_STIME 14
|
||||||
|
#define STAT_VSZ 22
|
||||||
|
#define STAT_RSS 23
|
||||||
|
|
||||||
|
//Global Process Info Node List
|
||||||
|
list_t Proc_List;
|
||||||
|
|
||||||
|
void printProcInfo(Proc_Info *pProcInfo) {
|
||||||
|
printf("PID:%d,name:%s,point:%d\n", pProcInfo->pid, pProcInfo->name, pProcInfo->point);
|
||||||
|
int i;
|
||||||
|
printf("cpu:");
|
||||||
|
for (i = 0; i < UPDATE_FREQUENCY; i++) {
|
||||||
|
printf("s=%ld u=%ld,", pProcInfo->cpuInfo[i].stime, pProcInfo->cpuInfo[i].utime);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
printf("mem:");
|
||||||
|
for (i = 0; i < UPDATE_FREQUENCY; i++) {
|
||||||
|
printf("vsz=%ld rss=%ld,", pProcInfo->memInfo[i].vsz, pProcInfo->memInfo[i].rss);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Proc_Info_ *newProcInfo(unsigned int pid, char name[LIMIT_PROCESS_Name_Length]) {
|
||||||
|
struct Proc_Info_ *proc;
|
||||||
|
proc = (struct Proc_Info_ *) malloc(sizeof(struct Proc_Info_));
|
||||||
|
memset(proc, 0, sizeof(struct Proc_Info_));
|
||||||
|
proc->pid = pid;
|
||||||
|
strcpy(proc->name, name);
|
||||||
|
#if defined(LOG)
|
||||||
|
printf("newProcInfoNode-Create:");
|
||||||
|
printProcInfo(proc);
|
||||||
|
#endif
|
||||||
|
return proc;
|
||||||
|
}
|
||||||
|
|
||||||
|
//not found,return -1
|
||||||
|
//found,return id
|
||||||
|
int foundProcNode(unsigned int pid) {
|
||||||
|
list_node_t *node;
|
||||||
|
list_iterator_t *it = list_iterator_new(&Proc_List, LIST_HEAD);
|
||||||
|
|
||||||
|
while ((node = list_iterator_next(it))) {
|
||||||
|
struct Proc_Info_ *proc_node;
|
||||||
|
proc_node = (struct Proc_Info_ *) node->val;
|
||||||
|
if (proc_node->pid == pid) {
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int setProcNode(unsigned int pid) {
|
||||||
|
//found PID name
|
||||||
|
char buf[BUFFER_SIZE_PROC_STATUS] = {0};
|
||||||
|
char PID_name[LIMIT_PROCESS_Name_Length] = {0};
|
||||||
|
char file_path[64] = {0};
|
||||||
|
sprintf(file_path, "/proc/%d/status", pid);
|
||||||
|
FILE *fp;
|
||||||
|
if ((fp = fopen(file_path, "r")) == NULL) {
|
||||||
|
perror("fail to read /proc/PID/status");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fgets(buf, BUFFER_SIZE_PROC_STATUS, fp);
|
||||||
|
#if defined(LOG)
|
||||||
|
printf("/proc/%d/status: %s", pid, buf);
|
||||||
|
#endif
|
||||||
|
sscanf(buf, "Name: %s", PID_name);
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
//compare PID name with whitelist and regex
|
||||||
|
|
||||||
|
//check PID in ProcList
|
||||||
|
if (foundProcNode(pid) == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//set Proc Info
|
||||||
|
struct Proc_Info_ *proc = newProcInfo(pid, PID_name);
|
||||||
|
list_rpush(&Proc_List, (void *) list_node_new(proc));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int monitorProcDirChange() {
|
||||||
|
struct dirent **namelist;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
n = scandir("/proc", &namelist, 0, alphasort);
|
||||||
|
if (n < 0)
|
||||||
|
perror("scandir /proc");
|
||||||
|
else {
|
||||||
|
while (n--) {
|
||||||
|
//printf("%s\n", namelist[n]->d_name);
|
||||||
|
free(namelist[n]);
|
||||||
|
}
|
||||||
|
free(namelist);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//unsigned int *getProcess() {
|
||||||
|
// DIR *dir;
|
||||||
|
// struct dirent *entry;
|
||||||
|
// unsigned int id = 0;
|
||||||
|
// static unsigned int ids[LIMIT_PROCESS_NUMBER] = {0};
|
||||||
|
//
|
||||||
|
// if ((dir = opendir("/proc/")) == NULL) {
|
||||||
|
// perror("cannot access /proc directory");
|
||||||
|
// exit(-1);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// int index = 0;
|
||||||
|
// int i;
|
||||||
|
// unsigned int temp;
|
||||||
|
// while ((direntp = readdir(dirp)) != NULL) {
|
||||||
|
// id = atoi(direntp->d_name);
|
||||||
|
// if (id > 0) {
|
||||||
|
// for (i = 0; i < index; i++) {
|
||||||
|
// if (ids[i] > id) {
|
||||||
|
// temp = id;
|
||||||
|
// id = ids[i];
|
||||||
|
// ids[i] = temp;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// ids[index] = id;
|
||||||
|
// index++;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// closedir(dirp);
|
||||||
|
// return &ids[0];
|
||||||
|
//}
|
||||||
|
|
||||||
|
//update process cpu time and mem info by /proc/PID/stat
|
||||||
|
//example: 1 (systemd) S 0 1 1 0 -1 4194560 16465 675919 50 519 44 100 678 258 20 0 1 0 13 44421120 1253 18446744073709551615 94869015482368 94869016924823 140724538057904 0 0 0 671173123 4096 1260 1 0 0 17 0 0 0 14 0 0 94869019025816 94869019170360 94869036843008 140724538064796 140724538064863 140724538064863 140724538064863 0
|
||||||
|
/* pid 进程ID 0
|
||||||
|
* comm task_struct结构体的进程名
|
||||||
|
* state 进程状态, 此处为S
|
||||||
|
* ppid 父进程ID (父进程是指通过fork方式,通过clone并非父进程)
|
||||||
|
* pgrp 进程组ID
|
||||||
|
* session 进程会话组ID
|
||||||
|
* tty_nr 当前进程的tty终点设备号
|
||||||
|
* tpgid 控制进程终端的前台进程号
|
||||||
|
* flags 进程标识位,定义在include/linux/sched.h中的PF
|
||||||
|
* minflt 次要缺页中断的次数,即无需从磁盘加载内存页. 比如COW和匿名页
|
||||||
|
* cminfl 当前进程等待子进程的minflt
|
||||||
|
* majflt 主要缺页中断的次数,需要从磁盘加载内存页. 比如map文件
|
||||||
|
* majflt 当前进程等待子进程的majflt
|
||||||
|
* utime 该进程处于用户态的时间,单位jiffies 13
|
||||||
|
* stime 该进程处于内核态的时间,单位jiffies 14
|
||||||
|
* cutime 当前进程等待子进程的utime
|
||||||
|
* cstime 当前进程等待子进程的utime
|
||||||
|
* priority 进程优先级, 此次等于10.
|
||||||
|
* nice nice值,取值范围[19, -20],此处等于-10
|
||||||
|
* num_threads 线程个数, 此处等于221
|
||||||
|
* itrealvalue 该字段已废弃,恒等于0
|
||||||
|
* starttime 自系统启动后的进程创建时间,单位jiffies
|
||||||
|
* vsize 进程的虚拟内存大小,单位为bytes 22
|
||||||
|
* rss 进程独占内存,单位pages,4K 23
|
||||||
|
* rsslim rss大小上限
|
||||||
|
* start_code 该任务在虚拟地址空间的代码段的起始地址
|
||||||
|
* end_code 该任务在虚拟地址空间的代码段的结束地址。
|
||||||
|
* start_stack 该任务在虚拟地址空间的栈的结束地址。
|
||||||
|
* kstkesp esp(32 位堆栈指针) 的当前值, 与在进程的内核堆栈页得到的一致。
|
||||||
|
* kstkeip 指向将要执行的指令的指针, EIP(32 位指令指针)的当前值。
|
||||||
|
* pendingsig 待处理信号的位图,记录发送给进程的普通信号。
|
||||||
|
* block_sig 阻塞信号的位图。
|
||||||
|
* sigign 忽略的信号的位图。
|
||||||
|
* sigcatch 被俘获的信号的位图。
|
||||||
|
* wchan 如果该进程是睡眠状态,该值给出调度的调用点。
|
||||||
|
* nswap 被swapped的页数,当前没用。
|
||||||
|
* cnswap 所有子进程被swapped 的页数的和,当前没用。
|
||||||
|
* exit_signal 该进程结束时,向父进程所发送的信号。
|
||||||
|
* task_cpu 运行在哪个 CPU 上。
|
||||||
|
* task_rt_priority 实时进程的相对优先级别。
|
||||||
|
* task_policy 进程的调度策略,0=非实时进程,1=FIFO实时进程;2=RR实时进程
|
||||||
|
* blio_ticks 等待阻塞IO的时间
|
||||||
|
* gtime guest time of the task in jiffies
|
||||||
|
* cgtime guest time of the task children in jiffies
|
||||||
|
* start_data address above which program data+bss is placed
|
||||||
|
* end_data address below which program data+bss is placed
|
||||||
|
* start_brk address above which program heap can be expanded with br
|
||||||
|
*/
|
||||||
|
int updateProcInfo(Proc_Info *proc) {
|
||||||
|
char file_path[64] = {0};
|
||||||
|
char buffer[BUFFER_SIZE_PROC_STAT] = {0};
|
||||||
|
sprintf(file_path, "/proc/%d/stat", proc->pid);
|
||||||
|
FILE *fd = NULL;
|
||||||
|
fd = fopen(file_path, "r");
|
||||||
|
if (fd == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
unsigned long utime, stime, vsz, rss;
|
||||||
|
fgets(buffer, BUFFER_SIZE_PROC_STAT, fd);
|
||||||
|
// 14 utime 15 stime 23 24 vsz rss
|
||||||
|
// 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
||||||
|
sscanf(buffer, "%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %lu %lu %*s %*s %*s %*s %*s %*s %*s %*s %lu %lu ",
|
||||||
|
&utime, &stime, &vsz, &rss);
|
||||||
|
#if defined(LOG)
|
||||||
|
printf("ProcInfo:PID=%d,Name=%s,utime=%ld,stime=%ld,vsz=%ld,rss=%ld\n", proc->pid, proc->name, utime, stime, vsz,
|
||||||
|
rss);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
proc->point++;
|
||||||
|
proc->point %= UPDATE_FREQUENCY;
|
||||||
|
proc->cpuInfo[proc->point].utime = utime;
|
||||||
|
proc->cpuInfo[proc->point].stime = stime;
|
||||||
|
proc->memInfo[proc->point].vsz = vsz;
|
||||||
|
proc->memInfo[proc->point].rss = rss * 4 * 1024;
|
||||||
|
fclose(fd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void initProcList() {
|
||||||
|
list_t *pProc_List = list_new();
|
||||||
|
Proc_List = *pProc_List;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateProcList() {
|
||||||
|
#if defined(LOG)
|
||||||
|
printf("/****** Proc Info ******/\n");
|
||||||
|
monitorProcDirChange();
|
||||||
|
|
||||||
|
setProcNode(1);
|
||||||
|
setProcNode(150361);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char file_path[64] = {0};
|
||||||
|
struct Proc_Info_ *proc_node;
|
||||||
|
list_node_t *node;
|
||||||
|
list_iterator_t *it = list_iterator_new(&Proc_List, LIST_HEAD);
|
||||||
|
|
||||||
|
while ((node = list_iterator_next(it))) {
|
||||||
|
proc_node = (struct Proc_Info_ *) node->val;
|
||||||
|
printProcInfo(proc_node);
|
||||||
|
if (updateProcInfo(proc_node) == -1) {
|
||||||
|
//check path exist
|
||||||
|
sprintf(file_path, "/proc/%d", proc_node->pid);
|
||||||
|
if (access(file_path, F_OK)) {
|
||||||
|
list_node_t *node_to_delete = node;
|
||||||
|
printf("remove proc list node due to cannot access /proc/PID");
|
||||||
|
node = list_iterator_next(it);
|
||||||
|
list_remove(&Proc_List, node_to_delete);
|
||||||
|
free(proc_node);
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
44
src/ProcessInfo.h
Normal file
44
src/ProcessInfo.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
//
|
||||||
|
// Created by Iain on 2021/7/17.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef ATOP_PROCESSINFO_H
|
||||||
|
#define ATOP_PROCESSINFO_H
|
||||||
|
|
||||||
|
#define UPDATE_FREQUENCY 60 //update times per minute
|
||||||
|
#define LIMIT_PROCESS_NUMBER 64 //max monitor 64 process
|
||||||
|
#define LIMIT_PROCESS_Name_Length 128
|
||||||
|
|
||||||
|
#include "list.h"
|
||||||
|
|
||||||
|
//proc/PID/stat
|
||||||
|
typedef struct Proc_CPU_Time_ {
|
||||||
|
unsigned long utime; //user time
|
||||||
|
unsigned long stime; //kernel time
|
||||||
|
} Proc_CPU_Time;
|
||||||
|
|
||||||
|
//proc/PID/stat
|
||||||
|
typedef struct Proc_Mem_ {
|
||||||
|
unsigned long vsz; //Virtual Memory Size, includes all memory that the process can access
|
||||||
|
unsigned long rss; //Resident Set Size
|
||||||
|
} Proc_Mem;
|
||||||
|
|
||||||
|
typedef struct Proc_Info_ {
|
||||||
|
unsigned int pid;
|
||||||
|
char name[LIMIT_PROCESS_Name_Length];
|
||||||
|
int point; //[0,UPDATE_FREQUENCY-1)
|
||||||
|
Proc_CPU_Time cpuInfo[UPDATE_FREQUENCY];
|
||||||
|
Proc_Mem memInfo[UPDATE_FREQUENCY];
|
||||||
|
} Proc_Info;
|
||||||
|
|
||||||
|
//kill this process
|
||||||
|
void findProcListByMem();
|
||||||
|
|
||||||
|
//kill this process
|
||||||
|
void findProcListByCPU();
|
||||||
|
|
||||||
|
void updateProcList();
|
||||||
|
|
||||||
|
void initProcList();
|
||||||
|
|
||||||
|
#endif //ATOP_PROCESSINFO_H
|
||||||
98
src/SystemInfo.c
Normal file
98
src/SystemInfo.c
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
//
|
||||||
|
// Created by Iain on 2021/7/17.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "SystemInfo.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define LOG
|
||||||
|
#define BUFFER_SIZE_STATINFO 256
|
||||||
|
#define BUFFER_SIZE_MEMINFO 128
|
||||||
|
#define SYSTEM_CPU_INFO_PATH "/proc/stat"
|
||||||
|
#define SYSTEM_MEM_INFO_PATH "/proc/meminfo"
|
||||||
|
|
||||||
|
extern Sys_CPU_Time Sys_CPU_Time_Info;
|
||||||
|
extern Sys_Mem Sys_Mem_Info;
|
||||||
|
|
||||||
|
void updateSystemCPU(Sys_CPU_Time *cpuInfo) {
|
||||||
|
char buf[BUFFER_SIZE_STATINFO]; /*缓冲区*/
|
||||||
|
FILE *fp; /*文件指针*/
|
||||||
|
if ((fp = fopen(SYSTEM_CPU_INFO_PATH, "r")) == NULL) {
|
||||||
|
perror("fail to read /proc/stat");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fgets(buf, BUFFER_SIZE_STATINFO, fp);
|
||||||
|
#if defined(LOG)
|
||||||
|
printf("/proc/stat:%s", buf);
|
||||||
|
#endif
|
||||||
|
unsigned long cpu_user, cpu_nice, cpu_sys, cpu_idle;
|
||||||
|
sscanf(buf, "cpu %ld %ld %ld %ld", &cpu_user, &cpu_nice, &cpu_sys, &cpu_idle);
|
||||||
|
if (cpuInfo->Total_Cpu_Time.user == cpu_user && cpuInfo->Total_Cpu_Time.idle == cpu_idle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpuInfo->Unit_Cpu_Time.user = cpu_user - cpuInfo->Total_Cpu_Time.user;
|
||||||
|
cpuInfo->Unit_Cpu_Time.nice = cpu_nice - cpuInfo->Total_Cpu_Time.nice;
|
||||||
|
cpuInfo->Unit_Cpu_Time.system = cpu_sys - cpuInfo->Total_Cpu_Time.system;
|
||||||
|
cpuInfo->Unit_Cpu_Time.idle = cpu_idle - cpuInfo->Total_Cpu_Time.idle;
|
||||||
|
cpuInfo->Total_Cpu_Time.user = cpu_user;
|
||||||
|
cpuInfo->Total_Cpu_Time.nice = cpu_nice;
|
||||||
|
cpuInfo->Total_Cpu_Time.system = cpu_sys;
|
||||||
|
cpuInfo->Total_Cpu_Time.idle = cpu_idle;
|
||||||
|
int total_cpu_time;
|
||||||
|
total_cpu_time = cpuInfo->Unit_Cpu_Time.user + cpuInfo->Unit_Cpu_Time.nice + cpuInfo->Unit_Cpu_Time.system +
|
||||||
|
cpuInfo->Unit_Cpu_Time.idle;
|
||||||
|
cpuInfo->Usage = 1 - (float) cpuInfo->Unit_Cpu_Time.idle / total_cpu_time;
|
||||||
|
#if defined(LOG)
|
||||||
|
printf("SystemCPU:Usage=%f,User=%ld,Nice=%ld,Sys=%ld,Idle=%ld\n", cpuInfo->Usage, cpuInfo->Total_Cpu_Time.user,
|
||||||
|
cpuInfo->Total_Cpu_Time.nice, cpuInfo->Total_Cpu_Time.system, cpuInfo->Total_Cpu_Time.idle);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateSystemMem(Sys_Mem *memInfo) {
|
||||||
|
char buf[BUFFER_SIZE_MEMINFO]; /*缓冲区*/
|
||||||
|
FILE *fp; /*文件指针*/
|
||||||
|
|
||||||
|
if ((fp = fopen(SYSTEM_MEM_INFO_PATH, "r")) == NULL) {
|
||||||
|
perror("fail to read /proc/meminfo");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fgets(buf, BUFFER_SIZE_MEMINFO, fp);
|
||||||
|
sscanf(buf, "MemTotal: %lu kB", &memInfo->Total);
|
||||||
|
#if defined(LOG)
|
||||||
|
printf("/proc/stat: %s", buf);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fgets(buf, BUFFER_SIZE_MEMINFO, fp);
|
||||||
|
sscanf(buf, "MemFree: %lu kB", &memInfo->Free);
|
||||||
|
#if defined(LOG)
|
||||||
|
printf("/proc/stat: %s", buf);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fgets(buf, BUFFER_SIZE_MEMINFO, fp);
|
||||||
|
sscanf(buf, "MemAvailable: %lu kB", &memInfo->Available);
|
||||||
|
memInfo->Usage = 1 - (float) memInfo->Available / memInfo->Total;
|
||||||
|
#if defined(LOG)
|
||||||
|
printf("/proc/stat: %s", buf);
|
||||||
|
printf("SystemMem:Usage=%f,Total=%ld,Free=%ld,Available=%ld\n", memInfo->Usage, memInfo->Total, memInfo->Free,
|
||||||
|
memInfo->Available);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateSystemInfo() {
|
||||||
|
#if defined(LOG)
|
||||||
|
printf("/****** System Info ******/\n");
|
||||||
|
#endif
|
||||||
|
updateSystemCPU(&Sys_CPU_Time_Info);
|
||||||
|
updateSystemMem(&Sys_Mem_Info);
|
||||||
|
}
|
||||||
32
src/SystemInfo.h
Normal file
32
src/SystemInfo.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
//
|
||||||
|
// Created by Iain on 2021/7/17.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef ATOP_SYSTEMINFO_H
|
||||||
|
#define ATOP_SYSTEMINFO_H
|
||||||
|
|
||||||
|
typedef struct CPU_Time_ {
|
||||||
|
unsigned long user;
|
||||||
|
unsigned long nice;
|
||||||
|
unsigned long system;
|
||||||
|
unsigned long idle;
|
||||||
|
} CPU_Time;
|
||||||
|
|
||||||
|
typedef struct Sys_CPU_Time_ {
|
||||||
|
float Usage;
|
||||||
|
CPU_Time Unit_Cpu_Time;
|
||||||
|
CPU_Time Total_Cpu_Time;
|
||||||
|
} Sys_CPU_Time;
|
||||||
|
|
||||||
|
typedef struct Sys_Mem_ {
|
||||||
|
float Usage;
|
||||||
|
unsigned long Total;
|
||||||
|
unsigned long Free;
|
||||||
|
unsigned long Available;
|
||||||
|
} Sys_Mem;
|
||||||
|
|
||||||
|
void updateSystemInfo();
|
||||||
|
|
||||||
|
Sys_CPU_Time Sys_CPU_Time_Info;
|
||||||
|
Sys_Mem Sys_Mem_Info;
|
||||||
|
#endif //ATOP_SYSTEMINFO_H
|
||||||
92
src/filter.c
Normal file
92
src/filter.c
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
//
|
||||||
|
// Created by Iain on 2021/7/17.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "filter.h"
|
||||||
|
#include "ProcessInfo.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dirent.h> // read dir
|
||||||
|
#include <regex.h> // regular expression
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 结构体dirent的属性d_name里存储了app的名字
|
||||||
|
* 由于c语言没有字符串数组,而且不知道师兄想怎么处理app名,所以我直接存储的数组元素类型是dirent*
|
||||||
|
* 通过app_list[index]->d_name就可以获取文件名
|
||||||
|
*/
|
||||||
|
#define AOSP_APP_Path "/data/data"
|
||||||
|
#define White_List_Path "atop_whitelist.txt"
|
||||||
|
|
||||||
|
//static char Regex_Pattern[2][64] = {{"com.android.*"},
|
||||||
|
// {"com.google.*"}};
|
||||||
|
//static regex_t Regex_Compare[2]; //the Regex_Compare array size must equal to Regex_Rule array size
|
||||||
|
//
|
||||||
|
//int filterByRegex(char *buf) {
|
||||||
|
// // variable declaration for regular expression
|
||||||
|
// err_code = regexec(®, buf, 0, NULL, 0)
|
||||||
|
// return 0;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//int filterByWhiteList(char *buf) {
|
||||||
|
// return 0;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//int getAppName() {
|
||||||
|
// DIR *dir = NULL;
|
||||||
|
// int app_index = 0;
|
||||||
|
// struct dirent *read_result;
|
||||||
|
// struct dirent *app_list[LIMIT_PROCESS_NUMBER];
|
||||||
|
//
|
||||||
|
// if ((dir = opendir(AOSP_APP_Path)) == NULL) {
|
||||||
|
// printf("open dir failed\n");
|
||||||
|
// return -1;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// while ((read_result = readdir(dir)) != NULL) {
|
||||||
|
// // filter, ignore current dir + parent dir
|
||||||
|
// if (filterByRegex(read_result->d_name) == 0 ||
|
||||||
|
// filterByWhiteList(read_result->d_name) == 0 ||
|
||||||
|
// strcmp(read_result->d_name, ".") == 0 ||
|
||||||
|
// strcmp(read_result->d_name, "..") == 0)
|
||||||
|
// continue;
|
||||||
|
// // d_type = 4 means it's a directory
|
||||||
|
// if (read_result->d_type == 4) {
|
||||||
|
// app_list[app_index] = read_result;
|
||||||
|
// app_index++;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // print apps' names
|
||||||
|
// printf("we have %d apps\n", app_index);
|
||||||
|
// for (int i = 0; i < app_index; i++) {
|
||||||
|
// printf("app %d : %s\n", i, app_list[i]->d_name);
|
||||||
|
// }
|
||||||
|
// return 0;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//int init_regex() {
|
||||||
|
// int rule_num = sizeof(Regex_Pattern);
|
||||||
|
// if (sizeof(Regex_Compare) != rule_num) {
|
||||||
|
// return -1;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// int id;
|
||||||
|
// int err_code;
|
||||||
|
// int compression_flags = REG_EXTENDED | REG_ICASE;
|
||||||
|
//
|
||||||
|
// for (id = 0; id < rule_num; id++)
|
||||||
|
// if ((err_code = regcomp(&Regex_Compare[id], Regex_Pattern[id], compression_flags)) != 0) {
|
||||||
|
// perror("set regular expression failed:\n");
|
||||||
|
// return -1;
|
||||||
|
// }
|
||||||
|
// return 0;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//int init() {
|
||||||
|
// if (init_regex() == -1) {
|
||||||
|
// return -1;
|
||||||
|
// }
|
||||||
|
// return 0;
|
||||||
|
//}
|
||||||
|
|
||||||
11
src/filter.h
Normal file
11
src/filter.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
//
|
||||||
|
// Created by Iain on 2021/7/17.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef ATOP_FILTER_H
|
||||||
|
#define ATOP_FILTER_H
|
||||||
|
|
||||||
|
int init();
|
||||||
|
|
||||||
|
|
||||||
|
#endif //ATOP_FILTER_H
|
||||||
182
src/list.c
Normal file
182
src/list.c
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
|
||||||
|
#include "list.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate a new list_t. NULL on failure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
list_t *list_new(void) {
|
||||||
|
list_t *self;
|
||||||
|
if (!(self = LIST_MALLOC(sizeof(list_t))))
|
||||||
|
return NULL;
|
||||||
|
self->head = NULL;
|
||||||
|
self->tail = NULL;
|
||||||
|
self->free = NULL;
|
||||||
|
self->match = NULL;
|
||||||
|
self->len = 0;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free the list.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void list_destroy(list_t *self) {
|
||||||
|
unsigned int len = self->len;
|
||||||
|
list_node_t *next;
|
||||||
|
list_node_t *curr = self->head;
|
||||||
|
|
||||||
|
while (len--) {
|
||||||
|
next = curr->next;
|
||||||
|
if (self->free) self->free(curr->val);
|
||||||
|
LIST_FREE(curr);
|
||||||
|
curr = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
LIST_FREE(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Append the given node to the list
|
||||||
|
* and return the node, NULL on failure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
list_node_t *list_rpush(list_t *self, list_node_t *node) {
|
||||||
|
if (!node) return NULL;
|
||||||
|
if (self->len) {
|
||||||
|
node->prev = self->tail;
|
||||||
|
node->next = NULL;
|
||||||
|
self->tail->next = node;
|
||||||
|
self->tail = node;
|
||||||
|
} else {
|
||||||
|
self->head = self->tail = node;
|
||||||
|
node->prev = node->next = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
++self->len;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return / detach the last node in the list, or NULL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
list_node_t *list_rpop(list_t *self) {
|
||||||
|
if (!self->len) return NULL;
|
||||||
|
|
||||||
|
list_node_t *node = self->tail;
|
||||||
|
|
||||||
|
if (--self->len) {
|
||||||
|
(self->tail = node->prev)->next = NULL;
|
||||||
|
} else {
|
||||||
|
self->tail = self->head = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
node->next = node->prev = NULL;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return / detach the first node in the list, or NULL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
list_node_t *list_lpop(list_t *self) {
|
||||||
|
if (!self->len) return NULL;
|
||||||
|
|
||||||
|
list_node_t *node = self->head;
|
||||||
|
|
||||||
|
if (--self->len) {
|
||||||
|
(self->head = node->next)->prev = NULL;
|
||||||
|
} else {
|
||||||
|
self->head = self->tail = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
node->next = node->prev = NULL;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prepend the given node to the list
|
||||||
|
* and return the node, NULL on failure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
list_node_t *list_lpush(list_t *self, list_node_t *node) {
|
||||||
|
if (!node) return NULL;
|
||||||
|
|
||||||
|
if (self->len) {
|
||||||
|
node->next = self->head;
|
||||||
|
node->prev = NULL;
|
||||||
|
self->head->prev = node;
|
||||||
|
self->head = node;
|
||||||
|
} else {
|
||||||
|
self->head = self->tail = node;
|
||||||
|
node->prev = node->next = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
++self->len;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the node associated to val or NULL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
list_node_t *list_find(list_t *self, void *val) {
|
||||||
|
list_iterator_t *it = list_iterator_new(self, LIST_HEAD);
|
||||||
|
list_node_t *node;
|
||||||
|
|
||||||
|
while ((node = list_iterator_next(it))) {
|
||||||
|
if (self->match) {
|
||||||
|
if (self->match(val, node->val)) {
|
||||||
|
list_iterator_destroy(it);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (val == node->val) {
|
||||||
|
list_iterator_destroy(it);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list_iterator_destroy(it);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the node at the given index or NULL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
list_node_t *list_at(list_t *self, int index) {
|
||||||
|
list_direction_t direction = LIST_HEAD;
|
||||||
|
|
||||||
|
if (index < 0) {
|
||||||
|
direction = LIST_TAIL;
|
||||||
|
index = ~index;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((unsigned) index < self->len) {
|
||||||
|
list_iterator_t *it = list_iterator_new(self, direction);
|
||||||
|
list_node_t *node = list_iterator_next(it);
|
||||||
|
while (index--) node = list_iterator_next(it);
|
||||||
|
list_iterator_destroy(it);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove the given node from the list, freeing it and it's value.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void list_remove(list_t *self, list_node_t *node) {
|
||||||
|
node->prev ? (node->prev->next = node->next) : (self->head = node->next);
|
||||||
|
|
||||||
|
node->next ? (node->next->prev = node->prev) : (self->tail = node->prev);
|
||||||
|
|
||||||
|
if (self->free) self->free(node->val);
|
||||||
|
|
||||||
|
LIST_FREE(node);
|
||||||
|
--self->len;
|
||||||
|
}
|
||||||
130
src/list.h
Normal file
130
src/list.h
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
|
||||||
|
//
|
||||||
|
// list.h
|
||||||
|
//
|
||||||
|
// Copyright (c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __CLIBS_LIST_H__
|
||||||
|
#define __CLIBS_LIST_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
// Library version
|
||||||
|
|
||||||
|
#define LIST_VERSION "0.2.0"
|
||||||
|
|
||||||
|
// Memory management macros
|
||||||
|
#ifdef LIST_CONFIG_H
|
||||||
|
#define _STR(x) #x
|
||||||
|
#define STR(x) _STR(x)
|
||||||
|
#include STR(LIST_CONFIG_H)
|
||||||
|
#undef _STR
|
||||||
|
#undef STR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LIST_MALLOC
|
||||||
|
#define LIST_MALLOC malloc
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LIST_FREE
|
||||||
|
#define LIST_FREE free
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* list_t iterator direction.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
LIST_HEAD
|
||||||
|
, LIST_TAIL
|
||||||
|
} list_direction_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* list_t node struct.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct list_node {
|
||||||
|
struct list_node *prev;
|
||||||
|
struct list_node *next;
|
||||||
|
void *val;
|
||||||
|
} list_node_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* list_t struct.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
list_node_t *head;
|
||||||
|
list_node_t *tail;
|
||||||
|
unsigned int len;
|
||||||
|
void (*free)(void *val);
|
||||||
|
int (*match)(void *a, void *b);
|
||||||
|
} list_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* list_t iterator struct.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
list_node_t *next;
|
||||||
|
list_direction_t direction;
|
||||||
|
} list_iterator_t;
|
||||||
|
|
||||||
|
// Node prototypes.
|
||||||
|
|
||||||
|
list_node_t *
|
||||||
|
list_node_new(void *val);
|
||||||
|
|
||||||
|
// list_t prototypes.
|
||||||
|
|
||||||
|
list_t *
|
||||||
|
list_new(void);
|
||||||
|
|
||||||
|
list_node_t *
|
||||||
|
list_rpush(list_t *self, list_node_t *node);
|
||||||
|
|
||||||
|
list_node_t *
|
||||||
|
list_lpush(list_t *self, list_node_t *node);
|
||||||
|
|
||||||
|
list_node_t *
|
||||||
|
list_find(list_t *self, void *val);
|
||||||
|
|
||||||
|
list_node_t *
|
||||||
|
list_at(list_t *self, int index);
|
||||||
|
|
||||||
|
list_node_t *
|
||||||
|
list_rpop(list_t *self);
|
||||||
|
|
||||||
|
list_node_t *
|
||||||
|
list_lpop(list_t *self);
|
||||||
|
|
||||||
|
void
|
||||||
|
list_remove(list_t *self, list_node_t *node);
|
||||||
|
|
||||||
|
void
|
||||||
|
list_destroy(list_t *self);
|
||||||
|
|
||||||
|
// list_t iterator prototypes.
|
||||||
|
|
||||||
|
list_iterator_t *
|
||||||
|
list_iterator_new(list_t *list, list_direction_t direction);
|
||||||
|
|
||||||
|
list_iterator_t *
|
||||||
|
list_iterator_new_from_node(list_node_t *node, list_direction_t direction);
|
||||||
|
|
||||||
|
list_node_t *
|
||||||
|
list_iterator_next(list_iterator_t *self);
|
||||||
|
|
||||||
|
void
|
||||||
|
list_iterator_destroy(list_iterator_t *self);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __CLIBS_LIST_H__ */
|
||||||
61
src/list_iterator.c
Normal file
61
src/list_iterator.c
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
|
||||||
|
//
|
||||||
|
// iterator.c
|
||||||
|
//
|
||||||
|
// Copyright (c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "list.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate a new list_iterator_t. NULL on failure.
|
||||||
|
* Accepts a direction, which may be LIST_HEAD or LIST_TAIL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
list_iterator_t *
|
||||||
|
list_iterator_new(list_t *list, list_direction_t direction) {
|
||||||
|
list_node_t *node = direction == LIST_HEAD
|
||||||
|
? list->head
|
||||||
|
: list->tail;
|
||||||
|
return list_iterator_new_from_node(node, direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate a new list_iterator_t with the given start
|
||||||
|
* node. NULL on failure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
list_iterator_t *
|
||||||
|
list_iterator_new_from_node(list_node_t *node, list_direction_t direction) {
|
||||||
|
list_iterator_t *self;
|
||||||
|
if (!(self = LIST_MALLOC(sizeof(list_iterator_t))))
|
||||||
|
return NULL;
|
||||||
|
self->next = node;
|
||||||
|
self->direction = direction;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the next list_node_t or NULL when no more
|
||||||
|
* nodes remain in the list.
|
||||||
|
*/
|
||||||
|
|
||||||
|
list_node_t *list_iterator_next(list_iterator_t *self) {
|
||||||
|
list_node_t *curr = self->next;
|
||||||
|
if (curr) {
|
||||||
|
self->next = self->direction == LIST_HEAD
|
||||||
|
? curr->next
|
||||||
|
: curr->prev;
|
||||||
|
}
|
||||||
|
return curr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free the list iterator.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
list_iterator_destroy(list_iterator_t *self) {
|
||||||
|
LIST_FREE(self);
|
||||||
|
self = NULL;
|
||||||
|
}
|
||||||
23
src/list_node.c
Normal file
23
src/list_node.c
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
//
|
||||||
|
// node.c
|
||||||
|
//
|
||||||
|
// Copyright (c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "list.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocates a new list_node_t. NULL on failure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
list_node_t *
|
||||||
|
list_node_new(void *val) {
|
||||||
|
list_node_t *self;
|
||||||
|
if (!(self = LIST_MALLOC(sizeof(list_node_t))))
|
||||||
|
return NULL;
|
||||||
|
self->prev = NULL;
|
||||||
|
self->next = NULL;
|
||||||
|
self->val = val;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
97
src/server.c
Normal file
97
src/server.c
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
//
|
||||||
|
// Created by Iain on 2021/7/18.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "server.h"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
|
||||||
|
//unix socket server
|
||||||
|
#define SOCK_PATH "/var/atop.server"
|
||||||
|
#define SOCK_LIMIT 5
|
||||||
|
#define DATA "Hello from server"
|
||||||
|
|
||||||
|
int server() {
|
||||||
|
int server_sock, client_sock, len, rc;
|
||||||
|
int bytes_rec = 0;
|
||||||
|
struct sockaddr_un server_sockaddr;
|
||||||
|
struct sockaddr_un client_sockaddr;
|
||||||
|
char buf[256];
|
||||||
|
memset(&server_sockaddr, 0, sizeof(struct sockaddr_un));
|
||||||
|
memset(&client_sockaddr, 0, sizeof(struct sockaddr_un));
|
||||||
|
memset(buf, 0, 256);
|
||||||
|
|
||||||
|
server_sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
if (server_sock == -1) {
|
||||||
|
perror("ERROR:Unix Domain Socket Open");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
server_sockaddr.sun_family = AF_UNIX;
|
||||||
|
strcpy(server_sockaddr.sun_path, SOCK_PATH);
|
||||||
|
len = sizeof(server_sockaddr);
|
||||||
|
|
||||||
|
unlink(SOCK_PATH);
|
||||||
|
rc = bind(server_sock, (struct sockaddr *) &server_sockaddr, len);
|
||||||
|
if (rc == -1) {
|
||||||
|
perror("ERROR:Unix Domain Socket Bind");
|
||||||
|
close(server_sock);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = listen(server_sock, SOCK_LIMIT);
|
||||||
|
if (rc == -1) {
|
||||||
|
perror("ERROR:Unix Domain Socket Listen");
|
||||||
|
close(server_sock);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
printf("socket listening...\n");
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
client_sock = accept(server_sock, (struct sockaddr *) &client_sockaddr, &len);
|
||||||
|
if (client_sock == -1) {
|
||||||
|
perror("ERROR:Unix Domain Socket Accept");
|
||||||
|
close(server_sock);
|
||||||
|
close(client_sock);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
len = sizeof(client_sockaddr);
|
||||||
|
rc = getpeername(client_sock, (struct sockaddr *) &client_sockaddr, &len);
|
||||||
|
if (rc == -1) {
|
||||||
|
close(server_sock);
|
||||||
|
close(client_sock);
|
||||||
|
exit(1);
|
||||||
|
} else {
|
||||||
|
printf("Client socket filepath: %s\n", client_sockaddr.sun_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("waiting to read...\n");
|
||||||
|
bytes_rec = recv(client_sock, buf, sizeof(buf), 0);
|
||||||
|
if (bytes_rec == -1) {
|
||||||
|
perror("ERROR:Unix Domain Socket Recv");
|
||||||
|
close(server_sock);
|
||||||
|
close(client_sock);
|
||||||
|
exit(1);
|
||||||
|
} else {
|
||||||
|
printf("DATA RECEIVED = %s\n", buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(buf, 0, 256);
|
||||||
|
strcpy(buf, DATA);
|
||||||
|
printf("Sending data...\n");
|
||||||
|
rc = send(client_sock, buf, strlen(buf), 0);
|
||||||
|
if (rc == -1) {
|
||||||
|
perror("ERROR:Unix Domain Socket Send");
|
||||||
|
close(server_sock);
|
||||||
|
close(client_sock);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
close(client_sock);
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/server.h
Normal file
10
src/server.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
//
|
||||||
|
// Created by Iain on 2021/7/18.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef ATOP_SERVER_H
|
||||||
|
#define ATOP_SERVER_H
|
||||||
|
|
||||||
|
int server();
|
||||||
|
|
||||||
|
#endif //ATOP_SERVER_H
|
||||||
30
test.c
30
test.c
@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* test.c
|
|
||||||
* Copyright (C) 2021 light <light@lightdeMBP>
|
|
||||||
*
|
|
||||||
* Distributed under terms of the MIT license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "./include/test.h"
|
|
||||||
#include<stdio.h>
|
|
||||||
#define MAX_LINE 1024
|
|
||||||
|
|
||||||
double get_sqrt(double var1)
|
|
||||||
{
|
|
||||||
return sqrt(var1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateMem(unsigned int *all, unsigned int *fre, float *useage) {
|
|
||||||
char buf[MAX_LINE]; /*缓冲区*/
|
|
||||||
FILE *fp; /*文件指针*/
|
|
||||||
if((fp = fopen("./meminfo","r")) == NULL)
|
|
||||||
{
|
|
||||||
perror("fail to read");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fgets(buf,MAX_LINE,fp);
|
|
||||||
sscanf(buf, "%*s %u kB",all);
|
|
||||||
fgets(buf,MAX_LINE,fp);
|
|
||||||
sscanf(buf, "%*s %u kB",fre);
|
|
||||||
*useage = 1 - (float) *fre / *all;
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user