Linux下CC查找某一进程.docx
《Linux下CC查找某一进程.docx》由会员分享,可在线阅读,更多相关《Linux下CC查找某一进程.docx(13页珍藏版)》请在冰豆网上搜索。
Linux下CC查找某一进程
Linux下C/C++查找某一进程
一、前言:
要在程序中启动某一程序,如果程序已经存在了,就不再启动。
查找了N篇文档,有所收获,总结一下。
二、实现
大体分两种:
1、exec或popen执行ps的命令行,然后运用某几个字符串匹配函数。
#include
#include
#include
#include
intmain()
{
FILE*pstr;
charcmd[128],buff[512],*p;
pid_tpID;
intpidnum;
char*name="ping";//要查找的进程名
intret=3;
memset(cmd,0,sizeof(cmd));
sprintf(cmd,"ps-ef|grep%s",name);
pstr=popen(cmd,"r");//
if(pstr==NULL)
return1;
memset(buff,0,sizeof(buff));
fgets(buff,512,pstr);
p=strtok(buff,"");
p=strtok(NULL,"");//这句是否去掉,取决于当前系统中ps后,进程ID号是否是第一个字段
pclose(pstr);
if(p==NULL)
return1;
if(strlen(p)==0)
return1;
if((pidnum=atoi(p))==0)
return1;
printf("pidnum:
%d\n",pidnum);
pID=(pid_t)pidnum;
ret=kill(pID,0);//这里不是要杀死进程,而是验证一下进程是否真的存在,返回0表示真的存在
printf("ret=%d\n",ret);
if(0==ret)
printf("Process:
%sexist!
\n",name);
elseprintf("Process:
%snotexist!
\n",name);
return0;
}
2、读取/proc文件
找到个代码如下:
读取/proc文件查找进程
#ifndef__cplusplus//识别C/C++的宏,望文生义
#define_GNU_SOURCE
#endif
#include
#include
#include//foropendir(),readdir(),closedir()
#include//forstat()
#ifdef__cplusplus
#include
#include
#include
#include
#else
#include
#include
#include
#include
#endif
#definePROC_DIRECTORY"/proc/"
#defineCASE_SENSITIVE1
#defineCASE_INSENSITIVE0
#defineEXACT_MATCH1
#defineINEXACT_MATCH0
//是不是数字
intIsNumeric(constchar*ccharptr_CharacterList)
{
for(;*ccharptr_CharacterList;ccharptr_CharacterList++)
if(*ccharptr_CharacterList<'0'||*ccharptr_CharacterList>'9')return0;//false
return1;//true
}
//intCaseSensitive=0大小写不敏感
intstrcmp_Wrapper(constchar*s1,constchar*s2,intintCaseSensitive)
{
if(intCaseSensitive)
return!
strcmp(s1,s2);
else
return!
strcasecmp(s1,s2);
}
//intCaseSensitive=0大小写不敏感
intstrstr_Wrapper(constchar*haystack,constchar*needle,intintCaseSensitive)
{
if(intCaseSensitive)
return(int)strstr(haystack,needle);
else
return(int)strcasestr(haystack,needle);
}
#ifdef__cplusplus
pid_tGetPIDbyName(constchar*cchrptr_ProcessName,intintCaseSensitiveness,intintExactMatch)
#else
pid_tGetPIDbyName_implements(constchar*cchrptr_ProcessName,intintCaseSensitiveness,intintExactMatch)
#endif
{
charchrarry_CommandLinePath[100];
charchrarry_NameOfProcess[300];
char*chrptr_StringToCompare=NULL;
pid_tpid_ProcessIdentifier=(pid_t)-1;
structdirent*de_DirEntity=NULL;
DIR*dir_proc=NULL;
int(*CompareFunction)(constchar*,constchar*,int);
if(intExactMatch)
CompareFunction=&strcmp_Wrapper;
else
CompareFunction=&strstr_Wrapper;
dir_proc=opendir(PROC_DIRECTORY);
if(dir_proc==NULL)
{
perror("Couldn'topenthe"PROC_DIRECTORY"directory");
return(pid_t)-2;
}
//LoopwhilenotNULL
while((de_DirEntity=readdir(dir_proc)))
{
if(de_DirEntity->d_type==DT_DIR)
{
if(IsNumeric(de_DirEntity->d_name))
{
strcpy(chrarry_CommandLinePath,PROC_DIRECTORY);
strcat(chrarry_CommandLinePath,de_DirEntity->d_name);
strcat(chrarry_CommandLinePath,"/cmdline");
FILE*fd_CmdLineFile=fopen(chrarry_CommandLinePath,"rt");//openthefileforreadingtext
if(fd_CmdLineFile)
{
fscanf(fd_CmdLineFile,"%s",chrarry_NameOfProcess);//readfrom/proc//cmdline
fclose(fd_CmdLineFile);//closethefilepriortoexitingtheroutine
if(strrchr(chrarry_NameOfProcess,'/'))
chrptr_StringToCompare=strrchr(chrarry_NameOfProcess,'/')+1;
else
chrptr_StringToCompare=chrarry_NameOfProcess;
//printf("Processname:
%s\n",chrarry_NameOfProcess);
//这个是全路径,比如/bin/ls
//printf("PureProcessname:
%s\n",chrptr_StringToCompare);
//这个是纯进程名,比如ls
//这里可以比较全路径名,设置为chrarry_NameOfProcess即可
if(CompareFunction(chrptr_StringToCompare,cchrptr_ProcessName,intCaseSensitiveness))
{
pid_ProcessIdentifier=(pid_t)atoi(de_DirEntity->d_name);
closedir(dir_proc);
returnpid_ProcessIdentifier;
}
}
}
}
}
closedir(dir_proc);
returnpid_ProcessIdentifier;
}
#ifdef__cplusplus
pid_tGetPIDbyName(constchar*cchrptr_ProcessName)
{
returnGetPIDbyName(cchrptr_ProcessName,CASE_INSENSITIVE,EXACT_MATCH);
}
#else
//Ccannotoverloadfunctions-fixed
/*这里是原文的实现,但貌似需要某些牛X的设置,因不需要,删之
pid_tGetPIDbyName_Wrapper(constchar*cchrptr_ProcessName,...)
{
intintTempArgument;
intintInputArguments[2];
//intInputArguments[0]=0;
//intInputArguments[1]=0;
memset(intInputArguments,0,sizeof(intInputArguments));
intintInputIndex;
va_Listargptr;
va_start(argptr,cchrptr_ProcessName);
for(intInputIndex=0;(intTempArgument=va_arg(argptr,int))!
=15;++intInputIndex)
{
intInputArguments[intInputIndex]=intTempArgument;
}
va_end(argptr);
returnGetPIDbyName_implements(cchrptr_ProcessName,intInputArguments[0],intInputArguments[1]);
}
#defineGetPIDbyName(ProcessName,...)GetPIDbyName_Wrapper(ProcessName,##__VA_ARGS__,(int)15)
*/
//简单实现
pid_tGetPIDbyName_Wrapper(constchar*cchrptr_ProcessName)
{
returnGetPIDbyName_implements(cchrptr_ProcessName,0,0);//大小写不敏感}
#endif
intmain()
{
pid_tpid=GetPIDbyName_Wrapper("bash");//If-1=notfound,if-2=procfsaccesserror
printf("PID%d\n",pid);
returnEXIT_SUCCESS;
}
通过比较全路径,能一定程度上避免第1种方法的问题。
以下是整理后的C语言实现:
#include
#include
#include//foropendir(),readdir(),closedir()
#include//forstat()
#include
#include
#include
#include
#definePROC_DIRECTORY"/proc/"
#defineCASE_SENSITIVE1
#defineCASE_INSENSITIVE0
#defineEXACT_MATCH1
#defineINEXACT_MATCH0
//是不是数字
intIsNumeric(constchar*ccharptr_CharacterList)
{
for(;*ccharptr_CharacterList;ccharptr_CharacterList++)
if(*ccharptr_CharacterList<'0'||*ccharptr_CharacterList>'9')
return0;//false
return1;//true
}
//intCaseSensitive=0大小写不敏感
intstrcmp_Wrapper(constchar*s1,constchar*s2,intintCaseSensitive)
{
if(intCaseSensitive)
return!
strcmp(s1,s2);
else
return!
strcasecmp(s1,s2);
}
//intCaseSensitive=0大小写不敏感
intstrstr_Wrapper(constchar*haystack,constchar*needle,intintCaseSensitive)
{
if(intCaseSensitive)
return(int)strstr(haystack,needle);
else
return(int)strcasestr(haystack,needle);
}
pid_tGetPIDbyName_implements(constchar*cchrptr_ProcessName,intintCaseSensitiveness,intintExactMatch)
{
charchrarry_CommandLinePath[100];
charchrarry_NameOfProcess[300];
char*chrptr_StringToCompare=NULL;
pid_tpid_ProcessIdentifier=(pid_t)-1;
structdirent*de_DirEntity=NULL;
DIR*dir_proc=NULL;
int(*CompareFunction)(constchar*,constchar*,int);
if(intExactMatch)
CompareFunction=&strcmp_Wrapper;
else
CompareFunction=&strstr_Wrapper;
dir_proc=opendir(PROC_DIRECTORY);
if(dir_proc==NULL)
{
perror("Couldn'topenthe"PROC_DIRECTORY"directory");
return(pid_t)-2;
}
//LoopwhilenotNULL
while((de_DirEntity=readdir(dir_proc)))
{
if(de_DirEntity->d_type==DT_DIR)
{
if(IsNumeric(de_DirEntity->d_name))
{
strcpy(chrarry_CommandLinePath,PROC_DIRECTORY);
strcat(chrarry_CommandLinePath,de_DirEntity->d_name);
strcat(chrarry_CommandLinePath,"/cmdline");
FILE*fd_CmdLineFile=fopen(chrarry_CommandLinePath,"rt");//open
thefileforreadingtext
if(fd_CmdLineFile)
{
fscanf(fd_CmdLineFile,"%s",chrarry_NameOfProcess);//readfrom/proc//cmdline
fclose(fd_CmdLineFile);//closethefilepriortoexitingtheroutine
if(strrchr(chrarry_NameOfProcess,'/'))
chrptr_StringToCompare=strrchr(chrarry_NameOfProcess,'/')+1;
else
chrptr_StringToCompare=chrarry_NameOfProcess;
//printf("Processname:
%s\n",chrarry_NameOfProcess);
//这个是全路径,比如/bin/ls
//printf("PureProcessname:
%s\n",chrptr_StringToCompare);
//这个是纯进程名,比如ls
//这里可以比较全路径名,设置为chrarry_NameOfProcess即可
if(CompareFunction(chrptr_StringToCompare,cchrptr_ProcessName,intCaseSensitiveness))
{
pid_ProcessIdentifier=(pid_t)atoi(de_DirEntity->d_name);
closedir(dir_proc);
returnpid_ProcessIdentifier;
}
}
}
}
}
closedir(dir_proc);
returnpid_ProcessIdentifier;
}
//简单实现
pid_tGetPIDbyName_Wrapper(constchar*cchrptr_ProcessName)
{
returnGetPIDbyName_implements(cchrptr_ProcessName,0,0);//大小写不敏感}
intmain()
{
pid_tpid=GetPIDbyName_Wrapper("bash");//If-1=notfound,if-2=procfsaccesserror
printf("PID%d\n",pid);
returnEXIT_SUCCESS;
}
通过比较全路径,一定程度上避免了1的问题。