링크 ux 의 daemon 프로 세 스

23421 단어 Daemon
http://www.cublog.cn/u3/100661/showart_2091898.html
#include
 
int daemon(int nochdir,int noclose)
 
엘 프 프로 세 스 를 만 들 때 엘 프 프로 세 스 의 작업 디 렉 터 리 를 '/' 루트 디 렉 터 리 로 변경 해 야 합 니 다.
 
또한 표준 입력, 출력, 오류 출력 을 / dev / null 로 재 설정 합 니 다.
 
daemon 의 역할 은 인자 nochdir 가 0 일 때 루트 디 렉 터 리 를 작업 디 렉 터 리 로 변경 하 는 것 입 니 다.
 
noclose 가 0 일 때 입력, 출력 및 오류 출력 을 / dev / null 로 재 설정 합 니 다.
 
실행 성공 반환 0
 
오류 반환 - 1
 
 
<-----------------------------------------> daemon

#include <unistd.h>
int main(int argc, char *argv[])
{
    ...
    if (daemon(0, 0)) {// glibc daemon, daemon
        perror("daemon");
        return -1;
    }
     daemon [luther.gliethttp].
    ...
}
=========================================================
int daemon( int nochdir, int noclose )
{
   pid_t pid;

   if ( !nochdir && chdir("/") != 0 )// nochdir=0, "/"
       return -1;
   
   if ( !noclose )// close
   {
     int fd = open("/dev/null", O_RDWR);// .

     if ( fd < 0 )
      return -1;

// , fds :0,1 2 fops ,
//fdt->fd[0],fdt->fd[1],fdt->fd[2],
// , , [luther.gliethttp].
// open , 3 , open 3[luther.gliethttp].
//dup2(unsigned int oldfd, unsigned int newfd) oldfd fops file, newfd
// :fdt->fd[newfd] = fdt->fd[oldfd];
     if ( dup2( fd, 0 ) < 0 || // /dev/null fops , 0 .
     dup2( fd, 1 ) < 0 || // /dev/null fops , 1 .
          dup2( fd, 2 ) < 0 ) // /dev/null fops , 2 .
     {
       close(fd);
      return -1;
     }
// , , 0,1,2 fops ,
// "/dev/null" fops. 0,1,2 , /dev/null .
     close(fd);// /dev/null
  }
  
   pid = fork();// .
   if (pid < 0)
    return -1;

   if (pid > 0)
    _exit(0);// , , .

//ok, daemon .
   if ( setsid() < 0 )// session id.
     return -1;

   return 0;// daemon [luther.gliethttp].
}

http://docs.linuxtone.org/ebooks/C&CPP/c/ch34s03.html
http://blog.csdn.net/yyyzlf/article/details/5267954
 
