1 Articles, Search Results for 'Signal

  1. 2008/02/03 Unix Signal 처리 by 소리나는연탄

Unix Signal 처리

2008/02/03 00:31 / Resource
SIGPIPE signal 처리

* Scenario: server가 다른 작업을 수행중인 동안 client가 종료한 경우 client는 server로 FIN packet을 전송한다. server가 client가 종료한 것을 모르는 상태에서 socket에 write를 하는경우 client쪽 TCP는 RST packet을 전송한다. server가 RST packet을 수신한 상태에서 다시 socket에 write를 하는 경우 SIGPIPE signal을 받게된다.

* FIN packet을 수신한 상태에서 socket을 read 하는 경우: EOF(0)
* RST packet을 수신한 상태에서 socket을 read 하는 경우: error (ECONNRESET)

* FIN packet을 수신한 상태에서 socket에 write를 하는 경우는 error가 아니지만 RST packet을 수신한 상태에서 socket에 write를 하는 경우는 error (EPIPE)

* SIGPIPE signal 처리
- SIGPIPE signal을 ignore (SIG_IGN)한다.
- write에서 return 되는 error (EPIPE)를 처리한다.



SIGCHLD signal 처리
* fork를 사용하여 child process를 생성하는 경우 parent process는 child process를 wait하여 child process가 zombie가 되는 것을 막아야 한다. 일반적으로 SIGCHLD 처리 함수안에서 waitpid 함수를 사용하여 child process가 zombie가 되는 것을 막는다.

* waitpid함수의 pid value를 -1을 사용하면 종료된 첫번째 child process를 wait하며 WNOHANG option을 사용하면 종료된 child process가 없더라도 waitpid 함수에서 block되는 것을 막을 수 있다.

* accept, read, write, select, open 과 같은 함수를 호출하는 중간에 SIGCHLD signal을 받아 interrupt된 경우 EINTR errno를 받게되며 이러한 경우 다시 위의 함수를 호출하면 된다. 하지만, connect 함수를 호출하는 중간에 interrupt된 경우 socket함수부터 다시 시작해야 한다.

* accept 함수를 사용하는 경우 block되는 것을 방지하기 위해서는 listening socket을 nonblocking으로 setting하며 EWOULDBLOCK, ECONNABORTED, EPROTO, EINTR error는 무시한다.

* 출처: UNIX Network Programming V.1 by W. Richard Stevens




◈ SIGHUP
- 터미널 인터페이스에 의해 연결의 단절이 감지되면 해당 제어 터미널과 연결된 제어 프로세스(세션 리더)에게 전달
- 세션 리더가 종료했을 때도 발생하는데 이때는 foreground 프로세스 그룹내의 모든 프로세스들에게 전달
- SIGHUP 시그널은 원래 모뎀 연결 끊김 등의 시리얼 라인이 끊어지면 발생하는 시그널이다.
- 이름 있는 시스템 데몬들은 SIGHUP 시그널을 configure file을 다시 읽어들이는 등의 초기화 신호로 해석한다.
  . bootp(8), gated(8), inetd(8), mountd(8), named(8), nfsd(8), ypbind(8)
  . pppd(8) 처럼 SIGHUP을 원래의 의도에 충실하게 세션 종료의 뜻으로 받아들이는 사례도 간혹 있는데, 요새는 보편적으로 이 역할을 SIGTERM이 맡는다.
  . daemon은 제어 단말기 없이 돌기 때문에 kernel로부터 SIGHUP 신호를 수신하지 못한다.
    그러므로 많은 daemon은 이 신호를 daemon의 구성 파일이 변경되어 daemon이 그 파일을 새로 읽어야 된다는 것을 알려주는 관리자로부터의 통지로 사용한다.
  . daemon이 수신할 수 없는 다른 두 개의 신호로 SIGINT와 SIGWINCH가 있고 이들도 역시 어떤 변화를 daemon에게 통지하기 위해 사용될 수 있다.

