in OpsWorks/sample-cookbooks/cpulimit-ruby/files/default/cpulimit-master/src/cpulimit.c [301:514]
int main(int argc, char **argv) {
//argument variables
const char *exe = NULL;
int perclimit = 0;
int exe_ok = 0;
int pid_ok = 0;
int limit_ok = 0;
pid_t pid = 0;
int include_children = 0;
//get program name
char *p = (char*)memrchr(argv[0], (unsigned int)'/', strlen(argv[0]));
program_name = p==NULL ? argv[0] : (p+1);
//get current pid
cpulimit_pid = getpid();
//get cpu count
NCPU = get_ncpu();
//parse arguments
int next_option;
int option_index = 0;
//A string listing valid short options letters
const char* short_options = "+p:e:l:vzih";
//An array describing valid long options
const struct option long_options[] = {
{ "pid", required_argument, NULL, 'p' },
{ "exe", required_argument, NULL, 'e' },
{ "limit", required_argument, NULL, 'l' },
{ "verbose", no_argument, NULL, 'v' },
{ "lazy", no_argument, NULL, 'z' },
{ "include-children", no_argument, NULL, 'i' },
{ "help", no_argument, NULL, 'h' },
{ 0, 0, 0, 0 }
};
do {
next_option = getopt_long(argc, argv, short_options,long_options, &option_index);
switch(next_option) {
case 'p':
pid = atoi(optarg);
pid_ok = 1;
break;
case 'e':
exe = optarg;
exe_ok = 1;
break;
case 'l':
perclimit = atoi(optarg);
limit_ok = 1;
break;
case 'v':
verbose = 1;
break;
case 'z':
lazy = 1;
break;
case 'i':
include_children = 1;
break;
case 'h':
print_usage(stdout, 1);
break;
case '?':
print_usage(stderr, 1);
break;
case -1:
break;
default:
abort();
}
} while(next_option != -1);
if (pid_ok && (pid <= 1 || pid >= get_pid_max())) {
fprintf(stderr,"Error: Invalid value for argument PID\n");
print_usage(stderr, 1);
exit(1);
}
if (pid != 0) {
lazy = 1;
}
if (!limit_ok) {
fprintf(stderr,"Error: You must specify a cpu limit percentage\n");
print_usage(stderr, 1);
exit(1);
}
double limit = perclimit / 100.0;
if (limit<0 || limit >NCPU) {
fprintf(stderr,"Error: limit must be in the range 0-%d00\n", NCPU);
print_usage(stderr, 1);
exit(1);
}
int command_mode = optind < argc;
if (exe_ok + pid_ok + command_mode == 0) {
fprintf(stderr,"Error: You must specify one target process, either by name, pid, or command line\n");
print_usage(stderr, 1);
exit(1);
}
if (exe_ok + pid_ok + command_mode > 1) {
fprintf(stderr,"Error: You must specify exactly one target process, either by name, pid, or command line\n");
print_usage(stderr, 1);
exit(1);
}
//all arguments are ok!
signal(SIGINT, quit);
signal(SIGTERM, quit);
//print the number of available cpu
if (verbose) printf("%d cpu detected\n", NCPU);
if (command_mode) {
int i;
//executable file
const char *cmd = argv[optind];
//command line arguments
char **cmd_args = (char**)malloc((argc-optind + 1) * sizeof(char*));
if (cmd_args==NULL) exit(2);
for (i=0; i<argc-optind; i++) {
cmd_args[i] = argv[i+optind];
}
cmd_args[i] = NULL;
if (verbose) {
printf("Running command: '%s", cmd);
for (i=1; i<argc-optind; i++) {
printf(" %s", cmd_args[i]);
}
printf("'\n");
}
int child = fork();
if (child < 0) {
exit(EXIT_FAILURE);
}
else if (child == 0) {
//target process code
int ret = execvp(cmd, cmd_args);
//if we are here there was an error, show it
perror("Error");
exit(ret);
}
else {
//parent code
free(cmd_args);
int limiter = fork();
if (limiter < 0) {
exit(EXIT_FAILURE);
}
else if (limiter > 0) {
//parent
int status_process;
int status_limiter;
waitpid(child, &status_process, 0);
waitpid(limiter, &status_limiter, 0);
if (WIFEXITED(status_process)) {
if (verbose) printf("Process %d terminated with exit status %d\n", child, (int)WEXITSTATUS(status_process));
exit(WEXITSTATUS(status_process));
}
printf("Process %d terminated abnormally\n", child);
exit(status_process);
}
else {
//limiter code
if (verbose) printf("Limiting process %d\n",child);
limit_process(child, limit, include_children);
exit(0);
}
}
}
while(1) {
//look for the target process..or wait for it
pid_t ret = 0;
if (pid_ok) {
//search by pid
ret = find_process_by_pid(pid);
if (ret == 0) {
printf("No process found\n");
}
else if (ret < 0) {
printf("Process found but you aren't allowed to control it\n");
}
}
else {
//search by file or path name
ret = find_process_by_name(exe);
if (ret == 0) {
printf("No process found\n");
}
else if (ret < 0) {
printf("Process found but you aren't allowed to control it\n");
}
else {
pid = ret;
}
}
if (ret > 0) {
if (ret == cpulimit_pid) {
printf("Target process %d is cpulimit itself! Aborting because it makes no sense\n", ret);
exit(1);
}
printf("Process %d found\n", pid);
//control
limit_process(pid, limit, include_children);
}
if (lazy) break;
sleep(2);
};
exit(0);
}