데 몬 의 특성 상 데 몬 프로그램 을 만 들 려 면 일정한 규칙 을 지 켜 야 합 니 다.이 절 은 이러한 규칙 의 요점 을 논술 하고 관련 코드 를 제시 할 것 이다.
8.2.1  데 몬 구현 절차
Linux 시스템 에서 데 몬 을 프로 그래 밍 하려 면 다음 절 차 를 지 켜 야 합 니 다.
1. init 프로 세 스 를 새로 만 든 부모 프로 세 스 로 만 듭 니 다.
fork 함 수 를 호출 하여 하위 프로 세 스 를 만 든 후 부모 프로 세 스 를 즉시 종료 합 니 다.이렇게 하면 발생 하 는 하위 프로 세 스 는 고아 프로 세 스 가 되 고 init 프로 세 스 에 의 해 인수 되 며, 동시에 발생 하 는 새로운 프로 세 스 는 배경 에서 실 행 됩 니 다.
2. setsid 함수 호출
setsid 함 수 를 호출 하여 새로 만 든 프로 세 스 를 제어 터미널 에서 벗 어 나 게 하고 새로운 프로 세 스 그룹 을 만 들 며 이 프로 세 스 그룹의 첫 번 째 프로 세 스 가 됩 니 다.독자 들 이 이 절 차 를 잘 이해 하도록 프로 세 스 팀, 세 션 (session) 의 기본 개념 을 소개 한다.
리 눅 스 시스템 에서 모든 프로 세 스 는 각자 의 프로 세 스 그룹 에 속한다.프로 세 스 그룹 은 하나 이상 의 프로 세 스 의 집합 입 니 다.예 를 들 어 어떤 반 은 프로 세 스 팀 이 고 그 중의 구성원 은 프로 세 스 라 고 볼 수 있다.한 반 에 적어도 한 명의 구성원 이 있다.한 반 의 마지막 구성원 이 존재 하지 않 을 때 이 반 도 존재 하지 않 는 다. 즉, 프로 세 스 팀 이 사라 진 것 이다.
모든 프로 세 스 그룹 은 프로 세 스 번호 와 유사 한 표 지 를 가지 고 있 으 며 프로 세 스 그룹 ID 라 고 합 니 다.프로 세 스 그룹 ID 는 선두 프로 세 스 의 프로 세 스 번호 에 의 해 결정 되 며, 모든 프로 세 스 그룹 에는 선두 프로 세 스 가 존재 합 니 다.프로 세 스 그룹의 존재 여 부 는 선두 프로 세 스 가 존재 하 는 지 여부 와 관계 가 없습니다.
세 션 은 하나 이상 의 프로 세 스 그룹의 집합 입 니 다.프로 세 스 그룹 과 유사 합 니 다. 세 션 마다 선두 프로 세 스 가 존재 합 니 다.리 눅 스 는 여러 사용자 의 운영 체제 로 같은 시간 에 서로 다른 사용자 에 속 하 는 여러 프로 세 스 가 존재 합 니 다.만약 에 사용자 가 특정한 터미널 에서 특정한 신 호 를 보 냈 다 면 예 를 들 어 'Ctrl + C' 를 누 르 고 SIGINT 신 호 를 보 내 면 어떻게 신호 가 해당 하 는 프로 세 스 로 정확하게 전송 되 는 지 확인 하 는 동시에 다른 터미널 을 사용 하 는 사용자 의 프로 세 스 에 영향 을 주지 않 습 니까?
세 션 과 프로 세 스 그룹 은 리 눅 스 커 널 이 여러 사용자 의 경우 사용자 프로 세 스 를 관리 하 는 방법 입 니 다.모든 프로 세 스 는 하나의 프로 세 스 그룹 에 속 하고, 프로 세 스 그룹 은 또 하나의 세 션 에 속한다.사용자 가 터미널 로그 인 시스템 (터미널 이 든 가짜 터미널 이 든) 에서 시스템 은 새로운 세 션 을 만 들 것 입 니 다.이 터미널 에서 시작 하 는 프로 세 스 는 세 션 의 프로 세 스 그룹 으로 시스템 에 의 해 분 리 됩 니 다.
세 션 의 프로 세 스 는 이 세 션 의 선두 프로 세 스 를 통 해 터미널 과 연 결 됩 니 다.이 단말 기 는 세 션 의 제어 단말기 입 니 다.하나의 세 션 은 하나의 제어 단말기 만 있 을 수 있 고, 반대로 같다.세 션 에 제어 터미널 이 존재 한다 면 프론트 프로 세 스 그룹 이 있 을 것 입 니 다.이 그룹 에 속 하 는 프로 세 스 는 제어 단말기 에서 입력 을 받 을 수 있 습 니 다.이 때 다른 프로 세 스 그룹 은 백 엔 드 프로 세 스 그룹 입 니 다.그림 8.3 은 세 션, 프로 세 스 그룹, 프로 세 스 와 제어 단말기 간 의 관 계 를 보 여 준다.
그림 8.3  세 션, 프로 세 스 그룹, 프로 세 스 와 제어 단말기 의 관계
데 몬 이 터미널 을 제어 하지 않 았 기 때문에 fork 함수 로 만 든 하위 프로 세 스 는 부모 프로 세 스 의 제어 터미널, 세 션, 프로 세 스 그룹 을 계승 합 니 다. 따라서 부모 프로 세 스 의 영향 에서 벗 어 나 기 위해 새로운 세 션 을 만들어 야 합 니 다.Linux 시스템 은 새 세 션 을 만 드 는 데 setsid 함 수 를 제공 합 니 다.setsid 함수 의 정 보 는 표 8.1 과 같다.
시계                                                              setsid 함수
헤더 파일

