linux内核实验一实现过程
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/time.h>
#include <string.h>
FILE *fd;
void sampleLoadAvg(){
printf("系统负载探测:\n");
printf("====================================================\n");
//fread读出的字符数,用以判断是否读完,以及在创建新的数组的时候组为参数表示数组的大小
int num=0;
//读出缓冲区
char buffer[80];
//打开负载文件
fd = fopen("/proc/loadavg","r");
//读文件
num = fread(buffer,sizeof(char),79,fd);
//关闭文件
close(fd);
//根据读出的字符的多少,创建新的数组
char *str=malloc(num);
strncpy(str,buffer,num);
//以空格为分割符,分割str
char *delim=" ";
//单个的字符串临时变量
char *p;
//第一次调用strtok函数
p=strtok(str,delim);
int index=0;
/*index=0 表示1秒钟的负载
*index=1 表示5秒钟的负载
*index=2 表示15秒钟的负载
*index=3 表示当前由内核调度的实体(进程线程)的数目\当前系统存货的调度 实体的数目
*index=4 表示最后一个由内核创建的进程PID
*/
do
{
switch(index){
case 0:
printf("1秒钟的负载为:%s\n",p);
break;
case 1:
printf("5秒钟的负载为:%s\n",p);
break;
case 2:
printf("15秒钟的负载为:%s\n",p);
break;
case 3:
printf("当前内核调度的实体的数目\\系统中的实体的总数:%s\n",p);
break;
case 4:
printf("有内核创建的最后一个进程的进程号:%s\n",p);
break;
}
index++;
//printf("%s \n",p);
}
while((p=strtok(NULL,delim)));
free(str);
printf("=========================================================\n\n\n");
}
void runtime(){
printf("系统运行时间 :\n");
printf("=========================================================\n");
char buffer[80];
int num=0;
fd= fopen("/proc/uptime","r");
num= fread(buffer,sizeof(char),79,fd);
//关闭文件
close(fd);
char *str=malloc(num);
strncpy(str,buffer,num);
char *delim=" ";
char *p;
p=strtok(str,delim);
int index=0;
do{
switch(index){
case 0:
{
//显示启动时间
float time =0;
time=strtod(p,NULL);
printf("总共的运行时间(以秒为单位):%f\n",time);
int day=time/(24*60*60);
int hour=(time-day*24*60*60)/(60*60);
int minute=(time-day*24*60*60-hour*60*60)/60;
int second=(time-day*24*60*60-hour*60*60-minute*60);
printf("dd:hh:mm:ss:%d:%d:%d:%d\n",day,hour,minute,second);
}
break;
case 1:
{
//显示空闲时间
float time =0;
time=strtod(p,NULL);
printf("总共的空闲时间(以秒为单位):%f\n",time);
int day=time/(24*60*60);
int hour=(time-day*24*60*60)/(60*60);
int minute=(time-day*24*60*60-hour*60*60)/60;
int second=(time-day*24*60*60-hour*60*60-minute*60);
printf("dd:hh:mm:ss:%d:%d:%d:%d\n",day,hour,minute,second);
break;
}
}
index++;
}
while((p=strtok(NULL,delim)));
free(str);
printf("=========================================================\n\n\n\n");
}
void meminfo(){
printf("内存信息:\n");
printf("=========================================================\n");
char buffer[80];
int num=0;
fd= fopen("/proc/meminfo","r");
num= fread(buffer,sizeof(char),79,fd);
//关闭文件
close(fd);
char *str=malloc(num);
strncpy(str,buffer,num);
char *delim=" \n";
char *p;
p=strtok(str,delim);
int index=0;
/*
*
*
*/
do{
switch(index){
case 0:{
printf("内存总量:%s\n",p=strtok(NULL,delim));
strtok(NULL,delim);//跳过符号K
break;
}
case 1:{
printf("剩余内存:%s\n",p=strtok(NULL,delim));
strtok(NULL,delim);//跳过符号K
break;
}
}
index++;
}
while(p=strtok(NULL,delim));
free(str);
printf("=========================================================\n\n\n");
}
void cpuModelName(){
printf("cpu类型:\n");
printf("=========================================================\n");
char buffer[200];
int num=0;
fd= fopen("/proc/cpuinfo","r");
num= fread(buffer,sizeof(char),200,fd);
//关闭文件
close(fd);
char *str=malloc(num);
strncpy(str,buffer,num);
char *delim="\n";
char *delim2=" ";
char *p;
p=strtok(str,delim);
int index=0;
do{
switch(index){
case 4:{
//printf("%s\n",p);
char *pp=strtok(p,":");
pp=strtok(NULL,":");
printf("cpu model name is:%s\n",pp);
break;
}
}
index++;
}
while(p=strtok(NULL,delim));
free(str);
printf("=============================================================\n\n\n");
}
void kernelversion(){
printf("内核信息:\n");
printf("=========================================================\n");
char buffer[200];
int num=0;
fd= fopen("/proc/version","r");
num= fread(buffer,sizeof(char),200,fd);
//关闭文件
close(fd);
char *str=malloc(num);
strncpy(str,buffer,num);
char *delim="(";
char *p;
p=strtok(str,delim);
int index=0;
do{
switch(index){
case 0:{
printf("linux version is:%s\n",p);
break;
}
}
index++;
}
while(p=strtok(NULL,delim));
free(str);
printf("=============================================================\n\n\n");
}
//解决实验part c部分的问题
void partc(){
printf("=========================================================\n");
int charnum=2000;
char buffer[charnum];
int num=0;
fd=fopen("/proc/stat","r");
num=fread(buffer,sizeof(char),charnum,fd);
//关闭文件
close(fd);
char *str=malloc(num);
strncpy(str,buffer,num);
char *delim="\n";
char *delim2=" ";
char *p;
//存放一行信息
char *substr;
char *subp;
p=strtok(str,delim);
int index=0;
/*
index presents the linenumber!!
通过对/proc/stat文件的分心,我们知道
index=0:
“cpu”行后的八个值分别表示以1/100(jiffies)秒为单位的统计值(包括系统运行于用户模式、
低优先级用户模式,运系统模式、空闲模式、I/O等待模式的时间等);
index=5:
“intr”行给出中断的信息,第一个为自系统启动以来,发生的所有的中断的次数;然后每个数对应一个特定
的中断自系统启动以来所发生的次数;
index=6:
“ctxt”给出了自系统启动以来CPU发生的上下文交换的次数。
index=8:
“processes (total_forks) 自系统启动以来所创建的任务的个数目;
*/
//从这里看出连续使用strtok是不对的,因为在遍历是使用的是同一个缓冲区,如果再次使用strtok那么原来的在缓冲区中存放的内容就可能被覆盖掉
//解决的方法,先把整个句子分割为几个子字符串,并把这些子字符串存放到某个缓冲区中,然后针对每一个缓冲区再分别使用strtok分割
char *substrs[12];
int nums=0;
do{
substrs[nums]=p;
nums++;
//printf("%d\n",nums);
}
while(p=strtok(NULL,delim));
int index2=0;
for(index2=0;index2<12;index2++){
//printf("%s\n",substrs[index2]);
char *substrpt=strtok(substrs[index2],delim2);
int interindex=0;
do{
if(index2==0){
if(interindex==1)
printf("执行用户模式时间:%s\n",substrpt);
else if(interindex==2)
printf("执行系统模式时间:%s\n",substrpt);
else if(interindex==3)
printf("空闲态所用的时间:%s\n",substrpt);
}
else if(index2==5){
if(interindex==1)
printf("中断的次数:%s\n",substrpt);
}
else if(index2==6){
if(interindex==1)
printf("上下文切换的次数:%s\n",substrpt);
}
else if(index2==8){
if(interindex==1)
printf("进程的个数:%s\n",substrpt);
}
//printf("%s",substrpt);
interindex++;
}
while(substrpt=strtok(NULL,delim2));
}
free(str);
printf("=============================================================\n\n\n");
}
//实验part E部分
void parte(){
printf("=========================================================\n");
int charnum=2;
int num=0;
//read sysrq
char buffer1[charnum];
FILE* fsysrq=fopen("/proc/sys/kernel/sysrq","rb");
num=fread(buffer1,sizeof(char),charnum,fsysrq);
close(fsysrq);//close it
buffer1[1]='\0';
//read ctrl-alt-del
char buffer2[charnum];
FILE * fcad=fopen("/proc/sys/kernel/ctrl-alt-del","rb");
num=fread(buffer2,sizeof(char),charnum,fcad);
close(fcad);//close it
buffer2[1]='\0';
/*
在c语言中如果一个字符数组的最后一个字符不是\0,而是空格等,那么在printf中作为一个参数输出时,就会产生乱码。
因此一个比较好的使用字符数组的方式是在填充字符数组之前首先使用'\0'对其进行初始化。然后在进行相应的初始化.
在c语言中实际上这是c类型字符串的一个特色。
*/
printf("The values before changed are: \nsysrq:%s\nctrl-alt-del:%s\n",buffer1,buffer2);
//取反
fsysrq=fopen("/proc/sys/kernel/sysrq","wb");
fcad=fopen("/proc/sys/kernel/ctrl-alt-del","wb");
char newsysrq[charnum];
char newcad[charnum];
//默认的新
memset(newsysrq,'\0',sizeof(newsysrq));
memset(newcad,'\0',sizeof(newcad));
newsysrq[0]='0';
newcad[0]='0';
printf("newsysrq and newcad:%s %s\n",newsysrq,newcad);
if(buffer1[0]=='0'){
newsysrq[0]='1';
}
if(buffer2[0]=='0')
newcad[0]='1';
printf("values new %s %s\n",newsysrq,newcad);
if(fwrite(newsysrq,sizeof(char),1,fsysrq)!=1){
printf("error\n");
}
//这里写成fwrite(newsysrq,sizeof(newcad),1,fsysrq)不对
if(fwrite(newcad,sizeof(char),1,fcad)!=1){
printf("error\n");
}
printf("The values of sysrq and ctrl-alt-del have been changed\n");
//关闭文件
close(fsysrq);
close(fcad);
printf("=========================================================\n");
}
int main(int argc,char *argv[]){
if(argc==1){
printf("too few arguments!\n");
exit(1);
}
char c1,c2;
sscanf(argv[1],"%c%c",&c1,&c2);
if(c1!='-'){
printf("cmdline without '-'\n");
exit(1);
}
if(c2=='a'){//A part
printf("**************PART A*****************\n\n");
cpuModelName();
kernelversion();
}
else if(c2=='b'){//B part
printf("**************PART B*****************\n\n");
runtime();
}
else if(c2=='c'){//C part
printf("**************PART C*****************\n\n");
partc();
}
else if(c2=='d'){//D part
printf("**************PART D*****************\n\n");
sampleLoadAvg();
meminfo();
}
else{//E part
printf("**************PART E*****************\n\n");
parte();
}
//sampleLoadAvg();
//runtime();
//meminfo();
//cpuModelName();
//kernelversion();
return 0;
}
linux内核实验一实现过程
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/time.h>
#include <string.h>
FILE *fd;
void sampleLoadAvg(){
printf("系统负载探测:\n");
printf("====================================================\n");
//fread读出的字符数,用以判断是否读完,以及在创建新的数组的时候组为参数表示数组的大小
int num=0;
//读出缓冲区
char buffer[80];
//打开负载文件
fd = fopen("/proc/loadavg","r");
//读文件
num = fread(buffer,sizeof(char),79,fd);
//关闭文件
close(fd);
//根据读出的字符的多少,创建新的数组
char *str=malloc(num);
strncpy(str,buffer,num);
//以空格为分割符,分割str
char *delim=" ";
//单个的字符串临时变量
char *p;
//第一次调用strtok函数
p=strtok(str,delim);
int index=0;
/*index=0 表示1秒钟的负载
*index=1 表示5秒钟的负载
*index=2 表示15秒钟的负载
*index=3 表示当前由内核调度的实体(进程线程)的数目\当前系统存货的调度 实体的数目
*index=4 表示最后一个由内核创建的进程PID
*/
do
{
switch(index){
case 0:
printf("1秒钟的负载为:%s\n",p);
break;
case 1:
printf("5秒钟的负载为:%s\n",p);
break;
case 2:
printf("15秒钟的负载为:%s\n",p);
break;
case 3:
printf("当前内核调度的实体的数目\\系统中的实体的总数:%s\n",p);
break;
case 4:
printf("有内核创建的最后一个进程的进程号:%s\n",p);
break;
}
index++;
//printf("%s \n",p);
}
while((p=strtok(NULL,delim)));
free(str);
printf("=========================================================\n\n\n");
}
void runtime(){
printf("系统运行时间 :\n");
printf("=========================================================\n");
char buffer[80];
int num=0;
fd= fopen("/proc/uptime","r");
num= fread(buffer,sizeof(char),79,fd);
//关闭文件
close(fd);
char *str=malloc(num);
strncpy(str,buffer,num);
char *delim=" ";
char *p;
p=strtok(str,delim);
int index=0;
do{
switch(index){
case 0:
{
//显示启动时间
float time =0;
time=strtod(p,NULL);
printf("总共的运行时间(以秒为单位):%f\n",time);
int day=time/(24*60*60);
int hour=(time-day*24*60*60)/(60*60);
int minute=(time-day*24*60*60-hour*60*60)/60;
int second=(time-day*24*60*60-hour*60*60-minute*60);
printf("dd:hh:mm:ss:%d:%d:%d:%d\n",day,hour,minute,second);
}
break;
case 1:
{
//显示空闲时间
float time =0;
time=strtod(p,NULL);
printf("总共的空闲时间(以秒为单位):%f\n",time);
int day=time/(24*60*60);
int hour=(time-day*24*60*60)/(60*60);
int minute=(time-day*24*60*60-hour*60*60)/60;
int second=(time-day*24*60*60-hour*60*60-minute*60);
printf("dd:hh:mm:ss:%d:%d:%d:%d\n",day,hour,minute,second);
break;
}
}
index++;
}
while((p=strtok(NULL,delim)));
free(str);
printf("=========================================================\n\n\n\n");
}
void meminfo(){
printf("内存信息:\n");
printf("=========================================================\n");
char buffer[80];
int num=0;
fd= fopen("/proc/meminfo","r");
num= fread(buffer,sizeof(char),79,fd);
//关闭文件
close(fd);
char *str=malloc(num);
strncpy(str,buffer,num);
char *delim=" \n";
char *p;
p=strtok(str,delim);
int index=0;
/*
*
*
*/
do{
switch(index){
case 0:{
printf("内存总量:%s\n",p=strtok(NULL,delim));
strtok(NULL,delim);//跳过符号K
break;
}
case 1:{
printf("剩余内存:%s\n",p=strtok(NULL,delim));
strtok(NULL,delim);//跳过符号K
break;
}
}
index++;
}
while(p=strtok(NULL,delim));
free(str);
printf("=========================================================\n\n\n");
}
void cpuModelName(){
printf("cpu类型:\n");
printf("=========================================================\n");
char buffer[200];
int num=0;
fd= fopen("/proc/cpuinfo","r");
num= fread(buffer,sizeof(char),200,fd);
//关闭文件
close(fd);
char *str=malloc(num);
strncpy(str,buffer,num);
char *delim="\n";
char *delim2=" ";
char *p;
p=strtok(str,delim);
int index=0;
do{
switch(index){
case 4:{
//printf("%s\n",p);
char *pp=strtok(p,":");
pp=strtok(NULL,":");
printf("cpu model name is:%s\n",pp);
break;
}
}
index++;
}
while(p=strtok(NULL,delim));
free(str);
printf("=============================================================\n\n\n");
}
void kernelversion(){
printf("内核信息:\n");
printf("=========================================================\n");
char buffer[200];
int num=0;
fd= fopen("/proc/version","r");
num= fread(buffer,sizeof(char),200,fd);
//关闭文件
close(fd);
char *str=malloc(num);
strncpy(str,buffer,num);
char *delim="(";
char *p;
p=strtok(str,delim);
int index=0;
do{
switch(index){
case 0:{
printf("linux version is:%s\n",p);
break;
}
}
index++;
}
while(p=strtok(NULL,delim));
free(str);
printf("=============================================================\n\n\n");
}
//解决实验part c部分的问题
void partc(){
printf("=========================================================\n");
int charnum=2000;
char buffer[charnum];
int num=0;
fd=fopen("/proc/stat","r");
num=fread(buffer,sizeof(char),charnum,fd);
//关闭文件
close(fd);
char *str=malloc(num);
strncpy(str,buffer,num);
char *delim="\n";
char *delim2=" ";
char *p;
//存放一行信息
char *substr;
char *subp;
p=strtok(str,delim);
int index=0;
/*
index presents the linenumber!!
通过对/proc/stat文件的分心,我们知道
index=0:
“cpu”行后的八个值分别表示以1/100(jiffies)秒为单位的统计值(包括系统运行于用户模式、
低优先级用户模式,运系统模式、空闲模式、I/O等待模式的时间等);
index=5:
“intr”行给出中断的信息,第一个为自系统启动以来,发生的所有的中断的次数;然后每个数对应一个特定
的中断自系统启动以来所发生的次数;
index=6:
“ctxt”给出了自系统启动以来CPU发生的上下文交换的次数。
index=8:
“processes (total_forks) 自系统启动以来所创建的任务的个数目;
*/
//从这里看出连续使用strtok是不对的,因为在遍历是使用的是同一个缓冲区,如果再次使用strtok那么原来的在缓冲区中存放的内容就可能被覆盖掉
//解决的方法,先把整个句子分割为几个子字符串,并把这些子字符串存放到某个缓冲区中,然后针对每一个缓冲区再分别使用strtok分割
char *substrs[12];
int nums=0;
do{
substrs[nums]=p;
nums++;
//printf("%d\n",nums);
}
while(p=strtok(NULL,delim));
int index2=0;
for(index2=0;index2<12;index2++){
//printf("%s\n",substrs[index2]);
char *substrpt=strtok(substrs[index2],delim2);
int interindex=0;
do{
if(index2==0){
if(interindex==1)
printf("执行用户模式时间:%s\n",substrpt);
else if(interindex==2)
printf("执行系统模式时间:%s\n",substrpt);
else if(interindex==3)
printf("空闲态所用的时间:%s\n",substrpt);
}
else if(index2==5){
if(interindex==1)
printf("中断的次数:%s\n",substrpt);
}
else if(index2==6){
if(interindex==1)
printf("上下文切换的次数:%s\n",substrpt);
}
else if(index2==8){
if(interindex==1)
printf("进程的个数:%s\n",substrpt);
}
//printf("%s",substrpt);
interindex++;
}
while(substrpt=strtok(NULL,delim2));
}
free(str);
printf("=============================================================\n\n\n");
}
//实验part E部分
void parte(){
printf("=========================================================\n");
int charnum=2;
int num=0;
//read sysrq
char buffer1[charnum];
FILE* fsysrq=fopen("/proc/sys/kernel/sysrq","rb");
num=fread(buffer1,sizeof(char),charnum,fsysrq);
close(fsysrq);//close it
buffer1[1]='\0';
//read ctrl-alt-del
char buffer2[charnum];
FILE * fcad=fopen("/proc/sys/kernel/ctrl-alt-del","rb");
num=fread(buffer2,sizeof(char),charnum,fcad);
close(fcad);//close it
buffer2[1]='\0';
/*
在c语言中如果一个字符数组的最后一个字符不是\0,而是空格等,那么在printf中作为一个参数输出时,就会产生乱码。
因此一个比较好的使用字符数组的方式是在填充字符数组之前首先使用'\0'对其进行初始化。然后在进行相应的初始化.
在c语言中实际上这是c类型字符串的一个特色。
*/
printf("The values before changed are: \nsysrq:%s\nctrl-alt-del:%s\n",buffer1,buffer2);
//取反
fsysrq=fopen("/proc/sys/kernel/sysrq","wb");
fcad=fopen("/proc/sys/kernel/ctrl-alt-del","wb");
char newsysrq[charnum];
char newcad[charnum];
//默认的新
memset(newsysrq,'\0',sizeof(newsysrq));
memset(newcad,'\0',sizeof(newcad));
newsysrq[0]='0';
newcad[0]='0';
printf("newsysrq and newcad:%s %s\n",newsysrq,newcad);
if(buffer1[0]=='0'){
newsysrq[0]='1';
}
if(buffer2[0]=='0')
newcad[0]='1';
printf("values new %s %s\n",newsysrq,newcad);
if(fwrite(newsysrq,sizeof(char),1,fsysrq)!=1){
printf("error\n");
}
//这里写成fwrite(newsysrq,sizeof(newcad),1,fsysrq)不对
if(fwrite(newcad,sizeof(char),1,fcad)!=1){
printf("error\n");
}
printf("The values of sysrq and ctrl-alt-del have been changed\n");
//关闭文件
close(fsysrq);
close(fcad);
printf("=========================================================\n");
}
int main(int argc,char *argv[]){
if(argc==1){
printf("too few arguments!\n");
exit(1);
}
char c1,c2;
sscanf(argv[1],"%c%c",&c1,&c2);
if(c1!='-'){
printf("cmdline without '-'\n");
exit(1);
}
if(c2=='a'){//A part
printf("**************PART A*****************\n\n");
cpuModelName();
kernelversion();
}
else if(c2=='b'){//B part
printf("**************PART B*****************\n\n");
runtime();
}
else if(c2=='c'){//C part
printf("**************PART C*****************\n\n");
partc();
}
else if(c2=='d'){//D part
printf("**************PART D*****************\n\n");
sampleLoadAvg();
meminfo();
}
else{//E part
printf("**************PART E*****************\n\n");
parte();
}
//sampleLoadAvg();
//runtime();
//meminfo();
//cpuModelName();
//kernelversion();
return 0;
}