◈ SIGINT
- 인터럽트 키 (DELETE 또는 Control-C)가 눌렸을 때 발생

◈ SIGQUIT
- Control-backslash 에 의해 발생

◈ SIGCHLD
- 프로세스가 종료하거나 정지하면, 부모 프로세스에게 전달된다.
- 부모 프로세스는 wait() 시스템 콜을 사용하여 무슨 일이 일어났는지 알아본다.
- 이 시그널에 대한 default 처리는 무시하는 것이다. 즉 프로세스가 이 신호를 받으려고 할 때만 전달된다.

◈ SIGSEGV
- 유효하지 않은 가상 메모리 주소를 참조하거나 사용 권한이 없는 메모리에 접근할 때 프로세스로 전달된다.

◈ SIGTERM
- kill 명령에 의해 기본적으로 발생

◈ SIGKILL
- "극단의 조치(extreme prejudice)"로 프로그램을 종료하는 데 사용된다.
- 시그널 catch 하거나 무시할 수 없다.

◈ SIGALRM
- alarm()이나 setitimer() 시스템 콜로 설정한 알람 시간이 초과 했을 때 프로세스로 전달된다.

◈ SIGTSTP
-
Control-Z 키에 의해 발생
- 기본 처리 방법은 SIGCONT 신호를 받을 때까지 프로세스를 중단한다.

◈ SIGCONT
-
정지한 프로세스를 계속 실행시키려 할 때 발생
- 이 신호는 받을 수 있지만 블록하거나 무시할 수 없다.
- 기본 처리 방법은 중단된 프로세스를 재시작하는 것이다. 그러나 프로세스가 신호를 받지 않는다면 신호를 버린다.
- vi 에디터를 사용할 때
. Control-Z 를 눌러 수행을 잠시 정지시키면 쉘이 키 입력을 처리하게 되는데
. 이때 fg 명령을 실행시키면 쉘은 vi 에게 SIGCONT 시그널을 전달하며
. vi는 이 시그널에 대한 처리로 화면을 다시 그리고 사용자 키 입력을 받는 상태로 돌아간다.

◈ SIGSTOP
-
SIGTSTP과 동일하나 catch 하거나 무시할 수 없다.
- 이 신호를 받으면 무조건 SIGCONT 신호를 받을 때까지 프로세스를 중단한다.

◈ SIGABRT
-
abort() 함수의 호출로 발생

◈ SIGBUS
-
하드웨어 결함으로 발생

◈ SIGEMT
-
하드웨어 결함으로 발생

SIGFPE
-
divide-by-0나 부동 소숫점 오버플로우와 같은 산술 연산 오류에서 발생

◈ SIGILL

◈ SIGINFO

◈ SIGIO

◈ SIGIOT

◈ SIGPIPE
-
pipe 통신에서 수신 프로세스가 종료했을 때 송신 프로세스가 파이프에 write 하면 발생
- 프로세스가 RST를 받은 소켓에 데이터를 쓰면, 커널은 그 프로세스에 ISGPIPE 신호를 보낸다.
- 이 신호의 기본 동작은 프로세스를 종료시키는 것이므로, 프로세스가 원하지 않는 종료를 피하기 위해서는 이 신호를 포착해야 한다.

◈ SIGPOLL

◈ SIGROF

◈ SIGPWR

◈ SIGSYS

◈ SIGTTIN
-
background에 있는 프로세스가 제어 터미널로부터의 읽기를 시도한다.

◈ SIGTTOU
-
background에 있는 프로세스가 제어 터미널로부터의 쓰기를 시도한다.

◈ SIGURG
-
SIGIO와 SIGURG 라는 두 개의 신호는 소켓이 F_SETOWN 명령으로 소유주에게 할당되었을 때만 소켓에 대해 발생한다.

◈ SIGUSR1

◈ SIGUSR2

◈ SIGVTALRM

◈ SIGWINCH

◈ SIGXCPU

◈ SIGXFSZ
크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기
Posted by 소리나는연탄.
TAGS ,

Leave your greetings here.