함수 형식
pid_t setsid(void);
반환 값
성공 하 다.
실패 하 다.
errno 설정 여부
프로 세 스 의 세 션 ID 호출
−1
예.
setsid 함 수 는 새 세 션 을 만 들 고 setsid 함 수 를 호출 하 는 프로 세 스 를 새 세 션 의 선두 프로 세 스 로 만 듭 니 다.setsid 함 수 를 호출 하 는 프로 세 스 는 세 션 을 새로 만 드 는 유일한 프로 세 스 그룹 입 니 다. 프로 세 스 그룹 ID 는 프로 세 스 를 호출 하 는 프로 세 스 번호 입 니 다.setsid 함수 가 이 결 과 를 만 드 는 데 는 프로 세 스 가 프로 세 스 의 선두 프로 세 스 가 아 닌 조건 이 있 습 니 다.첫 번 째 단계 에서 fork 를 호출 하 는 부모 프로 세 스 가 종료 되 었 기 때문에 하위 프로 세 스 가 프로 세 스 그룹의 선두 프로 세 스 가 될 수 없습니다.이 세 션 의 선두 프로 세 스 는 터미널 과 연결 되 는 것 을 제어 하지 않 았 다.이로써 데 몬 이 터미널 을 제어 하지 않 았 다 는 요 구 를 만족 시 켰 습 니 다.
3. 현재 작업 디 렉 터 리 변경
fork 함수 로 생 성 된 하위 프로 세 스 는 부모 프로 세 스 의 현재 작업 디 렉 터 리 를 계승 합 니 다.프로 세 스 가 끝나 지 않 았 을 때 작업 디 렉 터 리 는 마 운 트 해제 할 수 없습니다.이러한 문 제 를 방지 하기 위해 데 몬 은 작업 디 렉 터 리 를 루트 디 렉 터 리 (/ 디 렉 터 리) 로 변경 합 니 다.작업 디 렉 터 리 변경 에 사용 할 함 수 는 chdir 입 니 다.
4. 파일 설명 자 를 닫 고 표준 입력, 출력, 오류 출력 으로 바 꿉 니 다.
새로 생 성 된 프로 세 스 는 부모 프로 세 스에 서 열 린 파일 설명 자 를 계승 합 니 다. 이 파일 설명 자 를 사용 하지 않 으 면 닫 아야 합 니 다.데 몬 은 시스템 배경 에서 실 행 됩 니 다. 터미널 에 출력 정보 가 있어 서 는 안 됩 니 다.dup 함 수 를 사용 하여 표준 입 출력 과 오류 출력 을 / dev / null 장치 로 재 설정 할 수 있 습 니 다 (/ dev / null 은 빈 장치 이 며 데 이 터 를 기록 하 는 데 아무런 출력 이 없습니다).다음은 구체 적 인 코드 를 드 리 겠 습 니 다.

      int fd;
      //표준 입 출력 을 빈 장치 로 재 설정 합 니 다.
      fd = open ("/dev/null", O_RDWR, 0);
      if (fd != -1)
    {
      dup2 (fd, STDIN_FILENO);
      dup2 (fd, STDOUT_FILENO);
      dup2 (fd, STDERR_FILENO);
      if (fd > 2)
        close (fd);
    }

5. 데 몬 의 파일 권한 을 설정 하여 마스크 만 들 기
데 몬 은 임시 파일 을 만 드 는 경우 가 많 습 니 다. 보안 을 고려 하여 다른 사용자 가 보 기 를 원 하지 않 는 경우 가 많 습 니 다. 이 때 는 umask 함수 로 파일 권한 을 수정 하고 마스크 의 값 을 만들어 데 몬 의 요 구 를 만족 시 킬 수 있 습 니 다.
8.2.2  데 몬 구현
이 절 은 데 몬 생 성 을 위 한 인 스 턴 스 를 제공 합 니 다. 프로그램 p8.1. c 에 서 는 데 몬 함 수 를 정의 하여 데 몬 생 성 을 실현 합 니 다. 생 성 사상 은 8.2.1 에 상세 하 게 소개 되 어 있 습 니 다. 프로그램의 구체 적 인 코드 는 다음 과 같 습 니 다.
/ / p8.1. c 데 몬 의 실현
#include
#include
#include
#include
#include
/ * daemon 함 수 는 호출 함수 의 프로 세 스 를 데 몬 으로 바 꾸 는 데 사 용 됩 니 다 * /
int
daemon (int nochdir, int noclose)
{
  pid_t pid;
  pid = fork ();
  /* 프로 세 스 를 만 드 는 데 실패 하면 * /
  if (pid < 0)
    {
      perror ("fork");
      return -1;
    }
  /* 부모 프로 세 스 실행 종료 * /
  if (pid != 0)
    exit (0);
  /* 세 션 선두 프로 세 스 가 되 기 * /
  pid = setsid();
  if (pid < -1)
    {
      perror ("setsid");
      return -1;
    }
  /* 작업 디 렉 터 리 를 루트 디 렉 터 리 로 수정 * /
  if (! nochdir)
    chdir ("/");
  /* 표준 입 출력 을 빈 장치 로 재 설정 * /
  if (! noclose)
    {
      int fd;
      fd = open ("/dev/null", O_RDWR, 0);
      if (fd != -1)
    {
      dup2 (fd, STDIN_FILENO);
      dup2 (fd, STDOUT_FILENO);
      dup2 (fd, STDERR_FILENO);
      if (fd > 2)
        close (fd);
    }
    }
  umask (0027);
  return 0;
}
int main(void)
{
      daemon(0,0);
      sleep(1000);
   
      return 0;
}  
gcc 로 p8.1. c 를 컴 파일 하여 p8.1 이라는 실행 가능 한 파일 을 얻 습 니 다. 이 프로그램 을 실행 하면 프로그램 은 데 몬 상태 로 실 행 됩 니 다. 그림 8.4 참조.

좋은 웹페이지 즐겨찾기