리눅스에서 자신이 만든 프로그램이 하나만 동작 해야 하는데, 두개가 동시에 동작되어 테스트가 실패되거나 프로그램에서 오류현상이 발생하는 경우가 있다.
리눅스 콘솔 프로그램등의 경우 백그라운드로 구동되면 사용자는 ps 명령을 통해서 확인해보지 않는 동시에 동작하면 안되는 하나이상의 프로그램이 동작되고 있는 상태를 확인하지 못한다. 따라서 하나만 구동되어야 하는 데몬이나 또는 자신이 만든 프로그램의 오류를 막기 위해서 그것도 아니면, 특정 프로세스를 다른프로세스에서 강제 종료한다거나 하는 용도의 기능이 필요하게 된다.
다음의 예제는 그러한 경우 유용하게 사용할 수 있는 예제이다. 필자도 더러 이용하는 코드이다.
출처 : embeddedclub.net
1. 소스
아래의 get_process_id는 사용자로 부터 받은 문자열을 /proc에서 디렉터리의 끝까지 반복하여 검사한다. 리눅스에서 동작되는 각 프로세스의 정보는 /proc아래에 생성되고 추가적인 정보를 읽을 수 있다.
// Embeddedclub.net Sample Code
// Auth : embeddedclub.net
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <fcntl.h>
#include <dirent.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
unsigned int get_process_id(char *p_processname);
int main(int argc, char** argv)
{
int retv=0;
retv = get_process_id(argv[1]);
if(retv<1)
{
printf("%s process not found!\n",argv[1]);
return -1;
}
printf("%s process ID is %d.\n",argv[1],retv);
return 0;
}
unsigned int get_process_id(char *p_processname)
{
DIR *dir_p;
struct dirent *dir_entry_p;
char dir_name[40]; // ??? buffer overrun potential
char target_name[252]; // ??? buffer overrun potential
int target_result;
char exe_link[252];
int errorcount;
int result;
errorcount=0;
result=0;
// Open /proc/ directory
dir_p = opendir("/proc/");
// Reading /proc/ entries
while(NULL != (dir_entry_p = readdir(dir_p)))
{
// Checking for numbered directories
if (strspn(dir_entry_p->d_name, "0123456789") == strlen(dir_entry_p->d_name))
{
strcpy(dir_name, "/proc/");
strcat(dir_name, dir_entry_p->d_name);
strcat(dir_name, "/");
exe_link[0] = 0;
strcat(exe_link, dir_name);
// Getting the full-path of that exe link
strcat(exe_link, "exe");
target_result = readlink(exe_link, target_name, sizeof(target_name)-1);
// Getting the target of the exe ie to which binary it points to
if (target_result > 0)
{
target_name[target_result] = 0;
if (strstr(target_name, p_processname) != NULL)
{
// Searching for process name in the target name -- ??? could be a better search !!!
result = atoi(dir_entry_p->d_name);
//printf("getProcessID(%s) :Found. id = %d\n", p_processname, result);
closedir(dir_p);
return result;
}
}
}
}
closedir(dir_p);
// printf("getProcessID(%s) : id = 0 (could not find process)\n", p_processname);
return result;
}
2. 실행결과
실행 결과는 다음과 같다. 먼저 소스를 컴파일하고, ps 명령을 통해 확인해보니 PID값 4623에 bash가 실행되고 있다는 것을 확인할 수 있다. bash는 지금 표시되는 터미널 쉘(명령창)이다. 컴파일된 readdir_ex를 통해 bash라고 입력하면 프로세스가 확인되고 프로세스 번호를 출력하는 것을 확인할 수 있다. 이러한 프로그램은 프로그램 시작전에 동일한 프로그램이 구동되고 있는지, 혹은 종료할때 함께 종료시킬 프로그램의 PID값을 가져오는데 사용하면 유용하다.
... 끝.
최근댓글