📄 cpuctl.c
字号:
/* * Copyright (c) 2005 Alf Schlichting * All rights reserved. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */#include<sys/types.h>#include<sys/un.h>#include<sys/socket.h>#include <sys/param.h>#include<err.h>#include<stdio.h>#include<stdlib.h>#include<string.h>#include<unistd.h>#include "pathnames.h"#include "common.h"#include "cpuctl.h"#include "util.h"extern char *__progname;struct scheme s;struct fields fld[] = { {"treshhold", "[ 0 - 100 ]", &s.treshhold, PERCENT, FALSE}, {"stepup", "[ 0 - 100 ]", &s.stepup, PERCENT, FALSE}, {"stepdown", "[ 0 - 100 ]", &s.stepdown, PERCENT, FALSE}, {"sleep", "[ 1 - ~ ]", &s.sleep, SLEEPVAL, FALSE}, {"ac_con.cpu_rate", "[ 0 - 100 ]", &s.ac_con.cpu_rate_full_power, \ PERCENT, FALSE}, {"ac_con_charging.cpu_rate", "[ 0 - 100 ]", &s.ac_con_charging.cpu_rate_full_power, PERCENT, FALSE}, {"ac_discon.borderline", "[ 0, 1 ]", &s.ac_discon.borderline, \ PERCENT, FALSE}, {"ac_discon.cpu_rate_full_power", "[ 0 - 100 ]", &s.ac_discon.cpu_rate_full_power, PERCENT, FALSE}, {"ac_discon.cpu_rate_low_power", "[ 0 - 100 ]", &s.ac_discon.cpu_rate_low_power, PERCENT, FALSE}, { 0 } /* END */};char *sock_path; /* where to connect to */size_t plen; /* size of struct perf_command */int verbose; /* bla ? */int open_socket(void);void build_command(struct perf_command *, struct scheme *, int);void init_scheme(void);int check_scheme(struct perf_command *);void send_scheme(struct perf_command *);void get_scheme(struct perf_command *);void print_scheme(char **, int, struct perf_command *);void handle_val(char **, int, struct perf_command *, struct scheme *);void usage(void);/** Program to control cpud(1) from the command line or by* parsing its configuration file.*/intmain(int argc, char **argv){ struct perf_command *pc; struct scheme *s_ptr; char *scheme_name; /* name of the scheme */ char *conf_path; /* Path to configuration file */ int set_flag, all_flag; /* what to do */ int opt; /* getopt */ int cmd; /* GET|SET_SCHEME */ /* set some default values */ set_flag = 0; all_flag = 0; verbose = 0; cmd = GET_SCHEME; plen = sizeof(struct perf_command); conf_path = CONF_PATH; sock_path = PATH_CPUD_UNIX_SOCKET; scheme_name = NULL; pc = calloc(1, sizeof(struct perf_command)); s_ptr = calloc(1, sizeof(struct scheme)); while ((opt = getopt(argc, argv, "ac:f:s:v")) != -1) { switch (opt) { case 'a': all_flag = 1; break; case 'c': conf_path = optarg; break; case 'f': sock_path = optarg; break; case 's': set_flag = 1; scheme_name = optarg; cmd = SET_SCHEME; break; case 'v': verbose = 1; break; default: usage(); } } argc -= optind; argv += optind; if (!set_flag && !all_flag && argv[0] == NULL) usage(); if (all_flag && argv[0]) usage(); if (all_flag && set_flag) /* exclude each other */ usage(); init_scheme(); if (argv[0]) { if (strchr(argv[0], '=')) { get_scheme(pc); handle_val(argv, argc, pc, s_ptr); build_command(pc, s_ptr, SET_SCHEME); send_scheme(pc); print_scheme(argv, argc, pc); } else { get_scheme(pc); print_scheme(argv, argc, pc); } } else if (all_flag) { get_scheme(pc); print_scheme(NULL, 0, pc); } else if (set_flag) { read_scheme(s_ptr, scheme_name, conf_path); build_command(pc, s_ptr, cmd); if (check_scheme(pc) == -1) exit(1); send_scheme(pc); if (verbose) print_scheme(NULL, 0, pc); } exit(0);}/* Construct the command to send */voidbuild_command(struct perf_command *p, struct scheme *sc, int cmd){ p->command = cmd; p->s = *sc;}/* Initialize scheme s to NOT_USED */voidinit_scheme() { int i; for (i = 0; fld[i].f_name; i++) { switch (fld[i].type) { case PERCENT: case SLEEPVAL: *(int *)fld[i].ptr = NOT_USED; break; default: err(1, "unknown type"); } }}/* Check if all values are set */intcheck_scheme(struct perf_command *pc){ int i; for (i = 0; fld[i].f_name; i++) { switch (fld[i].type) { case PERCENT: case SLEEPVAL: if (*(int *)fld[i].ptr == NOT_USED) { fprintf(stderr, "Configuration parse error: " "%s not set\n", fld[i].f_name); return -1; } break; default: err(1, "unknown type"); } } return 0;}/* Send a scheme to cpud(1) */voidsend_scheme(struct perf_command *pc) { int fd; fd = open_socket(); if (write_sock(fd, (char *)pc, plen) != plen) err(1, "write"); close(fd);}/* read a scheme from cpud(1) */voidget_scheme(struct perf_command *pc){ int fd; int n; fd = open_socket(); if (write_sock(fd, (char *)pc, plen) != plen) err(1, "write"); if ((n = read_sock(fd, (char *)pc, plen)) != plen) warn("read %d bytes, wanted %d\n", n, plen); close(fd);}/* print a scheme to stdout */voidprint_scheme(char **out, int count, struct perf_command *pc){ int i; char *p; s = pc->s; if (!count) { fprintf(stdout, "[%s]\n", pc->s.name); for (i = 0; fld[i].f_name; i++) { switch (fld[i].type) { case PERCENT: case SLEEPVAL: if (*(int *)fld[i].ptr == NOT_USED) continue; fprintf(stdout, "%s=%d", fld[i].f_name, *(int *)fld[i].ptr); if (verbose) fprintf(stdout, " %s", fld[i].pos_val); fprintf(stdout, "\n"); break; default: err(1, "unknown type"); } } } else { while(count--) { p = strchr(*out, '='); if (p) *p = '\0'; i = get_field(*out); out++; if (i == -1) errx(1, "No such value: %s", *out); switch (fld[i].type) { case PERCENT: case SLEEPVAL: fprintf(stdout, "%s=%d", fld[i].f_name, *(int *)fld[i].ptr); if (verbose) fprintf(stdout, " %s", fld[i].pos_val); fprintf(stdout, "\n"); break; default: err(1, "unknown type"); } } }}/* Parse the args from the commandline */voidhandle_val(char **val, int count, struct perf_command *pc, struct scheme *sch){ s = pc->s; while(count--) { if (parse_scheme(*val++) == -1) usage(); } memcpy(sch, &s, sizeof(struct scheme));}/* returns a valid socket */intopen_socket(void){ int fd; int sun_l; struct sockaddr_un sun; if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) err(1, "socket"); sun.sun_family = AF_UNIX; sun_l = sizeof(struct sockaddr_un); strlcpy(sun.sun_path, sock_path, sizeof(sun.sun_path)); if (connect(fd, (struct sockaddr *)&sun, sun_l) == -1) err(1, "connect"); return fd;}/* usage */voidusage(void){ fprintf(stderr, "usage: %s [-v] [-f socket] -a\n" " %s [-v] [-f socket] name ...\n" " %s [-v] [-f socket] name=value ...\n" " %s [-v] [-f socket] [-c configuration file]" " -s scheme\n", __progname, __progname, __progname, __progname); exit(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -