디시인사이드 갤러리

갤러리 이슈박스, 최근방문 갤러리

갤러리 본문 영역

제미니랑 작성한 Ada 코드: posix 시그널 래퍼

나르시갤로그로 이동합니다. 2025.07.23 18:28:10
조회 29 추천 0 댓글 0

네, 우리가 함께 완성한 POSIX 시그널 처리 라이브러리의 전체 소스 코드를 재출력합니다.

이 코드는 다음과 같은 파일들로 구성됩니다.

  1. posix-c.ads: C 기본 타입 및 시그널 상수 정의
  2. posix-unistd.ads / adb: pipe, read, write  unistd 함수 래퍼
  3. posix-signals.ads / adb: sigaction 함수 저수준 래퍼
  4. posix-signal_handler.ads / adb: 최종 고수준 시그널 핸들러 (듀얼 모델 지원)

1. posix-c.ads

-- posix-c.ads

with Interfaces.C;

package POSIX.C is
  pragma Preelaborate;

  type C_int is new Interfaces.C.int;
  type PID_T is new C_int;

  type Signal_Number is new C_int;

  -- Standard Signal Numbers
  SIGHUP    : constant Signal_Number := 1;
  SIGINT    : constant Signal_Number := 2;
  SIGQUIT   : constant Signal_Number := 3;
  SIGILL    : constant Signal_Number := 4;
  SIGTRAP   : constant Signal_Number := 5;
  SIGABRT   : constant Signal_Number := 6;
  SIGKILL   : constant Signal_Number := 9;
  SIGSEGV   : constant Signal_Number := 11;
  SIGPIPE   : constant Signal_Number := 13;
  SIGALRM   : constant Signal_Number := 14;
  SIGTERM   : constant Signal_Number := 15;
  SIGUSR1   : constant Signal_Number := 10;
  SIGUSR2   : constant Signal_Number := 12;
  SIGCHLD   : constant Signal_Number := 17;
  SIGCONT   : constant Signal_Number := 18;
  SIGSTOP   : constant Signal_Number := 19;

  -- Return codes
  SUCCESS : constant C_int := 0;
  FAILURE : constant C_int := -1;

end POSIX.C;

2. posix-unistd.ads

-- posix-unistd.ads

with Ada.Streams;
with Interfaces.C;

package POSIX.Unistd is

  -- Custom exception for POSIX errors
  POSIX_Error : exception;

  -- Type-safe declarations for common identifiers
  type File_Descriptor is new Interfaces.C.int;
  type Process_ID      is new Interfaces.C.int;
  type User_ID         is new Interfaces.C.unsigned;
  type Group_ID        is new Interfaces.C.unsigned;

  -- Standard file descriptors
  STDIN_FD  : constant File_Descriptor := 0;
  STDOUT_FD : constant File_Descriptor := 1;
  STDERR_FD : constant File_Descriptor := 2;

  -- For the pipe() system call
  type Pipe_Ends is record
    Read_End  : File_Descriptor;
    Write_End : File_Descriptor;
  end record;


  -- Process identifier functions
  function get_process_id return Process_ID;
  function get_parent_process_id return Process_ID;
  function fork return Process_ID;

  -- I/O operations
  procedure close_file (fd : in File_Descriptor);
  function read_from
    (fd     : in File_Descriptor;
     buffer : in out Ada.Streams.Stream_Element_Array
  ) return Natural;

  function write_to
    (fd     : in File_Descriptor;
     buffer : in Ada.Streams.Stream_Element_Array
  ) return Natural;

  -- Pipe creation
  procedure create_pipe (ends : out Pipe_Ends);

end POSIX.Unistd;

3. posix-unistd.adb

-- posix-unistd.adb

with Interfaces.C;
with System;

package body POSIX.Unistd is

  -- § Low-level C bindings (private to this package body)
  -------------------------------------------------------
  package C is
    function c_getpid return Process_ID;
    pragma Import (C, c_getpid, "getpid");

    function c_getppid return Process_ID;
    pragma Import (C, c_getppid, "getppid");

    function c_fork return Process_ID;
    pragma Import (C, c_fork, "fork");

    function c_close (fd : File_Descriptor) return Interfaces.C.int;
    pragma Import (C, c_close, "close");

    function c_pipe (fds : System.Address) return Interfaces.C.int;
    pragma Import (C, c_pipe, "pipe");

    function c_read
      (fd  : File_Descriptor;
       buf : System.Address;
       len : Interfaces.C.size_t)
       return Interfaces.C.long; -- ssize_t
    pragma Import (C, c_read, "read");

    function c_write
      (fd  : File_Descriptor;
       buf : System.Address;
       len : Interfaces.C.size_t)
       return Interfaces.C.long; -- ssize_t
    pragma Import (C, c_write, "write");
  end C;

  -- § High-level Ada wrappers
  ---------------------------

  function get_process_id return Process_ID is
  begin
    return C.c_getpid;
  end get_process_id;

  function get_parent_process_id return Process_ID is
  begin
    return C.c_getppid;
  end get_parent_process_id;

  function fork return Process_ID is
    pid : constant Process_ID := C.c_fork;
  begin
    if pid < 0 then
      raise POSIX_Error with "fork failed";
    end if;
    return pid;
  end fork;

  procedure close_file (fd : in File_Descriptor) is
  begin
    if C.c_close (fd) /= 0 then
      raise POSIX_Error with "close failed";
    end if;
  end close_file;

  procedure create_pipe (ends : out Pipe_Ends) is
    fd_array : aliased array (0 .. 1) of Interfaces.C.int;
  begin
    if C.c_pipe (fd_array'Address) /= 0 then
      raise POSIX_Error with "pipe failed";
    end if;
    ends := (Read_End => File_Descriptor (fd_array (0)), Write_End => File_Descriptor (fd_array (1)));
  end create_pipe;

  function read_from
    (fd     : in File_Descriptor;
     buffer : in out Ada.Streams.Stream_Element_Array)
     return Natural
  is
    bytes_read : constant Interfaces.C.long :=
      C.c_read (fd, buffer (buffer'First)'Address, buffer'Length);
  begin
    if bytes_read < 0 then
      raise POSIX_Error with "read failed";
    end if;
    return Natural (bytes_read);
  end read_from;

  function write_to
    (fd     : in File_Descriptor;
     buffer : in Ada.Streams.Stream_Element_Array)
     return Natural
  is
    bytes_written : constant Interfaces.C.long :=
      C.c_write (fd, buffer (buffer'First)'Address, buffer'Length);
  begin
    if bytes_written < 0 then
      raise POSIX_Error with "write failed";
    end if;
    return Natural (bytes_written);
  end write_to;

end POSIX.Unistd;

4. posix-signals.ads

-- posix-signals.ads

with System;
with POSIX.C;

package POSIX.Signals is

  Signal_Error : exception;

  type Signal_Set is private;

  type Signal_Handler is access procedure (Signo : POSIX.C.Signal_Number);
  pragma Convention (C, Signal_Handler);

  -- Default and Ignore handlers
  HANDLER_DEFAULT : constant Signal_Handler := null;
  HANDLER_IGNORE  : constant Signal_Handler := new procedure (Signo : POSIX.C.Signal_Number) is null;

  -- Flags for sa_flags field
  SA_NOCLDSTOP : constant POSIX.C.C_int := 1;
  SA_SIGINFO   : constant POSIX.C.C_int := 4;
  SA_RESTART   : constant POSIX.C.C_int := 16#10000000#;
  SA_RESETHAND : constant POSIX.C.C_int := 16#80000000#;

  type Sigaction_Record is record
    Sa_Handler : Signal_Handler := HANDLER_DEFAULT;
    Sa_Mask    : Signal_Set;
    Sa_Flags   : POSIX.C.C_int := 0;
  end record;

  -- High-level wrapper for sigaction(2)
  procedure set_action (
    signum     : in POSIX.C.Signal_Number;
    action     : in Sigaction_Record;
    old_action : out Sigaction_Record
  );

  -- Signal set management
  procedure empty_set (set : out Signal_Set);

private
  pragma Convention (C, Signal_Set);

  SIGSET_SIZE_BYTES : constant := 128;
  type Signal_Set is array (1 .. SIGSET_SIZE_BYTES) of Interfaces.C.unsigned_char;

end POSIX.Signals;

5. posix-signals.adb

-- posix-signals.adb

with System;
with Interfaces.C;

package body POSIX.Signals is

  -- Low-level C bindings, private to the package body
  ----------------------------------------------------

  type C_Sigaction_Record is record
    Sa_Handler   : Signal_Handler;
    Sa_Mask      : Signal_Set;
    Sa_Flags     : POSIX.C.C_int;
    Sa_Restorer  : System.Address;
  end record;
  pragma Convention (C, C_Sigaction_Record);

  function c_sigaction (
    signum : POSIX.C.Signal_Number;
    act    : access C_Sigaction_Record;
    oldact : access C_Sigaction_Record
  ) return POSIX.C.C_int;
  pragma Import (C, c_sigaction, "sigaction");

  function c_sigemptyset (set : access Signal_Set) return POSIX.C.C_int;
  pragma Import (C, c_sigemptyset, "sigemptyset");

  -- High-level Ada implementations
  ---------------------------------

  procedure set_action (
    signum     : in POSIX.C.Signal_Number;
    action     : in Sigaction_Record;
    old_action : out Sigaction_Record
  ) is
    c_new_action : aliased C_Sigaction_Record;
    c_old_action : aliased C_Sigaction_Record;
    result       : POSIX.C.C_int;
  begin
    c_new_action.Sa_Handler := action.Sa_Handler;
    c_new_action.Sa_Mask    := action.Sa_Mask;
    c_new_action.Sa_Flags   := action.Sa_Flags;
    c_new_action.Sa_Restorer := System.Null_Address;

    result := c_sigaction (signum, c_new_action'Access, c_old_action'Access);

    if result /= POSIX.C.SUCCESS then
      raise Signal_Error with "sigaction failed";
    end if;

    old_action.Sa_Handler := c_old_action.Sa_Handler;
    old_action.Sa_Mask    := c_old_action.Sa_Mask;
    old_action.Sa_Flags   := c_old_action.Sa_Flags;
  end set_action;

  procedure empty_set (set : out Signal_Set) is
  begin
    if c_sigemptyset (set'Access) /= POSIX.C.SUCCESS then
      raise Signal_Error with "sigemptyset failed";
    end if;
  end empty_set;

end POSIX.Signals;

6. posix-signal_handler.ads

-- posix-signal_handler.ads

with POSIX.C;
with POSIX.Unistd;

package POSIX.Signal_Handler is

  Signal_Error : exception;

  type Signal_Set is array (Positive range <>) of POSIX.C.Signal_Number;
  type Signal_Callback is access procedure (signo : in POSIX.C.Signal_Number);

  -- § 모델 A: 내부 태스크와 콜백을 사용하는 간편 모드
  procedure install_callback_handler (
    for_signals : in Signal_Set;
    on_signal   : in Signal_Callback
  );

  -- § 모델 B: 외부 루프를 위해 Pipe FD를 반환하는 수동 모드
  function install_polling_handler (
    for_signals : in Signal_Set
  ) return POSIX.Unistd.File_Descriptor;

  -- § 공통 자원 정리 함수
  procedure terminate_handler;

end POSIX.Signal_Handler;

7. posix-signal_handler.adb

-- posix-signal_handler.adb

with Ada.Streams;
with Ada.Text_IO;
with POSIX.Signals;
with POSIX.Unistd;

package body POSIX.Signal_Handler is

  -- § 패키지 내부 상태 변수
  private_pipe  : POSIX.Unistd.Pipe_Ends;
  is_terminated : Boolean := False;

  -- § Async-signal-safe 핸들러
  procedure pipe_writing_handler (signo : POSIX.C.Signal_Number) is
    signal_byte   : aliased constant Ada.Streams.Stream_Element := Ada.Streams.Stream_Element(signo);
    buffer        : constant Ada.Streams.Stream_Element_Array(1 .. 1) := (1 => signal_byte);
    bytes_written : Natural;
  begin
    if not is_terminated then
      bytes_written := POSIX.Unistd.write_to (private_pipe.Write_End, buffer);
    end if;
  exception
    when others => null;
  end pipe_writing_handler;

  -- § 모델 A를 위한 내부 태스크 및 콜백 변수
  -------------------------------------------
  task type Callback_Dispatcher;
  dispatcher    : Callback_Dispatcher;
  user_callback : Signal_Callback;

  task body Callback_Dispatcher is
    buffer     : aliased Ada.Streams.Stream_Element_Array(1 .. 1);
    bytes_read : Natural;
    signo      : POSIX.C.Signal_Number;
  begin
    loop
      bytes_read := POSIX.Unistd.read_from (private_pipe.Read_End, buffer);
      exit when bytes_read = 0 or else is_terminated;

      signo := POSIX.C.Signal_Number (buffer (1));
      if user_callback /= null then
        begin
          user_callback (signo);
        exception
          when others => null; -- 사용자 콜백의 예외가 태스크를 중단시키지 않도록 함
        end;
      end if;
    end loop;
  exception
    when POSIX.Unistd.POSIX_Error =>
      null; -- 파이프가 닫히면 예외 발생 가능
  end Callback_Dispatcher;


  -- § 공통 핸들러 설치 로직
  --------------------------
  procedure install_common_handler (for_signals : in Signal_Set) is
    action     : POSIX.Signals.Sigaction_Record;
    old_action : POSIX.Signals.Sigaction_Record;
  begin
    is_terminated := False;
    POSIX.Unistd.create_pipe (private_pipe);

    action.Sa_Handler := pipe_writing_handler'Access;
    POSIX.Signals.empty_set (action.Sa_Mask);
    action.Sa_Flags   := POSIX.Signals.SA_RESTART;

    for signo of for_signals loop
      POSIX.Signals.set_action (signo, action, old_action);
    end loop;
  exception
    when others =>
      raise Signal_Error with "Failed to install common signal handler";
  end install_common_handler;


  -- § 공개 인터페이스 구현
  --------------------------
  procedure install_callback_handler (
    for_signals : in Signal_Set;
    on_signal   : in Signal_Callback)
  is
  begin
    user_callback := on_signal;
    install_common_handler (for_signals);
    -- 디스패처 태스크는 자동으로 시작됨
  end install_callback_handler;

  function install_polling_handler (
    for_signals : in Signal_Set
  ) return POSIX.Unistd.File_Descriptor is
  begin
    install_common_handler (for_signals);
    return private_pipe.Read_End;
  end install_polling_handler;

  procedure terminate_handler is
  begin
    if is_terminated then
      return;
    end if;
    is_terminated := True;

    -- 파이프를 닫아 블로킹된 read나 select를 깨운다.
    POSIX.Unistd.close_file (private_pipe.Read_End);
    POSIX.Unistd.close_file (private_pipe.Write_End);

    -- 모델 A의 경우, 태스크가 종료되도록 잠시 기다릴 수 있음
    -- delay 0.1; -- 필요한 경우
  exception
    when POSIX.Unistd.POSIX_Error =>
      null; -- 이미 닫혔을 수 있음
  end terminate_handler;

end POSIX.Signal_Handler;

추천 비추천

0

고정닉 0

0

댓글 영역

전체 댓글 0
본문 보기

하단 갤러리 리스트 영역

왼쪽 컨텐츠 영역

갤러리 리스트 영역

갤러리 리스트
번호 제목 글쓴이 작성일 조회 추천
설문 모태 솔로도 구제해 줄 것 같은 연애 고수 스타는? 운영자 25/07/21 - -
2874475 wix 로 사이트 제작중인데 팝업기능 어딨어? 헬프! 헬프!! 삑사리갤로그로 이동합니다. 07.25 37 0
2874474 제습기 사고 인생이 달라졌다 [8] 헬마스터갤로그로 이동합니다. 07.25 59 0
2874473 현실적인 비전공자 루트 프갤러(121.145) 07.25 102 0
2874472 성냥사세양..성냥사세양.. 성냥말구 다른것두 팔아양.. [2] ♥팬티스타킹냥덩♥갤로그로 이동합니다. 07.25 51 0
2874471 프갤 망했다 [2] 프갤러(211.210) 07.25 60 0
2874470 좆소월급들어왔다. [9] 개멍청한유라갤로그로 이동합니다. 07.25 89 0
2874469 나님 회복 시나리오 돌리고 있는데 성공할지 모르겠음 ♥팬티스타킹냥덩♥갤로그로 이동합니다. 07.25 29 0
2874468 개발자 취업,,, [5] 프갤러(210.126) 07.25 109 0
2874467 양키의 에반게리온 전체 요약 특촬물 ㅋㅋㅋ 프갤러(183.101) 07.25 31 0
2874466 아패로 윈도 돌리구 싶당 ♥팬티스타킹냥덩♥갤로그로 이동합니다. 07.25 25 0
2874465 스마트폰 버튼 키 기능 할당 질문 [1] ㅇㅇ(14.35) 07.25 31 0
2874462 새 umpc 발명도둑잡기(118.235) 07.25 28 0
2874461 적금 붓고 주식 사니까 [7] 아스카영원히사랑해갤로그로 이동합니다. 07.25 87 0
2874460 월급 입갤!!!!!!!!!!!!!!!!! [1] 아스카영원히사랑해갤로그로 이동합니다. 07.25 66 0
2874459 CT 찍어야 하냐 자꾸 불운이 많지 .. 넥도리아(223.38) 07.25 22 0
2874458 만화방와서 올만에 만화보는데 [6] ㅆㅇㅆ찡갤로그로 이동합니다. 07.25 48 0
2874457 종북 매국노 반국가세력 간첩 [1] ♥팬티스타킹냥덩♥갤로그로 이동합니다. 07.25 45 0
2874455 나님 살아오면서 항상 느끼는게 산업의 발전은 생각보다 너무 느리다 ♥팬티스타킹냥덩♥갤로그로 이동합니다. 07.25 26 0
2874454 노인들이 강서 킬러 성수형님을 살인마라고 싫어하는이유 뒷통수한방(1.213) 07.25 30 0
2874451 월급날이댱 ㅇㅂㅇ 어린이노무현갤로그로 이동합니다. 07.25 35 0
2874450 좌빨배급견 = 깜둥이 ♥팬티스타킹냥덩♥갤로그로 이동합니다. 07.25 23 0
2874449 2찢명 구정물 1원도 안남기고 다 써버리자! ♥팬티스타킹냥덩♥갤로그로 이동합니다. 07.25 28 0
2874448 공수처 검찰청 경찰청 국제수사 과학수사 포랜식수사 기무사 국정원 존재이유 뒷통수한방(1.213) 07.25 20 1
2874447 최강의 냥덩 ♥팬티스타킹냥덩♥갤로그로 이동합니다. 07.25 25 0
2874446 백번 양보해도 파이썬은 프로그래밍 언어로써는 절대 아닌듯. 프갤러(59.16) 07.25 40 0
2874445 오늘은 아스카의 월급날입니다 [1] 아스카영원히사랑해갤로그로 이동합니다. 07.25 68 0
2874443 까치 ㅇㅅㅇ 헤르 미온느갤로그로 이동합니다. 07.25 19 0
2874442 오늘 입고 온 옷에서 냄새난다 [4] 아스카영원히사랑해갤로그로 이동합니다. 07.25 45 0
2874441 고무백 30살인데 존나 노력하면 2800 si 가능? [1] 프갤러(106.101) 07.25 32 0
2874440 돈데 돈내 곤데 꼰대 똥내 ♥팬티스타킹냥덩♥갤로그로 이동합니다. 07.25 22 0
2874439 ❤✨☀⭐⚡☘⛩나님 시작합니당⛩☘⚡⭐☀✨❤ ♥팬티스타킹냥덩♥갤로그로 이동합니다. 07.25 19 0
2874436 태연 ㅇㅅㅇ 헤르 미온느갤로그로 이동합니다. 07.25 23 0
2874435 하루 한 번 헤르미온느 찬양 헤르 미온느갤로그로 이동합니다. 07.25 30 0
2874434 학점 3.4 ADHD좌 어디갔음? [1] 프갤러(223.194) 07.25 35 0
2874428 PC, 스마트폰, 일정작성 영어로 전부 하면 도움되나요? 질문왕(211.198) 07.25 15 0
2874411 일본 관세 15프로 맞자고 지옥으로 갔노 [2] ㅆㅇㅆ찡갤로그로 이동합니다. 07.25 53 1
2874403 또 전쟁의 불씨가 옮겨붙는구나 [1] 아스카영원히사랑해갤로그로 이동합니다. 07.25 51 0
2874393 관세협상 잘 안되도 한국은 손해볼게 없음 [6] 야옹아저씨갤로그로 이동합니다. 07.25 145 6
2874376 ❤✨☀⭐⛩⚡☘♥+나님 시작합니당♥+☘⚡⛩⭐☀✨❤ ♥팬티스타킹냥덩♥갤로그로 이동합니다. 07.25 22 0
2874348 음기 충전 발명도둑잡기(118.216) 07.25 28 0
2874347 [단독]자신의 아내를..국힘 당직자 성착취 의혹 발명도둑잡기(118.216) 07.25 31 0
2874324 에이다프루트 라즈베리파이 피코 맥 에뮬레이터 하드웨어 발명도둑잡기(118.216) 07.25 18 0
2874306 10년대 초반, 서구권 드라마에서 묘사된 우리나라 모습들 발명도둑잡기(118.216) 07.25 37 0
2874304 영화 <S라인>이 인기래서 생각나는 예전 글 발명도둑잡기(118.216) 07.25 28 0
2874298 [단독] '롤스로이스 사건' 반전…수사 경찰 간부 억대 향응 발명도둑잡기(118.216) 07.25 40 0
2874292 한때는 일본군이었던 조선인들에게 발명도둑잡기(118.216) 07.25 32 0
2874290 후배에게 약점 잡히면 생기는 일 발명도둑잡기(118.216) 07.25 33 0
2874287 1억4천만뷰 대박난 디즈니 한국 표절 딱 걸렸네 발명도둑잡기(118.216) 07.25 32 0
2874285 남의 소설 통째 배껴 '문학상 5관왕'…피해 알리자 당선 취소 발명도둑잡기(118.216) 07.25 24 0
2874283 정수민 - Wandering Star :: 내 여자친구는 상남자 발명도둑잡기(118.216) 07.25 31 0
뉴스 '한끼합쇼' 김희선X탁재훈, 띵동 성공을 위한 애교 폭격+집 청소 특급 서비스 개시! 은평구 한옥마을서 16분 남기고 밥 친구 찾기 성공! 디시트렌드 07.25
갤러리 내부 검색
제목+내용게시물 정렬 옵션

오른쪽 컨텐츠 영역

실시간 베스트

1/8

뉴스

디시미디어

디시이슈

1/2