/**************************************************************************** * apps/system/resmonitor/fillcpu.c * * SPDX-License-Identifier: Apache-2.0 * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. The * ASF licenses this file to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the * License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. * ****************************************************************************/ /**************************************************************************** * Included Files ****************************************************************************/ #include #include #include #include #include #include #include #include #include #include /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ #define PATH "/proc" #define CPULOAD "cpuload" #define LOADAVG "loadavg" /**************************************************************************** * Private Data ****************************************************************************/ static int go = 1; /**************************************************************************** * Private Functions ****************************************************************************/ static void handler(int sig) { go = 0; } static void show_usages(void) { syslog(LOG_WARNING, "Usage: CMD [-c ] [-f ] [-a]\n" "\t\t-c: set cpu occupation that you except, default 80\n" "\t\t-f: set write payload path, eg. /tmp/payload, program will " "write to memory if -f not set\n" "\t\t-a: the cpu (set by -c) is the cpu occupied by this program\n"); exit(1); } static float get_cpu(int pid) { float cpu = 0; char filepath[20]; int ret; if (pid <= 0) { ret = snprintf(filepath, 20, "%s/%s", PATH, CPULOAD); } else { ret = snprintf(filepath, 20, "%s/%d/%s", PATH, pid, LOADAVG); } if (ret < 0) { /* syslog(LOG_ERR, "snprintf error\n"); */ return cpu; } FILE *fp = fopen(filepath, "r"); if (!fp) { return cpu; } char buf[8]; fgets(buf, 8, fp); sscanf(buf, "%f", &cpu); fclose(fp); return cpu; } static int writefile(char *filepath, char *buffer1, char *buffer2) { if (strlen(filepath) == 0) { memset(buffer2, '*', 1024); memcpy(buffer1, buffer2, 1024); return 0; } else { int fd; memset(buffer1, '*', 1024); if ((fd = open(filepath, O_WRONLY | O_CREAT, 0700)) <= 0) { syslog(LOG_ERR, "open file error\n"); return -1; } if (write(fd, buffer1, 1024) <= 0) { syslog(LOG_ERR, "write file error\n"); close(fd); return -1; } return close(fd); } } int main(int argc, char *argv[]) { char buf1[1024]; char buf2[1024]; char filepath[40]; struct timeval sleeptime; int n = 0; int lowcount = 0; int cpu = 80; bool ispid = false; int time = 10000; float fcpu; int o; memset(filepath, 0, 40); go = 1; if (argc == 1) { show_usages(); } while ((o = getopt(argc, argv, "c:f:a")) != EOF) { switch (o) { case 'c': cpu = atoi(optarg); break; case 'f': snprintf(filepath, 40, "%s", optarg); break; case 'a': ispid = true; break; default: show_usages(); break; } } signal(SIGINT, handler); signal(SIGKILL, handler); while (go) { if (time < 1000) { time = 1000; lowcount++; if (lowcount > 4) { lowcount = 0; n += 2; } } else if (time > 10000) { time = 10000; n -= 1; n = (n < 0 ? 0 : n); } else { lowcount = 0; } sleeptime.tv_sec = 0; sleeptime.tv_usec = time; select(0, NULL, NULL, NULL, &sleeptime); if (ispid) { fcpu = get_cpu(getpid()); } else { fcpu = get_cpu(0); } if (fcpu > cpu) { time += 1000; } else { time -= 1000; } for (int i = 0; i < n; i++) { if (writefile(filepath, buf1, buf2) != 0) { break; } } } syslog(LOG_INFO, "program complete!\n"); return 0; }