├── .gitignore ├── .travis.yml ├── Makefile ├── README.md ├── guardian.sh ├── include ├── busybox.h ├── cJSON.h ├── customization.h ├── ev.h ├── iopp.h ├── iotop.h ├── jsonrpc-c.h ├── procrank.h ├── ps.h └── sysstat.h ├── libs └── arm-libev │ ├── ev.h │ └── libev.a ├── prebuilt-binaries ├── arm-lepd └── x86-lepd ├── src ├── cJSON.c ├── jsonrpc-c.c ├── modules │ ├── busybox-lite │ │ ├── Makefile │ │ ├── inc │ │ │ ├── autoconf.h │ │ │ ├── grp_.h │ │ │ ├── libbb.h │ │ │ ├── platform.h │ │ │ ├── pwd_.h │ │ │ ├── pwd_grp_internal.c │ │ │ ├── shadow_.h │ │ │ ├── unicode.h │ │ │ ├── xatonum.h │ │ │ └── xatonum_template.c │ │ └── src │ │ │ ├── bb_pwd.c │ │ │ ├── bb_strtonum.c │ │ │ ├── copyfd.c │ │ │ ├── default_error_retval.c │ │ │ ├── df.c │ │ │ ├── dmesg.c │ │ │ ├── find_mount_point.c │ │ │ ├── free.c │ │ │ ├── full_write.c │ │ │ ├── get_last_path_component.c │ │ │ ├── getopt32.c │ │ │ ├── human_readable.c │ │ │ ├── last_char_is.c │ │ │ ├── llist.c │ │ │ ├── messages.c │ │ │ ├── perror_msg.c │ │ │ ├── platform.c │ │ │ ├── procps.c │ │ │ ├── ptr_to_globals.c │ │ │ ├── pwd_grp.c │ │ │ ├── read.c │ │ │ ├── read_key.c │ │ │ ├── safe_poll.c │ │ │ ├── safe_strncpy.c │ │ │ ├── safe_write.c │ │ │ ├── signals.c │ │ │ ├── skip_whitespace.c │ │ │ ├── time.c │ │ │ ├── top.c │ │ │ ├── verror_msg.c │ │ │ ├── wfopen.c │ │ │ ├── xatonum.c │ │ │ ├── xfunc_die.c │ │ │ ├── xfuncs.c │ │ │ ├── xfuncs_printf.c │ │ │ ├── xreadlink.c │ │ │ └── xrealloc_vector.c │ ├── customization │ │ ├── Makefile │ │ └── src │ │ │ ├── cgtop.c │ │ │ └── irq_info.c │ ├── iopp │ │ ├── Makefile │ │ └── src │ │ │ └── iopp.c │ ├── iotop │ │ ├── Makefile │ │ ├── inc │ │ │ └── iotop.h │ │ └── src │ │ │ ├── ioprio.c │ │ │ ├── main.c │ │ │ ├── utils.c │ │ │ ├── views.c │ │ │ └── xxxid_info.c │ ├── procrank │ │ ├── Makefile │ │ ├── inc │ │ │ ├── pagemap.h │ │ │ └── pm_map.h │ │ └── src │ │ │ ├── pm_kernel.c │ │ │ ├── pm_map.c │ │ │ ├── pm_memusage.c │ │ │ ├── pm_process.c │ │ │ ├── procrank.c │ │ │ └── strlcpy.c │ ├── ps │ │ ├── Makefile │ │ ├── inc │ │ │ ├── alloc.h │ │ │ ├── c.h │ │ │ ├── common.h │ │ │ ├── devname.h │ │ │ ├── escape.h │ │ │ ├── fileutils.h │ │ │ ├── nls.h │ │ │ ├── procps-private.h │ │ │ ├── procps.h │ │ │ ├── pwcache.h │ │ │ ├── readproc.h │ │ │ ├── sig.h │ │ │ ├── slab.h │ │ │ ├── sysinfo.h │ │ │ ├── version.h │ │ │ ├── wchan.h │ │ │ └── whattime.h │ │ └── src │ │ │ ├── alloc.c │ │ │ ├── devname.c │ │ │ ├── display.c │ │ │ ├── escape.c │ │ │ ├── global.c │ │ │ ├── help.c │ │ │ ├── output.c │ │ │ ├── parser.c │ │ │ ├── pwcache.c │ │ │ ├── readproc.c │ │ │ ├── select.c │ │ │ ├── sig.c │ │ │ ├── slab.c │ │ │ ├── sortformat.c │ │ │ ├── stacktrace.c │ │ │ ├── sysinfo.c │ │ │ ├── version.c │ │ │ ├── wchan.c │ │ │ └── whattime.c │ └── sysstat-lite │ │ ├── Makefile │ │ ├── inc │ │ ├── common.h │ │ ├── count.h │ │ ├── ioconf.h │ │ ├── iostat.h │ │ ├── mpstat.h │ │ ├── rd_stats.h │ │ ├── sysconfig.h │ │ └── version.h │ │ └── src │ │ ├── common.c │ │ ├── count.c │ │ ├── cpuinfo.c │ │ ├── ioconf.c │ │ ├── iostat.c │ │ ├── mpstat.c │ │ └── rd_stats.c └── server.c └── test-workloads ├── load-sim.c ├── malloc.c └── random.sh /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | language: c 3 | complier: gcc 4 | script: make 5 | before_script: sudo apt-get install libev-dev 6 | notifications: 7 | email: 8 | recipients: 9 | - 21cnbao@gmail.com 10 | - lliubbo@gmail.com 11 | - shinyxxn@hotmail.com 12 | - chensong@linuxep.com 13 | on_success: change 14 | on_failure: always 15 | 16 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PROJECT_TOP_DIR=$(PWD) 2 | PROJECT_OBJ_DIR=$(PROJECT_TOP_DIR)/.objs 3 | PROJECT_LIB_DIR=$(PROJECT_TOP_DIR)/libs 4 | PROJECT_EV_DIR=$(PROJECT_LIB_DIR)/arm-libev 5 | PROJECT_PREBUILT_DIR=$(PROJECT_TOP_DIR)/prebuilt-binaries 6 | 7 | PROJECT_INC_DIR=$(PROJECT_TOP_DIR)/include 8 | PROJECT_SRC_DIR=$(PROJECT_TOP_DIR)/src 9 | PROJECT_MODULE_DIR=$(PROJECT_SRC_DIR)/modules 10 | PROJECT_SYSSTAT_DIR=$(PROJECT_MODULE_DIR)/sysstat-lite 11 | PROJECT_BUSYBOX_DIR=$(PROJECT_MODULE_DIR)/busybox-lite 12 | PROJECT_PROCRANK_DIR=$(PROJECT_MODULE_DIR)/procrank 13 | #PROJECT_IOPP_DIR=$(PROJECT_MODULE_DIR)/iopp 14 | PROJECT_PS_DIR=$(PROJECT_MODULE_DIR)/ps 15 | PROJECT_IOTOP_DIR=$(PROJECT_MODULE_DIR)/iotop 16 | PROJECT_CUSTOMIZATION_DIR=$(PROJECT_MODULE_DIR)/customization 17 | MKDIR := mkdir -p 18 | 19 | ARCH ?= x86 20 | ifeq ($(ARCH), x86) 21 | CC=gcc 22 | AR=ar 23 | LD=ld 24 | #CFLAGS := -Wl,-Bstatic -lev -lm -g -I$(PROJECT_INC_DIR) -D_BUILTIN_FUNC -D_MULTITHREAD -Wl,-Bdynamic -lpthread 25 | CFLAGS := -lev -lm -lrt -lpthread -I$(PROJECT_INC_DIR) -D_BUILTIN_FUNC -D_MULTITHREAD 26 | LDFLAG := 27 | else 28 | CROSS_COMPILE=arm-linux-gnueabi- 29 | CC=$(CROSS_COMPILE)gcc 30 | AR=$(CROSS_COMPILE)ar 31 | LD=$(CROSS_COMPILE)ld 32 | CFLAGS := -lev -lm -lrt -lpthread -static -I$(PROJECT_INC_DIR) -D_BUILTIN_FUNC -D_MULTITHREAD 33 | #CFLAGS := -Wl,-Bstatic -lev -Wl,-Bdynamic -lm -I$(PROJECT_INC_DIR) -D_BUILTIN_FUNC -D_MULTITHREAD -Wl,-Bdynamic -lpthread 34 | LDFLAG := -L$(PROJECT_EV_DIR) 35 | endif 36 | 37 | export CROSS_COMPILE CC AR LD 38 | #DEFS = -DBUILDIN_FUNC 39 | 40 | SUBDIRS := $(PROJECT_SYSSTAT_DIR) \ 41 | $(PROJECT_BUSYBOX_DIR) \ 42 | $(PROJECT_PROCRANK_DIR) \ 43 | $(PROJECT_IOTOP_DIR) \ 44 | $(PROJECT_PS_DIR) \ 45 | $(PROJECT_CUSTOMIZATION_DIR) 46 | 47 | 48 | TARGETS = lepd 49 | 50 | src :=$(wildcard $(PROJECT_SRC_DIR)/*.c) 51 | dir := $(notdir $(src)) 52 | PROJECT_OBJ := $(patsubst %.c,%.o,$(dir) ) 53 | 54 | PROJECT_ALL_OBJS := $(addprefix $(PROJECT_OBJ_DIR)/, $(PROJECT_OBJ)) 55 | 56 | define build_libs 57 | for lib in $(SUBDIRS) ; do \ 58 | echo $${lib} && cd $${lib} && $(MAKE); \ 59 | done ; 60 | endef 61 | 62 | define clean_libs 63 | for lib in $(SUBDIRS) ; do \ 64 | echo $${lib} && cd $${lib} && $(MAKE) clean; \ 65 | done ; 66 | endef 67 | 68 | all:$(PROJECT_ALL_OBJS) 69 | $(CC) $(wildcard $(PROJECT_SRC_DIR)/*.c) $(wildcard $(PROJECT_LIB_DIR)/*.a) $(CFLAGS) -o $(TARGETS) $(LDFLAG) 70 | 71 | prepare: 72 | $(MKDIR) $(PROJECT_OBJ_DIR) 73 | $(MKDIR) $(PROJECT_LIB_DIR) 74 | $(call build_libs) 75 | 76 | $(PROJECT_OBJ_DIR)/%.o : $(PROJECT_SRC_DIR)/%.c prepare 77 | $(CC) -c $(CFLAGS) $< -o $@ 78 | 79 | clean: 80 | rm -fr $(PROJECT_OBJ_DIR) 81 | rm -fr $(TARGETS) 82 | -rm $(PROJECT_LIB_DIR)/* 83 | $(call clean_libs) 84 | 85 | install: 86 | ifeq ($(ARCH), x86) 87 | cp $(TARGETS) $(PROJECT_PREBUILT_DIR)/x86_lepd 88 | else 89 | cp $(TARGETS) $(PROJECT_PREBUILT_DIR)/arm_lepd 90 | endif 91 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # lepd 2 | server daemon of LEP 3 | 4 | ## LepD是什么 5 | 6 | 7 | LEP的结构采用的是Client/Server的模型, Client端是Django+Web服务器,负责显示从Server端取得的数据。 Server端是我们最终需要profile的target。 LepD运行在Server(Target)端, 它的工作如下: 8 | 9 | 10 | 是一个JsonRpcServer, Client通过JsonRpc连接 11 | LepD会解析接收到的RPC命令,取得系统的各类不同的数据信息,比如内存,CPU,IO状态 12 | 将取得的结果,转换成Json格式返回给Client 13 | 14 | ## LepD应用 15 | 16 | 17 | LepvClient通过JsonRpc连接 18 | 19 | 简单测试时,通过Linux nc命令即可 20 | 21 | 发送"ListAllMethod?"这个rpc方法,可以获得LepD所支持的所有方法 22 | ```console 23 | root@bob-VirtualBox:~# echo "{\"method\":\"ListAllMethod\"}" | nc 12307 24 | ``` 25 | { 26 | 27 | "result": "SayHello ListAllMethod GetProcMeminfo GetProcLoadavg GetProcVmstat GetProcZoneinfo GetProcBuddyinfo GetProcCpuinfo GetProcSlabinfo GetProcSwaps GetProcInterrupts GetProcSoftirqs GetProcDiskstats GetProcVersion GetProcStat GetProcModules GetCmdFree GetCmdProcrank GetCmdIostat GetCmdVmstat GetCmdTop GetCmdTopH GetCmdIotop GetCmdSmem GetCmdDmesg lepdendstring" 28 | } 29 | 30 | root@bob-VirtualBox:~# 31 | 32 | 具体某个方法,比如想获得内存的信息 33 | ```console 34 | root@bob-VirtualBox:~# echo "{\"method\":\"GetProcMeminfo\"}" | nc 12307 35 | ``` 36 | { 37 | 38 | "result": "MemTotal: 1017788 kB\nMemFree: 426560 kB\nBuffers: 77080 kB\nCached: 231968 kB\nSwapCached: 0 kB\nActive: 342212 kB\nInactive: 172488 kB\nActive(anon): 207000 kB\nInactive(anon): 11256 kB\nActive(file): 135212 kB\nInactive(file): 161232 kB\nUnevictable: 0 kB\nMlocked: 0 kB\nSwapTotal: 0 kB\nSwapFree: 0 kB\nDirty: 92 kB\nWriteback: 0 kB\nAnonPages: 205652 kB\nMapped: 40480 kB\nShmem: 12608 kB\nSlab: 50868 kB\nSReclaimable: 39328 kB\nSUnreclaim: 11540 kB\nKernelStack: 1336 kB\nPageTables: 6768 kB\nNFS_Unstable: 0 kB\nBounce: 0 kB\nWritebackTmp: 0 kB\nCommitLimit: 508892 kB\nCommitted_AS: 947444 kB\nVmallocTotal: 34359738367 kB\nVmallocUsed: 8796 kB\nVmallocChunk: 34359721724 kB\nHardwareCorrupted: 0 kB\nAnonHugePages: 67584 kB\nHugePages_Total: 0\nHugePages_Free: 0\nHugePages_Rsvd: 0\nHugePages_Surp: 0\nHugepagesize: 2048 kB\nDirectMap4k: 63360 kB\nDirectMap2M: 985088 kB\nDirectMap1G: 0 kB\nlepdendstring" 39 | } 40 | ```console 41 | root@bob-VirtualBox:~# 42 | ``` 43 | 当发现LepD连不上,或者获得不到数据时,直接Kill掉lepd进程,然后再通过如下命令把LepD重启 44 | git@iZ22ngfe4n3Z:~$ /opt/deploy_lepv/lepd & 45 | 46 | ## 如何编译 47 | ```console 48 | root@bob-VirtualBox:~# git clone https://github.com/linuxep/lepd 49 | ``` 50 | For X86(电脑需要安装libev-dev库): 51 | 52 | 电脑需要提前安装: 53 | 54 | { 55 | 56 | apt-get install libev-dev 57 | apt-get install linux-tools-common linux-tools-generic linux-tools-`uname -r` 58 | apt-get install libncurses5-dev 59 | } 60 | ```console 61 | root@bob-VirtualBox:~/lepd-src# make 62 | ``` 63 | For ARM(电脑需要安装arm-linux-gnueabi-gcc): 64 | ```console 65 | root@bob-VirtualBox:~/lepd-src# make ARCH=arm 66 | ``` 67 | ## 如何运行 68 | 69 | 运行lepd需要root权限,因为系统有些proc文件无root权限无法读取。 70 | 71 | lepd运行的板子、服务器的内核需要使能TASKSTATS,这样IOTOP的功能才可以起来: 72 | General setup ---> 73 | 74 | CPU/Task time and stats accounting ---> 75 | 76 | [*] Export task/process statistics through netlink 77 | 78 | [*] Enable per-task delay accounting 79 | 80 | [*] Enable extended accounting over taskstats 81 | 82 | [*] Enable per-task storage I/O accounting 83 | 84 | 目前,LEPD还没有集成perf的功能,因此,要求目标平台上,还是有安装perf,内核也使能perf相关的支持。 85 | 86 | ## 如果要在浏览器中支持火焰图,也需要lepd运行的目标平台上支持了perf! 87 | 88 | ## 实现 89 | 90 | 用了cJSON和jsonrpc-c 91 | 92 | 在server.c里面解析rpc方法,结果转成Json格式的字符串返回给Client 93 | 94 | -------------------------------------------------------------------------------- /guardian.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | #进程名字可修改 3 | PRO_NAME=lepd 4 | CMD="sudo ./lepd" 5 | while true ; do 6 | #用ps获取$PRO_NAME进程数量 7 | NUM=`ps aux | grep -w ${PRO_NAME} | grep -v grep |wc -l` 8 | #echo $NUM 9 | #少于1,重启进程 10 | if [ "${NUM}" -lt "1" ];then 11 | echo "${PRO_NAME} was killed" 12 | $CMD 13 | #大于1,杀掉所有进程,重启 14 | elif [ "${NUM}" -gt "1" ];then 15 | echo "more than 1 ${PRO_NAME},killall ${PRO_NAME}" 16 | killall -9 $PRO_NAME 17 | $CMD 18 | fi 19 | #kill僵尸进程 20 | NUM_STAT=`ps aux | grep -w ${PRO_NAME} | grep T | grep -v grep | wc -l` 21 | if [ "${NUM_STAT}" -gt "0" ];then 22 | killall -9 ${PRO_NAME} 23 | $CMD 24 | fi 25 | sleep 5s 26 | done 27 | 28 | exit 0 29 | -------------------------------------------------------------------------------- /include/busybox.h: -------------------------------------------------------------------------------- 1 | #ifndef BUSYBOX_H_ 2 | #define BUSYBOX_H_ 3 | int free_main(int argc, char **argv, int fd); 4 | int dmesg_main(int argc, char **argv, int fd); 5 | int top_main(int argc, char **argv, int fd); 6 | int df_main(int argc, char **argv, int fd); 7 | #endif 8 | -------------------------------------------------------------------------------- /include/cJSON.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 Dave Gamble 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | #ifndef cJSON__h 24 | #define cJSON__h 25 | 26 | #ifdef __cplusplus 27 | extern "C" 28 | { 29 | #endif 30 | 31 | /* cJSON Types: */ 32 | #define cJSON_False 0 33 | #define cJSON_True 1 34 | #define cJSON_NULL 2 35 | #define cJSON_Number 3 36 | #define cJSON_String 4 37 | #define cJSON_Array 5 38 | #define cJSON_Object 6 39 | 40 | #define cJSON_IsReference 256 41 | 42 | /* The cJSON structure: */ 43 | typedef struct cJSON { 44 | struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ 45 | struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ 46 | 47 | int type; /* The type of the item, as above. */ 48 | 49 | char *valuestring; /* The item's string, if type==cJSON_String */ 50 | int valueint; /* The item's number, if type==cJSON_Number */ 51 | double valuedouble; /* The item's number, if type==cJSON_Number */ 52 | 53 | char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ 54 | } cJSON; 55 | 56 | typedef struct cJSON_Hooks { 57 | void *(*malloc_fn)(size_t sz); 58 | void (*free_fn)(void *ptr); 59 | } cJSON_Hooks; 60 | 61 | /* Supply malloc, realloc and free functions to cJSON */ 62 | extern void cJSON_InitHooks(cJSON_Hooks* hooks); 63 | 64 | 65 | /* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */ 66 | extern cJSON *cJSON_Parse(const char *value); 67 | /* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. 68 | * end_ptr will point to 1 past the end of the JSON object */ 69 | extern cJSON *cJSON_Parse_Stream(const char *value, char **end_ptr); 70 | /* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */ 71 | extern char *cJSON_Print(cJSON *item); 72 | /* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */ 73 | extern char *cJSON_PrintUnformatted(cJSON *item); 74 | /* Delete a cJSON entity and all subentities. */ 75 | extern void cJSON_Delete(cJSON *c); 76 | 77 | /* Returns the number of items in an array (or object). */ 78 | extern int cJSON_GetArraySize(cJSON *array); 79 | /* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */ 80 | extern cJSON *cJSON_GetArrayItem(cJSON *array,int item); 81 | /* Get item "string" from object. Case insensitive. */ 82 | extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string); 83 | 84 | /* These calls create a cJSON item of the appropriate type. */ 85 | extern cJSON *cJSON_CreateNull(); 86 | extern cJSON *cJSON_CreateTrue(); 87 | extern cJSON *cJSON_CreateFalse(); 88 | extern cJSON *cJSON_CreateBool(int b); 89 | extern cJSON *cJSON_CreateNumber(double num); 90 | extern cJSON *cJSON_CreateString(const char *string); 91 | extern cJSON *cJSON_CreateArray(); 92 | extern cJSON *cJSON_CreateObject(); 93 | 94 | /* These utilities create an Array of count items. */ 95 | extern cJSON *cJSON_CreateIntArray(int *numbers,int count); 96 | extern cJSON *cJSON_CreateFloatArray(float *numbers,int count); 97 | extern cJSON *cJSON_CreateDoubleArray(double *numbers,int count); 98 | extern cJSON *cJSON_CreateStringArray(const char **strings,int count); 99 | 100 | /* Append item to the specified array/object. */ 101 | extern void cJSON_AddItemToArray(cJSON *array, cJSON *item); 102 | extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item); 103 | /* 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. */ 104 | extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); 105 | extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item); 106 | 107 | /* Remove/Detatch items from Arrays/Objects. */ 108 | extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which); 109 | extern void cJSON_DeleteItemFromArray(cJSON *array,int which); 110 | extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string); 111 | extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string); 112 | 113 | /* Update array items. */ 114 | extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem); 115 | extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); 116 | 117 | #define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull()) 118 | #define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue()) 119 | #define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse()) 120 | #define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n)) 121 | #define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s)) 122 | 123 | #ifdef __cplusplus 124 | } 125 | #endif 126 | 127 | #endif 128 | -------------------------------------------------------------------------------- /include/customization.h: -------------------------------------------------------------------------------- 1 | #ifndef CUSTOMIZATION_H_ 2 | #define CUSTOMIZATION_H_ 3 | 4 | int irq_info_main(int argc, char **argv, int out_fd); 5 | int cgtop_main(int argc, char *argv[],int out_fd); 6 | #endif 7 | -------------------------------------------------------------------------------- /include/iopp.h: -------------------------------------------------------------------------------- 1 | #ifndef IOPP_H_ 2 | #define IOPP_H_ 3 | int iopp_main(int argc, char *argv[]); 4 | #endif 5 | -------------------------------------------------------------------------------- /include/iotop.h: -------------------------------------------------------------------------------- 1 | #ifndef IOPP_H_ 2 | #define IOPP_H_ 3 | int iotop_main(int argc, char *argv[], int fd); 4 | #endif 5 | -------------------------------------------------------------------------------- /include/jsonrpc-c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jsonrpc-c.h 3 | * 4 | * Created on: Oct 11, 2012 5 | * Author: hmng 6 | */ 7 | 8 | #ifndef JSONRPCC_H_ 9 | #define JSONRPCC_H_ 10 | 11 | #include "cJSON.h" 12 | #include 13 | #include 14 | 15 | /* 16 | * 17 | * http://www.jsonrpc.org/specification 18 | * 19 | * code message meaning 20 | * -32700 Parse error Invalid JSON was received by the server. 21 | * An error occurred on the server while parsing the JSON text. 22 | * -32600 Invalid Request The JSON sent is not a valid Request object. 23 | * -32601 Method not found The method does not exist / is not available. 24 | * -32602 Invalid params Invalid method parameter(s). 25 | * -32603 Internal error Internal JSON-RPC error. 26 | * -32000 to -32099 Server error Reserved for implementation-defined server-errors. 27 | */ 28 | 29 | #define JRPC_PARSE_ERROR -32700 30 | #define JRPC_INVALID_REQUEST -32600 31 | #define JRPC_METHOD_NOT_FOUND -32601 32 | #define JRPC_INVALID_PARAMS -32603 33 | #define JRPC_INTERNAL_ERROR -32693 34 | 35 | typedef struct { 36 | void *data; 37 | int error_code; 38 | char * error_message; 39 | } jrpc_context; 40 | 41 | typedef cJSON* (*jrpc_function)(jrpc_context *context, cJSON *params, cJSON* id); 42 | 43 | struct jrpc_procedure { 44 | char * name; 45 | jrpc_function function; 46 | void *data; 47 | }; 48 | 49 | struct jrpc_server { 50 | int port_number; 51 | struct ev_loop *loop; 52 | ev_io listen_watcher; 53 | int procedure_count; 54 | struct jrpc_procedure *procedures; 55 | int debug_level; 56 | }; 57 | 58 | struct jrpc_connection { 59 | struct ev_io io; 60 | int fd; 61 | int pos; 62 | unsigned int buffer_size; 63 | char * buffer; 64 | int debug_level; 65 | }; 66 | 67 | int jrpc_server_init(struct jrpc_server *server, int port_number); 68 | 69 | int jrpc_server_init_with_ev_loop(struct jrpc_server *server, 70 | int port_number, struct ev_loop *loop); 71 | 72 | void jrpc_server_run(struct jrpc_server *server); 73 | 74 | int jrpc_server_stop(struct jrpc_server *server); 75 | 76 | void jrpc_server_destroy(struct jrpc_server *server); 77 | 78 | int jrpc_register_procedure(struct jrpc_server *server, 79 | jrpc_function function_pointer, char *name, void *data); 80 | 81 | int jrpc_deregister_procedure(struct jrpc_server *server, char *name); 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /include/procrank.h: -------------------------------------------------------------------------------- 1 | #ifndef PROCRANK_H_ 2 | #define PROCRANK_H_ 3 | 4 | int procrank_main(int argc, char **argv, int fd); 5 | #endif 6 | -------------------------------------------------------------------------------- /include/ps.h: -------------------------------------------------------------------------------- 1 | #ifndef PS_H_ 2 | #define PS_H_ 3 | int ps_main(int argc, char *argv[], int fd); 4 | #endif 5 | 6 | -------------------------------------------------------------------------------- /include/sysstat.h: -------------------------------------------------------------------------------- 1 | #ifndef SYSSTAT_H_ 2 | #define SYSSTAT_H_ 3 | 4 | int iostat_main(int argc, char **argv, int fd); 5 | int mpstat_main(int argc, char **argv, int fd); 6 | int cpuinfo_main(int argc, char **argv, int out_fd); 7 | #endif 8 | -------------------------------------------------------------------------------- /libs/arm-libev/libev.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linuxep/lepd/1173d0b84acb2a2736a81bcc84f40bff8c1eb066/libs/arm-libev/libev.a -------------------------------------------------------------------------------- /prebuilt-binaries/arm-lepd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linuxep/lepd/1173d0b84acb2a2736a81bcc84f40bff8c1eb066/prebuilt-binaries/arm-lepd -------------------------------------------------------------------------------- /prebuilt-binaries/x86-lepd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linuxep/lepd/1173d0b84acb2a2736a81bcc84f40bff8c1eb066/prebuilt-binaries/x86-lepd -------------------------------------------------------------------------------- /src/modules/busybox-lite/Makefile: -------------------------------------------------------------------------------- 1 | DIR_INC = ./inc 2 | DIR_SRC = ./src 3 | DIR_OBJ = ./obj 4 | 5 | 6 | SRC = $(wildcard ${DIR_SRC}/*.c) 7 | OBJ = $(patsubst %.c,${DIR_OBJ}/%.o,$(notdir ${SRC})) 8 | 9 | TARGET = libbusybox.a 10 | 11 | 12 | #CROSS_COMPILE=arm-linux-gnueabi- 13 | #CC=$(CROSS_COMPILE)gcc 14 | #AR=$(CROSS_COMPILE)ar 15 | #LD=$(CROSS_COMPILE)ld 16 | 17 | 18 | CFLAGS = -I$(DIR_INC) -Wall -static -g 19 | 20 | 21 | 22 | ${TARGET}:${OBJ} 23 | $(AR) rc $@ $^ 24 | @mv $(TARGET) ../../../libs/ 25 | ${DIR_OBJ}/%.o:${DIR_SRC}/%.c 26 | @mkdir -p $(DIR_OBJ) 27 | $(CC) $(CFLAGS) -c $< -o $@ 28 | 29 | .PHONY:clean 30 | clean: 31 | @rm -rf $(DIR_OBJ) 32 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/inc/grp_.h: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* Copyright (C) 1991,92,95,96,97,98,99,2000,01 Free Software Foundation, Inc. 3 | This file is part of the GNU C Library. 4 | 5 | The GNU C Library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | The GNU C Library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with the GNU C Library; if not, write to the Free 17 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 18 | 02111-1307 USA. 19 | */ 20 | /* 21 | * POSIX Standard: 9.2.1 Group Database Access 22 | */ 23 | #ifndef BB_GRP_H 24 | #define BB_GRP_H 1 25 | 26 | PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN 27 | 28 | /* This file is #included after #include 29 | * We will use libc-defined structures, but will #define function names 30 | * so that function calls are directed to bb_internal_XXX replacements 31 | */ 32 | #undef endgrent 33 | #define setgrent bb_internal_setgrent 34 | #define endgrent bb_internal_endgrent 35 | #define getgrent bb_internal_getgrent 36 | #define fgetgrent bb_internal_fgetgrent 37 | #define putgrent bb_internal_putgrent 38 | #define getgrgid bb_internal_getgrgid 39 | #define getgrnam bb_internal_getgrnam 40 | #define getgrent_r bb_internal_getgrent_r 41 | #define getgrgid_r bb_internal_getgrgid_r 42 | #define getgrnam_r bb_internal_getgrnam_r 43 | #define fgetgrent_r bb_internal_fgetgrent_r 44 | #define getgrouplist bb_internal_getgrouplist 45 | #define initgroups bb_internal_initgroups 46 | 47 | 48 | /* All function names below should be remapped by #defines above 49 | * in order to not collide with libc names. */ 50 | 51 | 52 | /* Rewind the group-file stream. */ 53 | extern void setgrent(void); 54 | 55 | /* Close the group-file stream. */ 56 | extern void endgrent(void); 57 | 58 | #ifdef UNUSED_SINCE_WE_AVOID_STATIC_BUFS 59 | /* Read an entry from the group-file stream, opening it if necessary. */ 60 | extern struct group *getgrent(void); 61 | 62 | /* Read a group entry from STREAM. */ 63 | extern struct group *fgetgrent(FILE *__stream); 64 | 65 | /* Write the given entry onto the given stream. */ 66 | extern int putgrent(const struct group *__restrict __p, 67 | FILE *__restrict __f); 68 | #endif 69 | 70 | /* Search for an entry with a matching group ID. */ 71 | extern struct group *getgrgid(gid_t __gid); 72 | 73 | /* Search for an entry with a matching group name. */ 74 | extern struct group *getgrnam(const char *__name); 75 | 76 | /* Reentrant versions of some of the functions above. 77 | 78 | PLEASE NOTE: the `getgrent_r' function is not (yet) standardized. 79 | The interface may change in later versions of this library. But 80 | the interface is designed following the principals used for the 81 | other reentrant functions so the chances are good this is what the 82 | POSIX people would choose. */ 83 | 84 | extern int getgrent_r(struct group *__restrict __resultbuf, 85 | char *__restrict __buffer, size_t __buflen, 86 | struct group **__restrict __result); 87 | 88 | /* Search for an entry with a matching group ID. */ 89 | extern int getgrgid_r(gid_t __gid, struct group *__restrict __resultbuf, 90 | char *__restrict __buffer, size_t __buflen, 91 | struct group **__restrict __result); 92 | 93 | /* Search for an entry with a matching group name. */ 94 | extern int getgrnam_r(const char *__restrict __name, 95 | struct group *__restrict __resultbuf, 96 | char *__restrict __buffer, size_t __buflen, 97 | struct group **__restrict __result); 98 | 99 | /* Read a group entry from STREAM. This function is not standardized 100 | an probably never will. */ 101 | extern int fgetgrent_r(FILE *__restrict __stream, 102 | struct group *__restrict __resultbuf, 103 | char *__restrict __buffer, size_t __buflen, 104 | struct group **__restrict __result); 105 | 106 | /* Store at most *NGROUPS members of the group set for USER into 107 | *GROUPS. Also include GROUP. The actual number of groups found is 108 | returned in *NGROUPS. Return -1 if the if *NGROUPS is too small. */ 109 | extern int getgrouplist(const char *__user, gid_t __group, 110 | gid_t *__groups, int *__ngroups); 111 | 112 | /* Initialize the group set for the current user 113 | by reading the group database and using all groups 114 | of which USER is a member. Also include GROUP. */ 115 | extern int initgroups(const char *__user, gid_t __group); 116 | 117 | POP_SAVED_FUNCTION_VISIBILITY 118 | 119 | #endif 120 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/inc/pwd_.h: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* Copyright (C) 1991,92,95,96,97,98,99,2001 Free Software Foundation, Inc. 3 | This file is part of the GNU C Library. 4 | 5 | The GNU C Library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | The GNU C Library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with the GNU C Library; if not, write to the Free 17 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 18 | 02111-1307 USA. */ 19 | 20 | /* 21 | * POSIX Standard: 9.2.2 User Database Access 22 | */ 23 | 24 | #ifndef BB_PWD_H 25 | #define BB_PWD_H 1 26 | 27 | PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN 28 | 29 | /* This file is #included after #include 30 | * We will use libc-defined structures, but will #define function names 31 | * so that function calls are directed to bb_internal_XXX replacements 32 | */ 33 | #undef endpwent 34 | #define setpwent bb_internal_setpwent 35 | #define endpwent bb_internal_endpwent 36 | #define getpwent bb_internal_getpwent 37 | #define fgetpwent bb_internal_fgetpwent 38 | #define putpwent bb_internal_putpwent 39 | #define getpwuid bb_internal_getpwuid 40 | #define getpwnam bb_internal_getpwnam 41 | #define getpwent_r bb_internal_getpwent_r 42 | #define getpwuid_r bb_internal_getpwuid_r 43 | #define getpwnam_r bb_internal_getpwnam_r 44 | #define fgetpwent_r bb_internal_fgetpwent_r 45 | 46 | 47 | /* All function names below should be remapped by #defines above 48 | * in order to not collide with libc names. */ 49 | 50 | 51 | /* Rewind the password-file stream. */ 52 | extern void setpwent(void); 53 | 54 | /* Close the password-file stream. */ 55 | extern void endpwent(void); 56 | 57 | #ifdef UNUSED_SINCE_WE_AVOID_STATIC_BUFS 58 | /* Read an entry from the password-file stream, opening it if necessary. */ 59 | extern struct passwd *getpwent(void); 60 | 61 | /* Read an entry from STREAM. */ 62 | extern struct passwd *fgetpwent(FILE *__stream); 63 | 64 | /* Write the given entry onto the given stream. */ 65 | extern int putpwent(const struct passwd *__restrict __p, 66 | FILE *__restrict __f); 67 | #endif 68 | 69 | /* Search for an entry with a matching user ID. */ 70 | extern struct passwd *getpwuid(uid_t __uid); 71 | 72 | /* Search for an entry with a matching username. */ 73 | extern struct passwd *getpwnam(const char *__name); 74 | 75 | /* Reentrant versions of some of the functions above. 76 | 77 | PLEASE NOTE: the `getpwent_r' function is not (yet) standardized. 78 | The interface may change in later versions of this library. But 79 | the interface is designed following the principals used for the 80 | other reentrant functions so the chances are good this is what the 81 | POSIX people would choose. */ 82 | 83 | extern int getpwent_r(struct passwd *__restrict __resultbuf, 84 | char *__restrict __buffer, size_t __buflen, 85 | struct passwd **__restrict __result); 86 | 87 | extern int getpwuid_r(uid_t __uid, 88 | struct passwd *__restrict __resultbuf, 89 | char *__restrict __buffer, size_t __buflen, 90 | struct passwd **__restrict __result); 91 | 92 | extern int getpwnam_r(const char *__restrict __name, 93 | struct passwd *__restrict __resultbuf, 94 | char *__restrict __buffer, size_t __buflen, 95 | struct passwd **__restrict __result); 96 | 97 | /* Read an entry from STREAM. This function is not standardized and 98 | probably never will. */ 99 | extern int fgetpwent_r(FILE *__restrict __stream, 100 | struct passwd *__restrict __resultbuf, 101 | char *__restrict __buffer, size_t __buflen, 102 | struct passwd **__restrict __result); 103 | 104 | POP_SAVED_FUNCTION_VISIBILITY 105 | 106 | #endif 107 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/inc/pwd_grp_internal.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* Copyright (C) 2003 Manuel Novoa III 3 | * 4 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. 5 | */ 6 | 7 | /* Nov 6, 2003 Initial version. 8 | * 9 | * NOTE: This implementation is quite strict about requiring all 10 | * field seperators. It also does not allow leading whitespace 11 | * except when processing the numeric fields. glibc is more 12 | * lenient. See the various glibc difference comments below. 13 | * 14 | * TODO: 15 | * Move to dynamic allocation of (currently statically allocated) 16 | * buffers; especially for the group-related functions since 17 | * large group member lists will cause error returns. 18 | */ 19 | 20 | #ifndef GETXXKEY_R_FUNC 21 | #error GETXXKEY_R_FUNC is not defined! 22 | #endif 23 | 24 | int GETXXKEY_R_FUNC(GETXXKEY_R_KEYTYPE key, 25 | GETXXKEY_R_ENTTYPE *__restrict resultbuf, 26 | char *__restrict buffer, size_t buflen, 27 | GETXXKEY_R_ENTTYPE **__restrict result) 28 | { 29 | FILE *stream; 30 | int rv; 31 | 32 | *result = NULL; 33 | 34 | stream = fopen_for_read(GETXXKEY_R_PATHNAME); 35 | if (!stream) 36 | return errno; 37 | while (1) { 38 | rv = bb__pgsreader(GETXXKEY_R_PARSER, resultbuf, buffer, buflen, stream); 39 | if (!rv) { 40 | if (GETXXKEY_R_TEST(resultbuf)) { /* found key? */ 41 | *result = resultbuf; 42 | break; 43 | } 44 | } else { 45 | if (rv == ENOENT) { /* EOF encountered */ 46 | rv = 0; 47 | } 48 | break; 49 | } 50 | } 51 | fclose(stream); 52 | 53 | return rv; 54 | } 55 | 56 | #undef GETXXKEY_R_FUNC 57 | #undef GETXXKEY_R_PARSER 58 | #undef GETXXKEY_R_ENTTYPE 59 | #undef GETXXKEY_R_TEST 60 | #undef GETXXKEY_R_KEYTYPE 61 | #undef GETXXKEY_R_PATHNAME 62 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/inc/shadow_.h: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc. 3 | This file is part of the GNU C Library. 4 | 5 | The GNU C Library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | The GNU C Library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with the GNU C Library; if not, write to the Free 17 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 18 | 02111-1307 USA. */ 19 | 20 | /* Declaration of types and functions for shadow password suite */ 21 | 22 | #ifndef BB_SHADOW_H 23 | #define BB_SHADOW_H 1 24 | 25 | PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN 26 | 27 | /* Structure of the password file */ 28 | struct spwd { 29 | char *sp_namp; /* Login name */ 30 | char *sp_pwdp; /* Encrypted password */ 31 | long sp_lstchg; /* Date of last change */ 32 | long sp_min; /* Minimum number of days between changes */ 33 | long sp_max; /* Maximum number of days between changes */ 34 | long sp_warn; /* Number of days to warn user to change the password */ 35 | long sp_inact; /* Number of days the account may be inactive */ 36 | long sp_expire; /* Number of days since 1970-01-01 until account expires */ 37 | unsigned long sp_flag; /* Reserved */ 38 | }; 39 | 40 | #define setspent bb_internal_setspent 41 | #define endspent bb_internal_endspent 42 | #define getspent bb_internal_getspent 43 | #define getspnam bb_internal_getspnam 44 | #define sgetspent bb_internal_sgetspent 45 | #define fgetspent bb_internal_fgetspent 46 | #define putspent bb_internal_putspent 47 | #define getspent_r bb_internal_getspent_r 48 | #define getspnam_r bb_internal_getspnam_r 49 | #define sgetspent_r bb_internal_sgetspent_r 50 | #define fgetspent_r bb_internal_fgetspent_r 51 | #define lckpwdf bb_internal_lckpwdf 52 | #define ulckpwdf bb_internal_ulckpwdf 53 | 54 | 55 | /* All function names below should be remapped by #defines above 56 | * in order to not collide with libc names. */ 57 | 58 | #ifdef UNUSED_FOR_NOW 59 | /* Open database for reading */ 60 | extern void setspent(void); 61 | 62 | /* Close database */ 63 | extern void endspent(void); 64 | 65 | /* Get next entry from database, perhaps after opening the file */ 66 | extern struct spwd *getspent(void); 67 | 68 | /* Get shadow entry matching NAME */ 69 | extern struct spwd *getspnam(const char *__name); 70 | 71 | /* Read shadow entry from STRING */ 72 | extern struct spwd *sgetspent(const char *__string); 73 | 74 | /* Read next shadow entry from STREAM */ 75 | extern struct spwd *fgetspent(FILE *__stream); 76 | 77 | /* Write line containing shadow password entry to stream */ 78 | extern int putspent(const struct spwd *__p, FILE *__stream); 79 | 80 | /* Reentrant versions of some of the functions above */ 81 | extern int getspent_r(struct spwd *__result_buf, char *__buffer, 82 | size_t __buflen, struct spwd **__result); 83 | #endif 84 | 85 | extern int getspnam_r(const char *__name, struct spwd *__result_buf, 86 | char *__buffer, size_t __buflen, 87 | struct spwd **__result); 88 | 89 | #ifdef UNUSED_FOR_NOW 90 | extern int sgetspent_r(const char *__string, struct spwd *__result_buf, 91 | char *__buffer, size_t __buflen, 92 | struct spwd **__result); 93 | 94 | extern int fgetspent_r(FILE *__stream, struct spwd *__result_buf, 95 | char *__buffer, size_t __buflen, 96 | struct spwd **__result); 97 | /* Protect password file against multi writers */ 98 | extern int lckpwdf(void); 99 | 100 | /* Unlock password file */ 101 | extern int ulckpwdf(void); 102 | #endif 103 | 104 | POP_SAVED_FUNCTION_VISIBILITY 105 | 106 | #endif /* shadow.h */ 107 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/inc/unicode.h: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Licensed under GPLv2, see file LICENSE in this source tree. 4 | */ 5 | #ifndef UNICODE_H 6 | #define UNICODE_H 1 7 | 8 | #if ENABLE_UNICODE_USING_LOCALE 9 | # include 10 | # include 11 | #endif 12 | 13 | PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN 14 | 15 | enum { 16 | UNICODE_UNKNOWN = 0, 17 | UNICODE_OFF = 1, 18 | UNICODE_ON = 2, 19 | }; 20 | 21 | #define unicode_bidi_isrtl(wc) 0 22 | #define unicode_bidi_is_neutral_wchar(wc) (wc <= 126 && !isalpha(wc)) 23 | 24 | #if !ENABLE_UNICODE_SUPPORT 25 | 26 | # define unicode_strlen(string) strlen(string) 27 | # define unicode_strwidth(string) strlen(string) 28 | # define unicode_status UNICODE_OFF 29 | # define init_unicode() ((void)0) 30 | # define reinit_unicode(LANG) ((void)0) 31 | 32 | #else 33 | 34 | # if CONFIG_LAST_SUPPORTED_WCHAR < 126 || CONFIG_LAST_SUPPORTED_WCHAR >= 0x30000 35 | # undef CONFIG_LAST_SUPPORTED_WCHAR 36 | # define CONFIG_LAST_SUPPORTED_WCHAR 0x2ffff 37 | # endif 38 | 39 | # if CONFIG_LAST_SUPPORTED_WCHAR < 0x300 40 | # undef ENABLE_UNICODE_COMBINING_WCHARS 41 | # define ENABLE_UNICODE_COMBINING_WCHARS 0 42 | # endif 43 | 44 | # if CONFIG_LAST_SUPPORTED_WCHAR < 0x1100 45 | # undef ENABLE_UNICODE_WIDE_WCHARS 46 | # define ENABLE_UNICODE_WIDE_WCHARS 0 47 | # endif 48 | 49 | # if CONFIG_LAST_SUPPORTED_WCHAR < 0x590 50 | # undef ENABLE_UNICODE_BIDI_SUPPORT 51 | # define ENABLE_UNICODE_BIDI_SUPPORT 0 52 | # endif 53 | 54 | /* Number of unicode chars. Falls back to strlen() on invalid unicode */ 55 | size_t FAST_FUNC unicode_strlen(const char *string); 56 | /* Width on terminal */ 57 | size_t FAST_FUNC unicode_strwidth(const char *string); 58 | enum { 59 | UNI_FLAG_PAD = (1 << 0), 60 | }; 61 | //UNUSED: unsigned FAST_FUNC unicode_padding_to_width(unsigned width, const char *src); 62 | //UNUSED: char* FAST_FUNC unicode_conv_to_printable2(uni_stat_t *stats, const char *src, unsigned width, int flags); 63 | char* FAST_FUNC unicode_conv_to_printable(uni_stat_t *stats, const char *src); 64 | //UNUSED: char* FAST_FUNC unicode_conv_to_printable_maxwidth(uni_stat_t *stats, const char *src, unsigned maxwidth); 65 | char* FAST_FUNC unicode_conv_to_printable_fixedwidth(/*uni_stat_t *stats,*/ const char *src, unsigned width); 66 | 67 | # if ENABLE_UNICODE_USING_LOCALE 68 | 69 | extern uint8_t unicode_status; 70 | void init_unicode(void) FAST_FUNC; 71 | void reinit_unicode(const char *LANG) FAST_FUNC; 72 | 73 | # else 74 | 75 | /* Homegrown Unicode support. It knows only C and Unicode locales. */ 76 | 77 | # if !ENABLE_FEATURE_CHECK_UNICODE_IN_ENV 78 | # define unicode_status UNICODE_ON 79 | # define init_unicode() ((void)0) 80 | # define reinit_unicode(LANG) ((void)0) 81 | # else 82 | extern uint8_t unicode_status; 83 | void init_unicode(void) FAST_FUNC; 84 | void reinit_unicode(const char *LANG) FAST_FUNC; 85 | # endif 86 | 87 | # undef MB_CUR_MAX 88 | # define MB_CUR_MAX 6 89 | 90 | /* Prevent name collisions */ 91 | # define wint_t bb_wint_t 92 | # define mbstate_t bb_mbstate_t 93 | # define mbstowcs bb_mbstowcs 94 | # define wcstombs bb_wcstombs 95 | # define wcrtomb bb_wcrtomb 96 | # define iswspace bb_iswspace 97 | # define iswalnum bb_iswalnum 98 | # define iswpunct bb_iswpunct 99 | # define wcwidth bb_wcwidth 100 | 101 | typedef int32_t wint_t; 102 | typedef struct { 103 | char bogus; 104 | } mbstate_t; 105 | 106 | size_t mbstowcs(wchar_t *dest, const char *src, size_t n) FAST_FUNC; 107 | size_t wcstombs(char *dest, const wchar_t *src, size_t n) FAST_FUNC; 108 | size_t wcrtomb(char *s, wchar_t wc, mbstate_t *ps) FAST_FUNC; 109 | int iswspace(wint_t wc) FAST_FUNC; 110 | int iswalnum(wint_t wc) FAST_FUNC; 111 | int iswpunct(wint_t wc) FAST_FUNC; 112 | int wcwidth(unsigned ucs) FAST_FUNC; 113 | # if ENABLE_UNICODE_BIDI_SUPPORT 114 | # undef unicode_bidi_isrtl 115 | int unicode_bidi_isrtl(wint_t wc) FAST_FUNC; 116 | # if ENABLE_UNICODE_NEUTRAL_TABLE 117 | # undef unicode_bidi_is_neutral_wchar 118 | int unicode_bidi_is_neutral_wchar(wint_t wc) FAST_FUNC; 119 | # endif 120 | # endif 121 | 122 | 123 | # endif /* !UNICODE_USING_LOCALE */ 124 | 125 | #endif /* UNICODE_SUPPORT */ 126 | 127 | POP_SAVED_FUNCTION_VISIBILITY 128 | 129 | #endif 130 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/inc/xatonum_template.c: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Licensed under GPLv2, see file LICENSE in this source tree. 4 | */ 5 | /* 6 | You need to define the following (example): 7 | 8 | #define type long 9 | #define xstrtou(rest) xstrtoul##rest 10 | #define xstrto(rest) xstrtol##rest 11 | #define xatou(rest) xatoul##rest 12 | #define xato(rest) xatol##rest 13 | #define XSTR_UTYPE_MAX ULONG_MAX 14 | #define XSTR_TYPE_MAX LONG_MAX 15 | #define XSTR_TYPE_MIN LONG_MIN 16 | #define XSTR_STRTOU strtoul 17 | */ 18 | 19 | unsigned type FAST_FUNC xstrtou(_range_sfx)(const char *numstr, int base, 20 | unsigned type lower, 21 | unsigned type upper, 22 | const struct suffix_mult *suffixes) 23 | { 24 | unsigned type r; 25 | int old_errno; 26 | char *e; 27 | 28 | /* Disallow '-' and any leading whitespace. */ 29 | if (*numstr == '-' || *numstr == '+' || isspace(*numstr)) 30 | goto inval; 31 | 32 | /* Since this is a lib function, we're not allowed to reset errno to 0. 33 | * Doing so could break an app that is deferring checking of errno. 34 | * So, save the old value so that we can restore it if successful. */ 35 | old_errno = errno; 36 | errno = 0; 37 | r = XSTR_STRTOU(numstr, &e, base); 38 | /* Do the initial validity check. Note: The standards do not 39 | * guarantee that errno is set if no digits were found. So we 40 | * must test for this explicitly. */ 41 | if (errno || numstr == e) 42 | goto inval; /* error / no digits / illegal trailing chars */ 43 | 44 | errno = old_errno; /* Ok. So restore errno. */ 45 | 46 | /* Do optional suffix parsing. Allow 'empty' suffix tables. 47 | * Note that we also allow nul suffixes with associated multipliers, 48 | * to allow for scaling of the numstr by some default multiplier. */ 49 | if (suffixes) { 50 | while (suffixes->mult) { 51 | if (strcmp(suffixes->suffix, e) == 0) { 52 | if (XSTR_UTYPE_MAX / suffixes->mult < r) 53 | goto range; /* overflow! */ 54 | r *= suffixes->mult; 55 | goto chk_range; 56 | } 57 | ++suffixes; 58 | } 59 | } 60 | 61 | /* Note: trailing space is an error. 62 | * It would be easy enough to allow though if desired. */ 63 | if (*e) 64 | goto inval; 65 | chk_range: 66 | /* Finally, check for range limits. */ 67 | if (r >= lower && r <= upper) 68 | return r; 69 | range: 70 | bb_error_msg_and_die("number %s is not in %llu..%llu range", 71 | numstr, (unsigned long long)lower, 72 | (unsigned long long)upper); 73 | inval: 74 | bb_error_msg_and_die("invalid number '%s'", numstr); 75 | } 76 | 77 | unsigned type FAST_FUNC xstrtou(_range)(const char *numstr, int base, 78 | unsigned type lower, 79 | unsigned type upper) 80 | { 81 | return xstrtou(_range_sfx)(numstr, base, lower, upper, NULL); 82 | } 83 | 84 | unsigned type FAST_FUNC xstrtou(_sfx)(const char *numstr, int base, 85 | const struct suffix_mult *suffixes) 86 | { 87 | return xstrtou(_range_sfx)(numstr, base, 0, XSTR_UTYPE_MAX, suffixes); 88 | } 89 | 90 | unsigned type FAST_FUNC xstrtou()(const char *numstr, int base) 91 | { 92 | return xstrtou(_range_sfx)(numstr, base, 0, XSTR_UTYPE_MAX, NULL); 93 | } 94 | 95 | unsigned type FAST_FUNC xatou(_range_sfx)(const char *numstr, 96 | unsigned type lower, 97 | unsigned type upper, 98 | const struct suffix_mult *suffixes) 99 | { 100 | return xstrtou(_range_sfx)(numstr, 10, lower, upper, suffixes); 101 | } 102 | 103 | unsigned type FAST_FUNC xatou(_range)(const char *numstr, 104 | unsigned type lower, 105 | unsigned type upper) 106 | { 107 | return xstrtou(_range_sfx)(numstr, 10, lower, upper, NULL); 108 | } 109 | 110 | unsigned type FAST_FUNC xatou(_sfx)(const char *numstr, 111 | const struct suffix_mult *suffixes) 112 | { 113 | return xstrtou(_range_sfx)(numstr, 10, 0, XSTR_UTYPE_MAX, suffixes); 114 | } 115 | 116 | unsigned type FAST_FUNC xatou()(const char *numstr) 117 | { 118 | return xatou(_sfx)(numstr, NULL); 119 | } 120 | 121 | /* Signed ones */ 122 | 123 | type FAST_FUNC xstrto(_range_sfx)(const char *numstr, int base, 124 | type lower, 125 | type upper, 126 | const struct suffix_mult *suffixes) 127 | { 128 | unsigned type u = XSTR_TYPE_MAX; 129 | type r; 130 | const char *p = numstr; 131 | 132 | /* NB: if you'll decide to disallow '+': 133 | * at least renice applet needs to allow it */ 134 | if (p[0] == '+' || p[0] == '-') { 135 | ++p; 136 | if (p[0] == '-') 137 | ++u; /* = _MIN (01111... + 1 == 10000...) */ 138 | } 139 | 140 | r = xstrtou(_range_sfx)(p, base, 0, u, suffixes); 141 | 142 | if (*numstr == '-') { 143 | r = -r; 144 | } 145 | 146 | if (r < lower || r > upper) { 147 | bb_error_msg_and_die("number %s is not in %lld..%lld range", 148 | numstr, (long long)lower, (long long)upper); 149 | } 150 | 151 | return r; 152 | } 153 | 154 | type FAST_FUNC xstrto(_range)(const char *numstr, int base, type lower, type upper) 155 | { 156 | return xstrto(_range_sfx)(numstr, base, lower, upper, NULL); 157 | } 158 | 159 | type FAST_FUNC xstrto()(const char *numstr, int base) 160 | { 161 | return xstrto(_range_sfx)(numstr, base, XSTR_TYPE_MIN, XSTR_TYPE_MAX, NULL); 162 | } 163 | 164 | type FAST_FUNC xato(_range_sfx)(const char *numstr, 165 | type lower, 166 | type upper, 167 | const struct suffix_mult *suffixes) 168 | { 169 | return xstrto(_range_sfx)(numstr, 10, lower, upper, suffixes); 170 | } 171 | 172 | type FAST_FUNC xato(_range)(const char *numstr, type lower, type upper) 173 | { 174 | return xstrto(_range_sfx)(numstr, 10, lower, upper, NULL); 175 | } 176 | 177 | type FAST_FUNC xato(_sfx)(const char *numstr, const struct suffix_mult *suffixes) 178 | { 179 | return xstrto(_range_sfx)(numstr, 10, XSTR_TYPE_MIN, XSTR_TYPE_MAX, suffixes); 180 | } 181 | 182 | type FAST_FUNC xato()(const char *numstr) 183 | { 184 | return xstrto(_range_sfx)(numstr, 10, XSTR_TYPE_MIN, XSTR_TYPE_MAX, NULL); 185 | } 186 | 187 | #undef type 188 | #undef xstrtou 189 | #undef xstrto 190 | #undef xatou 191 | #undef xato 192 | #undef XSTR_UTYPE_MAX 193 | #undef XSTR_TYPE_MAX 194 | #undef XSTR_TYPE_MIN 195 | #undef XSTR_STRTOU 196 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/src/bb_pwd.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * password utility routines. 4 | * 5 | * Copyright (C) 1999-2004 by Erik Andersen 6 | * Copyright (C) 2008 by Tito Ragusa 7 | * 8 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. 9 | */ 10 | 11 | #include "libbb.h" 12 | 13 | /* TODO: maybe change API to return malloced data? 14 | * This will allow to stop using libc functions returning 15 | * pointers to static data (getpwuid) 16 | */ 17 | 18 | struct passwd* FAST_FUNC xgetpwnam(const char *name) 19 | { 20 | struct passwd *pw = getpwnam(name); 21 | if (!pw) 22 | bb_error_msg_and_die("unknown user %s", name); 23 | return pw; 24 | } 25 | 26 | struct group* FAST_FUNC xgetgrnam(const char *name) 27 | { 28 | struct group *gr = getgrnam(name); 29 | if (!gr) 30 | bb_error_msg_and_die("unknown group %s", name); 31 | return gr; 32 | } 33 | 34 | 35 | struct passwd* FAST_FUNC xgetpwuid(uid_t uid) 36 | { 37 | struct passwd *pw = getpwuid(uid); 38 | if (!pw) 39 | bb_error_msg_and_die("unknown uid %u", (unsigned)uid); 40 | return pw; 41 | } 42 | 43 | struct group* FAST_FUNC xgetgrgid(gid_t gid) 44 | { 45 | struct group *gr = getgrgid(gid); 46 | if (!gr) 47 | bb_error_msg_and_die("unknown gid %u", (unsigned)gid); 48 | return gr; 49 | } 50 | 51 | char* FAST_FUNC xuid2uname(uid_t uid) 52 | { 53 | struct passwd *pw = xgetpwuid(uid); 54 | return pw->pw_name; 55 | } 56 | 57 | char* FAST_FUNC xgid2group(gid_t gid) 58 | { 59 | struct group *gr = xgetgrgid(gid); 60 | return gr->gr_name; 61 | } 62 | 63 | char* FAST_FUNC uid2uname(uid_t uid) 64 | { 65 | struct passwd *pw = getpwuid(uid); 66 | return (pw) ? pw->pw_name : NULL; 67 | } 68 | 69 | char* FAST_FUNC gid2group(gid_t gid) 70 | { 71 | struct group *gr = getgrgid(gid); 72 | return (gr) ? gr->gr_name : NULL; 73 | } 74 | 75 | char* FAST_FUNC uid2uname_utoa(uid_t uid) 76 | { 77 | char *name = uid2uname(uid); 78 | return (name) ? name : utoa(uid); 79 | } 80 | 81 | char* FAST_FUNC gid2group_utoa(gid_t gid) 82 | { 83 | char *name = gid2group(gid); 84 | return (name) ? name : utoa(gid); 85 | } 86 | 87 | long FAST_FUNC xuname2uid(const char *name) 88 | { 89 | struct passwd *myuser; 90 | 91 | myuser = xgetpwnam(name); 92 | return myuser->pw_uid; 93 | } 94 | 95 | long FAST_FUNC xgroup2gid(const char *name) 96 | { 97 | struct group *mygroup; 98 | 99 | mygroup = xgetgrnam(name); 100 | return mygroup->gr_gid; 101 | } 102 | 103 | unsigned long FAST_FUNC get_ug_id(const char *s, 104 | long FAST_FUNC (*xname2id)(const char *)) 105 | { 106 | unsigned long r; 107 | 108 | r = bb_strtoul(s, NULL, 10); 109 | if (errno) 110 | return xname2id(s); 111 | return r; 112 | } 113 | 114 | /* Experimental "mallocing" API. 115 | * The goal is nice: "we want to support a case when "guests" group is very large" 116 | * but the code is butt-ugly. 117 | */ 118 | #if 0 119 | static char *find_latest(char last, char *cp) 120 | { 121 | if (!cp) 122 | return last; 123 | cp += strlen(cp) + 1; 124 | if (last < cp) 125 | last = cp; 126 | return last; 127 | } 128 | 129 | struct group* FAST_FUNC xmalloc_getgrnam(const char *name) 130 | { 131 | struct { 132 | struct group gr; 133 | // May still be not enough! 134 | char buf[64*1024 - sizeof(struct group) - 16]; 135 | } *s; 136 | struct group *grp; 137 | int r; 138 | char *last; 139 | char **gr_mem; 140 | 141 | s = xmalloc(sizeof(*s)); 142 | r = getgrnam_r(name, &s->gr, s->buf, sizeof(s->buf), &grp); 143 | if (!grp) { 144 | free(s); 145 | return grp; 146 | } 147 | last = find_latest(s->buf, grp->gr_name); 148 | last = find_latest(last, grp->gr_passwd); 149 | gr_mem = grp->gr_mem; 150 | while (*gr_mem) 151 | last = find_latest(last, *gr_mem++); 152 | gr_mem++; /* points past NULL */ 153 | if (last < (char*)gr_mem) 154 | last = (char*)gr_mem; 155 | //FIXME: what if we get not only truncated, but also moved here? 156 | // grp->gr_name pointer and friends are invalid now!!! 157 | s = xrealloc(s, last - (char*)s); 158 | return grp; 159 | } 160 | #endif 161 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/src/bb_strtonum.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Utility routines. 4 | * 5 | * Copyright (C) 1999-2004 by Erik Andersen 6 | * 7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 | */ 9 | 10 | #include "libbb.h" 11 | 12 | /* On exit: errno = 0 only if there was non-empty, '\0' terminated value 13 | * errno = EINVAL if value was not '\0' terminated, but otherwise ok 14 | * Return value is still valid, caller should just check whether end[0] 15 | * is a valid terminating char for particular case. OTOH, if caller 16 | * requires '\0' terminated input, [s]he can just check errno == 0. 17 | * errno = ERANGE if value had alphanumeric terminating char ("1234abcg"). 18 | * errno = ERANGE if value is out of range, missing, etc. 19 | * errno = ERANGE if value had minus sign for strtouXX (even "-0" is not ok ) 20 | * return value is all-ones in this case. 21 | * 22 | * Test code: 23 | * char *endptr; 24 | * const char *minus = "-"; 25 | * errno = 0; 26 | * bb_strtoi(minus, &endptr, 0); // must set ERANGE 27 | * printf("minus:%p endptr:%p errno:%d EINVAL:%d\n", minus, endptr, errno, EINVAL); 28 | * errno = 0; 29 | * bb_strtoi("-0-", &endptr, 0); // must set EINVAL and point to second '-' 30 | * printf("endptr[0]:%c errno:%d EINVAL:%d\n", endptr[0], errno, EINVAL); 31 | */ 32 | 33 | static unsigned long long ret_ERANGE(void) 34 | { 35 | errno = ERANGE; /* this ain't as small as it looks (on glibc) */ 36 | return ULLONG_MAX; 37 | } 38 | 39 | static unsigned long long handle_errors(unsigned long long v, char **endp) 40 | { 41 | char next_ch = **endp; 42 | 43 | /* errno is already set to ERANGE by strtoXXX if value overflowed */ 44 | if (next_ch) { 45 | /* "1234abcg" or out-of-range? */ 46 | if (isalnum(next_ch) || errno) 47 | return ret_ERANGE(); 48 | /* good number, just suspicious terminator */ 49 | errno = EINVAL; 50 | } 51 | return v; 52 | } 53 | 54 | 55 | unsigned long long FAST_FUNC bb_strtoull(const char *arg, char **endp, int base) 56 | { 57 | unsigned long long v; 58 | char *endptr; 59 | 60 | if (!endp) endp = &endptr; 61 | *endp = (char*) arg; 62 | 63 | /* strtoul(" -4200000000") returns 94967296, errno 0 (!) */ 64 | /* I don't think that this is right. Preventing this... */ 65 | if (!isalnum(arg[0])) return ret_ERANGE(); 66 | 67 | /* not 100% correct for lib func, but convenient for the caller */ 68 | errno = 0; 69 | v = strtoull(arg, endp, base); 70 | return handle_errors(v, endp); 71 | } 72 | 73 | long long FAST_FUNC bb_strtoll(const char *arg, char **endp, int base) 74 | { 75 | unsigned long long v; 76 | char *endptr; 77 | char first; 78 | 79 | if (!endp) endp = &endptr; 80 | *endp = (char*) arg; 81 | 82 | /* Check for the weird "feature": 83 | * a "-" string is apparently a valid "number" for strto[u]l[l]! 84 | * It returns zero and errno is 0! :( */ 85 | first = (arg[0] != '-' ? arg[0] : arg[1]); 86 | if (!isalnum(first)) return ret_ERANGE(); 87 | 88 | errno = 0; 89 | v = strtoll(arg, endp, base); 90 | return handle_errors(v, endp); 91 | } 92 | 93 | #if ULONG_MAX != ULLONG_MAX 94 | unsigned long FAST_FUNC bb_strtoul(const char *arg, char **endp, int base) 95 | { 96 | unsigned long v; 97 | char *endptr; 98 | 99 | if (!endp) endp = &endptr; 100 | *endp = (char*) arg; 101 | 102 | if (!isalnum(arg[0])) return ret_ERANGE(); 103 | errno = 0; 104 | v = strtoul(arg, endp, base); 105 | return handle_errors(v, endp); 106 | } 107 | 108 | long FAST_FUNC bb_strtol(const char *arg, char **endp, int base) 109 | { 110 | long v; 111 | char *endptr; 112 | char first; 113 | 114 | if (!endp) endp = &endptr; 115 | *endp = (char*) arg; 116 | 117 | first = (arg[0] != '-' ? arg[0] : arg[1]); 118 | if (!isalnum(first)) return ret_ERANGE(); 119 | 120 | errno = 0; 121 | v = strtol(arg, endp, base); 122 | return handle_errors(v, endp); 123 | } 124 | #endif 125 | 126 | #if UINT_MAX != ULONG_MAX 127 | unsigned FAST_FUNC bb_strtou(const char *arg, char **endp, int base) 128 | { 129 | unsigned long v; 130 | char *endptr; 131 | 132 | if (!endp) endp = &endptr; 133 | *endp = (char*) arg; 134 | 135 | if (!isalnum(arg[0])) return ret_ERANGE(); 136 | errno = 0; 137 | v = strtoul(arg, endp, base); 138 | if (v > UINT_MAX) return ret_ERANGE(); 139 | return handle_errors(v, endp); 140 | } 141 | 142 | int FAST_FUNC bb_strtoi(const char *arg, char **endp, int base) 143 | { 144 | long v; 145 | char *endptr; 146 | char first; 147 | 148 | if (!endp) endp = &endptr; 149 | *endp = (char*) arg; 150 | 151 | first = (arg[0] != '-' ? arg[0] : arg[1]); 152 | if (!isalnum(first)) return ret_ERANGE(); 153 | 154 | errno = 0; 155 | v = strtol(arg, endp, base); 156 | if (v > INT_MAX) return ret_ERANGE(); 157 | if (v < INT_MIN) return ret_ERANGE(); 158 | return handle_errors(v, endp); 159 | } 160 | 161 | static const char *applet_name = "debug stuff usage"; 162 | void bb_show_usage(void) 163 | { 164 | fprintf(stderr, "Usage: %s [-p] [-r] [-t] -[x] [-n max_arg] [-s max_chars]\n", 165 | applet_name); 166 | exit(EXIT_FAILURE); 167 | } 168 | #endif 169 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/src/copyfd.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Utility routines. 4 | * 5 | * Copyright (C) 1999-2005 by Erik Andersen 6 | * 7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 | */ 9 | 10 | #include "libbb.h" 11 | 12 | /* Used by NOFORK applets (e.g. cat) - must not use xmalloc. 13 | * size < 0 means "ignore write errors", used by tar --to-command 14 | * size = 0 means "copy till EOF" 15 | */ 16 | static off_t bb_full_fd_action(int src_fd, int dst_fd, off_t size) 17 | { 18 | int status = -1; 19 | off_t total = 0; 20 | bool continue_on_write_error = 0; 21 | #if CONFIG_FEATURE_COPYBUF_KB <= 4 22 | char buffer[CONFIG_FEATURE_COPYBUF_KB * 1024]; 23 | enum { buffer_size = sizeof(buffer) }; 24 | #else 25 | char *buffer; 26 | int buffer_size; 27 | #endif 28 | 29 | if (size < 0) { 30 | size = -size; 31 | continue_on_write_error = 1; 32 | } 33 | 34 | #if CONFIG_FEATURE_COPYBUF_KB > 4 35 | if (size > 0 && size <= 4 * 1024) 36 | goto use_small_buf; 37 | /* We want page-aligned buffer, just in case kernel is clever 38 | * and can do page-aligned io more efficiently */ 39 | buffer = mmap(NULL, CONFIG_FEATURE_COPYBUF_KB * 1024, 40 | PROT_READ | PROT_WRITE, 41 | MAP_PRIVATE | MAP_ANON, 42 | /* ignored: */ -1, 0); 43 | buffer_size = CONFIG_FEATURE_COPYBUF_KB * 1024; 44 | if (buffer == MAP_FAILED) { 45 | use_small_buf: 46 | buffer = alloca(4 * 1024); 47 | buffer_size = 4 * 1024; 48 | } 49 | #endif 50 | 51 | if (src_fd < 0) 52 | goto out; 53 | 54 | if (!size) { 55 | size = buffer_size; 56 | status = 1; /* copy until eof */ 57 | } 58 | 59 | while (1) { 60 | ssize_t rd; 61 | 62 | rd = safe_read(src_fd, buffer, size > buffer_size ? buffer_size : size); 63 | 64 | if (!rd) { /* eof - all done */ 65 | status = 0; 66 | break; 67 | } 68 | if (rd < 0) { 69 | bb_perror_msg(bb_msg_read_error); 70 | break; 71 | } 72 | /* dst_fd == -1 is a fake, else... */ 73 | if (dst_fd >= 0) { 74 | ssize_t wr = full_write(dst_fd, buffer, rd); 75 | if (wr < rd) { 76 | if (!continue_on_write_error) { 77 | bb_perror_msg(bb_msg_write_error); 78 | break; 79 | } 80 | dst_fd = -1; 81 | } 82 | } 83 | total += rd; 84 | if (status < 0) { /* if we aren't copying till EOF... */ 85 | size -= rd; 86 | if (!size) { 87 | /* 'size' bytes copied - all done */ 88 | status = 0; 89 | break; 90 | } 91 | } 92 | } 93 | out: 94 | 95 | #if CONFIG_FEATURE_COPYBUF_KB > 4 96 | if (buffer_size != 4 * 1024) 97 | munmap(buffer, buffer_size); 98 | #endif 99 | return status ? -1 : total; 100 | } 101 | 102 | 103 | #if 0 104 | void FAST_FUNC complain_copyfd_and_die(off_t sz) 105 | { 106 | if (sz != -1) 107 | bb_error_msg_and_die("short read"); 108 | /* if sz == -1, bb_copyfd_XX already complained */ 109 | xfunc_die(); 110 | } 111 | #endif 112 | 113 | off_t FAST_FUNC bb_copyfd_size(int fd1, int fd2, off_t size) 114 | { 115 | if (size) { 116 | return bb_full_fd_action(fd1, fd2, size); 117 | } 118 | return 0; 119 | } 120 | 121 | void FAST_FUNC bb_copyfd_exact_size(int fd1, int fd2, off_t size) 122 | { 123 | off_t sz = bb_copyfd_size(fd1, fd2, size); 124 | if (sz == (size >= 0 ? size : -size)) 125 | return; 126 | if (sz != -1) 127 | bb_error_msg_and_die("short read"); 128 | /* if sz == -1, bb_copyfd_XX already complained */ 129 | xfunc_die(); 130 | } 131 | 132 | off_t FAST_FUNC bb_copyfd_eof(int fd1, int fd2) 133 | { 134 | return bb_full_fd_action(fd1, fd2, 0); 135 | } 136 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/src/default_error_retval.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Copyright (C) 2003 Manuel Novoa III 4 | * 5 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. 6 | */ 7 | 8 | /* Seems silly to copyright a global variable. ;-) Oh well. 9 | * 10 | * At least one applet (cmp) returns a value different from the typical 11 | * EXIT_FAILURE values (1) when an error occurs. So, make it configurable 12 | * by the applet. I suppose we could use a wrapper function to set it, but 13 | * that too seems silly. 14 | */ 15 | 16 | #include "libbb.h" 17 | 18 | uint8_t xfunc_error_retval = EXIT_FAILURE; 19 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/src/dmesg.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * 4 | * dmesg - display/control kernel ring buffer. 5 | * 6 | * Copyright 2006 Rob Landley 7 | * Copyright 2006 Bernhard Reutner-Fischer 8 | * 9 | * Licensed under GPLv2, see file LICENSE in this source tree. 10 | */ 11 | 12 | //usage:#define dmesg_trivial_usage 13 | //usage: "[-c] [-n LEVEL] [-s SIZE]" 14 | //usage:#define dmesg_full_usage "\n\n" 15 | //usage: "Print or control the kernel ring buffer\n" 16 | //usage: "\n -c Clear ring buffer after printing" 17 | //usage: "\n -n LEVEL Set console logging level" 18 | //usage: "\n -s SIZE Buffer size" 19 | 20 | #include 21 | #include "libbb.h" 22 | 23 | int dmesg_main(int argc, char **argv, int fd) //MAIN_EXTERNALLY_VISIBLE; 24 | //int dmesg_main(int argc UNUSED_PARAM, char **argv) 25 | { 26 | int len = 2048, level; 27 | char *buf; 28 | unsigned opts = 0; 29 | enum { 30 | OPT_c = 1 << 0, 31 | OPT_s = 1 << 1, 32 | OPT_n = 1 << 2 33 | }; 34 | 35 | FILE *fp = fdopen(fd, "w"); 36 | if(fp == NULL) return EXIT_SUCCESS; 37 | 38 | opt_complementary = "s+:n+"; /* numeric */ 39 | opts = getopt32(argv, "cs:n:", &len, &level); 40 | if (opts & OPT_n) { 41 | if (klogctl(8, NULL, (long) level)) 42 | bb_perror_msg_and_die("klogctl"); 43 | return EXIT_SUCCESS; 44 | } 45 | 46 | #if 0 47 | if (!(opts & OPT_s)) 48 | len = klogctl(10, NULL, 0); /* read ring buffer size */ 49 | if (len < 16*1024) 50 | len = 16*1024; 51 | if (len > 16*1024*1024) 52 | len = 16*1024*1024; 53 | #endif 54 | buf = malloc(len); 55 | len = klogctl(3 + (opts & OPT_c), buf, len); /* read ring buffer */ 56 | if (len < 0) 57 | //bb_perror_msg_and_die("klogctl"); 58 | goto exit; 59 | if (len == 0) 60 | //return EXIT_SUCCESS; 61 | goto exit; 62 | 63 | 64 | //if (ENABLE_FEATURE_DMESG_PRETTY) { 65 | if (0) { 66 | int last = '\n'; 67 | int in = 0; 68 | 69 | /* Skip <[0-9]+> at the start of lines */ 70 | while (1) { 71 | if (last == '\n' && buf[in] == '<') { 72 | while (buf[in++] != '>' && in < len) 73 | ; 74 | } else { 75 | last = buf[in++]; 76 | putchar(last); 77 | } 78 | if (in >= len) 79 | break; 80 | } 81 | /* Make sure we end with a newline */ 82 | if (last != '\n') 83 | bb_putchar('\n'); 84 | } else { 85 | //full_write(STDOUT_FILENO, buf, len); 86 | //if (buf[len-1] != '\n') 87 | //bb_putchar('\n'); 88 | fprintf(fp,"%s\n",buf); 89 | } 90 | 91 | //if (ENABLE_FEATURE_CLEAN_UP) free(buf); 92 | exit: 93 | free(buf); 94 | fclose(fp); 95 | return EXIT_SUCCESS; 96 | } 97 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/src/find_mount_point.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Utility routines. 4 | * 5 | * Copyright (C) 1999-2004 by Erik Andersen 6 | * 7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 | */ 9 | 10 | #include "libbb.h" 11 | #include 12 | 13 | /* 14 | * Given a block device, find the mount table entry if that block device 15 | * is mounted. 16 | * 17 | * Given any other file (or directory), find the mount table entry for its 18 | * filesystem. 19 | */ 20 | struct mntent* FAST_FUNC find_mount_point(const char *name, int subdir_too) 21 | { 22 | struct stat s; 23 | FILE *mtab_fp; 24 | struct mntent *mountEntry; 25 | dev_t devno_of_name; 26 | bool block_dev; 27 | 28 | if (stat(name, &s) != 0) 29 | return NULL; 30 | 31 | devno_of_name = s.st_dev; 32 | block_dev = 0; 33 | /* Why S_ISCHR? - UBI volumes use char devices, not block */ 34 | if (S_ISBLK(s.st_mode) || S_ISCHR(s.st_mode)) { 35 | devno_of_name = s.st_rdev; 36 | block_dev = 1; 37 | } 38 | 39 | mtab_fp = setmntent(bb_path_mtab_file, "r"); 40 | if (!mtab_fp) 41 | return NULL; 42 | 43 | while ((mountEntry = getmntent(mtab_fp)) != NULL) { 44 | /* rootfs mount in Linux 2.6 exists always, 45 | * and it makes sense to always ignore it. 46 | * Otherwise people can't reference their "real" root! */ 47 | if (ENABLE_FEATURE_SKIP_ROOTFS && strcmp(mountEntry->mnt_fsname, "rootfs") == 0) 48 | continue; 49 | 50 | if (strcmp(name, mountEntry->mnt_dir) == 0 51 | || strcmp(name, mountEntry->mnt_fsname) == 0 52 | ) { /* String match. */ 53 | break; 54 | } 55 | 56 | if (!(subdir_too || block_dev)) 57 | continue; 58 | 59 | /* Is device's dev_t == name's dev_t? */ 60 | if (stat(mountEntry->mnt_fsname, &s) == 0 && s.st_rdev == devno_of_name) 61 | break; 62 | /* Match the directory's mount point. */ 63 | if (stat(mountEntry->mnt_dir, &s) == 0 && s.st_dev == devno_of_name) 64 | break; 65 | } 66 | endmntent(mtab_fp); 67 | 68 | return mountEntry; 69 | } 70 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/src/free.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Mini free implementation for busybox 4 | * 5 | * Copyright (C) 1999-2004 by Erik Andersen 6 | * 7 | * Licensed under GPLv2, see file LICENSE in this source tree. 8 | */ 9 | 10 | /* getopt not needed */ 11 | 12 | //usage:#define free_trivial_usage 13 | //usage: "" IF_DESKTOP("[-b/k/m/g]") 14 | //usage:#define free_full_usage "\n\n" 15 | //usage: "Display the amount of free and used system memory" 16 | //usage: 17 | //usage:#define free_example_usage 18 | //usage: "$ free\n" 19 | //usage: " total used free shared buffers\n" 20 | //usage: " Mem: 257628 248724 8904 59644 93124\n" 21 | //usage: " Swap: 128516 8404 120112\n" 22 | //usage: "Total: 386144 257128 129016\n" 23 | 24 | #include "libbb.h" 25 | #ifdef __linux__ 26 | # include 27 | #endif 28 | #include 29 | 30 | struct globals { 31 | unsigned mem_unit; 32 | #if ENABLE_DESKTOP 33 | unsigned unit_steps; 34 | # define G_unit_steps G.unit_steps 35 | #else 36 | # define G_unit_steps 10 37 | #endif 38 | } FIX_ALIASING; 39 | #define G (*(struct globals*)&bb_common_bufsiz1) 40 | #define INIT_G() do { memset(bb_common_bufsiz1, 0, sizeof(struct globals)); } while (0) 41 | 42 | 43 | static unsigned long long scale(unsigned long d) 44 | { 45 | return ((unsigned long long)d * G.mem_unit) >> G_unit_steps; 46 | } 47 | 48 | static unsigned long get_cache_from_meminfo(void) 49 | { 50 | #define LINE_LEN 256 51 | FILE *fp; 52 | char str[LINE_LEN]; 53 | unsigned long long cached; 54 | if((fp = fopen("/proc/meminfo","rt")) == NULL) { 55 | printf("Cantnot open /proc/meminfo"); 56 | exit(1); 57 | } 58 | 59 | while(1) { 60 | fgets(str, LINE_LEN, fp); 61 | if (!strncmp(str, "Cached:", strlen("Cached:"))) 62 | break; 63 | } 64 | 65 | cached = atoi(str + strlen("Cached:")); 66 | 67 | fclose(fp); 68 | 69 | return cached; 70 | } 71 | 72 | int free_main(int argc, char **argv, int fd) //MAIN_EXTERNALLY_VISIBLE; 73 | //int free_main(int argc UNUSED_PARAM, char **argv IF_NOT_DESKTOP(UNUSED_PARAM)) 74 | { 75 | struct sysinfo info; 76 | unsigned long long cached; 77 | 78 | FILE *fp = fdopen(fd, "w"); 79 | if(fp == NULL) return EXIT_SUCCESS; 80 | 81 | INIT_G(); 82 | 83 | #if ENABLE_DESKTOP 84 | 85 | G.unit_steps = 10; 86 | 87 | if (argv[1] && argv[1][0] == '-') { 88 | switch (argv[1][1]) { 89 | case 'b': 90 | G.unit_steps = 0; 91 | break; 92 | case 'k': /* 2^10 */ 93 | /* G.unit_steps = 10; - already is */ 94 | break; 95 | case 'm': /* 2^(2*10) */ 96 | G.unit_steps = 20; 97 | break; 98 | case 'g': /* 2^(3*10) */ 99 | G.unit_steps = 30; 100 | break; 101 | default: 102 | //bb_show_usage(); 103 | break; 104 | } 105 | } 106 | #endif 107 | 108 | sysinfo(&info); 109 | cached = get_cache_from_meminfo(); 110 | /* Kernels prior to 2.4.x will return info.mem_unit==0, so cope... */ 111 | G.mem_unit = (info.mem_unit ? info.mem_unit : 1); 112 | 113 | fprintf(fp," %13s%13s%13s%13s%13s%13s\n", 114 | "total", 115 | "used", 116 | "free", 117 | "shared", "buffers", "cached" /* swap and total don't have these columns */ 118 | /* procps version 3.2.8 also shows "cached" column, but 119 | * sysinfo() does not provide this value, need to parse 120 | * /proc/meminfo instead and get "Cached: NNN kB" from there. 121 | */ 122 | ); 123 | 124 | #define FIELDS_6 "%13llu%13llu%13llu%13llu%13llu%13llu\n" 125 | #define FIELDS_3 (FIELDS_6 + 3*6) 126 | #define FIELDS_2 (FIELDS_6 + 4*6) 127 | 128 | fprintf(fp,"Mem: "); 129 | fprintf(fp,FIELDS_6, 130 | scale(info.totalram), 131 | scale(info.totalram - info.freeram), 132 | scale(info.freeram), 133 | scale(info.sharedram), 134 | scale(info.bufferram), 135 | cached 136 | ); 137 | /* Show alternate, more meaningful busy/free numbers by counting 138 | * buffer cache as free memory (make it "-/+ buffers/cache" 139 | * if/when we add support for "cached" column): */ 140 | fprintf(fp,"-/+ buffers/cache: "); 141 | fprintf(fp,FIELDS_2, 142 | scale(info.totalram - info.freeram - info.bufferram) - cached, 143 | scale(info.freeram + info.bufferram) + cached 144 | ); 145 | #if BB_MMU 146 | fprintf(fp,"Swap: "); 147 | fprintf(fp,FIELDS_3, 148 | scale(info.totalswap), 149 | scale(info.totalswap - info.freeswap), 150 | scale(info.freeswap) 151 | ); 152 | #endif 153 | fclose(fp); 154 | return EXIT_SUCCESS; 155 | } 156 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/src/full_write.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Utility routines. 4 | * 5 | * Copyright (C) 1999-2004 by Erik Andersen 6 | * 7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 | */ 9 | 10 | #include "libbb.h" 11 | 12 | /* 13 | * Write all of the supplied buffer out to a file. 14 | * This does multiple writes as necessary. 15 | * Returns the amount written, or -1 on an error. 16 | */ 17 | ssize_t FAST_FUNC full_write(int fd, const void *buf, size_t len) 18 | { 19 | ssize_t cc; 20 | ssize_t total; 21 | 22 | total = 0; 23 | 24 | while (len) { 25 | cc = safe_write(fd, buf, len); 26 | 27 | if (cc < 0) { 28 | if (total) { 29 | /* we already wrote some! */ 30 | /* user can do another write to know the error code */ 31 | return total; 32 | } 33 | return cc; /* write() returns -1 on failure. */ 34 | } 35 | 36 | total += cc; 37 | buf = ((const char *)buf) + cc; 38 | len -= cc; 39 | } 40 | 41 | return total; 42 | } 43 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/src/get_last_path_component.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * bb_get_last_path_component implementation for busybox 4 | * 5 | * Copyright (C) 2001 Manuel Novoa III 6 | * 7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 | */ 9 | #include "libbb.h" 10 | 11 | const char* FAST_FUNC bb_basename(const char *name) 12 | { 13 | const char *cp = strrchr(name, '/'); 14 | if (cp) 15 | return cp + 1; 16 | return name; 17 | } 18 | 19 | /* 20 | * "/" -> "/" 21 | * "abc" -> "abc" 22 | * "abc/def" -> "def" 23 | * "abc/def/" -> "" 24 | */ 25 | char* FAST_FUNC bb_get_last_path_component_nostrip(const char *path) 26 | { 27 | char *slash = strrchr(path, '/'); 28 | 29 | if (!slash || (slash == path && !slash[1])) 30 | return (char*)path; 31 | 32 | return slash + 1; 33 | } 34 | 35 | /* 36 | * "/" -> "/" 37 | * "abc" -> "abc" 38 | * "abc/def" -> "def" 39 | * "abc/def/" -> "def" !! 40 | */ 41 | char* FAST_FUNC bb_get_last_path_component_strip(char *path) 42 | { 43 | char *slash = last_char_is(path, '/'); 44 | 45 | if (slash) 46 | while (*slash == '/' && slash != path) 47 | *slash-- = '\0'; 48 | 49 | return bb_get_last_path_component_nostrip(path); 50 | } 51 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/src/human_readable.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * June 30, 2001 Manuel Novoa III 4 | * 5 | * All-integer version (hey, not everyone has floating point) of 6 | * make_human_readable_str, modified from similar code I had written 7 | * for busybox several months ago. 8 | * 9 | * Notes: 10 | * 1) I'm using an unsigned long long to hold the product size * block_size, 11 | * as df (which calls this routine) could request a representation of a 12 | * partition size in bytes > max of unsigned long. If long longs aren't 13 | * available, it would be possible to do what's needed using polynomial 14 | * representations (say, powers of 1024) and manipulating coefficients. 15 | * The base ten "bytes" output could be handled similarly. 16 | * 17 | * 2) This routine always outputs a decimal point and a tenths digit when 18 | * display_unit != 0. Hence, it isn't uncommon for the returned string 19 | * to have a length of 5 or 6. 20 | * 21 | * It might be nice to add a flag to indicate no decimal digits in 22 | * that case. This could be either an additional parameter, or a 23 | * special value of display_unit. Such a flag would also be nice for du. 24 | * 25 | * Some code to omit the decimal point and tenths digit is sketched out 26 | * and "#if 0"'d below. 27 | * 28 | * Licensed under GPLv2, see file LICENSE in this source tree. 29 | */ 30 | 31 | #include "libbb.h" 32 | 33 | const char* FAST_FUNC make_human_readable_str(unsigned long long val, 34 | unsigned long block_size, unsigned long display_unit) 35 | { 36 | static const char unit_chars[] ALIGN1 = { 37 | '\0', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' 38 | }; 39 | 40 | static char *str; 41 | 42 | unsigned frac; /* 0..9 - the fractional digit */ 43 | const char *u; 44 | const char *fmt; 45 | 46 | if (val == 0) 47 | return "0"; 48 | 49 | fmt = "%llu"; 50 | if (block_size > 1) 51 | val *= block_size; 52 | frac = 0; 53 | u = unit_chars; 54 | 55 | if (display_unit) { 56 | val += display_unit/2; /* Deal with rounding */ 57 | val /= display_unit; /* Don't combine with the line above! */ 58 | /* will just print it as ulonglong (below) */ 59 | } else { 60 | while ((val >= 1024) 61 | /* && (u < unit_chars + sizeof(unit_chars) - 1) - always true */ 62 | ) { 63 | fmt = "%llu.%u%c"; 64 | u++; 65 | frac = (((unsigned)val % 1024) * 10 + 1024/2) / 1024; 66 | val /= 1024; 67 | } 68 | if (frac >= 10) { /* we need to round up here */ 69 | ++val; 70 | frac = 0; 71 | } 72 | #if 1 73 | /* If block_size is 0, dont print fractional part */ 74 | if (block_size == 0) { 75 | if (frac >= 5) { 76 | ++val; 77 | } 78 | fmt = "%llu%*c"; 79 | frac = 1; 80 | } 81 | #endif 82 | } 83 | 84 | if (!str) { 85 | /* sufficient for any width of val */ 86 | str = xmalloc(sizeof(val)*3 + 2 + 3); 87 | } 88 | sprintf(str, fmt, val, frac, *u); 89 | return str; 90 | } 91 | 92 | 93 | /* vda's implementations of the similar idea */ 94 | 95 | /* Convert unsigned long long value into compact 5-char representation. 96 | * String is not terminated (buf[5] is untouched) */ 97 | char* FAST_FUNC smart_ulltoa5(unsigned long long ul, char buf[5], const char *scale) 98 | { 99 | const char *fmt; 100 | char c; 101 | unsigned v, u, idx = 0; 102 | 103 | if (ul > 99999) { // do not scale if 99999 or less 104 | ul *= 10; 105 | do { 106 | ul /= 1024; 107 | idx++; 108 | } while (ul >= 100000); 109 | } 110 | v = ul; // ullong divisions are expensive, avoid them 111 | 112 | fmt = " 123456789"; 113 | u = v / 10; 114 | v = v % 10; 115 | if (!idx) { 116 | // 99999 or less: use "12345" format 117 | // u is value/10, v is last digit 118 | c = buf[0] = " 123456789"[u/1000]; 119 | if (c != ' ') fmt = "0123456789"; 120 | c = buf[1] = fmt[u/100%10]; 121 | if (c != ' ') fmt = "0123456789"; 122 | c = buf[2] = fmt[u/10%10]; 123 | if (c != ' ') fmt = "0123456789"; 124 | buf[3] = fmt[u%10]; 125 | buf[4] = "0123456789"[v]; 126 | } else { 127 | // value has been scaled into 0..9999.9 range 128 | // u is value, v is 1/10ths (allows for 92.1M format) 129 | if (u >= 100) { 130 | // value is >= 100: use "1234M', " 123M" formats 131 | c = buf[0] = " 123456789"[u/1000]; 132 | if (c != ' ') fmt = "0123456789"; 133 | c = buf[1] = fmt[u/100%10]; 134 | if (c != ' ') fmt = "0123456789"; 135 | v = u % 10; 136 | u = u / 10; 137 | buf[2] = fmt[u%10]; 138 | } else { 139 | // value is < 100: use "92.1M" format 140 | c = buf[0] = " 123456789"[u/10]; 141 | if (c != ' ') fmt = "0123456789"; 142 | buf[1] = fmt[u%10]; 143 | buf[2] = '.'; 144 | } 145 | buf[3] = "0123456789"[v]; 146 | buf[4] = scale[idx]; /* typically scale = " kmgt..." */ 147 | } 148 | return buf + 5; 149 | } 150 | 151 | /* Convert unsigned long long value into compact 4-char 152 | * representation. Examples: "1234", "1.2k", " 27M", "123T" 153 | * String is not terminated (buf[4] is untouched) */ 154 | char* FAST_FUNC smart_ulltoa4(unsigned long long ul, char buf[4], const char *scale) 155 | { 156 | const char *fmt; 157 | char c; 158 | unsigned v, u, idx = 0; 159 | 160 | if (ul > 9999) { // do not scale if 9999 or less 161 | ul *= 10; 162 | do { 163 | ul /= 1024; 164 | idx++; 165 | } while (ul >= 10000); 166 | } 167 | v = ul; // ullong divisions are expensive, avoid them 168 | 169 | fmt = " 123456789"; 170 | u = v / 10; 171 | v = v % 10; 172 | if (!idx) { 173 | // 9999 or less: use "1234" format 174 | // u is value/10, v is last digit 175 | c = buf[0] = " 123456789"[u/100]; 176 | if (c != ' ') fmt = "0123456789"; 177 | c = buf[1] = fmt[u/10%10]; 178 | if (c != ' ') fmt = "0123456789"; 179 | buf[2] = fmt[u%10]; 180 | buf[3] = "0123456789"[v]; 181 | } else { 182 | // u is value, v is 1/10ths (allows for 9.2M format) 183 | if (u >= 10) { 184 | // value is >= 10: use "123M', " 12M" formats 185 | c = buf[0] = " 123456789"[u/100]; 186 | if (c != ' ') fmt = "0123456789"; 187 | v = u % 10; 188 | u = u / 10; 189 | buf[1] = fmt[u%10]; 190 | } else { 191 | // value is < 10: use "9.2M" format 192 | buf[0] = "0123456789"[u]; 193 | buf[1] = '.'; 194 | } 195 | buf[2] = "0123456789"[v]; 196 | buf[3] = scale[idx]; /* typically scale = " kmgt..." */ 197 | } 198 | return buf + 4; 199 | } 200 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/src/last_char_is.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * busybox library eXtended function 4 | * 5 | * Copyright (C) 2001 Larry Doolittle, 6 | * 7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 | */ 9 | 10 | #include "libbb.h" 11 | 12 | /* Find out if the last character of a string matches the one given. 13 | * Don't underrun the buffer if the string length is 0. 14 | */ 15 | char* FAST_FUNC last_char_is(const char *s, int c) 16 | { 17 | if (s && *s) { 18 | size_t sz = strlen(s) - 1; 19 | s += sz; 20 | if ( (unsigned char)*s == c) 21 | return (char*)s; 22 | } 23 | return NULL; 24 | } 25 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/src/llist.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * linked list helper functions. 4 | * 5 | * Copyright (C) 2003 Glenn McGrath 6 | * Copyright (C) 2005 Vladimir Oleynik 7 | * Copyright (C) 2005 Bernhard Reutner-Fischer 8 | * Copyright (C) 2006 Rob Landley 9 | * 10 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. 11 | */ 12 | 13 | #include "libbb.h" 14 | 15 | /* Add data to the start of the linked list. */ 16 | void FAST_FUNC llist_add_to(llist_t **old_head, void *data) 17 | { 18 | llist_t *new_head = xmalloc(sizeof(llist_t)); 19 | 20 | new_head->data = data; 21 | new_head->link = *old_head; 22 | *old_head = new_head; 23 | } 24 | 25 | /* Add data to the end of the linked list. */ 26 | void FAST_FUNC llist_add_to_end(llist_t **list_head, void *data) 27 | { 28 | while (*list_head) 29 | list_head = &(*list_head)->link; 30 | *list_head = xzalloc(sizeof(llist_t)); 31 | (*list_head)->data = data; 32 | /*(*list_head)->link = NULL;*/ 33 | } 34 | 35 | /* Remove first element from the list and return it */ 36 | void* FAST_FUNC llist_pop(llist_t **head) 37 | { 38 | void *data = NULL; 39 | llist_t *temp = *head; 40 | 41 | if (temp) { 42 | data = temp->data; 43 | *head = temp->link; 44 | free(temp); 45 | } 46 | return data; 47 | } 48 | 49 | /* Unlink arbitrary given element from the list */ 50 | void FAST_FUNC llist_unlink(llist_t **head, llist_t *elm) 51 | { 52 | if (!elm) 53 | return; 54 | while (*head) { 55 | if (*head == elm) { 56 | *head = (*head)->link; 57 | break; 58 | } 59 | head = &(*head)->link; 60 | } 61 | } 62 | 63 | /* Recursively free all elements in the linked list. If freeit != NULL 64 | * call it on each datum in the list */ 65 | void FAST_FUNC llist_free(llist_t *elm, void (*freeit)(void *data)) 66 | { 67 | while (elm) { 68 | void *data = llist_pop(&elm); 69 | 70 | if (freeit) 71 | freeit(data); 72 | } 73 | } 74 | 75 | /* Reverse list order. */ 76 | llist_t* FAST_FUNC llist_rev(llist_t *list) 77 | { 78 | llist_t *rev = NULL; 79 | 80 | while (list) { 81 | llist_t *next = list->link; 82 | 83 | list->link = rev; 84 | rev = list; 85 | list = next; 86 | } 87 | return rev; 88 | } 89 | 90 | llist_t* FAST_FUNC llist_find_str(llist_t *list, const char *str) 91 | { 92 | while (list) { 93 | if (strcmp(list->data, str) == 0) 94 | break; 95 | list = list->link; 96 | } 97 | return list; 98 | } 99 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/src/messages.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Copyright (C) 1999-2004 by Erik Andersen 4 | * 5 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. 6 | */ 7 | 8 | #include "libbb.h" 9 | 10 | /* allow default system PATH to be extended via CFLAGS */ 11 | #ifndef BB_ADDITIONAL_PATH 12 | #define BB_ADDITIONAL_PATH "" 13 | #endif 14 | 15 | /* allow version to be extended, via CFLAGS */ 16 | #ifndef BB_EXTRA_VERSION 17 | #define BB_EXTRA_VERSION BB_BT 18 | #endif 19 | 20 | #define BANNER "BusyBox v" //BB_VER " (" BB_EXTRA_VERSION ")" 21 | 22 | const char bb_banner[] ALIGN1 = BANNER; 23 | 24 | 25 | const char bb_msg_memory_exhausted[] ALIGN1 = "out of memory"; 26 | const char bb_msg_invalid_date[] ALIGN1 = "invalid date '%s'"; 27 | const char bb_msg_unknown[] ALIGN1 = "(unknown)"; 28 | const char bb_msg_can_not_create_raw_socket[] ALIGN1 = "can't create raw socket"; 29 | const char bb_msg_perm_denied_are_you_root[] ALIGN1 = "permission denied (are you root?)"; 30 | const char bb_msg_you_must_be_root[] ALIGN1 = "you must be root"; 31 | const char bb_msg_requires_arg[] ALIGN1 = "%s requires an argument"; 32 | const char bb_msg_invalid_arg[] ALIGN1 = "invalid argument '%s' to '%s'"; 33 | const char bb_msg_standard_input[] ALIGN1 = "standard input"; 34 | const char bb_msg_standard_output[] ALIGN1 = "standard output"; 35 | 36 | const char bb_hexdigits_upcase[] ALIGN1 = "0123456789ABCDEF"; 37 | 38 | const char bb_busybox_exec_path[] ALIGN1 = CONFIG_BUSYBOX_EXEC_PATH; 39 | const char bb_default_login_shell[] ALIGN1 = LIBBB_DEFAULT_LOGIN_SHELL; 40 | /* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin, 41 | * but I want to save a few bytes here. Check libbb.h before changing! */ 42 | const char bb_PATH_root_path[] ALIGN1 = 43 | "PATH=/sbin:/usr/sbin:/bin:/usr/bin" BB_ADDITIONAL_PATH; 44 | 45 | 46 | const int const_int_1 = 1; 47 | /* explicitly = 0, otherwise gcc may make it a common variable 48 | * and it will end up in bss */ 49 | const int const_int_0 = 0; 50 | 51 | #if ENABLE_FEATURE_WTMP 52 | /* This is usually something like "/var/adm/wtmp" or "/var/log/wtmp" */ 53 | const char bb_path_wtmp_file[] ALIGN1 = 54 | # if defined _PATH_WTMP 55 | _PATH_WTMP; 56 | # elif defined WTMP_FILE 57 | WTMP_FILE; 58 | # else 59 | # error unknown path to wtmp file 60 | # endif 61 | #endif 62 | 63 | /* We use it for "global" data via *(struct global*)&bb_common_bufsiz1. 64 | * Since gcc insists on aligning struct global's members, it would be a pity 65 | * (and an alignment fault on some CPUs) to mess it up. */ 66 | char bb_common_bufsiz1[COMMON_BUFSIZE] ALIGNED(sizeof(long long)); 67 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/src/perror_msg.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Utility routines. 4 | * 5 | * Copyright (C) 1999-2004 by Erik Andersen 6 | * 7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 | */ 9 | #include "libbb.h" 10 | 11 | void FAST_FUNC bb_perror_msg(const char *s, ...) 12 | { 13 | va_list p; 14 | 15 | va_start(p, s); 16 | /* Guard against ": Success" */ 17 | bb_verror_msg(s, p, errno ? strerror(errno) : NULL); 18 | va_end(p); 19 | } 20 | 21 | void FAST_FUNC bb_perror_msg_and_die(const char *s, ...) 22 | { 23 | va_list p; 24 | 25 | va_start(p, s); 26 | /* Guard against ": Success" */ 27 | bb_verror_msg(s, p, errno ? strerror(errno) : NULL); 28 | va_end(p); 29 | xfunc_die(); 30 | } 31 | 32 | void FAST_FUNC bb_simple_perror_msg(const char *s) 33 | { 34 | bb_perror_msg("%s", s); 35 | } 36 | 37 | void FAST_FUNC bb_simple_perror_msg_and_die(const char *s) 38 | { 39 | bb_perror_msg_and_die("%s", s); 40 | } 41 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/src/platform.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Replacements for common but usually nonstandard functions that aren't 3 | * supplied by all platforms. 4 | * 5 | * Copyright (C) 2009 by Dan Fandrich , et. al. 6 | * 7 | * Licensed under GPLv2, see file LICENSE in this source tree. 8 | */ 9 | #include "libbb.h" 10 | 11 | #ifndef HAVE_STRCHRNUL 12 | char* FAST_FUNC strchrnul(const char *s, int c) 13 | { 14 | while (*s != '\0' && *s != c) 15 | s++; 16 | return (char*)s; 17 | } 18 | #endif 19 | 20 | #ifndef HAVE_VASPRINTF 21 | int FAST_FUNC vasprintf(char **string_ptr, const char *format, va_list p) 22 | { 23 | int r; 24 | va_list p2; 25 | char buf[128]; 26 | 27 | va_copy(p2, p); 28 | r = vsnprintf(buf, 128, format, p); 29 | va_end(p); 30 | 31 | /* Note: can't use xstrdup/xmalloc, they call vasprintf (us) on failure! */ 32 | 33 | if (r < 128) { 34 | va_end(p2); 35 | *string_ptr = strdup(buf); 36 | return (*string_ptr ? r : -1); 37 | } 38 | 39 | *string_ptr = malloc(r+1); 40 | r = (*string_ptr ? vsnprintf(*string_ptr, r+1, format, p2) : -1); 41 | va_end(p2); 42 | 43 | return r; 44 | } 45 | #endif 46 | 47 | #ifndef HAVE_DPRINTF 48 | /* dprintf is now part of POSIX.1, but was only added in 2008 */ 49 | int dprintf(int fd, const char *format, ...) 50 | { 51 | va_list p; 52 | int r; 53 | char *string_ptr; 54 | 55 | va_start(p, format); 56 | r = vasprintf(&string_ptr, format, p); 57 | va_end(p); 58 | if (r >= 0) { 59 | r = full_write(fd, string_ptr, r); 60 | free(string_ptr); 61 | } 62 | return r; 63 | } 64 | #endif 65 | 66 | #ifndef HAVE_MEMRCHR 67 | /* Copyright (C) 2005 Free Software Foundation, Inc. 68 | * memrchr() is a GNU function that might not be available everywhere. 69 | * It's basically the inverse of memchr() - search backwards in a 70 | * memory block for a particular character. 71 | */ 72 | void* FAST_FUNC memrchr(const void *s, int c, size_t n) 73 | { 74 | const char *start = s, *end = s; 75 | 76 | end += n - 1; 77 | 78 | while (end >= start) { 79 | if (*end == (char)c) 80 | return (void *) end; 81 | end--; 82 | } 83 | 84 | return NULL; 85 | } 86 | #endif 87 | 88 | #ifndef HAVE_MKDTEMP 89 | /* This is now actually part of POSIX.1, but was only added in 2008 */ 90 | char* FAST_FUNC mkdtemp(char *template) 91 | { 92 | if (mktemp(template) == NULL || mkdir(template, 0700) != 0) 93 | return NULL; 94 | return template; 95 | } 96 | #endif 97 | 98 | #ifndef HAVE_STRCASESTR 99 | /* Copyright (c) 1999, 2000 The ht://Dig Group */ 100 | char* FAST_FUNC strcasestr(const char *s, const char *pattern) 101 | { 102 | int length = strlen(pattern); 103 | 104 | while (*s) { 105 | if (strncasecmp(s, pattern, length) == 0) 106 | return (char *)s; 107 | s++; 108 | } 109 | return 0; 110 | } 111 | #endif 112 | 113 | #ifndef HAVE_STRSEP 114 | /* Copyright (C) 2004 Free Software Foundation, Inc. */ 115 | char* FAST_FUNC strsep(char **stringp, const char *delim) 116 | { 117 | char *start = *stringp; 118 | char *ptr; 119 | 120 | if (!start) 121 | return NULL; 122 | 123 | if (!*delim) 124 | ptr = start + strlen(start); 125 | else { 126 | ptr = strpbrk(start, delim); 127 | if (!ptr) { 128 | *stringp = NULL; 129 | return start; 130 | } 131 | } 132 | 133 | *ptr = '\0'; 134 | *stringp = ptr + 1; 135 | 136 | return start; 137 | } 138 | #endif 139 | 140 | #ifndef HAVE_STPCPY 141 | char* FAST_FUNC stpcpy(char *p, const char *to_add) 142 | { 143 | while ((*p = *to_add) != '\0') { 144 | p++; 145 | to_add++; 146 | } 147 | return p; 148 | } 149 | #endif 150 | 151 | #ifndef HAVE_GETLINE 152 | ssize_t FAST_FUNC getline(char **lineptr, size_t *n, FILE *stream) 153 | { 154 | int ch; 155 | char *line = *lineptr; 156 | size_t alloced = *n; 157 | size_t len = 0; 158 | 159 | do { 160 | ch = fgetc(stream); 161 | if (ch == EOF) 162 | break; 163 | if (len + 1 >= alloced) { 164 | alloced += alloced/4 + 64; 165 | line = xrealloc(line, alloced); 166 | } 167 | line[len++] = ch; 168 | } while (ch != '\n'); 169 | 170 | if (len == 0) 171 | return -1; 172 | 173 | line[len] = '\0'; 174 | *lineptr = line; 175 | *n = alloced; 176 | return len; 177 | } 178 | #endif 179 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/src/ptr_to_globals.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Copyright (C) 2008 by Denys Vlasenko 4 | * 5 | * Licensed under GPLv2, see file LICENSE in this source tree. 6 | */ 7 | 8 | #include 9 | 10 | struct globals; 11 | 12 | #ifndef GCC_COMBINE 13 | 14 | /* We cheat here. It is declared as const ptr in libbb.h, 15 | * but here we make it live in R/W memory */ 16 | struct globals *ptr_to_globals; 17 | 18 | #ifdef __GLIBC__ 19 | int *bb_errno; 20 | #endif 21 | 22 | 23 | #else 24 | 25 | 26 | /* gcc -combine will see through and complain */ 27 | /* Using alternative method which is more likely to break 28 | * on weird architectures, compilers, linkers and so on */ 29 | struct globals *const ptr_to_globals __attribute__ ((section (".data"))); 30 | 31 | #ifdef __GLIBC__ 32 | int *const bb_errno __attribute__ ((section (".data"))); 33 | #endif 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/src/read.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Utility routines. 4 | * 5 | * Copyright (C) 1999-2004 by Erik Andersen 6 | * 7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 | */ 9 | #include "libbb.h" 10 | 11 | ssize_t FAST_FUNC safe_read(int fd, void *buf, size_t count) 12 | { 13 | ssize_t n; 14 | 15 | do { 16 | n = read(fd, buf, count); 17 | } while (n < 0 && errno == EINTR); 18 | 19 | return n; 20 | } 21 | 22 | /* 23 | * Read all of the supplied buffer from a file. 24 | * This does multiple reads as necessary. 25 | * Returns the amount read, or -1 on an error. 26 | * A short read is returned on an end of file. 27 | */ 28 | ssize_t FAST_FUNC full_read(int fd, void *buf, size_t len) 29 | { 30 | ssize_t cc; 31 | ssize_t total; 32 | 33 | total = 0; 34 | 35 | while (len) { 36 | cc = safe_read(fd, buf, len); 37 | 38 | if (cc < 0) { 39 | if (total) { 40 | /* we already have some! */ 41 | /* user can do another read to know the error code */ 42 | return total; 43 | } 44 | return cc; /* read() returns -1 on failure. */ 45 | } 46 | if (cc == 0) 47 | break; 48 | buf = ((char *)buf) + cc; 49 | total += cc; 50 | len -= cc; 51 | } 52 | 53 | return total; 54 | } 55 | 56 | ssize_t FAST_FUNC read_close(int fd, void *buf, size_t size) 57 | { 58 | /*int e;*/ 59 | size = full_read(fd, buf, size); 60 | /*e = errno;*/ 61 | close(fd); 62 | /*errno = e;*/ 63 | return size; 64 | } 65 | 66 | ssize_t FAST_FUNC open_read_close(const char *filename, void *buf, size_t size) 67 | { 68 | int fd = open(filename, O_RDONLY); 69 | if (fd < 0) 70 | return fd; 71 | return read_close(fd, buf, size); 72 | } 73 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/src/safe_poll.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Utility routines. 4 | * 5 | * Copyright (C) 2007 by Denys Vlasenko 6 | * 7 | * Licensed under GPLv2, see file LICENSE in this source tree. 8 | */ 9 | 10 | #include "libbb.h" 11 | 12 | /* Wrapper which restarts poll on EINTR or ENOMEM. 13 | * On other errors does perror("poll") and returns. 14 | * Warning! May take longer than timeout_ms to return! */ 15 | int FAST_FUNC safe_poll(struct pollfd *ufds, nfds_t nfds, int timeout) 16 | { 17 | while (1) { 18 | int n = poll(ufds, nfds, timeout); 19 | if (n >= 0) 20 | return n; 21 | /* Make sure we inch towards completion */ 22 | if (timeout > 0) 23 | timeout--; 24 | /* E.g. strace causes poll to return this */ 25 | if (errno == EINTR) 26 | continue; 27 | /* Kernel is very low on memory. Retry. */ 28 | /* I doubt many callers would handle this correctly! */ 29 | if (errno == ENOMEM) 30 | continue; 31 | bb_perror_msg("poll"); 32 | return n; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/src/safe_strncpy.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Utility routines. 4 | * 5 | * Copyright (C) 1999-2004 by Erik Andersen 6 | * 7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 | */ 9 | 10 | #include "libbb.h" 11 | 12 | /* Like strncpy but make sure the resulting string is always 0 terminated. */ 13 | char* FAST_FUNC safe_strncpy(char *dst, const char *src, size_t size) 14 | { 15 | if (!size) return dst; 16 | dst[--size] = '\0'; 17 | return strncpy(dst, src, size); 18 | } 19 | 20 | /* Like strcpy but can copy overlapping strings. */ 21 | void FAST_FUNC overlapping_strcpy(char *dst, const char *src) 22 | { 23 | /* Cheap optimization for dst == src case - 24 | * better to have it here than in many callers. 25 | */ 26 | if (dst != src) { 27 | while ((*dst = *src) != '\0') { 28 | dst++; 29 | src++; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/src/safe_write.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Utility routines. 4 | * 5 | * Copyright (C) 1999-2004 by Erik Andersen 6 | * 7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 | */ 9 | 10 | #include "libbb.h" 11 | 12 | ssize_t FAST_FUNC safe_write(int fd, const void *buf, size_t count) 13 | { 14 | ssize_t n; 15 | 16 | do { 17 | n = write(fd, buf, count); 18 | } while (n < 0 && errno == EINTR); 19 | 20 | return n; 21 | } 22 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/src/signals.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Utility routines. 4 | * 5 | * Copyright (C) 1999-2004 by Erik Andersen 6 | * Copyright (C) 2006 Rob Landley 7 | * Copyright (C) 2006 Denys Vlasenko 8 | * 9 | * Licensed under GPLv2, see file LICENSE in this source tree. 10 | */ 11 | 12 | #include "libbb.h" 13 | 14 | /* All known arches use small ints for signals */ 15 | smallint bb_got_signal; 16 | 17 | void record_signo(int signo) 18 | { 19 | bb_got_signal = signo; 20 | } 21 | 22 | /* Saves 2 bytes on x86! Oh my... */ 23 | int FAST_FUNC sigaction_set(int signum, const struct sigaction *act) 24 | { 25 | return sigaction(signum, act, NULL); 26 | } 27 | 28 | int FAST_FUNC sigprocmask_allsigs(int how) 29 | { 30 | sigset_t set; 31 | sigfillset(&set); 32 | return sigprocmask(how, &set, NULL); 33 | } 34 | 35 | void FAST_FUNC bb_signals(int sigs, void (*f)(int)) 36 | { 37 | int sig_no = 0; 38 | int bit = 1; 39 | 40 | while (sigs) { 41 | if (sigs & bit) { 42 | sigs -= bit; 43 | signal(sig_no, f); 44 | } 45 | sig_no++; 46 | bit <<= 1; 47 | } 48 | } 49 | 50 | void FAST_FUNC bb_signals_recursive_norestart(int sigs, void (*f)(int)) 51 | { 52 | int sig_no = 0; 53 | int bit = 1; 54 | struct sigaction sa; 55 | 56 | memset(&sa, 0, sizeof(sa)); 57 | sa.sa_handler = f; 58 | /*sa.sa_flags = 0;*/ 59 | /*sigemptyset(&sa.sa_mask); - hope memset did it*/ 60 | 61 | while (sigs) { 62 | if (sigs & bit) { 63 | sigs -= bit; 64 | sigaction_set(sig_no, &sa); 65 | } 66 | sig_no++; 67 | bit <<= 1; 68 | } 69 | } 70 | 71 | void FAST_FUNC sig_block(int sig) 72 | { 73 | sigset_t ss; 74 | sigemptyset(&ss); 75 | sigaddset(&ss, sig); 76 | sigprocmask(SIG_BLOCK, &ss, NULL); 77 | } 78 | 79 | void FAST_FUNC sig_unblock(int sig) 80 | { 81 | sigset_t ss; 82 | sigemptyset(&ss); 83 | sigaddset(&ss, sig); 84 | sigprocmask(SIG_UNBLOCK, &ss, NULL); 85 | } 86 | 87 | void FAST_FUNC wait_for_any_sig(void) 88 | { 89 | sigset_t ss; 90 | sigemptyset(&ss); 91 | sigsuspend(&ss); 92 | } 93 | 94 | /* Assuming the sig is fatal */ 95 | void FAST_FUNC kill_myself_with_sig(int sig) 96 | { 97 | signal(sig, SIG_DFL); 98 | sig_unblock(sig); 99 | raise(sig); 100 | _exit(sig | 128); /* Should not reach it */ 101 | } 102 | 103 | void FAST_FUNC signal_SA_RESTART_empty_mask(int sig, void (*handler)(int)) 104 | { 105 | struct sigaction sa; 106 | memset(&sa, 0, sizeof(sa)); 107 | /*sigemptyset(&sa.sa_mask);*/ 108 | sa.sa_flags = SA_RESTART; 109 | sa.sa_handler = handler; 110 | sigaction_set(sig, &sa); 111 | } 112 | 113 | void FAST_FUNC signal_no_SA_RESTART_empty_mask(int sig, void (*handler)(int)) 114 | { 115 | struct sigaction sa; 116 | memset(&sa, 0, sizeof(sa)); 117 | /*sigemptyset(&sa.sa_mask);*/ 118 | /*sa.sa_flags = 0;*/ 119 | sa.sa_handler = handler; 120 | sigaction_set(sig, &sa); 121 | } 122 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/src/skip_whitespace.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * skip_whitespace implementation for busybox 4 | * 5 | * Copyright (C) 2003 Manuel Novoa III 6 | * 7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 | */ 9 | 10 | #include "libbb.h" 11 | 12 | char* FAST_FUNC skip_whitespace(const char *s) 13 | { 14 | /* In POSIX/C locale (the only locale we care about: do we REALLY want 15 | * to allow Unicode whitespace in, say, .conf files? nuts!) 16 | * isspace is only these chars: "\t\n\v\f\r" and space. 17 | * "\t\n\v\f\r" happen to have ASCII codes 9,10,11,12,13. 18 | * Use that. 19 | */ 20 | while (*s == ' ' || (unsigned char)(*s - 9) <= (13 - 9)) 21 | s++; 22 | 23 | return (char *) s; 24 | } 25 | 26 | char* FAST_FUNC skip_non_whitespace(const char *s) 27 | { 28 | while (*s != '\0' && *s != ' ' && (unsigned char)(*s - 9) > (13 - 9)) 29 | s++; 30 | 31 | return (char *) s; 32 | } 33 | 34 | char* FAST_FUNC skip_dev_pfx(const char *tty_name) 35 | { 36 | if (strncmp(tty_name, "/dev/", 5) == 0) 37 | tty_name += 5; 38 | return (char*)tty_name; 39 | } 40 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/src/verror_msg.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Utility routines. 4 | * 5 | * Copyright (C) 1999-2004 by Erik Andersen 6 | * 7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 | */ 9 | #include "libbb.h" 10 | #if ENABLE_FEATURE_SYSLOG 11 | # include 12 | #endif 13 | 14 | static const char *applet_name = "debug stuff usage"; 15 | 16 | smallint logmode = LOGMODE_STDIO; 17 | const char *msg_eol = "\n"; 18 | 19 | void FAST_FUNC bb_verror_msg(const char *s, va_list p, const char* strerr) 20 | { 21 | char *msg, *msg1; 22 | int applet_len, strerr_len, msgeol_len, used; 23 | 24 | if (!logmode) 25 | return; 26 | 27 | if (!s) /* nomsg[_and_die] uses NULL fmt */ 28 | s = ""; /* some libc don't like printf(NULL) */ 29 | 30 | used = vasprintf(&msg, s, p); 31 | if (used < 0) 32 | return; 33 | 34 | /* This is ugly and costs +60 bytes compared to multiple 35 | * fprintf's, but is guaranteed to do a single write. 36 | * This is needed for e.g. httpd logging, when multiple 37 | * children can produce log messages simultaneously. */ 38 | 39 | applet_len = strlen(applet_name) + 2; /* "applet: " */ 40 | strerr_len = strerr ? strlen(strerr) : 0; 41 | msgeol_len = strlen(msg_eol); 42 | /* can't use xrealloc: it calls error_msg on failure, 43 | * that may result in a recursion */ 44 | /* +3 is for ": " before strerr and for terminating NUL */ 45 | msg1 = realloc(msg, applet_len + used + strerr_len + msgeol_len + 3); 46 | if (!msg1) { 47 | msg[used++] = '\n'; /* overwrites NUL */ 48 | applet_len = 0; 49 | } else { 50 | msg = msg1; 51 | /* TODO: maybe use writev instead of memmoving? Need full_writev? */ 52 | memmove(msg + applet_len, msg, used); 53 | used += applet_len; 54 | strcpy(msg, applet_name); 55 | msg[applet_len - 2] = ':'; 56 | msg[applet_len - 1] = ' '; 57 | if (strerr) { 58 | if (s[0]) { /* not perror_nomsg? */ 59 | msg[used++] = ':'; 60 | msg[used++] = ' '; 61 | } 62 | strcpy(&msg[used], strerr); 63 | used += strerr_len; 64 | } 65 | strcpy(&msg[used], msg_eol); 66 | used += msgeol_len; 67 | } 68 | 69 | if (logmode & LOGMODE_STDIO) { 70 | fflush_all(); 71 | full_write(STDERR_FILENO, msg, used); 72 | } 73 | #if ENABLE_FEATURE_SYSLOG 74 | if (logmode & LOGMODE_SYSLOG) { 75 | syslog(LOG_ERR, "%s", msg + applet_len); 76 | } 77 | #endif 78 | free(msg); 79 | } 80 | 81 | #ifdef VERSION_WITH_WRITEV 82 | /* Code size is approximately the same, but currently it's the only user 83 | * of writev in entire bbox. __libc_writev in uclibc is ~50 bytes. */ 84 | void FAST_FUNC bb_verror_msg(const char *s, va_list p, const char* strerr) 85 | { 86 | int strerr_len, msgeol_len; 87 | struct iovec iov[3]; 88 | 89 | #define used (iov[2].iov_len) 90 | #define msgv (iov[2].iov_base) 91 | #define msgc ((char*)(iov[2].iov_base)) 92 | #define msgptr (&(iov[2].iov_base)) 93 | 94 | if (!logmode) 95 | return; 96 | 97 | if (!s) /* nomsg[_and_die] uses NULL fmt */ 98 | s = ""; /* some libc don't like printf(NULL) */ 99 | 100 | /* Prevent "derefing type-punned ptr will break aliasing rules" */ 101 | used = vasprintf((char**)(void*)msgptr, s, p); 102 | if (used < 0) 103 | return; 104 | 105 | /* This is ugly and costs +60 bytes compared to multiple 106 | * fprintf's, but is guaranteed to do a single write. 107 | * This is needed for e.g. httpd logging, when multiple 108 | * children can produce log messages simultaneously. */ 109 | 110 | strerr_len = strerr ? strlen(strerr) : 0; 111 | msgeol_len = strlen(msg_eol); 112 | /* +3 is for ": " before strerr and for terminating NUL */ 113 | msgv = xrealloc(msgv, used + strerr_len + msgeol_len + 3); 114 | if (strerr) { 115 | msgc[used++] = ':'; 116 | msgc[used++] = ' '; 117 | strcpy(msgc + used, strerr); 118 | used += strerr_len; 119 | } 120 | strcpy(msgc + used, msg_eol); 121 | used += msgeol_len; 122 | 123 | if (logmode & LOGMODE_STDIO) { 124 | iov[0].iov_base = (char*)applet_name; 125 | iov[0].iov_len = strlen(applet_name); 126 | iov[1].iov_base = (char*)": "; 127 | iov[1].iov_len = 2; 128 | /*iov[2].iov_base = msgc;*/ 129 | /*iov[2].iov_len = used;*/ 130 | fflush_all(); 131 | writev(STDERR_FILENO, iov, 3); 132 | } 133 | # if ENABLE_FEATURE_SYSLOG 134 | if (logmode & LOGMODE_SYSLOG) { 135 | syslog(LOG_ERR, "%s", msgc); 136 | } 137 | # endif 138 | free(msgc); 139 | } 140 | #endif 141 | 142 | 143 | void FAST_FUNC bb_error_msg_and_die(const char *s, ...) 144 | { 145 | va_list p; 146 | 147 | va_start(p, s); 148 | bb_verror_msg(s, p, NULL); 149 | va_end(p); 150 | xfunc_die(); 151 | } 152 | 153 | void FAST_FUNC bb_error_msg(const char *s, ...) 154 | { 155 | va_list p; 156 | 157 | va_start(p, s); 158 | bb_verror_msg(s, p, NULL); 159 | va_end(p); 160 | } 161 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/src/wfopen.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Utility routines. 4 | * 5 | * Copyright (C) 1999-2004 by Erik Andersen 6 | * 7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 | */ 9 | 10 | #include "libbb.h" 11 | 12 | FILE* FAST_FUNC fopen_or_warn(const char *path, const char *mode) 13 | { 14 | FILE *fp = fopen(path, mode); 15 | if (!fp) { 16 | bb_simple_perror_msg(path); 17 | //errno = 0; /* why? */ 18 | } 19 | return fp; 20 | } 21 | 22 | FILE* FAST_FUNC fopen_for_read(const char *path) 23 | { 24 | return fopen(path, "r"); 25 | } 26 | 27 | FILE* FAST_FUNC xfopen_for_read(const char *path) 28 | { 29 | return xfopen(path, "r"); 30 | } 31 | 32 | FILE* FAST_FUNC fopen_for_write(const char *path) 33 | { 34 | return fopen(path, "w"); 35 | } 36 | 37 | FILE* FAST_FUNC xfopen_for_write(const char *path) 38 | { 39 | return xfopen(path, "w"); 40 | } 41 | 42 | static FILE* xfdopen_helper(unsigned fd_and_rw_bit) 43 | { 44 | FILE* fp = fdopen(fd_and_rw_bit >> 1, fd_and_rw_bit & 1 ? "w" : "r"); 45 | if (!fp) 46 | bb_error_msg_and_die(bb_msg_memory_exhausted); 47 | return fp; 48 | } 49 | FILE* FAST_FUNC xfdopen_for_read(int fd) 50 | { 51 | return xfdopen_helper(fd << 1); 52 | } 53 | FILE* FAST_FUNC xfdopen_for_write(int fd) 54 | { 55 | return xfdopen_helper((fd << 1) + 1); 56 | } 57 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/src/xatonum.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * ascii-to-numbers implementations for busybox 4 | * 5 | * Copyright (C) 2003 Manuel Novoa III 6 | * 7 | * Licensed under GPLv2, see file LICENSE in this source tree. 8 | */ 9 | 10 | #include "libbb.h" 11 | 12 | #define type long long 13 | #define xstrtou(rest) xstrtoull##rest 14 | #define xstrto(rest) xstrtoll##rest 15 | #define xatou(rest) xatoull##rest 16 | #define xato(rest) xatoll##rest 17 | #define XSTR_UTYPE_MAX ULLONG_MAX 18 | #define XSTR_TYPE_MAX LLONG_MAX 19 | #define XSTR_TYPE_MIN LLONG_MIN 20 | #define XSTR_STRTOU strtoull 21 | #include "../inc/xatonum_template.c" 22 | 23 | #if ULONG_MAX != ULLONG_MAX 24 | #define type long 25 | #define xstrtou(rest) xstrtoul##rest 26 | #define xstrto(rest) xstrtol##rest 27 | #define xatou(rest) xatoul##rest 28 | #define xato(rest) xatol##rest 29 | #define XSTR_UTYPE_MAX ULONG_MAX 30 | #define XSTR_TYPE_MAX LONG_MAX 31 | #define XSTR_TYPE_MIN LONG_MIN 32 | #define XSTR_STRTOU strtoul 33 | #include "../inc/xatonum_template.c" 34 | #endif 35 | 36 | #if UINT_MAX != ULONG_MAX 37 | static ALWAYS_INLINE 38 | unsigned bb_strtoui(const char *str, char **end, int b) 39 | { 40 | unsigned long v = strtoul(str, end, b); 41 | if (v > UINT_MAX) { 42 | errno = ERANGE; 43 | return UINT_MAX; 44 | } 45 | return v; 46 | } 47 | #define type int 48 | #define xstrtou(rest) xstrtou##rest 49 | #define xstrto(rest) xstrtoi##rest 50 | #define xatou(rest) xatou##rest 51 | #define xato(rest) xatoi##rest 52 | #define XSTR_UTYPE_MAX UINT_MAX 53 | #define XSTR_TYPE_MAX INT_MAX 54 | #define XSTR_TYPE_MIN INT_MIN 55 | /* libc has no strtoui, so we need to create/use our own */ 56 | #define XSTR_STRTOU bb_strtoui 57 | #include "xatonum_template.c" 58 | #endif 59 | 60 | /* A few special cases */ 61 | 62 | int FAST_FUNC xatoi_positive(const char *numstr) 63 | { 64 | return xatou_range(numstr, 0, INT_MAX); 65 | } 66 | 67 | uint16_t FAST_FUNC xatou16(const char *numstr) 68 | { 69 | return xatou_range(numstr, 0, 0xffff); 70 | } 71 | 72 | const struct suffix_mult bkm_suffixes[] = { 73 | { "b", 512 }, 74 | { "k", 1024 }, 75 | { "m", 1024*1024 }, 76 | { "", 0 } 77 | }; 78 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/src/xfunc_die.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Utility routines. 4 | * 5 | * Copyright (C) 2008 by Denys Vlasenko 6 | * 7 | * Licensed under GPLv2, see file LICENSE in this source tree. 8 | */ 9 | 10 | /* Keeping it separate allows to NOT suck in stdio for VERY small applets. 11 | * Try building busybox with only "true" enabled... */ 12 | 13 | #include "libbb.h" 14 | 15 | int die_sleep; 16 | #if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH 17 | jmp_buf die_jmp; 18 | #endif 19 | 20 | void FAST_FUNC xfunc_die(void) 21 | { 22 | if (die_sleep) { 23 | if ((ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH) 24 | && die_sleep < 0 25 | ) { 26 | /* Special case. We arrive here if NOFORK applet 27 | * calls xfunc, which then decides to die. 28 | * We don't die, but jump instead back to caller. 29 | * NOFORK applets still cannot carelessly call xfuncs: 30 | * p = xmalloc(10); 31 | * q = xmalloc(10); // BUG! if this dies, we leak p! 32 | */ 33 | /* -2222 means "zero" (longjmp can't pass 0) 34 | * run_nofork_applet() catches -2222. */ 35 | longjmp(die_jmp, xfunc_error_retval ? xfunc_error_retval : -2222); 36 | } 37 | sleep(die_sleep); 38 | } 39 | exit(xfunc_error_retval); 40 | } 41 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/src/xreadlink.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * xreadlink.c - safe implementation of readlink. 4 | * Returns a NULL on failure... 5 | * 6 | * Licensed under GPLv2, see file LICENSE in this source tree. 7 | */ 8 | 9 | #include "libbb.h" 10 | 11 | /* some systems (eg Hurd) does not have MAXSYMLINKS definition, 12 | * set it to some reasonable value if it isn't defined */ 13 | #ifndef MAXSYMLINKS 14 | # define MAXSYMLINKS 20 15 | #endif 16 | 17 | /* 18 | * NOTE: This function returns a malloced char* that you will have to free 19 | * yourself. 20 | */ 21 | char* FAST_FUNC xmalloc_readlink(const char *path) 22 | { 23 | enum { GROWBY = 80 }; /* how large we will grow strings by */ 24 | 25 | char *buf = NULL; 26 | int bufsize = 0, readsize = 0; 27 | 28 | do { 29 | bufsize += GROWBY; 30 | buf = xrealloc(buf, bufsize); 31 | readsize = readlink(path, buf, bufsize); 32 | if (readsize == -1) { 33 | free(buf); 34 | return NULL; 35 | } 36 | } while (bufsize < readsize + 1); 37 | 38 | buf[readsize] = '\0'; 39 | 40 | return buf; 41 | } 42 | 43 | /* 44 | * This routine is not the same as realpath(), which 45 | * canonicalizes the given path completely. This routine only 46 | * follows trailing symlinks until a real file is reached and 47 | * returns its name. If the path ends in a dangling link or if 48 | * the target doesn't exist, the path is returned in any case. 49 | * Intermediate symlinks in the path are not expanded -- only 50 | * those at the tail. 51 | * A malloced char* is returned, which must be freed by the caller. 52 | */ 53 | char* FAST_FUNC xmalloc_follow_symlinks(const char *path) 54 | { 55 | char *buf; 56 | char *lpc; 57 | char *linkpath; 58 | int bufsize; 59 | int looping = MAXSYMLINKS + 1; 60 | 61 | buf = xstrdup(path); 62 | goto jump_in; 63 | 64 | while (1) { 65 | linkpath = xmalloc_readlink(buf); 66 | if (!linkpath) { 67 | /* not a symlink, or doesn't exist */ 68 | if (errno == EINVAL || errno == ENOENT) 69 | return buf; 70 | goto free_buf_ret_null; 71 | } 72 | 73 | if (!--looping) { 74 | free(linkpath); 75 | free_buf_ret_null: 76 | free(buf); 77 | return NULL; 78 | } 79 | 80 | if (*linkpath != '/') { 81 | bufsize += strlen(linkpath); 82 | buf = xrealloc(buf, bufsize); 83 | lpc = bb_get_last_path_component_strip(buf); 84 | strcpy(lpc, linkpath); 85 | free(linkpath); 86 | } else { 87 | free(buf); 88 | buf = linkpath; 89 | jump_in: 90 | bufsize = strlen(buf) + 1; 91 | } 92 | } 93 | } 94 | 95 | char* FAST_FUNC xmalloc_readlink_or_warn(const char *path) 96 | { 97 | char *buf = xmalloc_readlink(path); 98 | if (!buf) { 99 | /* EINVAL => "file: Invalid argument" => puzzled user */ 100 | const char *errmsg = "not a symlink"; 101 | int err = errno; 102 | if (err != EINVAL) 103 | errmsg = strerror(err); 104 | bb_error_msg("%s: cannot read link: %s", path, errmsg); 105 | } 106 | return buf; 107 | } 108 | 109 | char* FAST_FUNC xmalloc_realpath(const char *path) 110 | { 111 | #if defined(__GLIBC__) || \ 112 | (defined(__UCLIBC__) && UCLIBC_VERSION >= KERNEL_VERSION(0, 9, 31)) 113 | /* glibc provides a non-standard extension */ 114 | /* new: POSIX.1-2008 specifies this behavior as well */ 115 | return realpath(path, NULL); 116 | #else 117 | char buf[PATH_MAX+1]; 118 | 119 | /* on error returns NULL (xstrdup(NULL) == NULL) */ 120 | return xstrdup(realpath(path, buf)); 121 | #endif 122 | } 123 | -------------------------------------------------------------------------------- /src/modules/busybox-lite/src/xrealloc_vector.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Utility routines. 4 | * 5 | * Copyright (C) 2008 Denys Vlasenko 6 | * 7 | * Licensed under GPLv2, see file LICENSE in this source tree. 8 | */ 9 | 10 | #include "libbb.h" 11 | 12 | /* Resize (grow) malloced vector. 13 | * 14 | * #define magic packed two parameters into one: 15 | * sizeof = sizeof_and_shift >> 8 16 | * shift = (sizeof_and_shift) & 0xff 17 | * 18 | * Lets say shift = 4. 1 << 4 == 0x10. 19 | * If idx == 0, 0x10, 0x20 etc, vector[] is resized to next higher 20 | * idx step, plus one: if idx == 0x20, vector[] is resized to 0x31, 21 | * thus last usable element is vector[0x30]. 22 | * 23 | * In other words: after xrealloc_vector(v, 4, idx), with any idx, 24 | * it's ok to use at least v[idx] and v[idx+1]. 25 | * v[idx+2] etc generally are not ok. 26 | * 27 | * New elements are zeroed out, but only if realloc was done 28 | * (not on every call). You can depend on v[idx] and v[idx+1] being 29 | * zeroed out if you use it like this: 30 | * v = xrealloc_vector(v, 4, idx); 31 | * v[idx].some_fields = ...; - the rest stays 0/NULL 32 | * idx++; 33 | * If you do not advance idx like above, you should be more careful. 34 | * Next call to xrealloc_vector(v, 4, idx) may or may not zero out v[idx]. 35 | */ 36 | void* FAST_FUNC xrealloc_vector_helper(void *vector, unsigned sizeof_and_shift, int idx) 37 | { 38 | int mask = 1 << (uint8_t)sizeof_and_shift; 39 | 40 | if (!(idx & (mask - 1))) { 41 | sizeof_and_shift >>= 8; /* sizeof(vector[0]) */ 42 | vector = xrealloc(vector, sizeof_and_shift * (idx + mask + 1)); 43 | memset((char*)vector + (sizeof_and_shift * idx), 0, sizeof_and_shift * (mask + 1)); 44 | } 45 | return vector; 46 | } 47 | -------------------------------------------------------------------------------- /src/modules/customization/Makefile: -------------------------------------------------------------------------------- 1 | DIR_INC = ./inc 2 | DIR_SRC = ./src 3 | DIR_OBJ = ./obj 4 | 5 | 6 | SRC = $(wildcard ${DIR_SRC}/*.c) 7 | OBJ = $(patsubst %.c,${DIR_OBJ}/%.o,$(notdir ${SRC})) 8 | 9 | TARGET = libcus.a 10 | 11 | 12 | #CROSS_COMPILE=arm-linux-gnueabi- 13 | #CC=$(CROSS_COMPILE)gcc 14 | #AR=$(CROSS_COMPILE)ar 15 | #LD=$(CROSS_COMPILE)ld 16 | 17 | 18 | CFLAGS = -I$(DIR_INC) -Wall -static 19 | 20 | 21 | 22 | ${TARGET}:${OBJ} 23 | $(AR) rc $@ $^ 24 | @mv $(TARGET) ../../../libs/ 25 | ${DIR_OBJ}/%.o:${DIR_SRC}/%.c 26 | @mkdir -p $(DIR_OBJ) 27 | $(CC) $(CFLAGS) -c $< -o $@ 28 | 29 | .PHONY:clean 30 | clean: 31 | @rm -rf $(DIR_OBJ) 32 | -------------------------------------------------------------------------------- /src/modules/customization/src/irq_info.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Lep Open Source Project 3 | * 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #define BUFFSIZE (64*1024) 18 | static unsigned long long sleep_time = 1; 19 | 20 | int irq_info_main(int argc, char *argv[], int out_fd){ 21 | 22 | /******************************* 23 | 1 read /proc/stat 24 | 2 get irqs 25 | b = strstr(buff, "intr "); 26 | if(b) sscanf(b, "intr %llu", &llbuf); 27 | *intr = llbuf; 28 | 3 get softirqs 29 | b = strstr(buff, "softirq "); 30 | if(b) sscanf(b, "softirq %llu", &llbuf); 31 | *sofrirq = llbuf; 32 | 4 sleep 1 sec 33 | 5 repeat 34 | 6 irq2 - irq1, softirq2 - softirq2 35 | 7 return 36 | **********************************/ 37 | unsigned long long irq[2]= {0}, softirq[2]= {0}; 38 | static int fd; 39 | const char *b = NULL; 40 | unsigned long long llbuf = 0; 41 | char buff[BUFFSIZE-1] = {0}; 42 | FILE *out_fp = fdopen(out_fd, "w"); 43 | 44 | fd = open("/proc/stat", O_RDONLY, 0); 45 | read(fd, buff, BUFFSIZE-1); 46 | b = strstr(buff, "intr"); 47 | if (b) 48 | sscanf(b, "intr %Lu", &llbuf); 49 | irq[0] = llbuf; 50 | 51 | b = strstr(buff, "softirq"); 52 | if (b) 53 | sscanf(b, "softirq %Lu", &llbuf); 54 | softirq[0] = llbuf; 55 | close(fd); 56 | 57 | sleep(sleep_time); 58 | 59 | fd = open("/proc/stat", O_RDONLY, 0); 60 | read(fd, buff, BUFFSIZE-1); 61 | b = strstr(buff, "intr"); 62 | if (b) 63 | sscanf(b, "intr %Lu", &llbuf); 64 | irq[1] = llbuf; 65 | 66 | b = strstr(buff, "softirq"); 67 | if (b) 68 | sscanf(b, "softirq %Lu", &llbuf); 69 | softirq[1] = llbuf; 70 | close(fd); 71 | 72 | fprintf(out_fp,"irq:%d/s softirq:%d/s \n", irq[1]-irq[0], softirq[1]-softirq[0]); 73 | fclose(out_fp); 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /src/modules/iopp/Makefile: -------------------------------------------------------------------------------- 1 | DIR_INC = ./inc 2 | DIR_SRC = ./src 3 | DIR_OBJ = ./obj 4 | 5 | 6 | SRC = $(wildcard ${DIR_SRC}/*.c) 7 | OBJ = $(patsubst %.c,${DIR_OBJ}/%.o,$(notdir ${SRC})) 8 | 9 | TARGET = libiopp.a 10 | 11 | 12 | #CROSS_COMPILE=arm-linux-gnueabi- 13 | #CC=$(CROSS_COMPILE)gcc 14 | #AR=$(CROSS_COMPILE)ar 15 | #LD=$(CROSS_COMPILE)ld 16 | 17 | 18 | CFLAGS = -I$(DIR_INC) -Wall -static -D_LARGEFILE64_SOURCE 19 | 20 | 21 | 22 | ${TARGET}:${OBJ} 23 | $(AR) rc $@ $^ 24 | @mv $(TARGET) ../../../libs/ 25 | ${DIR_OBJ}/%.o:${DIR_SRC}/%.c 26 | @mkdir -p $(DIR_OBJ) 27 | $(CC) $(CFLAGS) -c $< -o $@ 28 | 29 | .PHONY:clean 30 | clean: 31 | @rm -rf $(DIR_OBJ) 32 | -------------------------------------------------------------------------------- /src/modules/iotop/Makefile: -------------------------------------------------------------------------------- 1 | DIR_INC = ./inc 2 | DIR_SRC = ./src 3 | DIR_OBJ = ./obj 4 | 5 | 6 | SRC = $(wildcard ${DIR_SRC}/*.c) 7 | OBJ = $(patsubst %.c,${DIR_OBJ}/%.o,$(notdir ${SRC})) 8 | 9 | TARGET = libiotop.a 10 | 11 | 12 | #CROSS_COMPILE=arm-linux-gnueabi- 13 | #CC=$(CROSS_COMPILE)gcc 14 | #AR=$(CROSS_COMPILE)ar 15 | #LD=$(CROSS_COMPILE)ld 16 | 17 | 18 | CFLAGS = -I$(DIR_INC) -Wall -static -g 19 | 20 | 21 | 22 | ${TARGET}:${OBJ} 23 | $(AR) rc $@ $^ 24 | @mv $(TARGET) ../../../libs/ 25 | ${DIR_OBJ}/%.o:${DIR_SRC}/%.c 26 | @mkdir -p $(DIR_OBJ) 27 | $(CC) $(CFLAGS) -c $< -o $@ 28 | 29 | .PHONY:clean 30 | clean: 31 | @rm -rf $(DIR_OBJ) 32 | -------------------------------------------------------------------------------- /src/modules/iotop/inc/iotop.h: -------------------------------------------------------------------------------- 1 | #ifndef __IOTOP_H__ 2 | #define __IOTOP_H__ 3 | 4 | #define _POSIX_C_SOURCE 1 5 | #define _BSD_SOURCE 1 6 | 7 | #include 8 | #include 9 | 10 | #define VERSION "0.1" 11 | 12 | typedef union 13 | { 14 | struct _flags 15 | { 16 | int batch_mode; 17 | int only; 18 | int processes; 19 | int accumulated; 20 | int kilobytes; 21 | int timestamp; 22 | int quite; 23 | } f; 24 | int opts[7]; 25 | } config_t; 26 | 27 | typedef struct 28 | { 29 | int iter; 30 | int delay; 31 | int pid; 32 | int user_id; 33 | } params_t; 34 | 35 | extern config_t config; 36 | extern params_t params; 37 | 38 | 39 | struct xxxid_stats 40 | { 41 | pid_t tid; 42 | uint64_t swapin_delay_total; // nanoseconds 43 | uint64_t blkio_delay_total; // nanoseconds 44 | uint64_t read_bytes; 45 | uint64_t write_bytes; 46 | 47 | double blkio_val; 48 | double swapin_val; 49 | double read_val; 50 | double write_val; 51 | 52 | int io_prio; 53 | 54 | int euid; 55 | char *cmdline; 56 | 57 | void *__next; 58 | }; 59 | 60 | void nl_init(void); 61 | void nl_term(void); 62 | 63 | int nl_xxxid_info(pid_t xxxid, int isp, struct xxxid_stats *stats); 64 | void dump_xxxid_stats(struct xxxid_stats *stats); 65 | 66 | typedef int (*filter_callback)(struct xxxid_stats *); 67 | 68 | struct xxxid_stats* fetch_data(int processes, filter_callback); 69 | void free_stats_chain(struct xxxid_stats *chain); 70 | 71 | typedef void (*view_callback)(struct xxxid_stats *current, struct xxxid_stats *prev, int iter, int fd); 72 | 73 | void view_batch(struct xxxid_stats *, struct xxxid_stats *, int iter, int fd); 74 | void view_curses(struct xxxid_stats *, struct xxxid_stats *, int iter); 75 | void view_curses_finish(); 76 | 77 | typedef int (*how_to_sleep)(unsigned int seconds); 78 | int curses_sleep(unsigned int seconds); 79 | 80 | /* utils.c */ 81 | 82 | enum 83 | { 84 | PIDGEN_FLAGS_PROC, 85 | PIDGEN_FLAGS_TASK 86 | }; 87 | 88 | struct pidgen 89 | { 90 | void *__proc; 91 | void *__task; 92 | int __flags; 93 | }; 94 | 95 | //const char *xprintf(const char *format, ...); 96 | const char *read_cmdline2(int pid); 97 | 98 | struct pidgen *openpidgen(int flags); 99 | void closepidgen(struct pidgen *pg); 100 | int pidgen_next(struct pidgen *pg); 101 | 102 | /* ioprio.h */ 103 | 104 | int get_ioprio(pid_t pid); 105 | const char *str_ioprio(int io_prio); 106 | 107 | #endif // __IOTOP_H__ 108 | 109 | -------------------------------------------------------------------------------- /src/modules/iotop/src/ioprio.c: -------------------------------------------------------------------------------- 1 | #include "iotop.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | enum { 9 | IOPRIO_CLASS_NONE, 10 | IOPRIO_CLASS_RT, 11 | IOPRIO_CLASS_BE, 12 | IOPRIO_CLASS_IDLE, 13 | IOPRIO_CLASS_MAX 14 | }; 15 | 16 | enum { 17 | IOPRIO_WHO_PROCESS = 1, 18 | IOPRIO_WHO_PGRP, 19 | IOPRIO_WHO_USER 20 | }; 21 | 22 | #define IOPRIO_CLASS_SHIFT 13 23 | #define IOPRIO_STR_MAXSIZ 5 24 | #define IOPRIO_STR_FORMAT "%2s/%1i" 25 | 26 | #if defined(__i386__) 27 | #define __NR_ioprio_set 289 28 | #define __NR_ioprio_get 290 29 | #elif defined(__ppc__) 30 | #define __NR_ioprio_set 273 31 | #define __NR_ioprio_get 274 32 | #elif defined(__x86_64__) 33 | #define __NR_ioprio_set 251 34 | #define __NR_ioprio_get 252 35 | #elif defined(__ia64__) 36 | #define __NR_ioprio_set 1274 37 | #define __NR_ioprio_get 1275 38 | //#else 39 | //#error "Unsupported arch" 40 | #endif 41 | 42 | # define SYS_ioprio_set __NR_ioprio_set 43 | # define SYS_ioprio_get __NR_ioprio_get 44 | 45 | const char *str_ioprio_class[] = { "-", "rt", "be", "id" }; 46 | 47 | inline int get_ioprio(pid_t pid) 48 | { 49 | return syscall(SYS_ioprio_get, IOPRIO_WHO_PROCESS, pid); 50 | } 51 | 52 | const char *str_ioprio(int io_prio) 53 | { 54 | const static char corrupted[] = "xx/x"; 55 | static char buf[IOPRIO_STR_MAXSIZ]; 56 | int io_class = io_prio >> IOPRIO_CLASS_SHIFT; 57 | 58 | io_prio &= 0xff; 59 | 60 | if (io_class >= IOPRIO_CLASS_MAX) 61 | return corrupted; 62 | 63 | snprintf( 64 | buf, 65 | IOPRIO_STR_MAXSIZ, 66 | IOPRIO_STR_FORMAT, 67 | str_ioprio_class[io_class], 68 | io_prio 69 | ); 70 | 71 | return (const char *) buf; 72 | } 73 | 74 | 75 | 76 | const char *str_ioprio_ext(int io_prio, pid_t pid) 77 | { 78 | #define PRIO_PROCESS 0 79 | #define SCHED_IDLE 5 80 | const static char corrupted[] = "xx/x"; 81 | static char buf[IOPRIO_STR_MAXSIZ]; 82 | int io_class = io_prio >> IOPRIO_CLASS_SHIFT; 83 | 84 | io_prio &= 0xff; 85 | 86 | if (io_class >= IOPRIO_CLASS_MAX) 87 | return corrupted; 88 | 89 | if(io_class == 0){ 90 | int scheduler = sched_getscheduler(pid); 91 | int nice = getpriority(PRIO_PROCESS, pid); 92 | io_prio = (nice + 20)/5; 93 | 94 | if(scheduler == SCHED_FIFO || scheduler == SCHED_RR) 95 | io_class = IOPRIO_CLASS_RT; 96 | else if(scheduler == SCHED_IDLE) 97 | io_class = IOPRIO_CLASS_IDLE; 98 | else 99 | io_class = IOPRIO_CLASS_BE; 100 | } 101 | 102 | snprintf( 103 | buf, 104 | IOPRIO_STR_MAXSIZ, 105 | IOPRIO_STR_FORMAT, 106 | str_ioprio_class[io_class], 107 | io_prio 108 | ); 109 | 110 | return (const char *) buf; 111 | } 112 | 113 | -------------------------------------------------------------------------------- /src/modules/iotop/src/main.c: -------------------------------------------------------------------------------- 1 | #include "iotop.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | static char *progname = NULL; 15 | 16 | config_t config; 17 | params_t params; 18 | 19 | void 20 | init_params(void) 21 | { 22 | params.iter = 2; 23 | params.delay = 1; 24 | params.pid = -1; 25 | params.user_id = -1; 26 | } 27 | 28 | static char str_opt[] = "boPaktq"; 29 | 30 | void 31 | check_priv(void) 32 | { 33 | if (geteuid() == 0) 34 | return; 35 | 36 | errno = EACCES; 37 | perror(progname); 38 | 39 | exit(EXIT_FAILURE); 40 | } 41 | 42 | void 43 | print_help(void) 44 | { 45 | printf( 46 | "Usage: %s [OPTIONS]\n\n" 47 | "DISK READ and DISK WRITE are the block I/O bandwidth used during the sampling\n" 48 | "period. SWAPIN and IO are the percentages of time the thread spent respectively\n" 49 | "while swapping in and waiting on I/O more generally. PRIO is the I/O priority at\n" 50 | "which the thread is running (set using the ionice command).\n\n" 51 | "Controls: left and right arrows to change the sorting column, r to invert the\n" 52 | "sorting order, o to toggle the --only option, p to toggle the --processes\n" 53 | "option, a to toggle the --accumulated option, q to quit, any other key to force\n" 54 | "a refresh.\n\n" 55 | "Options:\n" 56 | " --version show program's version number and exit\n" 57 | " -h, --help show this help message and exit\n" 58 | " -o, --only only show processes or threads actually doing I/O\n" 59 | " -b, --batch non-interactive mode\n" 60 | " -n NUM, --iter=NUM number of iterations before ending [infinite]\n" 61 | " -d SEC, --delay=SEC delay between iterations [1 second]\n" 62 | " -p PID, --pid=PID processes/threads to monitor [all]\n" 63 | " -u USER, --user=USER users to monitor [all]\n" 64 | " -P, --processes only show processes, not all threads\n" 65 | " -a, --accumulated show accumulated I/O instead of bandwidth\n" 66 | " -k, --kilobytes use kilobytes instead of a human friendly unit\n" 67 | " -t, --time add a timestamp on each line (implies --batch)\n" 68 | " -q, --quiet suppress header line output (implies --batch)\n", 69 | progname 70 | ); 71 | } 72 | 73 | void 74 | parse_args(int argc, char *argv[]) 75 | { 76 | init_params(); 77 | memset(&config, 0, sizeof(config)); 78 | 79 | while (0) 80 | { 81 | static struct option long_options[] = 82 | { 83 | {"version", no_argument, NULL, 'v'}, 84 | {"help", no_argument, NULL, 'h'}, 85 | {"batch", no_argument, NULL, 'b'}, 86 | {"only", no_argument, NULL, 'o'}, 87 | {"iter", required_argument, NULL, 'n'}, 88 | {"delay", required_argument, NULL, 'd'}, 89 | {"pid", required_argument, NULL, 'p'}, 90 | {"user", required_argument, NULL, 'u'}, 91 | {"processes", no_argument, NULL, 'P'}, 92 | {"accumulated", no_argument, NULL, 'a'}, 93 | {"kilobytes", no_argument, NULL, 'k'}, 94 | {"timestamp", no_argument, NULL, 't'}, 95 | {"quite", no_argument, NULL, 'q'}, 96 | {NULL, 0, NULL, 0} 97 | }; 98 | 99 | int c = getopt_long(argc, argv, "vhbon:d:p:u:Paktq", 100 | long_options, NULL); 101 | 102 | if (c == -1) 103 | break; 104 | 105 | switch (c) 106 | { 107 | case 'v': 108 | printf("%s %s\n", argv[0], VERSION); 109 | exit(EXIT_SUCCESS); 110 | case 'h': 111 | print_help(); 112 | exit(EXIT_SUCCESS); 113 | case 'o': 114 | case 'b': 115 | case 'P': 116 | case 'a': 117 | case 'k': 118 | case 't': 119 | case 'q': 120 | config.opts[(unsigned int) (strchr(str_opt, c) - str_opt)] = 1; 121 | break; 122 | case 'n': 123 | params.iter = atoi(optarg); 124 | break; 125 | case 'd': 126 | params.delay = atoi(optarg); 127 | break; 128 | case 'p': 129 | params.pid = atoi(optarg); 130 | break; 131 | case 'u': 132 | if (isdigit(optarg[0])) 133 | params.user_id = atoi(optarg); 134 | else 135 | { 136 | struct passwd *pwd = getpwnam(optarg); 137 | if (!pwd) 138 | { 139 | fprintf(stderr, "%s: user %s not found\n", 140 | progname, optarg); 141 | exit(EXIT_FAILURE); 142 | } 143 | params.user_id = pwd->pw_uid; 144 | } 145 | break; 146 | default: 147 | fprintf(stderr, "%s: unknown option\n", progname); 148 | exit(EXIT_FAILURE); 149 | } 150 | } 151 | } 152 | 153 | int 154 | filter1(struct xxxid_stats *s) 155 | { 156 | if ((params.user_id != -1) && (s->euid != params.user_id)) 157 | return 1; 158 | 159 | if ((params.pid != -1) && (s->tid != params.pid)) 160 | return 1; 161 | 162 | return 0; 163 | } 164 | 165 | void 166 | sig_handler(int signo) 167 | { 168 | if (signo == SIGINT) 169 | { 170 | nl_term(); 171 | if (!config.f.batch_mode) 172 | view_curses_finish(); 173 | 174 | //exit(EXIT_SUCCESS); 175 | } 176 | } 177 | 178 | int 179 | iotop_main(int argc, char *argv[], int fd) 180 | { 181 | progname = argv[0]; 182 | 183 | parse_args(argc, argv); 184 | check_priv(); 185 | 186 | 187 | nl_init(); 188 | 189 | 190 | struct xxxid_stats *ps = NULL; 191 | struct xxxid_stats *cs = NULL; 192 | 193 | //if (config.f.timestamp || config.f.quite) 194 | config.f.batch_mode = 1; 195 | 196 | view_callback view = view_batch; 197 | how_to_sleep do_sleep = (how_to_sleep) sleep; 198 | 199 | /*if (!config.f.batch_mode) 200 | { 201 | view = view_curses; 202 | do_sleep = curses_sleep; 203 | }*/ 204 | 205 | 206 | do 207 | { 208 | cs = fetch_data(config.f.processes, filter1); 209 | view(cs, ps, params.iter,fd); 210 | 211 | if (ps) 212 | free_stats_chain(ps); 213 | 214 | ps = cs; 215 | if ((params.iter > -1) && ((--params.iter) == 0)) 216 | break; 217 | } 218 | while (!do_sleep(params.delay)); 219 | 220 | free_stats_chain(cs); 221 | sig_handler(SIGINT); 222 | 223 | 224 | return 0; 225 | } 226 | -------------------------------------------------------------------------------- /src/modules/iotop/src/utils.c: -------------------------------------------------------------------------------- 1 | #include "iotop.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | static const char *xprintf(const char *format, ...) 10 | { 11 | static char buf[BUFSIZ]; 12 | va_list args; 13 | 14 | memset(buf, 0, BUFSIZ); 15 | va_start(args, format); 16 | 17 | int j = vsnprintf(buf, BUFSIZ, format, args); 18 | 19 | va_end(args); 20 | 21 | return ((j >= 0) && (j < BUFSIZ)) ? buf : NULL; 22 | } 23 | 24 | const char *read_cmdline2(int pid) 25 | { 26 | static char buf[BUFSIZ]; 27 | FILE *fp = fopen(xprintf("/proc/%d/cmdline", pid), "rb"); 28 | char *rv = NULL; 29 | 30 | memset(buf, 0, BUFSIZ); 31 | if (fp) 32 | { 33 | size_t n = fread(buf, sizeof(char), BUFSIZ, fp); 34 | if (n > 0) 35 | { 36 | size_t k; 37 | for (k = 0; k < n - 1; k++) 38 | buf[k] = buf[k] ? buf[k] : ' '; 39 | rv = buf; 40 | } 41 | fclose(fp); 42 | } 43 | 44 | if (rv) 45 | return rv; 46 | 47 | fp = fopen(xprintf("/proc/%d/status", pid), "rb"); 48 | 49 | memset(buf, 0, BUFSIZ); 50 | if (fp) 51 | { 52 | size_t n = fread(buf, sizeof(char), BUFSIZ, fp); 53 | char *eol = NULL; 54 | 55 | if (n > 0 && (eol = strchr(buf, '\n') - 1) 56 | && (eol > strchr(buf, '\t'))) 57 | { 58 | eol[0] = 0; 59 | strcpy(buf, xprintf("[%s]", strchr(buf, '\t') + 1)); 60 | rv = buf; 61 | } 62 | fclose(fp); 63 | } 64 | 65 | return rv; 66 | } 67 | 68 | static int __next_pid(DIR *dir) 69 | { 70 | while (1) 71 | { 72 | struct dirent *de = readdir(dir); 73 | 74 | if (!de) 75 | return 0; 76 | 77 | char *eol = NULL; 78 | int pid = strtol(de->d_name, &eol, 10); 79 | 80 | if (*eol != '\0') 81 | continue; 82 | 83 | return pid; 84 | } 85 | 86 | return 0; 87 | } 88 | 89 | struct pidgen *openpidgen(int flags) 90 | { 91 | struct pidgen *pg = malloc(sizeof(struct pidgen)); 92 | 93 | if (!pg) 94 | return NULL; 95 | 96 | if ((pg->__proc = opendir("/proc"))) 97 | { 98 | pg->__task = NULL; 99 | pg->__flags = flags; 100 | return pg; 101 | } 102 | 103 | free(pg); 104 | return NULL; 105 | } 106 | 107 | void closepidgen(struct pidgen *pg) 108 | { 109 | if (pg->__proc) 110 | closedir((DIR *) pg->__proc); 111 | 112 | if (pg->__task) 113 | closedir((DIR *) pg->__task); 114 | 115 | free(pg); 116 | } 117 | 118 | int pidgen_next(struct pidgen *pg) 119 | { 120 | int pid; 121 | 122 | if (pg->__task) 123 | { 124 | pid = __next_pid((DIR *) pg->__task); 125 | 126 | if (pid < 1) 127 | { 128 | closedir((DIR *) pg->__task); 129 | pg->__task = NULL; 130 | return pidgen_next(pg); 131 | } 132 | 133 | return pid; 134 | } 135 | 136 | pid = __next_pid((DIR *) pg->__proc); 137 | 138 | if (pid && (pg->__flags & PIDGEN_FLAGS_TASK)) 139 | { 140 | pg->__task = (DIR *) opendir(xprintf("/proc/%d/task", pid)); 141 | return pidgen_next(pg); 142 | } 143 | 144 | return pid; 145 | } 146 | 147 | -------------------------------------------------------------------------------- /src/modules/procrank/Makefile: -------------------------------------------------------------------------------- 1 | DIR_INC = ./inc 2 | DIR_SRC = ./src 3 | DIR_OBJ = ./obj 4 | 5 | 6 | SRC = $(wildcard ${DIR_SRC}/*.c) 7 | OBJ = $(patsubst %.c,${DIR_OBJ}/%.o,$(notdir ${SRC})) 8 | 9 | TARGET = libprocrank.a 10 | 11 | 12 | #CROSS_COMPILE=arm-linux-gnueabi- 13 | #CC=$(CROSS_COMPILE)gcc 14 | #AR=$(CROSS_COMPILE)ar 15 | #LD=$(CROSS_COMPILE)ld 16 | 17 | 18 | CFLAGS = -I$(DIR_INC) -Wall -static -g -D_LARGEFILE64_SOURCE 19 | 20 | 21 | 22 | ${TARGET}:${OBJ} 23 | $(AR) rc $@ $^ 24 | @mv $(TARGET) ../../../libs/ 25 | ${DIR_OBJ}/%.o:${DIR_SRC}/%.c 26 | @mkdir -p $(DIR_OBJ) 27 | $(CC) $(CFLAGS) -c $< -o $@ 28 | 29 | .PHONY:clean 30 | clean: 31 | @rm -rf $(DIR_OBJ) 32 | -------------------------------------------------------------------------------- /src/modules/procrank/inc/pagemap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _PAGEMAP_PAGEMAP_H 18 | #define _PAGEMAP_PAGEMAP_H 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | typedef struct pm_memusage pm_memusage_t; 25 | 26 | /* Holds the various metrics for memory usage of a process or a mapping. */ 27 | struct pm_memusage { 28 | size_t vss; 29 | size_t rss; 30 | size_t pss; 31 | size_t uss; 32 | size_t swap; 33 | }; 34 | 35 | /* Clears a memusage. */ 36 | void pm_memusage_zero(pm_memusage_t *mu); 37 | /* Adds one memusage (a) to another (b). */ 38 | void pm_memusage_add(pm_memusage_t *a, pm_memusage_t *b); 39 | 40 | typedef struct pm_kernel pm_kernel_t; 41 | typedef struct pm_process pm_process_t; 42 | typedef struct pm_map pm_map_t; 43 | 44 | /* pm_kernel_t holds the state necessary to interface to the kernel's pagemap 45 | * system on a global level. */ 46 | struct pm_kernel { 47 | int kpagecount_fd; 48 | int kpageflags_fd; 49 | 50 | int pagesize; 51 | }; 52 | 53 | /* pm_process_t holds the state necessary to interface to a particular process' 54 | * pagemap. */ 55 | struct pm_process { 56 | pm_kernel_t *ker; 57 | 58 | pid_t pid; 59 | 60 | pm_map_t **maps; 61 | int num_maps; 62 | 63 | int pagemap_fd; 64 | }; 65 | 66 | /* pm_map_t holds the state necessary to access information about a particular 67 | * mapping in a particular process. */ 68 | struct pm_map { 69 | pm_process_t *proc; 70 | 71 | uint64_t start; 72 | uint64_t end; 73 | uint64_t offset; 74 | int flags; 75 | 76 | char *name; 77 | }; 78 | 79 | /* Create a pm_kernel_t. */ 80 | int pm_kernel_create(pm_kernel_t **ker_out); 81 | 82 | #define pm_kernel_pagesize(ker) ((ker)->pagesize) 83 | 84 | /* Get a list of probably-existing PIDs (returned through *pids_out). 85 | * Length of the array (in sizeof(pid_t) units) is returned through *len. 86 | * The array should be freed by the caller. */ 87 | int pm_kernel_pids(pm_kernel_t *ker, pid_t **pids_out, size_t *len); 88 | 89 | /* Get the map count (from /proc/kpagecount) of a physical frame. 90 | * The count is returned through *count_out. */ 91 | int pm_kernel_count(pm_kernel_t *ker, uint64_t pfn, uint64_t *count_out); 92 | 93 | /* Get the page flags (from /proc/kpageflags) of a physical frame. 94 | * The count is returned through *flags_out. */ 95 | int pm_kernel_flags(pm_kernel_t *ker, uint64_t pfn, uint64_t *flags_out); 96 | 97 | #define PM_PAGE_LOCKED (1 << 0) 98 | #define PM_PAGE_ERROR (1 << 1) 99 | #define PM_PAGE_REFERENCED (1 << 2) 100 | #define PM_PAGE_UPTODATE (1 << 3) 101 | #define PM_PAGE_DIRTY (1 << 4) 102 | #define PM_PAGE_LRU (1 << 5) 103 | #define PM_PAGE_ACTIVE (1 << 6) 104 | #define PM_PAGE_SLAB (1 << 7) 105 | #define PM_PAGE_WRITEBACK (1 << 8) 106 | #define PM_PAGE_RECLAIM (1 << 9) 107 | #define PM_PAGE_BUDDY (1 << 10) 108 | 109 | /* for kernels >= 2.6.31 */ 110 | #define PM_PAGE_MMAP (1 << 11) 111 | #define PM_PAGE_ANON (1 << 12) 112 | #define PM_PAGE_SWAPCACHE (1 << 13) 113 | #define PM_PAGE_SWAPBACKED (1 << 14) 114 | #define PM_PAGE_COMPOUND_HEAD (1 << 15) 115 | #define PM_PAGE_COMPOUND_TAIL (1 << 16) 116 | #define PM_PAGE_HUGE (1 << 17) 117 | #define PM_PAGE_UNEVICTABLE (1 << 18) 118 | #define PM_PAGE_HWPOISON (1 << 19) 119 | #define PM_PAGE_NOPAGE (1 << 20) 120 | 121 | /* for kernels >= 2.6.32 */ 122 | #define PM_PAGE_KSM (1 << 21) 123 | 124 | /* for kernels >= 3.4 */ 125 | #define PM_PAGE_THP (1 << 22) 126 | 127 | /* Destroy a pm_kernel_t. */ 128 | int pm_kernel_destroy(pm_kernel_t *ker); 129 | 130 | /* Get the PID of a pm_process_t. */ 131 | #define pm_process_pid(proc) ((proc)->pid) 132 | 133 | /* Create a pm_process_t and returns it through *proc_out. 134 | * Takes a pm_kernel_t, and the PID of the process. */ 135 | int pm_process_create(pm_kernel_t *ker, pid_t pid, pm_process_t **proc_out); 136 | 137 | /* Get the total memory usage of a process and store in *usage_out. */ 138 | int pm_process_usage(pm_process_t *proc, pm_memusage_t *usage_out); 139 | 140 | /* Get the total memory usage of a process and store in *usage_out, only 141 | * counting pages with specified flags. */ 142 | int pm_process_usage_flags(pm_process_t *proc, pm_memusage_t *usage_out, 143 | uint64_t flags_mask, uint64_t required_flags); 144 | 145 | /* Get the working set of a process (if ws_out != NULL), and reset it 146 | * (if reset != 0). */ 147 | int pm_process_workingset(pm_process_t *proc, pm_memusage_t *ws_out, int reset); 148 | 149 | /* Get the PFNs corresponding to a range of virtual addresses. 150 | * The array of PFNs is returned through *range_out, and the caller has the 151 | * responsibility to free it. */ 152 | int pm_process_pagemap_range(pm_process_t *proc, 153 | uint64_t low, uint64_t hi, 154 | uint64_t **range_out, size_t *len); 155 | 156 | #define _BITS(x, offset, bits) (((x) >> offset) & ((1LL << (bits)) - 1)) 157 | 158 | #define PM_PAGEMAP_PRESENT(x) (_BITS(x, 63, 1)) 159 | #define PM_PAGEMAP_SWAPPED(x) (_BITS(x, 62, 1)) 160 | #define PM_PAGEMAP_SHIFT(x) (_BITS(x, 55, 6)) 161 | #define PM_PAGEMAP_PFN(x) (_BITS(x, 0, 55)) 162 | #define PM_PAGEMAP_SWAP_OFFSET(x) (_BITS(x, 5, 50)) 163 | #define PM_PAGEMAP_SWAP_TYPE(x) (_BITS(x, 0, 5)) 164 | 165 | /* Get the maps in the virtual address space of this process. 166 | * Returns an array of pointers to pm_map_t through *maps. 167 | * The array should be freed by the caller, but the maps should not be 168 | * modified or destroyed. */ 169 | int pm_process_maps(pm_process_t *proc, pm_map_t ***maps_out, size_t *len); 170 | 171 | /* Destroy a pm_process_t. */ 172 | int pm_process_destroy(pm_process_t *proc); 173 | 174 | /* Get the name, flags, start/end address, or offset of a map. */ 175 | #define pm_map_name(map) ((map)->name) 176 | #define pm_map_flags(map) ((map)->flags) 177 | #define PM_MAP_READ 1 178 | #define PM_MAP_WRITE 2 179 | #define PM_MAP_EXEC 4 180 | #define PM_MAP_PERMISSIONS (PM_MAP_READ | PM_MAP_WRITE | PM_MAP_EXEC) 181 | #define pm_map_start(map) ((map)->start) 182 | #define pm_map_end(map) ((map)->end) 183 | #define pm_map_offset(map) ((map)->offset) 184 | 185 | /* Get the PFNs of the pages in the virtual address space of this map. 186 | * Array of PFNs is returned through *pagemap_out, and should be freed by the 187 | * caller. */ 188 | int pm_map_pagemap(pm_map_t *map, uint64_t **pagemap_out, size_t *len); 189 | 190 | /* Get the memory usage of this map alone. */ 191 | int pm_map_usage(pm_map_t *map, pm_memusage_t *usage_out); 192 | 193 | /* Get the memory usage of this map alone, only counting pages with specified 194 | * flags. */ 195 | int pm_map_usage_flags(pm_map_t *map, pm_memusage_t *usage_out, 196 | uint64_t flags_mask, uint64_t required_flags); 197 | 198 | /* Get the working set of this map alone. */ 199 | int pm_map_workingset(pm_map_t *map, pm_memusage_t *ws_out); 200 | 201 | #endif 202 | -------------------------------------------------------------------------------- /src/modules/procrank/inc/pm_map.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBS_PAGEMAP_PM_MAP_H 18 | #define _LIBS_PAGEMAP_PM_MAP_H 19 | 20 | #include "pagemap.h" 21 | 22 | int pm_map_destroy(pm_map_t *map); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/modules/procrank/src/pm_kernel.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "pagemap.h" 27 | 28 | int pm_kernel_create(pm_kernel_t **ker_out) { 29 | pm_kernel_t *ker; 30 | int error; 31 | 32 | if (!ker_out) 33 | return 1; 34 | 35 | ker = calloc(1, sizeof(*ker)); 36 | if (!ker) 37 | return errno; 38 | 39 | ker->kpagecount_fd = open("/proc/kpagecount", O_RDONLY); 40 | if (ker->kpagecount_fd < 0) { 41 | error = errno; 42 | free(ker); 43 | return error; 44 | } 45 | 46 | ker->kpageflags_fd = open("/proc/kpageflags", O_RDONLY); 47 | if (ker->kpageflags_fd < 0) { 48 | error = errno; 49 | close(ker->kpagecount_fd); 50 | free(ker); 51 | return error; 52 | } 53 | 54 | ker->pagesize = getpagesize(); 55 | 56 | *ker_out = ker; 57 | 58 | return 0; 59 | } 60 | 61 | #define INIT_PIDS 20 62 | int pm_kernel_pids(pm_kernel_t *ker, pid_t **pids_out, size_t *len) { 63 | DIR *proc; 64 | struct dirent *dir; 65 | pid_t pid, *pids, *new_pids; 66 | size_t pids_count, pids_size; 67 | int error; 68 | 69 | proc = opendir("/proc"); 70 | if (!proc) 71 | return errno; 72 | 73 | pids = malloc(INIT_PIDS * sizeof(pid_t)); 74 | if (!pids) { 75 | closedir(proc); 76 | return errno; 77 | } 78 | pids_count = 0; pids_size = INIT_PIDS; 79 | 80 | while ((dir = readdir(proc))) { 81 | if (sscanf(dir->d_name, "%d", &pid) < 1) 82 | continue; 83 | 84 | if (pids_count >= pids_size) { 85 | new_pids = realloc(pids, 2 * pids_size * sizeof(pid_t)); 86 | if (!new_pids) { 87 | error = errno; 88 | free(pids); 89 | closedir(proc); 90 | return error; 91 | } 92 | pids = new_pids; 93 | pids_size = 2 * pids_size; 94 | } 95 | 96 | pids[pids_count] = pid; 97 | 98 | pids_count++; 99 | } 100 | 101 | closedir(proc); 102 | 103 | new_pids = realloc(pids, pids_count * sizeof(pid_t)); 104 | if (!new_pids) { 105 | error = errno; 106 | free(pids); 107 | return error; 108 | } 109 | 110 | *pids_out = new_pids; 111 | *len = pids_count; 112 | 113 | return 0; 114 | } 115 | 116 | int pm_kernel_count(pm_kernel_t *ker, uint64_t pfn, uint64_t *count_out) { 117 | off64_t off; 118 | 119 | if (!ker || !count_out) 120 | return -1; 121 | 122 | off = lseek64(ker->kpagecount_fd, pfn * sizeof(uint64_t), SEEK_SET); 123 | if (off == (off_t)-1) 124 | return errno; 125 | if (read(ker->kpagecount_fd, count_out, sizeof(uint64_t)) < 126 | (ssize_t)sizeof(uint64_t)) 127 | return errno; 128 | 129 | return 0; 130 | } 131 | 132 | int pm_kernel_flags(pm_kernel_t *ker, uint64_t pfn, uint64_t *flags_out) { 133 | off64_t off; 134 | 135 | if (!ker || !flags_out) 136 | return -1; 137 | 138 | off = lseek64(ker->kpageflags_fd, pfn * sizeof(uint64_t), SEEK_SET); 139 | if (off == (off_t)-1) 140 | return errno; 141 | if (read(ker->kpageflags_fd, flags_out, sizeof(uint64_t)) < 142 | (ssize_t)sizeof(uint64_t)) 143 | return errno; 144 | 145 | return 0; 146 | } 147 | 148 | int pm_kernel_destroy(pm_kernel_t *ker) { 149 | if (!ker) 150 | return -1; 151 | 152 | close(ker->kpagecount_fd); 153 | close(ker->kpageflags_fd); 154 | 155 | free(ker); 156 | 157 | return 0; 158 | } 159 | -------------------------------------------------------------------------------- /src/modules/procrank/src/pm_map.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | #include "pagemap.h" 21 | 22 | int pm_map_pagemap(pm_map_t *map, uint64_t **pagemap_out, size_t *len) { 23 | if (!map) 24 | return -1; 25 | 26 | return pm_process_pagemap_range(map->proc, map->start, map->end, 27 | pagemap_out, len); 28 | } 29 | 30 | int pm_map_usage_flags(pm_map_t *map, pm_memusage_t *usage_out, 31 | uint64_t flags_mask, uint64_t required_flags) { 32 | uint64_t *pagemap; 33 | size_t len, i; 34 | uint64_t count; 35 | pm_memusage_t usage; 36 | int error; 37 | 38 | if (!map || !usage_out) 39 | return -1; 40 | 41 | error = pm_map_pagemap(map, &pagemap, &len); 42 | if (error) return error; 43 | 44 | pm_memusage_zero(&usage); 45 | 46 | for (i = 0; i < len; i++) { 47 | usage.vss += map->proc->ker->pagesize; 48 | 49 | if (!PM_PAGEMAP_PRESENT(pagemap[i])) 50 | continue; 51 | 52 | if (!PM_PAGEMAP_SWAPPED(pagemap[i])) { 53 | if (flags_mask) { 54 | uint64_t flags; 55 | error = pm_kernel_flags(map->proc->ker, PM_PAGEMAP_PFN(pagemap[i]), 56 | &flags); 57 | if (error) goto out; 58 | 59 | if ((flags & flags_mask) != required_flags) 60 | continue; 61 | } 62 | 63 | error = pm_kernel_count(map->proc->ker, PM_PAGEMAP_PFN(pagemap[i]), 64 | &count); 65 | if (error) goto out; 66 | 67 | usage.rss += (count >= 1) ? map->proc->ker->pagesize : (0); 68 | usage.pss += (count >= 1) ? (map->proc->ker->pagesize / count) : (0); 69 | usage.uss += (count == 1) ? (map->proc->ker->pagesize) : (0); 70 | } else { 71 | usage.swap += map->proc->ker->pagesize; 72 | } 73 | } 74 | 75 | memcpy(usage_out, &usage, sizeof(usage)); 76 | 77 | error = 0; 78 | 79 | out: 80 | free(pagemap); 81 | 82 | return error; 83 | } 84 | 85 | int pm_map_usage(pm_map_t *map, pm_memusage_t *usage_out) { 86 | return pm_map_usage_flags(map, usage_out, 0, 0); 87 | } 88 | 89 | int pm_map_workingset(pm_map_t *map, pm_memusage_t *ws_out) { 90 | uint64_t *pagemap; 91 | size_t len, i; 92 | uint64_t count, flags; 93 | pm_memusage_t ws; 94 | int error; 95 | 96 | if (!map || !ws_out) 97 | return -1; 98 | 99 | error = pm_map_pagemap(map, &pagemap, &len); 100 | if (error) return error; 101 | 102 | pm_memusage_zero(&ws); 103 | 104 | for (i = 0; i < len; i++) { 105 | error = pm_kernel_flags(map->proc->ker, PM_PAGEMAP_PFN(pagemap[i]), 106 | &flags); 107 | if (error) goto out; 108 | 109 | if (!(flags & PM_PAGE_REFERENCED)) 110 | continue; 111 | 112 | error = pm_kernel_count(map->proc->ker, PM_PAGEMAP_PFN(pagemap[i]), 113 | &count); 114 | if (error) goto out; 115 | 116 | ws.vss += map->proc->ker->pagesize; 117 | if( PM_PAGEMAP_SWAPPED(pagemap[i]) ) continue; 118 | ws.rss += (count >= 1) ? (map->proc->ker->pagesize) : (0); 119 | ws.pss += (count >= 1) ? (map->proc->ker->pagesize / count) : (0); 120 | ws.uss += (count == 1) ? (map->proc->ker->pagesize) : (0); 121 | } 122 | 123 | memcpy(ws_out, &ws, sizeof(ws)); 124 | 125 | error = 0; 126 | 127 | out: 128 | free(pagemap); 129 | 130 | return 0; 131 | } 132 | 133 | int pm_map_destroy(pm_map_t *map) { 134 | if (!map) 135 | return -1; 136 | 137 | free(map->name); 138 | free(map); 139 | 140 | return 0; 141 | } 142 | -------------------------------------------------------------------------------- /src/modules/procrank/src/pm_memusage.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "pagemap.h" 18 | 19 | void pm_memusage_zero(pm_memusage_t *mu) { 20 | mu->vss = mu->rss = mu->pss = mu->uss = mu->swap = 0; 21 | } 22 | 23 | void pm_memusage_add(pm_memusage_t *a, pm_memusage_t *b) { 24 | a->vss += b->vss; 25 | a->rss += b->rss; 26 | a->pss += b->pss; 27 | a->uss += b->uss; 28 | a->swap += b->swap; 29 | } 30 | -------------------------------------------------------------------------------- /src/modules/procrank/src/strlcpy.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */ 2 | 3 | /* 4 | * Copyright (c) 1998 Todd C. Miller 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | /* 23 | * Copy src to string dst of size siz. At most siz-1 characters 24 | * will be copied. Always NUL terminates (unless siz == 0). 25 | * Returns strlen(src); if retval >= siz, truncation occurred. 26 | */ 27 | size_t 28 | strlcpy(char *dst, const char *src, size_t siz) 29 | { 30 | char *d = dst; 31 | const char *s = src; 32 | size_t n = siz; 33 | 34 | /* Copy as many bytes as will fit */ 35 | if (n != 0) { 36 | while (--n != 0) { 37 | if ((*d++ = *s++) == '\0') 38 | break; 39 | } 40 | } 41 | 42 | /* Not enough room in dst, add NUL and traverse rest of src */ 43 | if (n == 0) { 44 | if (siz != 0) 45 | *d = '\0'; /* NUL-terminate dst */ 46 | while (*s++) 47 | ; 48 | } 49 | 50 | return(s - src - 1); /* count does not include NUL */ 51 | } 52 | -------------------------------------------------------------------------------- /src/modules/ps/Makefile: -------------------------------------------------------------------------------- 1 | DIR_INC = ./inc 2 | DIR_SRC = ./src 3 | DIR_OBJ = ./obj 4 | 5 | 6 | SRC = $(wildcard ${DIR_SRC}/*.c) 7 | OBJ = $(patsubst %.c,${DIR_OBJ}/%.o,$(notdir ${SRC})) 8 | 9 | TARGET = libps.a 10 | 11 | 12 | #CROSS_COMPILE=arm-linux-gnueabi- 13 | #CC=$(CROSS_COMPILE)gcc 14 | #AR=$(CROSS_COMPILE)ar 15 | #LD=$(CROSS_COMPILE)ld 16 | 17 | 18 | CFLAGS = -I$(DIR_INC) -Wall -static -g -std=c99 -DPACKAGE_VERSION="1.0" -D_GNU_SOURCE 19 | 20 | 21 | 22 | ${TARGET}:${OBJ} 23 | $(AR) rc $@ $^ 24 | @mv $(TARGET) ../../../libs/ 25 | ${DIR_OBJ}/%.o:${DIR_SRC}/%.c 26 | @mkdir -p $(DIR_OBJ) 27 | $(CC) $(CFLAGS) -c $< -o $@ 28 | 29 | .PHONY:clean 30 | clean: 31 | @rm -rf $(DIR_OBJ) 32 | -------------------------------------------------------------------------------- /src/modules/ps/inc/alloc.h: -------------------------------------------------------------------------------- 1 | #ifndef PROCPS_PROC_ALLOC_H 2 | #define PROCPS_PROC_ALLOC_H 3 | 4 | #include "procps.h" 5 | 6 | EXTERN_C_BEGIN 7 | 8 | /* change xalloc_err_handler to override the default fprintf(stderr... */ 9 | extern message_fn xalloc_err_handler; 10 | 11 | extern void *xcalloc(unsigned int size) MALLOC; 12 | extern void *xmalloc(size_t size) MALLOC; 13 | extern void *xrealloc(void *oldp, unsigned int size) MALLOC; 14 | extern char *xstrdup(const char *str) MALLOC; 15 | 16 | EXTERN_C_END 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/modules/ps/inc/c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This header was copied from util-linux at fall 2011. 3 | */ 4 | 5 | /* 6 | * Fundamental C definitions. 7 | */ 8 | 9 | #ifndef PROCPS_NG_C_H 10 | #define PROCPS_NG_C_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #ifdef HAVE_ERROR_H 20 | #include 21 | #else 22 | #include 23 | #endif 24 | 25 | /* 26 | * Compiler specific stuff 27 | */ 28 | #ifndef __GNUC_PREREQ 29 | # if defined __GNUC__ && defined __GNUC_MINOR__ 30 | # define __GNUC_PREREQ(maj, min) \ 31 | ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) 32 | # else 33 | # define __GNUC_PREREQ(maj, min) 0 34 | # endif 35 | #endif 36 | 37 | /* 38 | * Function attributes 39 | */ 40 | #ifndef __ul_alloc_size 41 | # if __GNUC_PREREQ (4, 3) 42 | # define __ul_alloc_size(s) __attribute__((alloc_size(s))) 43 | # else 44 | # define __ul_alloc_size(s) 45 | # endif 46 | #endif 47 | 48 | #ifndef __ul_calloc_size 49 | # if __GNUC_PREREQ (4, 3) 50 | # define __ul_calloc_size(n, s) __attribute__((alloc_size(n, s))) 51 | # else 52 | # define __ul_calloc_size(n, s) 53 | # endif 54 | #endif 55 | 56 | /* 57 | * Misc 58 | */ 59 | #ifndef PATH_MAX 60 | # define PATH_MAX 4096 61 | #endif 62 | 63 | #ifndef TRUE 64 | # define TRUE 1 65 | #endif 66 | 67 | #ifndef FALSE 68 | # define FALSE 0 69 | #endif 70 | 71 | /* 72 | * Program name. 73 | */ 74 | #ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAME 75 | # ifdef HAVE___PROGNAME 76 | extern char *__progname; 77 | # define program_invocation_short_name __progname 78 | # else 79 | # ifdef HAVE_GETEXECNAME 80 | # define program_invocation_short_name \ 81 | prog_inv_sh_nm_from_file(getexecname(), 0) 82 | # else 83 | # define program_invocation_short_name \ 84 | prog_inv_sh_nm_from_file(__FILE__, 1) 85 | # endif 86 | static char prog_inv_sh_nm_buf[256]; 87 | static inline char *prog_inv_sh_nm_from_file(char *f, char stripext) 88 | { 89 | char *t; 90 | 91 | if ((t = strrchr(f, '/')) != NULL) 92 | t++; 93 | else 94 | t = f; 95 | 96 | strncpy(prog_inv_sh_nm_buf, t, sizeof(prog_inv_sh_nm_buf) - 1); 97 | prog_inv_sh_nm_buf[sizeof(prog_inv_sh_nm_buf) - 1] = '\0'; 98 | 99 | if (stripext && (t = strrchr(prog_inv_sh_nm_buf, '.')) != NULL) 100 | *t = '\0'; 101 | 102 | return prog_inv_sh_nm_buf; 103 | } 104 | # endif 105 | #endif 106 | 107 | /* 108 | * Error printing. 109 | */ 110 | #ifndef HAVE_ERROR_H 111 | /* Emulate the error() function from glibc */ 112 | __attribute__((__format__(__printf__, 3, 4))) 113 | static void error(int status, int errnum, const char *format, ...) 114 | { 115 | va_list argp; 116 | fprintf(stderr, "%s: ", program_invocation_short_name); 117 | va_start(argp, format); 118 | vfprintf(stderr, format, argp); 119 | va_end(argp); 120 | if (errnum != 0) 121 | fprintf(stderr, ": error code %d", errnum); 122 | fprintf(stderr, "\n"); 123 | if (status != 0) 124 | exit(status); 125 | } 126 | 127 | /* Emulate the error_at_line() function from glibc */ 128 | __attribute__((__format__(__printf__, 5, 6))) 129 | static void error_at_line(int status, int errnum, const char *filename, 130 | unsigned int linenum, const char *format, ...) 131 | { 132 | va_list argp; 133 | fprintf(stderr, "%s:%s:%u: ", program_invocation_short_name, 134 | filename, linenum); 135 | va_start(argp, format); 136 | vfprintf(stderr, format, argp); 137 | va_end(argp); 138 | if (errnum != 0) 139 | fprintf(stderr, ": error code %d", errnum); 140 | fprintf(stderr, "\n"); 141 | if (status != 0) 142 | exit(status); 143 | } 144 | #endif 145 | #define xwarn(...) error(0, errno, __VA_ARGS__) 146 | #define xwarnx(...) error(0, 0, __VA_ARGS__) 147 | #define xerr(STATUS, ...) error(STATUS, errno, __VA_ARGS__) 148 | #define xerrx(STATUS, ...) error(STATUS, 0, __VA_ARGS__) 149 | 150 | /* 151 | * Constant strings for usage() functions. 152 | */ 153 | #define USAGE_HEADER _("\nUsage:\n") 154 | #define USAGE_OPTIONS _("\nOptions:\n") 155 | #define USAGE_SEPARATOR _("\n") 156 | #define USAGE_HELP _(" -h, --help display this help and exit\n") 157 | #define USAGE_VERSION _(" -V, --version output version information and exit\n") 158 | #define USAGE_MAN_TAIL(_man) _("\nFor more details see %s.\n"), _man 159 | 160 | #define PROCPS_NG_VERSION _("%s from %s\n"), program_invocation_short_name, "lepd-ps" 161 | 162 | #endif /* PROCPS_NG_C_H */ 163 | -------------------------------------------------------------------------------- /src/modules/ps/inc/devname.h: -------------------------------------------------------------------------------- 1 | #ifndef PROC_DEVNAME_H 2 | #define PROC_DEVNAME_H 3 | 4 | #include "procps.h" 5 | #include "readproc.h" 6 | 7 | EXTERN_C_BEGIN 8 | 9 | #define ABBREV_DEV 1 /* remove /dev/ */ 10 | #define ABBREV_TTY 2 /* remove tty */ 11 | #define ABBREV_PTS 4 /* remove pts/ */ 12 | 13 | extern unsigned dev_to_tty(char *__restrict ret, unsigned chop, dev_t dev_t_dev, int pid, unsigned int flags); 14 | 15 | extern int tty_to_dev(const char *__restrict const name); 16 | 17 | EXTERN_C_END 18 | #endif 19 | -------------------------------------------------------------------------------- /src/modules/ps/inc/escape.h: -------------------------------------------------------------------------------- 1 | #ifndef PROCPS_PROC_ESCAPE_H 2 | #define PROCPS_PROC_ESCAPE_H 3 | 4 | //#include 5 | #include 6 | #include "procps.h" 7 | #include "readproc.h" 8 | 9 | EXTERN_C_BEGIN 10 | 11 | #define ESC_STRETCH 1 // since we mangle to '?' this is 1 (would be 4 for octal escapes) 12 | 13 | #define ESC_ARGS 0x1 // try to use cmdline instead of cmd 14 | #define ESC_BRACKETS 0x2 // if using cmd, put '[' and ']' around it 15 | #define ESC_DEFUNCT 0x4 // mark zombies with " " 16 | 17 | extern int escape_strlist(char *__restrict dst, char *__restrict const *__restrict src, size_t n, int *cells); 18 | extern int escape_str(char *__restrict dst, const char *__restrict src, int bufsize, int *maxcells); 19 | extern int escape_command(char *__restrict const outbuf, const proc_t *__restrict const pp, int bytes, int *cells, unsigned flags); 20 | extern int escaped_copy(char *__restrict dst, const char *__restrict src, int bufsize, int *maxroom); 21 | 22 | EXTERN_C_END 23 | #endif 24 | -------------------------------------------------------------------------------- /src/modules/ps/inc/fileutils.h: -------------------------------------------------------------------------------- 1 | #ifndef PROCPS_NG_FILEUTILS 2 | #define PROCPS_NG_FILEUTILS 3 | 4 | int close_stream(FILE * stream); 5 | void close_stdout(void); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /src/modules/ps/inc/nls.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This header was copied from util-linux at fall 2011. 3 | */ 4 | 5 | #ifndef PROCPS_NG_NLS_H 6 | #define PROCPS_NG_NLS_H 7 | 8 | /* programs issuing textdomain() need PACKAGE string */ 9 | //#include "../config.h" 10 | 11 | /* programs issuing bindtextdomain() also need LOCALEDIR string */ 12 | #ifndef LOCALEDIR 13 | #define LOCALEDIR "/usr/share/locale" 14 | #endif 15 | 16 | #ifdef HAVE_LOCALE_H 17 | # include 18 | #else 19 | # undef setlocale 20 | # define setlocale(Category, Locale) /* empty */ 21 | #endif 22 | 23 | #ifdef ENABLE_NLS 24 | # include 25 | # define _(Text) gettext (Text) 26 | # ifdef gettext_noop 27 | # define N_(String) gettext_noop (String) 28 | # else 29 | # define N_(String) (String) 30 | # endif 31 | # define P_(Singular, Plural, n) ngettext (Singular, Plural, n) 32 | #else 33 | # undef bindtextdomain 34 | # define bindtextdomain(Domain, Directory) /* empty */ 35 | # undef textdomain 36 | # define textdomain(Domain) /* empty */ 37 | # define _(Text) (Text) 38 | # define N_(Text) (Text) 39 | # define P_(Singular, Plural, n) ((n) == 1 ? (Singular) : (Plural)) 40 | #endif /* ENABLE_NLS */ 41 | 42 | #ifdef HAVE_LANGINFO_H 43 | # include 44 | #else 45 | 46 | typedef int nl_item; 47 | extern char *langinfo_fallback(nl_item item); 48 | 49 | # define nl_langinfo langinfo_fallback 50 | 51 | enum { 52 | CODESET = 1, 53 | RADIXCHAR, 54 | THOUSEP, 55 | D_T_FMT, 56 | D_FMT, 57 | T_FMT, 58 | T_FMT_AMPM, 59 | AM_STR, 60 | PM_STR, 61 | 62 | DAY_1, 63 | DAY_2, 64 | DAY_3, 65 | DAY_4, 66 | DAY_5, 67 | DAY_6, 68 | DAY_7, 69 | 70 | ABDAY_1, 71 | ABDAY_2, 72 | ABDAY_3, 73 | ABDAY_4, 74 | ABDAY_5, 75 | ABDAY_6, 76 | ABDAY_7, 77 | 78 | MON_1, 79 | MON_2, 80 | MON_3, 81 | MON_4, 82 | MON_5, 83 | MON_6, 84 | MON_7, 85 | MON_8, 86 | MON_9, 87 | MON_10, 88 | MON_11, 89 | MON_12, 90 | 91 | ABMON_1, 92 | ABMON_2, 93 | ABMON_3, 94 | ABMON_4, 95 | ABMON_5, 96 | ABMON_6, 97 | ABMON_7, 98 | ABMON_8, 99 | ABMON_9, 100 | ABMON_10, 101 | ABMON_11, 102 | ABMON_12, 103 | 104 | ERA_D_FMT, 105 | ERA_D_T_FMT, 106 | ERA_T_FMT, 107 | ALT_DIGITS, 108 | CRNCYSTR, 109 | YESEXPR, 110 | NOEXPR 111 | }; 112 | 113 | #endif /* !HAVE_LANGINFO_H */ 114 | #endif /* PROCPS_NG_NLS_H */ 115 | -------------------------------------------------------------------------------- /src/modules/ps/inc/procps-private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libprocps - Library to read proc filesystem 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | #ifndef PROCPS_PRIVATE_H 19 | #define PROCPS_PRIVATE_H 20 | 21 | #include 22 | 23 | #define PROCPS_EXPORT __attribute__ ((visibility("default"))) 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /src/modules/ps/inc/procps.h: -------------------------------------------------------------------------------- 1 | #ifndef PROCPS_PROC_PROCPS_H 2 | #define PROCPS_PROC_PROCPS_H 3 | 4 | #ifdef __cplusplus 5 | #define EXTERN_C_BEGIN extern "C" { 6 | #define EXTERN_C_END } 7 | #else 8 | #define EXTERN_C_BEGIN 9 | #define EXTERN_C_END 10 | #endif 11 | 12 | // Some ports make the mistake of running a 32-bit userspace 13 | // on a 64-bit kernel. Shame on them. It's not at all OK to 14 | // make everything "long long", since that causes unneeded 15 | // slowness on 32-bit hardware. 16 | // 17 | // SPARC: The 32-bit kernel was looking like an ex-penguin, 18 | // but it lives! ("I'm not dead yet.") So, 64-bit users will 19 | // just have to compile for 64-bit. Aw, the suffering. 20 | // 21 | // MIPS: Used 32-bit for embedded systems and obsolete hardware. 22 | // The 64-bit systems use an n32 format executable, defining 23 | // _ABIN32 to indicate this. Since n32 doesn't currently run on 24 | // any 32-bit system, nobody get hurt if it's bloated. Not that 25 | // this is sane of course, but it won't hurt the 32-bit users. 26 | // __mips_eabi means eabi, which comes in both sizes, but isn't used. 27 | // 28 | // PowerPC: Big ugly problem! 32-bit Macs are still popular. :-/ 29 | // 30 | // x86-64: So far, nobody has been dumb enough to go 32-bit. 31 | // 32 | // Unknown: PA-RISC and zSeries 33 | // 34 | #if defined(k64test) || (defined(_ABIN32) && _MIPS_SIM == _ABIN32) 35 | #define KLONG long long // not typedef; want "unsigned KLONG" to work 36 | #define KLF "ll" 37 | #define STRTOUKL strtoull 38 | #else 39 | #define KLONG long 40 | #define KLF "l" 41 | #define STRTOUKL strtoul 42 | #endif 43 | 44 | // since gcc-2.5 45 | #define NORETURN __attribute__((__noreturn__)) 46 | #define FUNCTION __attribute__((__const__)) // no access to global mem, even via ptr, and no side effect 47 | 48 | #if __GNUC__ > 2 || __GNUC_MINOR__ >= 96 49 | // won't alias anything, and aligned enough for anything 50 | #define MALLOC __attribute__ ((__malloc__)) 51 | // no side effect, may read globals 52 | #define PURE __attribute__ ((__pure__)) 53 | // tell gcc what to expect: if(unlikely(err)) die(err); 54 | #define likely(x) __builtin_expect(!!(x),1) 55 | #define unlikely(x) __builtin_expect(!!(x),0) 56 | #define expected(x,y) __builtin_expect((x),(y)) 57 | #else 58 | #define MALLOC 59 | #define PURE 60 | #define likely(x) (x) 61 | #define unlikely(x) (x) 62 | #define expected(x,y) (x) 63 | #endif 64 | 65 | #ifdef SHARED 66 | # if SHARED==1 && (__GNUC__ > 2 || __GNUC_MINOR__ >= 96) 67 | # define LABEL_OFFSET 68 | # endif 69 | #endif 70 | 71 | #define STRINGIFY_ARG(a) #a 72 | #define STRINGIFY(a) STRINGIFY_ARG(a) 73 | 74 | // marks old junk, to warn non-procps-ng library users 75 | #if ( __GNUC__ == 3 && __GNUC_MINOR__ > 0 ) || __GNUC__ > 3 76 | #define OBSOLETE __attribute__((deprecated)) 77 | #else 78 | #define OBSOLETE 79 | #endif 80 | 81 | // Like HIDDEN, but for an alias that gets created. 82 | // In gcc-3.2 there is an alias+hidden conflict. 83 | // Many will have patched this bug, but oh well. 84 | #if ( __GNUC__ == 3 && __GNUC_MINOR__ > 2 ) || __GNUC__ > 3 85 | #define HIDDEN_ALIAS(x) extern __typeof(x) x##_direct __attribute__((alias(#x),visibility("hidden"))) 86 | #else 87 | #define HIDDEN_ALIAS(x) extern __typeof(x) x##_direct __attribute__((alias(#x))) 88 | #endif 89 | 90 | 91 | typedef void (*message_fn)(const char *__restrict, ...) __attribute__((format(printf,1,2))); 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /src/modules/ps/inc/pwcache.h: -------------------------------------------------------------------------------- 1 | #ifndef PROCPS_PROC_PWCACHE_H 2 | #define PROCPS_PROC_PWCACHE_H 3 | 4 | #include 5 | #include "procps.h" 6 | 7 | EXTERN_C_BEGIN 8 | 9 | // used in pwcache and in readproc to set size of username or groupname 10 | #define P_G_SZ 33 11 | 12 | char *pwcache_get_user(uid_t uid); 13 | char *pwcache_get_group(gid_t gid); 14 | 15 | EXTERN_C_END 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/modules/ps/inc/sig.h: -------------------------------------------------------------------------------- 1 | #ifndef PROC_SIG_H 2 | #define PROC_SIG_H 3 | /* 4 | * Copyright 1998-2003 by Albert Cahalan; all rights resered. 5 | * This file may be used subject to the terms and conditions of the 6 | * GNU Library General Public License Version 2, or any later version 7 | * at your option, as published by the Free Software Foundation. 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU Library General Public License for more details. 12 | */ 13 | 14 | #include "procps.h" 15 | 16 | EXTERN_C_BEGIN 17 | 18 | /* return -1 on failure */ 19 | extern int signal_name_to_number(const char *__restrict name); 20 | 21 | extern const char *signal_number_to_name(int signo); 22 | 23 | extern int print_given_signals(int argc, const char *__restrict const *__restrict argv, int max_line); 24 | 25 | extern char *strtosig(const char *__restrict s); 26 | 27 | extern void pretty_print_signals(void); 28 | 29 | extern void unix_print_signals(void); 30 | 31 | EXTERN_C_END 32 | #endif 33 | -------------------------------------------------------------------------------- /src/modules/ps/inc/slab.h: -------------------------------------------------------------------------------- 1 | #ifndef _PROC_SLAB_H 2 | #define _PROC_SLAB_H 3 | 4 | #define SLAB_INFO_NAME_LEN 128 5 | 6 | struct slab_info { 7 | char name[SLAB_INFO_NAME_LEN]; /* name of this cache */ 8 | struct slab_info *next; 9 | unsigned long cache_size; /* size of entire cache */ 10 | unsigned nr_objs; /* number of objects in this cache */ 11 | unsigned nr_active_objs; /* number of active objects */ 12 | unsigned obj_size; /* size of each object */ 13 | unsigned objs_per_slab; /* number of objects per slab */ 14 | unsigned pages_per_slab; /* number of pages per slab */ 15 | unsigned nr_slabs; /* number of slabs in this cache */ 16 | unsigned nr_active_slabs; /* number of active slabs */ 17 | unsigned use; /* percent full: total / active */ 18 | }; 19 | 20 | struct slab_stat { 21 | unsigned long total_size; /* size of all objects */ 22 | unsigned long active_size; /* size of all active objects */ 23 | unsigned nr_objs; /* number of objects, among all caches */ 24 | unsigned nr_active_objs; /* number of active objects, among all caches */ 25 | unsigned nr_pages; /* number of pages consumed by all objects */ 26 | unsigned nr_slabs; /* number of slabs, among all caches */ 27 | unsigned nr_active_slabs; /* number of active slabs, among all caches */ 28 | unsigned nr_caches; /* number of caches */ 29 | unsigned nr_active_caches; /* number of active caches */ 30 | unsigned avg_obj_size; /* average object size */ 31 | unsigned min_obj_size; /* size of smallest object */ 32 | unsigned max_obj_size; /* size of largest object */ 33 | }; 34 | 35 | extern void put_slabinfo(struct slab_info *); 36 | extern void free_slabinfo(struct slab_info *); 37 | extern int get_slabinfo(struct slab_info **, struct slab_stat *); 38 | 39 | #endif /* _PROC_SLAB_H */ 40 | -------------------------------------------------------------------------------- /src/modules/ps/inc/sysinfo.h: -------------------------------------------------------------------------------- 1 | #ifndef PROC_SYSINFO_H 2 | #define PROC_SYSINFO_H 3 | #include 4 | #include 5 | #include "procps.h" 6 | 7 | EXTERN_C_BEGIN 8 | 9 | extern unsigned long long Hertz; /* clock tick frequency */ 10 | extern long smp_num_cpus; /* number of CPUs */ 11 | extern int have_privs; /* boolean, true if setuid or similar */ 12 | extern long page_bytes; /* this architecture's bytes per page */ 13 | 14 | #if 0 15 | #define JT double 16 | extern void eight_cpu_numbers(JT *uret, JT *nret, JT *sret, JT *iret, JT *wret, JT *xret, JT *yret, JT *zret); 17 | #undef JT 18 | #endif 19 | 20 | extern int uptime (double *uptime_secs, double *idle_secs); 21 | extern unsigned long getbtime(void); 22 | extern void loadavg(double *av1, double *av5, double *av15); 23 | 24 | /* Shmem in 2.6.32+ */ 25 | extern unsigned long kb_main_shared; 26 | /* old but still kicking -- the important stuff */ 27 | extern unsigned long kb_main_buffers; 28 | extern unsigned long kb_main_cached; 29 | extern unsigned long kb_main_free; 30 | extern unsigned long kb_main_total; 31 | extern unsigned long kb_swap_free; 32 | extern unsigned long kb_swap_total; 33 | /* recently introduced */ 34 | extern unsigned long kb_high_free; 35 | extern unsigned long kb_high_total; 36 | extern unsigned long kb_low_free; 37 | extern unsigned long kb_low_total; 38 | extern unsigned long kb_main_available; 39 | /* 2.4.xx era */ 40 | extern unsigned long kb_active; 41 | extern unsigned long kb_inact_laundry; // grrr... 42 | extern unsigned long kb_inact_dirty; 43 | extern unsigned long kb_inact_clean; 44 | extern unsigned long kb_inact_target; 45 | extern unsigned long kb_swap_cached; /* late 2.4+ */ 46 | /* derived values */ 47 | extern unsigned long kb_swap_used; 48 | extern unsigned long kb_main_used; 49 | /* 2.5.41+ */ 50 | extern unsigned long kb_writeback; 51 | extern unsigned long kb_slab; 52 | extern unsigned long nr_reversemaps; 53 | extern unsigned long kb_committed_as; 54 | extern unsigned long kb_dirty; 55 | extern unsigned long kb_inactive; 56 | extern unsigned long kb_mapped; 57 | extern unsigned long kb_pagetables; 58 | 59 | #define BUFFSIZE (64*1024) 60 | typedef unsigned long long jiff; 61 | extern void getstat(jiff *__restrict cuse, jiff *__restrict cice, jiff *__restrict csys, jiff *__restrict cide, jiff *__restrict ciow, jiff *__restrict cxxx, jiff *__restrict cyyy, jiff *__restrict czzz, 62 | unsigned long *__restrict pin, unsigned long *__restrict pout, unsigned long *__restrict s_in, unsigned long *__restrict sout, 63 | unsigned *__restrict intr, unsigned *__restrict ctxt, 64 | unsigned int *__restrict running, unsigned int *__restrict blocked, 65 | unsigned int *__restrict btime, unsigned int *__restrict processes); 66 | 67 | extern void meminfo(void); 68 | 69 | 70 | extern unsigned long vm_nr_dirty; 71 | extern unsigned long vm_nr_writeback; 72 | extern unsigned long vm_nr_pagecache; 73 | extern unsigned long vm_nr_page_table_pages; 74 | extern unsigned long vm_nr_reverse_maps; 75 | extern unsigned long vm_nr_mapped; 76 | extern unsigned long vm_nr_slab; 77 | extern unsigned long vm_nr_slab_reclaimable; 78 | extern unsigned long vm_nr_slab_unreclaimable; 79 | extern unsigned long vm_nr_active_file; 80 | extern unsigned long vm_nr_inactive_file; 81 | extern unsigned long vm_nr_free_pages; 82 | extern unsigned long vm_pgpgin; 83 | extern unsigned long vm_pgpgout; 84 | extern unsigned long vm_pswpin; 85 | extern unsigned long vm_pswpout; 86 | extern unsigned long vm_pgalloc; 87 | extern unsigned long vm_pgfree; 88 | extern unsigned long vm_pgactivate; 89 | extern unsigned long vm_pgdeactivate; 90 | extern unsigned long vm_pgfault; 91 | extern unsigned long vm_pgmajfault; 92 | extern unsigned long vm_pgscan; 93 | extern unsigned long vm_pgrefill; 94 | extern unsigned long vm_pgsteal; 95 | extern unsigned long vm_kswapd_steal; 96 | extern unsigned long vm_pageoutrun; 97 | extern unsigned long vm_allocstall; 98 | 99 | extern void vminfo(void); 100 | 101 | typedef struct disk_stat{ 102 | unsigned long long reads_sectors; 103 | unsigned long long written_sectors; 104 | char disk_name [32]; 105 | unsigned inprogress_IO; 106 | unsigned merged_reads; 107 | unsigned merged_writes; 108 | unsigned milli_reading; 109 | unsigned milli_spent_IO; 110 | unsigned milli_writing; 111 | unsigned partitions; 112 | unsigned reads; 113 | unsigned weighted_milli_spent_IO; 114 | unsigned writes; 115 | }disk_stat; 116 | 117 | typedef struct partition_stat{ 118 | char partition_name [35]; 119 | unsigned long long reads_sectors; 120 | unsigned parent_disk; // index into a struct disk_stat array 121 | unsigned reads; 122 | unsigned writes; 123 | unsigned long long requested_writes; 124 | }partition_stat; 125 | 126 | extern unsigned int getpartitions_num(struct disk_stat *disks, int ndisks); 127 | extern unsigned int getdiskstat (struct disk_stat**,struct partition_stat**); 128 | 129 | typedef struct slab_cache{ 130 | char name[48]; 131 | unsigned active_objs; 132 | unsigned num_objs; 133 | unsigned objsize; 134 | unsigned objperslab; 135 | }slab_cache; 136 | 137 | extern unsigned int getslabinfo (struct slab_cache**); 138 | 139 | extern unsigned get_pid_digits(void) FUNCTION; 140 | 141 | extern void cpuinfo (void); 142 | 143 | EXTERN_C_END 144 | #endif /* SYSINFO_H */ 145 | -------------------------------------------------------------------------------- /src/modules/ps/inc/version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libprocps - Library to read proc filesystem 3 | * 4 | * Copyright (C) 1995 Martin Schulze 5 | * Copyright (C) 1996 Charles Blake 6 | * Copyright (C) 2003 Albert Cahalan 7 | * Copyright (C) 2015 Craig Small 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2.1 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | #ifndef PROC_VERSION_H 24 | #define PROC_VERSION_H 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | int procps_linux_version(void); 31 | 32 | /* Convenience macros for composing/decomposing version codes */ 33 | #define LINUX_VERSION(x,y,z) (0x10000*(x) + 0x100*(y) + z) 34 | #define LINUX_VERSION_MAJOR(x) (((x)>>16) & 0xFF) 35 | #define LINUX_VERSION_MINOR(x) (((x)>> 8) & 0xFF) 36 | #define LINUX_VERSION_PATCH(x) ( (x) & 0xFF) 37 | 38 | #ifdef __cplusplus 39 | } /* extern "C" */ 40 | #endif 41 | 42 | #endif /* PROC_VERSION_H */ 43 | -------------------------------------------------------------------------------- /src/modules/ps/inc/wchan.h: -------------------------------------------------------------------------------- 1 | #ifndef PROCPS_PROC_WCHAN_H 2 | #define PROCPS_PROC_WCHAN_H 3 | 4 | #include "procps.h" 5 | 6 | EXTERN_C_BEGIN 7 | 8 | extern const char * lookup_wchan (int pid); 9 | 10 | EXTERN_C_END 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/modules/ps/inc/whattime.h: -------------------------------------------------------------------------------- 1 | #ifndef PROC_WHATTIME_H 2 | #define PROC_WHATTIME_H 3 | 4 | #include "procps.h" 5 | 6 | EXTERN_C_BEGIN 7 | 8 | extern void print_uptime(int human_readable); 9 | extern char *sprint_uptime(int human_readable); 10 | 11 | EXTERN_C_END 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /src/modules/ps/src/alloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * alloc.c - memory allocation functions 3 | * Copyright (C) 1992-1998 by Michael K. Johnson, johnsonm@redhat.com 4 | * Copyright 2002 Albert Cahalan 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "alloc.h" 27 | 28 | static void xdefault_error(const char *restrict fmts, ...) __attribute__((format(printf,1,2))); 29 | static void xdefault_error(const char *restrict fmts, ...) { 30 | va_list va; 31 | 32 | va_start(va, fmts); 33 | fprintf(stderr, fmts, va); 34 | va_end(va); 35 | } 36 | 37 | message_fn xalloc_err_handler = xdefault_error; 38 | 39 | 40 | void *xcalloc(unsigned int size) { 41 | void * p; 42 | 43 | if (size == 0) 44 | ++size; 45 | p = calloc(1, size); 46 | if (!p) { 47 | xalloc_err_handler("%s failed to allocate %u bytes of memory", __func__, size); 48 | exit(EXIT_FAILURE); 49 | } 50 | return p; 51 | } 52 | #if 0 53 | void *xmalloc(size_t size) { 54 | void *p; 55 | 56 | if (size == 0) 57 | ++size; 58 | p = malloc(size); 59 | if (!p) { 60 | xalloc_err_handler("%s failed to allocate %zu bytes of memory", __func__, size); 61 | exit(EXIT_FAILURE); 62 | } 63 | return(p); 64 | } 65 | 66 | void *xrealloc(void *oldp, unsigned int size) { 67 | void *p; 68 | 69 | if (size == 0) 70 | ++size; 71 | p = realloc(oldp, size); 72 | if (!p) { 73 | xalloc_err_handler("%s failed to allocate %u bytes of memory", __func__, size); 74 | exit(EXIT_FAILURE); 75 | } 76 | return(p); 77 | } 78 | char *xstrdup(const char *str) { 79 | char *p = NULL; 80 | 81 | if (str) { 82 | unsigned int size = strlen(str) + 1; 83 | p = malloc(size); 84 | if (!p) { 85 | xalloc_err_handler("%s failed to allocate %u bytes of memory", __func__, size); 86 | exit(EXIT_FAILURE); 87 | } 88 | strcpy(p, str); 89 | } 90 | return(p); 91 | } 92 | #endif 93 | -------------------------------------------------------------------------------- /src/modules/ps/src/pwcache.c: -------------------------------------------------------------------------------- 1 | /* 2 | * pwcache.c - memory cache passwd file handling 3 | * 4 | * Copyright (C) 1992-1998 by Michael K. Johnson, johnsonm@redhat.com 5 | * Note: most likely none of his code remains 6 | * 7 | * Copyright 2002, Albert Cahalan 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2.1 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include "alloc.h" 30 | #include "pwcache.h" 31 | #include 32 | 33 | // might as well fill cache lines... else we waste memory anyway 34 | 35 | #define HASHSIZE 64 /* power of 2 */ 36 | #define HASH(x) ((x) & (HASHSIZE - 1)) 37 | 38 | static struct pwbuf { 39 | struct pwbuf *next; 40 | uid_t uid; 41 | char name[P_G_SZ]; 42 | } *pwhash[HASHSIZE]; 43 | 44 | char *pwcache_get_user(uid_t uid) { 45 | struct pwbuf **p; 46 | struct passwd *pw; 47 | 48 | p = &pwhash[HASH(uid)]; 49 | while (*p) { 50 | if ((*p)->uid == uid) 51 | return((*p)->name); 52 | p = &(*p)->next; 53 | } 54 | *p = (struct pwbuf *) xmalloc(sizeof(struct pwbuf)); 55 | (*p)->uid = uid; 56 | pw = getpwuid(uid); 57 | if(!pw || strlen(pw->pw_name) >= P_G_SZ) 58 | sprintf((*p)->name, "%u", uid); 59 | else 60 | strcpy((*p)->name, pw->pw_name); 61 | 62 | (*p)->next = NULL; 63 | return((*p)->name); 64 | } 65 | 66 | static struct grpbuf { 67 | struct grpbuf *next; 68 | gid_t gid; 69 | char name[P_G_SZ]; 70 | } *grphash[HASHSIZE]; 71 | 72 | char *pwcache_get_group(gid_t gid) { 73 | struct grpbuf **g; 74 | struct group *gr; 75 | 76 | g = &grphash[HASH(gid)]; 77 | while (*g) { 78 | if ((*g)->gid == gid) 79 | return((*g)->name); 80 | g = &(*g)->next; 81 | } 82 | *g = (struct grpbuf *) xmalloc(sizeof(struct grpbuf)); 83 | (*g)->gid = gid; 84 | gr = getgrgid(gid); 85 | if (!gr || strlen(gr->gr_name) >= P_G_SZ) 86 | sprintf((*g)->name, "%u", gid); 87 | else 88 | strcpy((*g)->name, gr->gr_name); 89 | (*g)->next = NULL; 90 | return((*g)->name); 91 | } 92 | -------------------------------------------------------------------------------- /src/modules/ps/src/select.c: -------------------------------------------------------------------------------- 1 | /* 2 | * select.c - ps process selection 3 | * Copyright 1998-2002 by Albert Cahalan 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "procps.h" 25 | #include "readproc.h" 26 | 27 | #include "common.h" 28 | 29 | //#define process_group_leader(p) ((p)->pgid == (p)->tgid) 30 | //#define some_other_user(p) ((p)->euid != cached_euid) 31 | #define has_our_euid(p) ((unsigned)(p)->euid == (unsigned)cached_euid) 32 | #define on_our_tty(p) ((unsigned)(p)->tty == (unsigned)cached_tty) 33 | #define running(p) (((p)->state=='R')||((p)->state=='D')) 34 | #define session_leader(p) ((p)->session == (p)->tgid) 35 | #define without_a_tty(p) (!(p)->tty) 36 | 37 | static unsigned long select_bits = 0; 38 | 39 | /***** prepare select_bits for use */ 40 | const char *select_bits_setup(void){ 41 | int switch_val = 0; 42 | /* don't want a 'g' screwing up simple_select */ 43 | if(!simple_select && !prefer_bsd_defaults){ 44 | select_bits = 0xaa00; /* the STANDARD selection */ 45 | return NULL; 46 | } 47 | /* For every BSD but SunOS, the 'g' option is a NOP. (enabled by default) */ 48 | if( !(personality & PER_NO_DEFAULT_g) && !(simple_select&(SS_U_a|SS_U_d)) ) 49 | switch_val = simple_select|SS_B_g; 50 | else 51 | switch_val = simple_select; 52 | switch(switch_val){ 53 | /* UNIX options */ 54 | case SS_U_a | SS_U_d: select_bits = 0x3f3f; break; /* 3333 or 3f3f */ 55 | case SS_U_a: select_bits = 0x0303; break; /* 0303 or 0f0f */ 56 | case SS_U_d: select_bits = 0x3333; break; 57 | /* SunOS 4 only (others have 'g' enabled all the time) */ 58 | case 0: select_bits = 0x0202; break; 59 | case SS_B_a: select_bits = 0x0303; break; 60 | case SS_B_x : select_bits = 0x2222; break; 61 | case SS_B_x | SS_B_a: select_bits = 0x3333; break; 62 | /* General BSD options */ 63 | case SS_B_g : select_bits = 0x0a0a; break; 64 | case SS_B_g | SS_B_a: select_bits = 0x0f0f; break; 65 | case SS_B_g | SS_B_x : select_bits = 0xaaaa; break; 66 | case SS_B_g | SS_B_x | SS_B_a: /* convert to -e instead of using 0xffff */ 67 | all_processes = 1; 68 | simple_select = 0; 69 | break; 70 | default: 71 | return _("process selection options conflict"); 72 | break; 73 | } 74 | return NULL; 75 | } 76 | 77 | /***** selected by simple option? */ 78 | static int table_accept(proc_t *buf){ 79 | unsigned proc_index; 80 | proc_index = (has_our_euid(buf) <<0) 81 | | (session_leader(buf) <<1) 82 | | (without_a_tty(buf) <<2) 83 | | (on_our_tty(buf) <<3); 84 | return (select_bits & (1<typecode){ 94 | default: 95 | catastrophic_failure(__FILE__, __LINE__, _("please report this bug")); 96 | 97 | #define return_if_match(foo,bar) \ 98 | i=sn->n; while(i--) \ 99 | if((unsigned)(buf->foo) == (unsigned)(*(sn->u+i)).bar) \ 100 | return 1 101 | 102 | break; case SEL_RUID: return_if_match(ruid,uid); 103 | break; case SEL_EUID: return_if_match(euid,uid); 104 | break; case SEL_SUID: return_if_match(suid,uid); 105 | break; case SEL_FUID: return_if_match(fuid,uid); 106 | 107 | break; case SEL_RGID: return_if_match(rgid,gid); 108 | break; case SEL_EGID: return_if_match(egid,gid); 109 | break; case SEL_SGID: return_if_match(sgid,gid); 110 | break; case SEL_FGID: return_if_match(fgid,gid); 111 | 112 | break; case SEL_PGRP: return_if_match(pgrp,pid); 113 | break; case SEL_PID : return_if_match(tgid,pid); 114 | break; case SEL_PID_QUICK : return_if_match(tgid,pid); 115 | break; case SEL_PPID: return_if_match(ppid,ppid); 116 | break; case SEL_TTY : return_if_match(tty,tty); 117 | break; case SEL_SESS: return_if_match(session,pid); 118 | 119 | break; case SEL_COMM: i=sn->n; while(i--) 120 | if(!strncmp( buf->cmd, (*(sn->u+i)).cmd, 15 )) return 1; 121 | 122 | 123 | 124 | #undef return_if_match 125 | 126 | } 127 | sn = sn->next; 128 | } 129 | return 0; 130 | } 131 | 132 | 133 | /***** This must satisfy Unix98 and as much BSD as possible */ 134 | int want_this_proc(proc_t *buf){ 135 | int accepted_proc = 1; /* assume success */ 136 | /* elsewhere, convert T to list, U sets x implicitly */ 137 | 138 | /* handle -e -A */ 139 | if(all_processes) goto finish; 140 | 141 | /* use table for -a a d g x */ 142 | if((simple_select || !selection_list)) 143 | if(table_accept(buf)) goto finish; 144 | 145 | /* search lists */ 146 | if(proc_was_listed(buf)) goto finish; 147 | 148 | /* fail, fall through to loose ends */ 149 | accepted_proc = 0; 150 | 151 | /* do r N */ 152 | finish: 153 | if(running_only && !running(buf)) accepted_proc = 0; 154 | if(negate_selection) return !accepted_proc; 155 | return accepted_proc; 156 | } 157 | -------------------------------------------------------------------------------- /src/modules/ps/src/stacktrace.c: -------------------------------------------------------------------------------- 1 | /* 2 | * stacktrace.c - ps debugging additions 3 | * Gnu debugger stack trace code provided by Peter Mattis 4 | * on Thu, 2 Nov 1995 5 | * 6 | * Modified for easy use by Albert Cahalan. 7 | * 8 | * This library is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public 10 | * License as published by the Free Software Foundation; either 11 | * version 2.1 of the License, or (at your option) any later version. 12 | * 13 | * This library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with this library; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #include "common.h" 34 | 35 | #define INTERACTIVE 0 36 | #define STACK_TRACE 1 37 | 38 | char *stored_prog_name = "you forgot to set \"program\""; 39 | static int stack_trace_done; 40 | 41 | /***********/ 42 | static void debug_stop(char **args){ 43 | execvp (args[0], args); 44 | perror ("exec failed"); 45 | _exit (0); 46 | } 47 | 48 | /***********/ 49 | static void stack_trace_sigchld(int signum){ 50 | (void)signum; 51 | stack_trace_done = 1; 52 | } 53 | 54 | /************/ 55 | static void stack_trace(char **args){ 56 | pid_t pid; 57 | int in_fd[2]; 58 | int out_fd[2]; 59 | fd_set fdset; 60 | fd_set readset; 61 | struct timeval tv; 62 | int sel, index, state; 63 | char buffer[256]; 64 | char c; 65 | 66 | stack_trace_done = 0; 67 | 68 | if((pipe (in_fd) == -1) || (pipe (out_fd) == -1)){ 69 | perror ("could open pipe"); 70 | _exit (0); 71 | } 72 | 73 | pid = fork (); 74 | if (pid == 0){ 75 | close (0); dup (in_fd[0]); /* set the stdin to the in pipe */ 76 | close (1); dup (out_fd[1]); /* set the stdout to the out pipe */ 77 | close (2); dup (out_fd[1]); /* set the stderr to the out pipe */ 78 | execvp (args[0], args); /* exec gdb */ 79 | perror ("exec failed"); 80 | _exit (0); 81 | } else { 82 | if(pid == (pid_t) -1){ 83 | perror ("could not fork"); 84 | _exit (0); 85 | } 86 | } 87 | 88 | FD_ZERO (&fdset); 89 | FD_SET (out_fd[0], &fdset); 90 | 91 | write (in_fd[1], "backtrace\n", 10); 92 | write (in_fd[1], "p x = 0\n", 8); 93 | write (in_fd[1], "quit\n", 5); 94 | 95 | index = 0; 96 | state = 0; 97 | 98 | for(;;){ 99 | readset = fdset; 100 | tv.tv_sec = 1; 101 | tv.tv_usec = 0; 102 | 103 | sel = select (FD_SETSIZE, &readset, NULL, NULL, &tv); 104 | if (sel == -1) break; 105 | 106 | if((sel > 0) && (FD_ISSET (out_fd[0], &readset))){ 107 | if(read (out_fd[0], &c, 1)){ 108 | switch(state){ 109 | case 0: 110 | if(c == '#'){ 111 | state = 1; 112 | index = 0; 113 | buffer[index++] = c; 114 | } 115 | break; 116 | case 1: 117 | buffer[index++] = c; 118 | if((c == '\n') || (c == '\r')){ 119 | buffer[index] = 0; 120 | fprintf (stderr, "%s", buffer); 121 | state = 0; 122 | index = 0; 123 | } 124 | break; 125 | default: 126 | break; 127 | } 128 | } 129 | } 130 | else if(stack_trace_done) break; 131 | } 132 | 133 | close (in_fd[0]); 134 | close (in_fd[1]); 135 | close (out_fd[0]); 136 | close (out_fd[1]); 137 | _exit (0); 138 | } 139 | 140 | /************/ 141 | void debug(int method, char *prog_name){ 142 | pid_t pid; 143 | char buf[16]; 144 | char *args[4] = { "gdb", NULL, NULL, NULL }; 145 | int x; 146 | 147 | snprintf (buf, sizeof(buf), "%d", getpid ()); 148 | 149 | args[1] = prog_name; 150 | args[2] = buf; 151 | 152 | pid = fork (); 153 | if(pid == 0){ 154 | switch (method){ 155 | case INTERACTIVE: 156 | fprintf (stderr, "debug_stop\n"); 157 | debug_stop(args); 158 | break; 159 | case STACK_TRACE: 160 | fprintf (stderr, "stack_trace\n"); 161 | stack_trace(args); 162 | break; 163 | } 164 | _exit(0); 165 | } else if(pid == (pid_t) -1){ 166 | perror ("could not fork"); 167 | return; 168 | } 169 | 170 | x = 1; 171 | while(x); /* wait for debugger? */ 172 | } 173 | 174 | /************/ 175 | static void stack_trace_sigsegv(int signum){ 176 | (void)signum; 177 | debug(STACK_TRACE, stored_prog_name); 178 | } 179 | 180 | /************/ 181 | #ifdef DEBUG 182 | void init_stack_trace(char *prog_name){ 183 | stored_prog_name = prog_name; 184 | } 185 | #endif 186 | -------------------------------------------------------------------------------- /src/modules/ps/src/version.c: -------------------------------------------------------------------------------- 1 | /* 2 | * libprocps - Library to read proc filesystem 3 | * 4 | * Copyright (C) 1995 Martin Schulze 5 | * Copyright (C) 1996 Charles Blake 6 | * Copyright (C) 2003 Albert Cahalan 7 | * Copyright (C) 2015 Craig Small 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2.1 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | #include 24 | #include 25 | #include "procps-private.h" 26 | #include "version.h" 27 | 28 | #define PROCFS_OSRELEASE "/proc/sys/kernel/osrelease" 29 | 30 | /* 31 | * procps_linux_version 32 | * 33 | * Return the current running Linux version release as shown in 34 | * the procps filesystem. 35 | * 36 | * There are three ways you can get OS release: 37 | * 1) /proc/sys/kernel/osrelease - returns correct version of procfs 38 | * 2) /proc/version - returns version of kernel e.g. BSD this is wrong 39 | * 3) uname and uts.release - same as /proc/version field #3 40 | * 41 | * Returns: version as an integer 42 | * Negative value means an error 43 | */ 44 | PROCPS_EXPORT int procps_linux_version(void) 45 | { 46 | FILE *fp; 47 | char buf[256]; 48 | unsigned int x = 0, y = 0, z = 0; 49 | int version_string_depth; 50 | 51 | if ((fp = fopen(PROCFS_OSRELEASE, "r")) == NULL) 52 | return -errno; 53 | if (fgets(buf, 256, fp) == NULL) { 54 | fclose(fp); 55 | return -EIO; 56 | } 57 | fclose(fp); 58 | version_string_depth = sscanf(buf, "%u.%u.%u", &x, &y, &z); 59 | if ((version_string_depth < 2) || /* Non-standard for all known kernels */ 60 | ((version_string_depth < 3) && (x < 3))) /* Non-standard for 2.x.x kernels */ 61 | return -ERANGE; 62 | return LINUX_VERSION(x,y,z); 63 | } 64 | -------------------------------------------------------------------------------- /src/modules/ps/src/wchan.c: -------------------------------------------------------------------------------- 1 | /* 2 | * wchan.c - kernel symbol handling 3 | * Copyright 1998-2003 by Albert Cahalan 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "wchan.h" // to verify prototype 27 | 28 | 29 | const char * lookup_wchan (int pid) { 30 | static char buf[64]; 31 | const char *ret = buf; 32 | ssize_t num; 33 | int fd; 34 | 35 | snprintf(buf, sizeof buf, "/proc/%d/wchan", pid); 36 | fd = open(buf, O_RDONLY); 37 | if (fd==-1) return "?"; 38 | 39 | num = read(fd, buf, sizeof buf - 1); 40 | close(fd); 41 | 42 | if (num<1) return "?"; // allow for "0" 43 | buf[num] = '\0'; 44 | 45 | if (buf[0]=='0' && buf[1]=='\0') return "-"; 46 | 47 | // lame ppc64 has a '.' in front of every name 48 | if (*ret=='.') ret++; 49 | while(*ret=='_') ret++; 50 | 51 | return ret; 52 | } 53 | -------------------------------------------------------------------------------- /src/modules/ps/src/whattime.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a trivial uptime program. I hereby release this program 3 | * into the public domain. I disclaim any responsibility for this 4 | * program --- use it at your own risk. (as if there were any.. ;-) 5 | * -michaelkjohnson (johnsonm@sunsite.unc.edu) 6 | * 7 | * Modified by Larry Greenfield to give a more traditional output, 8 | * count users, etc. (greenfie@gauss.rutgers.edu) 9 | * 10 | * Modified by mkj again to fix a few tiny buglies. 11 | * 12 | * Modified by J. Cowley to add printing the uptime message to a 13 | * string (for top) and to optimize file handling. 19 Mar 1993. 14 | * 15 | * This library is free software; you can redistribute it and/or 16 | * modify it under the terms of the GNU Lesser General Public 17 | * License as published by the Free Software Foundation; either 18 | * version 2.1 of the License, or (at your option) any later version. 19 | * 20 | * This library is distributed in the hope that it will be useful, 21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23 | * Lesser General Public License for more details. 24 | * 25 | * You should have received a copy of the GNU Lesser General Public 26 | * License along with this library; if not, write to the Free Software 27 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 28 | */ 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include "whattime.h" 39 | #include "sysinfo.h" 40 | 41 | static char buf[128]; 42 | static double av[3]; 43 | 44 | char *sprint_uptime(int human_readable) { 45 | struct utmp *utmpstruct; 46 | int upminutes, uphours, updays, upweeks, upyears, updecades; 47 | int pos; 48 | int comma; 49 | struct tm *realtime; 50 | time_t realseconds; 51 | int numuser; 52 | double uptime_secs, idle_secs; 53 | 54 | /* first get the current time */ 55 | 56 | if (!human_readable) { 57 | time(&realseconds); 58 | realtime = localtime(&realseconds); 59 | pos = sprintf(buf, " %02d:%02d:%02d ", 60 | realtime->tm_hour, realtime->tm_min, realtime->tm_sec); 61 | } else { 62 | pos = 0; 63 | } 64 | 65 | /* read and calculate the amount of uptime */ 66 | 67 | uptime(&uptime_secs, &idle_secs); 68 | 69 | if (human_readable) { 70 | updecades = (int) uptime_secs / (60*60*24*365*10); 71 | upyears = ((int) uptime_secs / (60*60*24*365)) % 10; 72 | upweeks = ((int) uptime_secs / (60*60*24*7)) % 52; 73 | updays = ((int) uptime_secs / (60*60*24)) % 7; 74 | } 75 | else 76 | updays = (int) uptime_secs / (60*60*24); 77 | 78 | strcat (buf, "up "); 79 | pos += 3; 80 | 81 | if (!human_readable) { 82 | if (updays) 83 | pos += sprintf(buf + pos, "%d day%s, ", updays, (updays != 1) ? "s" : ""); 84 | } 85 | 86 | upminutes = (int) uptime_secs / 60; 87 | uphours = upminutes / 60; 88 | uphours = uphours % 24; 89 | upminutes = upminutes % 60; 90 | 91 | if (!human_readable) { 92 | if(uphours) 93 | pos += sprintf(buf + pos, "%2d:%02d, ", uphours, upminutes); 94 | else 95 | pos += sprintf(buf + pos, "%d min, ", upminutes); 96 | 97 | /* count the number of users */ 98 | 99 | numuser = 0; 100 | setutent(); 101 | while ((utmpstruct = getutent())) { 102 | if ((utmpstruct->ut_type == USER_PROCESS) && 103 | (utmpstruct->ut_name[0] != '\0')) 104 | numuser++; 105 | } 106 | endutent(); 107 | 108 | pos += sprintf(buf + pos, "%2d user%s, ", numuser, numuser == 1 ? "" : "s"); 109 | 110 | loadavg(&av[0], &av[1], &av[2]); 111 | 112 | pos += sprintf(buf + pos, " load average: %.2f, %.2f, %.2f", 113 | av[0], av[1], av[2]); 114 | } 115 | 116 | if (human_readable) { 117 | comma = 0; 118 | 119 | if (updecades) { 120 | pos += sprintf(buf + pos, "%d %s", updecades, 121 | updecades > 1 ? "decades" : "decade"); 122 | comma += 1; 123 | } 124 | 125 | if (upyears) { 126 | pos += sprintf(buf + pos, "%s%d %s", comma > 0 ? ", " : "", upyears, 127 | upyears > 1 ? "years" : "year"); 128 | comma += 1; 129 | } 130 | 131 | if (upweeks) { 132 | pos += sprintf(buf + pos, "%s%d %s", comma > 0 ? ", " : "", upweeks, 133 | upweeks > 1 ? "weeks" : "week"); 134 | comma += 1; 135 | } 136 | 137 | if (updays) { 138 | pos += sprintf(buf + pos, "%s%d %s", comma > 0 ? ", " : "", updays, 139 | updays > 1 ? "days" : "day"); 140 | comma += 1; 141 | } 142 | 143 | if (uphours) { 144 | pos += sprintf(buf + pos, "%s%d %s", comma > 0 ? ", " : "", uphours, 145 | uphours > 1 ? "hours" : "hour"); 146 | comma += 1; 147 | } 148 | 149 | if (upminutes) { 150 | pos += sprintf(buf + pos, "%s%d %s", comma > 0 ? ", " : "", upminutes, 151 | upminutes > 1 ? "minutes" : "minute"); 152 | comma += 1; 153 | } 154 | } 155 | 156 | return buf; 157 | } 158 | 159 | void print_uptime(int human_readable) { 160 | printf("%s\n", sprint_uptime(human_readable)); 161 | } 162 | -------------------------------------------------------------------------------- /src/modules/sysstat-lite/Makefile: -------------------------------------------------------------------------------- 1 | DIR_INC = ./inc 2 | DIR_SRC = ./src 3 | DIR_OBJ = ./obj 4 | 5 | 6 | SRC = $(wildcard ${DIR_SRC}/*.c) 7 | OBJ = $(patsubst %.c,${DIR_OBJ}/%.o,$(notdir ${SRC})) 8 | 9 | TARGET = libsysstat.a 10 | 11 | 12 | #CROSS_COMPILE=arm-linux-gnueabi- 13 | #CC=$(CROSS_COMPILE)gcc 14 | #AR=$(CROSS_COMPILE)ar 15 | #LD=$(CROSS_COMPILE)ld 16 | 17 | 18 | CFLAGS = -g -I$(DIR_INC) -Wall -static -g 19 | 20 | 21 | 22 | ${TARGET}:${OBJ} 23 | $(AR) rc $@ $^ 24 | @mv $(TARGET) ../../../libs/ 25 | ${DIR_OBJ}/%.o:${DIR_SRC}/%.c 26 | @mkdir -p $(DIR_OBJ) 27 | $(CC) $(CFLAGS) -c $< -o $@ 28 | 29 | .PHONY:clean 30 | clean: 31 | @rm -rf $(DIR_OBJ) 32 | -------------------------------------------------------------------------------- /src/modules/sysstat-lite/inc/count.h: -------------------------------------------------------------------------------- 1 | /* 2 | * count.h: Include file used to count items for which 3 | * statistics will be collected. 4 | * (C) 1999-2016 by Sebastien Godard (sysstat orange.fr) 5 | */ 6 | 7 | #ifndef _COUNT_H 8 | #define _COUNT_H 9 | 10 | #include "common.h" 11 | 12 | /* 13 | *************************************************************************** 14 | * Prototypes for functions used to count number of items. 15 | *************************************************************************** 16 | */ 17 | 18 | int get_cpu_nr 19 | (unsigned int, int); 20 | int get_irqcpu_nr 21 | (char *, int, int); 22 | int get_diskstats_dev_nr 23 | (int, int); 24 | int get_irq_nr 25 | (void); 26 | int get_serial_nr 27 | (void); 28 | int get_iface_nr 29 | (void); 30 | int get_disk_nr 31 | (unsigned int); 32 | int get_freq_nr 33 | (void); 34 | int get_usb_nr 35 | (void); 36 | int get_filesystem_nr 37 | (void); 38 | int get_fchost_nr 39 | (void); 40 | 41 | #endif /* _COUNT_H */ 42 | -------------------------------------------------------------------------------- /src/modules/sysstat-lite/inc/ioconf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ioconf: ioconf configuration file handling code 3 | * Original code (C) 2004 by Red Hat (Charlie Bennett ) 4 | * 5 | * Modified and maintained by Sebastien GODARD (sysstat orange.fr) 6 | */ 7 | 8 | #ifndef _IOCONF_H 9 | #define _IOCONF_H 10 | 11 | #include "sysconfig.h" 12 | 13 | #define IOC_NAMELEN 31 14 | #define IOC_DESCLEN 63 15 | #define IOC_DEVLEN 47 16 | #define IOC_MAXMINOR 2047 17 | #define IOC_LINESIZ 255 18 | #define IOC_FMTLEN 15 19 | 20 | #ifndef MAX_BLKDEV 21 | #define MAX_BLKDEV 255 22 | #endif 23 | 24 | #define K_NODEV "nodev" 25 | 26 | #define IS_WHOLE(maj,min) ((min % ioconf[maj]->blkp->pcount) == 0) 27 | 28 | /* 29 | * When is C going to get templates? 30 | */ 31 | #define IOC_ALLOC(P,TYPE,SIZE) \ 32 | do { \ 33 | if (P == NULL) { \ 34 | P = (TYPE *) malloc(SIZE); \ 35 | if (P == NULL) { \ 36 | perror("malloc"); \ 37 | ioc_free(); \ 38 | goto free_and_return; \ 39 | } \ 40 | } \ 41 | } \ 42 | while (0) 43 | /* That dummy while allows ';' on the line that invokes the macro... */ 44 | 45 | 46 | struct blk_config { 47 | char name[IOC_NAMELEN + 1]; /* device basename */ 48 | char cfmt[IOC_FMTLEN + 1]; /* controller format string */ 49 | char dfmt[IOC_FMTLEN + 1]; /* disk format string */ 50 | char pfmt[IOC_FMTLEN + 1]; /* partition format string */ 51 | /* ctrlno is in the ioc_entry */ 52 | unsigned int ctrl_explicit; /* use "cN" in name */ 53 | unsigned int dcount; /* number of devices handled by this major */ 54 | unsigned int pcount; /* partitions per device */ 55 | char desc[IOC_DESCLEN + 1]; 56 | /* disk info unit # conversion function */ 57 | char *(*cconv)(unsigned int); 58 | 59 | /* extension properties (all this for initrd?) */ 60 | char ext_name[IOC_NAMELEN + 1]; 61 | unsigned int ext; /* flag - this is an extension record */ 62 | unsigned int ext_minor; /* which minor does this apply to */ 63 | }; 64 | 65 | #define BLK_CONFIG_SIZE (sizeof(struct blk_config)) 66 | 67 | 68 | struct ioc_entry { 69 | int live; /* is this a Direct entry? */ 70 | unsigned int ctrlno; /* controller number */ 71 | unsigned int basemajor; /* Major number of the template */ 72 | char *desc; /* (dynamic) per-controller description */ 73 | struct blk_config *blkp; /* the real info, may be a shared ref */ 74 | }; 75 | 76 | #define IOC_ENTRY_SIZE (sizeof(struct ioc_entry)) 77 | 78 | 79 | int ioc_iswhole 80 | (unsigned int, unsigned int); 81 | char *ioc_name 82 | (unsigned int, unsigned int); 83 | char *transform_devmapname 84 | (unsigned int, unsigned int); 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /src/modules/sysstat-lite/inc/iostat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * iostat: report CPU and I/O statistics 3 | * (C) 1999-2016 by Sebastien Godard (sysstat orange.fr) 4 | */ 5 | 6 | #ifndef _IOSTAT_H 7 | #define _IOSTAT_H 8 | 9 | #include "common.h" 10 | 11 | /* I_: iostat - D_: Display - F_: Flag */ 12 | #define I_D_CPU 0x00001 13 | #define I_D_DISK 0x00002 14 | #define I_D_TIMESTAMP 0x00004 15 | #define I_D_EXTENDED 0x00008 16 | #define I_D_PART_ALL 0x00010 17 | #define I_D_KILOBYTES 0x00020 18 | #define I_F_HAS_SYSFS 0x00040 19 | #define I_D_DEBUG 0x00080 20 | #define I_D_UNFILTERED 0x00100 21 | #define I_D_MEGABYTES 0x00200 22 | #define I_D_PARTITIONS 0x00400 23 | #define I_F_HAS_DISKSTATS 0x00800 24 | #define I_D_HUMAN_READ 0x01000 25 | #define I_D_PERSIST_NAME 0x02000 26 | #define I_D_OMIT_SINCE_BOOT 0x04000 27 | #define I_D_JSON_OUTPUT 0x08000 28 | #define I_D_DEVMAP_NAME 0x10000 29 | #define I_D_ISO 0x20000 30 | #define I_D_GROUP_TOTAL_ONLY 0x40000 31 | #define I_D_ZERO_OMIT 0x80000 32 | 33 | #define DISPLAY_CPU(m) (((m) & I_D_CPU) == I_D_CPU) 34 | #define DISPLAY_DISK(m) (((m) & I_D_DISK) == I_D_DISK) 35 | #define DISPLAY_TIMESTAMP(m) (((m) & I_D_TIMESTAMP) == I_D_TIMESTAMP) 36 | #define DISPLAY_EXTENDED(m) (((m) & I_D_EXTENDED) == I_D_EXTENDED) 37 | #define DISPLAY_PART_ALL(m) (((m) & I_D_PART_ALL) == I_D_PART_ALL) 38 | #define DISPLAY_KILOBYTES(m) (((m) & I_D_KILOBYTES) == I_D_KILOBYTES) 39 | #define DISPLAY_MEGABYTES(m) (((m) & I_D_MEGABYTES) == I_D_MEGABYTES) 40 | #define HAS_SYSFS(m) (((m) & I_F_HAS_SYSFS) == I_F_HAS_SYSFS) 41 | #define DISPLAY_DEBUG(m) (((m) & I_D_DEBUG) == I_D_DEBUG) 42 | #define DISPLAY_UNFILTERED(m) (((m) & I_D_UNFILTERED) == I_D_UNFILTERED) 43 | #define DISPLAY_PARTITIONS(m) (((m) & I_D_PARTITIONS) == I_D_PARTITIONS) 44 | #define HAS_DISKSTATS(m) (((m) & I_F_HAS_DISKSTATS) == I_F_HAS_DISKSTATS) 45 | #define DISPLAY_HUMAN_READ(m) (((m) & I_D_HUMAN_READ) == I_D_HUMAN_READ) 46 | #define DISPLAY_PERSIST_NAME_I(m) (((m) & I_D_PERSIST_NAME) == I_D_PERSIST_NAME) 47 | #define DISPLAY_OMIT_SINCE_BOOT(m) (((m) & I_D_OMIT_SINCE_BOOT) == I_D_OMIT_SINCE_BOOT) 48 | #define DISPLAY_DEVMAP_NAME(m) (((m) & I_D_DEVMAP_NAME) == I_D_DEVMAP_NAME) 49 | #define DISPLAY_ISO(m) (((m) & I_D_ISO) == I_D_ISO) 50 | #define DISPLAY_GROUP_TOTAL_ONLY(m) (((m) & I_D_GROUP_TOTAL_ONLY) == I_D_GROUP_TOTAL_ONLY) 51 | #define DISPLAY_ZERO_OMIT(m) (((m) & I_D_ZERO_OMIT) == I_D_ZERO_OMIT) 52 | #define DISPLAY_JSON_OUTPUT(m) (((m) & I_D_JSON_OUTPUT) == I_D_JSON_OUTPUT) 53 | 54 | /* Preallocation constants */ 55 | #define NR_DEV_PREALLOC 4 56 | 57 | /* Environment variable */ 58 | #define ENV_POSIXLY_CORRECT "POSIXLY_CORRECT" 59 | 60 | /* 61 | * Structures for I/O stats. 62 | * The number of structures allocated corresponds to the number of devices 63 | * present in the system, plus a preallocation number to handle those 64 | * that can be registered dynamically. 65 | * The number of devices is found by using /sys filesystem (if mounted). 66 | * For each io_stats structure allocated corresponds a io_hdr_stats structure. 67 | * A io_stats structure is considered as unused or "free" (containing no stats 68 | * for a particular device) if the 'major' field of the io_hdr_stats 69 | * structure is set to 0. 70 | */ 71 | struct io_stats { 72 | /* # of sectors read */ 73 | unsigned long rd_sectors __attribute__ ((aligned (8))); 74 | /* # of sectors written */ 75 | unsigned long wr_sectors __attribute__ ((packed)); 76 | /* # of read operations issued to the device */ 77 | unsigned long rd_ios __attribute__ ((packed)); 78 | /* # of read requests merged */ 79 | unsigned long rd_merges __attribute__ ((packed)); 80 | /* # of write operations issued to the device */ 81 | unsigned long wr_ios __attribute__ ((packed)); 82 | /* # of write requests merged */ 83 | unsigned long wr_merges __attribute__ ((packed)); 84 | /* Time of read requests in queue */ 85 | unsigned int rd_ticks __attribute__ ((packed)); 86 | /* Time of write requests in queue */ 87 | unsigned int wr_ticks __attribute__ ((packed)); 88 | /* # of I/Os in progress */ 89 | unsigned int ios_pgr __attribute__ ((packed)); 90 | /* # of ticks total (for this device) for I/O */ 91 | unsigned int tot_ticks __attribute__ ((packed)); 92 | /* # of ticks requests spent in queue */ 93 | unsigned int rq_ticks __attribute__ ((packed)); 94 | }; 95 | 96 | #define IO_STATS_SIZE (sizeof(struct io_stats)) 97 | 98 | /* Possible values for field "status" in io_hdr_stats structure */ 99 | #define DISK_UNREGISTERED 0 100 | #define DISK_REGISTERED 1 101 | #define DISK_GROUP 2 102 | 103 | /* 104 | * Each io_stats structure has an associated io_hdr_stats structure. 105 | * An io_hdr_stats structure tells if the corresponding device has been 106 | * unregistered or not (status field) and also indicates the device name. 107 | */ 108 | struct io_hdr_stats { 109 | unsigned int status __attribute__ ((aligned (4))); 110 | unsigned int used __attribute__ ((packed)); 111 | char name[MAX_NAME_LEN]; 112 | }; 113 | 114 | #define IO_HDR_STATS_SIZE (sizeof(struct io_hdr_stats)) 115 | 116 | /* List of devices entered on the command line */ 117 | struct io_dlist { 118 | /* Indicate whether its partitions are to be displayed or not */ 119 | int disp_part __attribute__ ((aligned (4))); 120 | /* Device name */ 121 | char dev_name[MAX_NAME_LEN]; 122 | }; 123 | 124 | #define IO_DLIST_SIZE (sizeof(struct io_dlist)) 125 | 126 | #endif /* _IOSTAT_H */ 127 | -------------------------------------------------------------------------------- /src/modules/sysstat-lite/inc/mpstat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * mpstat: per-processor statistics 3 | * (C) 2000-2016 by Sebastien Godard (sysstat orange.fr) 4 | */ 5 | 6 | #ifndef _MPSTAT_H 7 | #define _MPSTAT_H 8 | 9 | /* 10 | *************************************************************************** 11 | * mpstat's specific system files. 12 | *************************************************************************** 13 | */ 14 | 15 | #define SOFTIRQS "/proc/softirqs" 16 | 17 | /* 18 | *************************************************************************** 19 | * Activities definitions. 20 | *************************************************************************** 21 | */ 22 | 23 | #define M_D_CPU 0x0001 24 | #define M_D_IRQ_SUM 0x0002 25 | #define M_D_IRQ_CPU 0x0004 26 | #define M_D_SOFTIRQS 0x0008 27 | 28 | #define DISPLAY_CPU(m) (((m) & M_D_CPU) == M_D_CPU) 29 | #define DISPLAY_IRQ_SUM(m) (((m) & M_D_IRQ_SUM) == M_D_IRQ_SUM) 30 | #define DISPLAY_IRQ_CPU(m) (((m) & M_D_IRQ_CPU) == M_D_IRQ_CPU) 31 | #define DISPLAY_SOFTIRQS(m) (((m) & M_D_SOFTIRQS) == M_D_SOFTIRQS) 32 | 33 | /* 34 | *************************************************************************** 35 | * Keywords and constants. 36 | *************************************************************************** 37 | */ 38 | 39 | /* Indicate that option -P has been used */ 40 | #define F_P_OPTION 0x01 41 | /* Indicate that stats should be displayed on for online CPU ("-P ON") */ 42 | #define F_P_ON 0x02 43 | /* JSON output */ 44 | #define F_JSON_OUTPUT 0x04 45 | 46 | #define USE_P_OPTION(m) (((m) & F_P_OPTION) == F_P_OPTION) 47 | #define DISPLAY_ONLINE_CPU(m) (((m) & F_P_ON) == F_P_ON) 48 | #define DISPLAY_JSON_OUTPUT(m) (((m) & F_JSON_OUTPUT) == F_JSON_OUTPUT) 49 | 50 | #define K_SUM "SUM" 51 | #define K_CPU "CPU" 52 | #define K_SCPU "SCPU" 53 | #define K_ON "ON" 54 | 55 | #define NR_IRQCPU_PREALLOC 3 56 | 57 | #define MAX_IRQ_LEN 16 58 | 59 | /* 60 | *************************************************************************** 61 | * Structures used to store statistics. 62 | *************************************************************************** 63 | */ 64 | 65 | /* 66 | * stats_irqcpu->irq_name: IRQ#-A 67 | * stats_irqcpu->interrupt: number of IRQ#-A for proc 0 68 | * stats_irqcpu->irq_name: IRQ#-B 69 | * stats_irqcpu->interrupt: number of IRQ#-B for proc 0 70 | * ... 71 | * stats_irqcpu->irq_name: (undef'd) 72 | * stats_irqcpu->interrupt: number of IRQ#-A for proc 1 73 | * stats_irqcpu->irq_name: (undef'd) 74 | * stats_irqcpu->interrupt: number of IRQ#-B for proc 1 75 | * ... 76 | */ 77 | struct stats_irqcpu { 78 | unsigned int interrupt __attribute__ ((aligned (4))); 79 | char irq_name[MAX_IRQ_LEN]; 80 | }; 81 | 82 | #define STATS_IRQCPU_SIZE (sizeof(struct stats_irqcpu)) 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /src/modules/sysstat-lite/inc/sysconfig.h: -------------------------------------------------------------------------------- 1 | /* 2 | * sysstat: System performance tools for Linux 3 | * (C) 1999-2016 by Sebastien Godard (sysstat orange.fr) 4 | */ 5 | 6 | #ifndef _SYSCONFIG_H 7 | #define _SYSCONFIG_H 8 | 9 | /* sysstat configuration directory */ 10 | #define IOCONF "/home/chensong/work/linuxep/code/tools/sysstat-11.5.1/output/etc/kksysconfig/sysstat.ioconf" 11 | #define LOCAL_IOCONF "./sysstat.ioconf" 12 | 13 | #endif /* _SYSCONFIG_H */ 14 | -------------------------------------------------------------------------------- /src/modules/sysstat-lite/inc/version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * sysstat: System performance tools for Linux 3 | * (C) 1999-2016 by Sebastien Godard (sysstat orange.fr) 4 | */ 5 | 6 | #ifndef _VERSION_H 7 | #define _VERSION_H 8 | 9 | /* sysstat version number */ 10 | #define VERSION "11.5.1" 11 | 12 | #endif /* _VERSION_H */ 13 | -------------------------------------------------------------------------------- /src/modules/sysstat-lite/src/cpuinfo.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cpuinfo: get cpu information 3 | * (C) 2016-2017 by Barry Song 4 | * 5 | *************************************************************************** 6 | * This program is free software; you can redistribute it and/or modify it * 7 | * under the terms of the GNU General Public License as published by the * 8 | * Free Software Foundation; either version 2 of the License, or (at your * 9 | * option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, but * 12 | * WITHOUT ANY WARRANTY; without the implied warranty of MERCHANTABILITY * 13 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * 14 | * for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License along * 17 | * with this program; if not, write to the Free Software Foundation, Inc., * 18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA * 19 | *************************************************************************** 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include "common.h" 26 | #include "rd_stats.h" 27 | 28 | static void figureout_cpu(FILE *out_fp) 29 | { 30 | FILE *fp; 31 | char line[8192]; 32 | char *cpu_name = NULL; 33 | 34 | if ((fp = fopen(CPUINFO, "r")) == NULL) 35 | return; 36 | 37 | while (fgets(line, sizeof(line), fp) != NULL) { 38 | char *s, *n; 39 | s = strstr(line, ":"); 40 | n = strstr(s, "ARM"); 41 | if(!n) 42 | n = strstr(s, "AArch64"); 43 | if(!n) 44 | n = strstr(s, "Intel"); 45 | if(!n) 46 | n = strstr(s, "AMD"); 47 | if(n) { 48 | /* +2 to skip ": " */ 49 | cpu_name = s + 2; 50 | break; 51 | } 52 | } 53 | 54 | if(!cpu_name) 55 | cpu_name = "unknown"; 56 | 57 | fprintf(out_fp,"cpu_name: %s", cpu_name); 58 | 59 | fclose(fp); 60 | 61 | } 62 | 63 | int cpuinfo_main(int argc, char **argv, int out_fd) 64 | { 65 | int cpu_nr = 0; 66 | 67 | FILE *out_fp = fdopen(out_fd, "w"); 68 | if(out_fp == NULL) return EXIT_SUCCESS; 69 | 70 | /* What is the highest processor number on this machine? */ 71 | cpu_nr = get_cpu_nr(~0, TRUE); 72 | fprintf(out_fp,"cpunr: %d\n", cpu_nr); 73 | //printf("cpunr: %d\n", cpu_nr); 74 | figureout_cpu(out_fp); 75 | fclose(out_fp); 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /test-workloads/load-sim.c: -------------------------------------------------------------------------------- 1 | /* 2 | * running on server to emulate cpu load 3 | * 4 | * Copyright (c) 2016, Barry Song <21cnbao@gmail.com> 5 | * 6 | * Licensed under GPLv2 or later. 7 | */ 8 | 9 | 10 | #include 11 | void main(void) 12 | { 13 | fork(); 14 | while(1){ 15 | volatile int i; 16 | usleep(50 * (random()%10)); 17 | for(i=0;i<100000;i++); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test-workloads/malloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * running on server to emulate malloc/free load 3 | * 4 | * Copyright (c) 2016, Barry Song <21cnbao@gmail.com> 5 | * 6 | * Licensed under GPLv2 or later. 7 | */ 8 | 9 | void main(void) 10 | { 11 | while(1){ 12 | int *p=malloc(200*1024*1024); 13 | int i; 14 | for (i=0;i<50*1024*1024;i++) { 15 | p[i]=0; 16 | if (i%(1024*1024) == 0) 17 | sleep(0.1); 18 | } 19 | free(p); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /test-workloads/random.sh: -------------------------------------------------------------------------------- 1 | while true 2 | do 3 | COUNTER=1 4 | while [ "$COUNTER" -lt 6 ]; do 5 | echo "COUNTER is $COUNTER" 6 | COUNTER=$(($COUNTER+1)) 7 | stress -c 1 -i $COUNTER --verbose --timeout $COUNTER 8 | stress -c 2 -i $COUNTER --verbose --timeout $COUNTER 9 | sleep 1 10 | done 11 | done 12 | 13 | --------------------------------------------------------------------------------