Ada 코드입니다.
Cada는 C - Ada 바딩인 라이브러리입니다.
재업 완료
ㅋㅋㅋ

with System;
with Interfaces.C;
with Cada.Types;
with Cada.Error;
with sys_stat_h;
with sys_types_h;
with System.Storage_Elements;
with errno_h;
with unistd_h;
package body Cada.File is
use type Interfaces.C.Int;
use type Interfaces.C.long;
function c_open2 (path : Interfaces.C.Char_Array;
flags : Interfaces.C.Int) return File_Descriptor;
function c_open3 (path : Interfaces.C.Char_Array;
flags : Interfaces.C.Int;
mode : sys_types_h.mode_t) return File_Descriptor;
pragma import (c, c_open2, "open");
pragma import (c, c_open3, "open");
function open (path : String;
flags : File_Flags) return Object is
new_fd : constant File_Descriptor :=
c_open2 (Interfaces.C.to_c (path), Interfaces.C.Int (flags));
begin
if new_fd = -1 then
declare
error_code : constant Interfaces.C.int := Cada.Error.get_errno;
error_msg : constant String :=
"open(2) failed for path """ & path & """ (errno: " & error_code'image & ")";
begin
case error_code is
when errno_h.EACCES =>
raise Cada.Error.Permission_Denied with error_msg;
when errno_h.ENOENT =>
raise Cada.Error.No_Such_File_Or_Directory with error_msg;
when errno_h.EEXIST =>
raise Cada.Error.File_Exists with error_msg;
when errno_h.EISDIR =>
raise Cada.Error.Is_A_Directory with error_msg;
when errno_h.ENOTDIR =>
raise Cada.Error.Not_A_Directory with error_msg;
when others =>
declare
errno_text : constant String := Cada.Error.get_error_message(error_code);
begin
raise Cada.Error.Unknown_Error with errno_text & ": " & error_msg;
end;
end case;
end;
end if;
return (Ada.Finalization.Controlled with fd => new_fd);
end open;
-- open implementation (3 arguments)
function open (path : String;
flags : File_Flags;
mode : Cada.Types.File_Mode) return Object is
new_fd : constant File_Descriptor := c_open3 (Interfaces.C.to_c (path),
Interfaces.C.Int (flags),
sys_types_h.mode_t (mode));
begin
if new_fd = -1 then
declare
error_code : constant Interfaces.C.int := Cada.Error.get_errno;
error_msg : constant String :=
"open(2) failed for path """ & path & """ (errno: " & error_code'image & ")";
begin
case error_code is
when errno_h.EACCES =>
raise Cada.Error.Permission_Denied with error_msg;
when errno_h.ENOENT =>
raise Cada.Error.No_Such_File_Or_Directory with error_msg;
when errno_h.EEXIST =>
raise Cada.Error.File_Exists with error_msg;
when errno_h.EISDIR =>
raise Cada.Error.Is_A_Directory with error_msg;
when errno_h.ENOTDIR =>
raise Cada.Error.Not_A_Directory with error_msg;
when others =>
declare
errno_text : constant String := Cada.Error.get_error_message(error_code);
begin
raise Cada.Error.Unknown_Error with errno_text & ": " & error_msg;
end;
end case;
end;
end if;
return (Ada.Finalization.Controlled with fd => new_fd);
end open;
procedure close (self : in out Object) is
result : constant Interfaces.C.int := unistd_h.close (Interfaces.C.Int (self.fd));
begin
if result = -1 then
-- Embed the error handling logic directly.
declare
error_code : constant Interfaces.C.int := Cada.Error.get_errno;
error_msg : constant String :=
"close(2) failed for fd " & self.fd'image &
" (errno: " & error_code'image & ")";
begin
case error_code is
when errno_h.EBADF => -- Bad file descriptor
raise Cada.Error.Bad_File_Descriptor with error_msg;
when errno_h.EINTR => -- Interrupted system call
raise Cada.Error.Interrupted_System_Call with error_msg;
when errno_h.EIO => -- I/O error
raise Cada.Error.Input_Output_Error with error_msg;
when others =>
declare
errno_text : constant String := Cada.Error.get_error_message(error_code);
begin
raise Cada.Error.Unknown_Error with errno_text & ": " & error_msg;
end;
end case;
end;
end if;
self.fd := -1;
end close;
function write (self : in Object;
buffer : in System.Storage_Elements.Storage_Array)
return Natural is
bytes_written : constant sys_types_h.ssize_t :=
unistd_h.write (Interfaces.C.Int (self.fd),
buffer'address, buffer'length);
begin
if bytes_written = -1 then
-- [!] 오류 처리 로직을 내부에 직접 작성
declare
error_code : constant Interfaces.C.int := Cada.Error.get_errno;
error_msg : constant String :=
"write(2) failed for fd " & self.fd'image &
" (errno: " & error_code'image & ")";
begin
case error_code is
when errno_h.EBADF => -- Bad file descriptor
raise Cada.Error.Bad_File_Descriptor with error_msg;
when errno_h.EPIPE => -- Broken pipe
raise Cada.Error.Broken_Pipe with error_msg;
when errno_h.EINTR => -- Interrupted system call
raise Cada.Error.Interrupted_System_Call with error_msg;
when errno_h.EAGAIN => -- (or EWOULDBLOCK) Resource temporarily unavailable
raise Cada.Error.Resource_Temporarily_Unavailable with error_msg;
when errno_h.EFBIG => -- File too large
raise Cada.Error.File_Too_Large with error_msg;
when others =>
declare
errno_text : constant String := Cada.Error.get_error_message(error_code);
begin
raise Cada.Error.Unknown_Error with errno_text & ": " & error_msg;
end;
end case;
end;
end if;
return Natural (bytes_written);
end write;
function duplicate (self : in Object) return Object is
new_fd : constant File_Descriptor :=
File_Descriptor (unistd_h.dup (Interfaces.C.Int (self.fd)));
begin
if new_fd = -1 then
declare
error_code : constant Interfaces.C.int := Cada.Error.get_errno;
error_msg : constant String :=
"dup(2) failed for fd " & self.fd'image &
" (errno: " & error_code'image & ")";
begin
case error_code is
when errno_h.EBADF => -- Bad file descriptor
raise Cada.Error.Bad_File_Descriptor with error_msg;
when errno_h.EINTR => -- Interrupted system call
raise Cada.Error.Interrupted_System_Call with error_msg;
when errno_h.EMFILE => -- Per-process limit on open file descriptors reached
raise Cada.Error.Too_Many_Open_Files with error_msg;
when others =>
declare
errno_text : constant String := Cada.Error.get_error_message(error_code);
begin
raise Cada.Error.Unknown_Error with errno_text & ": " & error_msg;
end;
end case;
end;
end if;
return (Ada.Finalization.Controlled with fd => new_fd);
end duplicate;
function duplicate_to (self : in Object;
new_fd : File_Descriptor)
return Object is
result_fd : constant File_Descriptor :=
File_Descriptor (unistd_h.dup2 (Interfaces.C.Int (self.fd),
Interfaces.C.Int (new_fd)));
begin
if result_fd = -1 then
declare
error_code : constant Interfaces.C.int := Cada.Error.get_errno;
error_msg : constant String :=
"dup2(2) failed for old_fd " & self.fd'image & " to new_fd " &
new_fd'image & " (errno: " & error_code'image & ")";
begin
case error_code is
when errno_h.EBADF => -- Bad file descriptor
raise Cada.Error.Bad_File_Descriptor with error_msg;
when errno_h.EINTR => -- Interrupted system call
raise Cada.Error.Interrupted_System_Call with error_msg;
when errno_h.EBUSY => -- (Linux-specific) Race condition detected
raise Cada.Error.Device_Busy with error_msg;
when others =>
declare
errno_text : constant String := Cada.Error.get_error_message(error_code);
begin
raise Cada.Error.Unknown_Error with errno_text & ": " & error_msg;
end;
end case;
end;
end if;
return (Ada.Finalization.Controlled with fd => result_fd);
end duplicate_to;
function umask (new_mask : Cada.Types.File_Mode)
return Cada.Types.File_Mode is
mode : constant sys_types_h.mode_t :=
sys_stat_h.umask (sys_types_h.mode_t (new_mask));
begin
return Cada.Types.File_Mode (mode);
end umask;
overriding
procedure finalize (self : in out Object) is
begin
if self.fd /= -1 then
-- finalize에서는 예외를 전파하지 않는 것이 좋으므로,
-- 오류 발생 가능성이 있는 호출은 블록으로 감쌉니다.
declare
result : Interfaces.C.Int :=
unistd_h.close (Interfaces.C.Int (self.fd));
begin
if result /= 0 then
null; -- 오류를 무시하거나 내부 로그로 기록
end if;
end;
self.fd := -1;
end if;
end finalize;
end Cada.File;
댓글 영역
획득법
① NFT 발행
작성한 게시물을 NFT로 발행하면 일주일 동안 사용할 수 있습니다. (최초 1회)
② NFT 구매
다른 이용자의 NFT를 구매하면 한 달 동안 사용할 수 있습니다. (구매 시마다 갱신)
사용법
디시콘에서지갑연결시 바로 사용 가능합니다.