linux命令之ps源码,支持linux和android
16lz
2021-01-23
#include #include #include #include #include #include #include #include #include #include "sched_policy.h"//#include static char *nexttoksep(char **strp, char *sep){ char *p = strsep(strp,sep); return (p == 0) ? "" : p;}static char *nexttok(char **strp){ return nexttoksep(strp, " ");}#define SHOW_PRIO 1#define SHOW_TIME 2#define SHOW_POLICY 4static int display_flags = 0;static int ps_line(int pid, int tid, char *namefilter){ char statline[1024]; char cmdline[1024]; char user[32]; struct stat stats; int fd, r; char *ptr, *name, *state; int ppid, tty; unsigned wchan, rss, vss, eip; unsigned utime, stime; int prio, nice, rtprio, sched; struct passwd *pw; sprintf(statline, "/proc/%d", pid); stat(statline, &stats); if(tid) { sprintf(statline, "/proc/%d/task/%d/stat", pid, tid); cmdline[0] = 0; } else { sprintf(statline, "/proc/%d/stat", pid); sprintf(cmdline, "/proc/%d/cmdline", pid); fd = open(cmdline, O_RDONLY); if(fd == 0) { r = 0; } else { r = read(fd, cmdline, 1023); close(fd); if(r < 0) r = 0; } cmdline[r] = 0; } fd = open(statline, O_RDONLY); if(fd == 0) return -1; r = read(fd, statline, 1023); close(fd); if(r < 0) return -1; statline[r] = 0; ptr = statline; nexttok(&ptr); // skip pid ptr++; // skip "(" name = ptr; ptr = strrchr(ptr, ')'); // Skip to *last* occurence of ')', *ptr++ = '\0'; // and null-terminate name. ptr++; // skip " " state = nexttok(&ptr); ppid = atoi(nexttok(&ptr)); nexttok(&ptr); // pgrp nexttok(&ptr); // sid tty = atoi(nexttok(&ptr)); nexttok(&ptr); // tpgid nexttok(&ptr); // flags nexttok(&ptr); // minflt nexttok(&ptr); // cminflt nexttok(&ptr); // majflt nexttok(&ptr); // cmajflt#if 1 utime = atoi(nexttok(&ptr)); stime = atoi(nexttok(&ptr));#else nexttok(&ptr); // utime nexttok(&ptr); // stime#endif nexttok(&ptr); // cutime nexttok(&ptr); // cstime prio = atoi(nexttok(&ptr)); nice = atoi(nexttok(&ptr)); nexttok(&ptr); // threads nexttok(&ptr); // itrealvalue nexttok(&ptr); // starttime vss = strtoul(nexttok(&ptr), 0, 10); // vsize rss = strtoul(nexttok(&ptr), 0, 10); // rss nexttok(&ptr); // rlim nexttok(&ptr); // startcode nexttok(&ptr); // endcode nexttok(&ptr); // startstack nexttok(&ptr); // kstkesp eip = strtoul(nexttok(&ptr), 0, 10); // kstkeip nexttok(&ptr); // signal nexttok(&ptr); // blocked nexttok(&ptr); // sigignore nexttok(&ptr); // sigcatch wchan = strtoul(nexttok(&ptr), 0, 10); // wchan nexttok(&ptr); // nswap nexttok(&ptr); // cnswap nexttok(&ptr); // exit signal nexttok(&ptr); // processor rtprio = atoi(nexttok(&ptr)); // rt_priority sched = atoi(nexttok(&ptr)); // scheduling policy tty = atoi(nexttok(&ptr)); if(tid != 0) { ppid = pid; pid = tid; } pw = getpwuid(stats.st_uid); if(pw == 0) { sprintf(user,"%d",(int)stats.st_uid); } else { strcpy(user,pw->pw_name); } if(!namefilter || !strncmp(name, namefilter, strlen(namefilter))) { printf("%-9s %-5d %-5d %-6d %-5d", user, pid, ppid, vss / 1024, rss * 4); if(display_flags&SHOW_PRIO) printf(" %-5d %-5d %-5d %-5d", prio, nice, rtprio, sched); if (display_flags & SHOW_POLICY) { SchedPolicy p; if (get_sched_policy(pid, &p) < 0) printf(" un "); else { if (p == SP_BACKGROUND) printf(" bg "); else if (p == SP_FOREGROUND) printf(" fg "); else printf(" er "); } } printf(" %08x %08x %s %s", wchan, eip, state, cmdline[0] ? cmdline : name); if(display_flags&SHOW_TIME) printf(" (u:%d, s:%d)", utime, stime); printf("\n"); } return 0;}void ps_threads(int pid, char *namefilter){ char tmp[128]; DIR *d; struct dirent *de; sprintf(tmp,"/proc/%d/task",pid); d = opendir(tmp); if(d == 0) return; while((de = readdir(d)) != 0){ if(isdigit(de->d_name[0])){ int tid = atoi(de->d_name); if(tid == pid) continue; ps_line(pid, tid, namefilter); } } closedir(d); }//gcc -o test ps.c sched_policy.h sched_policy.c -lpthreadint main(int argc, char *argv[]){ DIR *d; struct dirent *de; char *namefilter = 0; int pidfilter = 0; int threads = 0; d = opendir("/proc"); if(d == 0) return -1; while(argc > 1){ if(!strcmp(argv[1],"-t")) { threads = 1; } else if(!strcmp(argv[1],"-x")) { display_flags |= SHOW_TIME; } else if(!strcmp(argv[1],"-P")) { display_flags |= SHOW_POLICY; } else if(!strcmp(argv[1],"-p")) { display_flags |= SHOW_PRIO; } else if(isdigit(argv[1][0])){ pidfilter = atoi(argv[1]); } else { namefilter = argv[1]; } argc--; argv++; } printf("USER PID PPID VSIZE RSS %s %s WCHAN PC NAME\n", (display_flags&SHOW_PRIO)?"PRIO NICE RTPRI SCHED ":"", (display_flags&SHOW_POLICY)?"PCY " : ""); while((de = readdir(d)) != 0){ if(isdigit(de->d_name[0])){ int pid = atoi(de->d_name); if(!pidfilter || (pidfilter == pid)) { ps_line(pid, 0, namefilter); if(threads) ps_threads(pid, namefilter); } } } closedir(d); return 0;}
/* libs/cutils/sched_policy.c**** Copyright 2007, The Android Open Source Project**** Licensed 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.*/#include #include #include #include #include #include #define LOG_TAG "SchedPolicy"#define SLOGE(...) printf( __VA_ARGS__)#define SLOGW(...) printf( __VA_ARGS__)#include #include #include "sched_policy.h"#ifndef SCHED_NORMAL #define SCHED_NORMAL 0#endif#ifndef SCHED_BATCH #define SCHED_BATCH 3#endif#define POLICY_DEBUG 0static pthread_once_t the_once = PTHREAD_ONCE_INIT;static int __sys_supports_schedgroups = -1;// File descriptors open to /dev/cpuctl/../tasks, setup by initialize, or -1 on error.static int normal_cgroup_fd = -1;static int bg_cgroup_fd = -1;/* Add tid to the scheduling group defined by the policy */static int add_tid_to_cgroup(int tid, SchedPolicy policy){ int fd; if (policy == SP_BACKGROUND) { fd = bg_cgroup_fd; } else { fd = normal_cgroup_fd; } if (fd < 0) { printf("add_tid_to_cgroup failed; background=%d\n", policy == SP_BACKGROUND ? 1 : 0); return -1; } // specialized itoa -- works for tid > 0 char text[22]; char *end = text + sizeof(text) - 1; char *ptr = end; *ptr = '\0'; while (tid > 0) { *--ptr = '0' + (tid % 10); tid = tid / 10; } if (write(fd, ptr, end - ptr) < 0) { /* * If the thread is in the process of exiting, * don't flag an error */ if (errno == ESRCH) return 0; SLOGW("add_tid_to_cgroup failed to write '%s' (%s); background=%d\n", ptr, strerror(errno), policy == SP_BACKGROUND ? 1 : 0); return -1; } return 0;}static void __initialize(void) { char* filename; if (!access("/dev/cpuctl/tasks", F_OK)) { __sys_supports_schedgroups = 1; filename = "/dev/cpuctl/tasks"; normal_cgroup_fd = open(filename, O_WRONLY); if (normal_cgroup_fd < 0) { SLOGE("open of %s failed: %s\n", filename, strerror(errno)); } filename = "/dev/cpuctl/bg_non_interactive/tasks"; bg_cgroup_fd = open(filename, O_WRONLY); if (bg_cgroup_fd < 0) { SLOGE("open of %s failed: %s\n", filename, strerror(errno)); } } else { __sys_supports_schedgroups = 0; }}/* * Try to get the scheduler group. * * The data from /proc//cgroup looks (something) like: * 2:cpu:/bg_non_interactive * 1:cpuacct:/ * * We return the part after the "/", which will be an empty string for * the default cgroup. If the string is longer than "bufLen", the string * will be truncated. */static int getSchedulerGroup(int tid, char* buf, size_t bufLen){#ifdef HAVE_ANDROID_OS char pathBuf[32]; char lineBuf[256]; FILE *fp; snprintf(pathBuf, sizeof(pathBuf), "/proc/%d/cgroup", tid); if (!(fp = fopen(pathBuf, "r"))) { return -1; } while(fgets(lineBuf, sizeof(lineBuf) -1, fp)) { char *next = lineBuf; char *subsys; char *grp; size_t len; /* Junk the first field */ if (!strsep(&next, ":")) { goto out_bad_data; } if (!(subsys = strsep(&next, ":"))) { goto out_bad_data; } if (strcmp(subsys, "cpu")) { /* Not the subsys we're looking for */ continue; } if (!(grp = strsep(&next, ":"))) { goto out_bad_data; } grp++; /* Drop the leading '/' */ len = strlen(grp); grp[len-1] = '\0'; /* Drop the trailing '\n' */ if (bufLen <= len) { len = bufLen - 1; } strncpy(buf, grp, len); buf[len] = '\0'; fclose(fp); return 0; } SLOGE("Failed to find cpu subsys"); fclose(fp); return -1; out_bad_data: SLOGE("Bad cgroup data {%s}", lineBuf); fclose(fp); return -1;#else errno = ENOSYS; return -1;#endif}int get_sched_policy(int tid, SchedPolicy *policy){ pthread_once(&the_once, __initialize); if (__sys_supports_schedgroups) { char grpBuf[32]; if (getSchedulerGroup(tid, grpBuf, sizeof(grpBuf)) < 0) return -1; if (grpBuf[0] == '\0') { *policy = SP_FOREGROUND; } else if (!strcmp(grpBuf, "bg_non_interactive")) { *policy = SP_BACKGROUND; } else { errno = ERANGE; return -1; } } else { int rc = sched_getscheduler(tid); if (rc < 0) return -1; else if (rc == SCHED_NORMAL) *policy = SP_FOREGROUND; else if (rc == SCHED_BATCH) *policy = SP_BACKGROUND; else { errno = ERANGE; return -1; } } return 0;}int set_sched_policy(int tid, SchedPolicy policy){ pthread_once(&the_once, __initialize);#if POLICY_DEBUG char statfile[64]; char statline[1024]; char thread_name[255]; int fd; sprintf(statfile, "/proc/%d/stat", tid); memset(thread_name, 0, sizeof(thread_name)); fd = open(statfile, O_RDONLY); if (fd >= 0) { int rc = read(fd, statline, 1023); close(fd); statline[rc] = 0; char *p = statline; char *q; for (p = statline; *p != '('; p++); p++; for (q = p; *q != ')'; q++); strncpy(thread_name, p, (q-p)); } if (policy == SP_BACKGROUND) { SLOGD("vvv tid %d (%s)", tid, thread_name); } else if (policy == SP_FOREGROUND) { SLOGD("^^^ tid %d (%s)", tid, thread_name); } else { SLOGD("??? tid %d (%s)", tid, thread_name); }#endif if (__sys_supports_schedgroups) { if (add_tid_to_cgroup(tid, policy)) { if (errno != ESRCH && errno != ENOENT) return -errno; } } else { struct sched_param param; param.sched_priority = 0; sched_setscheduler(tid, (policy == SP_BACKGROUND) ? SCHED_BATCH : SCHED_NORMAL, ¶m); } return 0;}
/* * Copyright (C) 2007 The Android Open Source Project * * Licensed 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. */#ifndef __CUTILS_SCHED_POLICY_H#define __CUTILS_SCHED_POLICY_H#ifdef __cplusplusextern "C" {#endiftypedef enum { SP_BACKGROUND = 0, SP_FOREGROUND = 1,} SchedPolicy;extern int set_sched_policy(int tid, SchedPolicy policy);extern int get_sched_policy(int tid, SchedPolicy *policy);#ifdef __cplusplus}#endif#endif /* __CUTILS_SCHED_POLICY_H */
源码:右键下载后保存为rar 更多相关文章
- 使用React-navigation时候 Android物理返回键&BackHandler exitA
- 自己实现Android关机命令
- Android 4.1.1源码编译
- Android弹出异常dialog源码分析
- Android UI滑动加载源码
- Android滑动开关-ToggleButton(附源码)
- RK平台修改android系统源码设置开机启动apk