C++에서 시스템 호출 작성

Abdul Mateen 2024년2월15일
  1. C++의 시스템 호출
  2. C++에서 쓰기 시스템 호출
C++에서 시스템 호출 작성

이 튜토리얼에서는 C++로 작성된 프로그램에서 write 시스템을 호출하는 방법에 대해 설명합니다. 먼저 시스템 호출, 특히 write 시스템 호출과 해당 프로토타입을 신속하게 새로 고칩니다.

나중에 C++ 프로그램에서 write 시스템 호출을 호출하는 방법에 대해 설명합니다.

C++의 시스템 호출

모든 운영 체제는 시스템 호출을 통해 일련의 서비스를 제공합니다. 컴퓨터 프로그램이 운영 체제에서 서비스를 요청하는 메커니즘입니다.

시스템 호출은 다음 서비스를 제공합니다.

  1. 프로세스 생성 및 관리
  2. 메인 메모리 관리
  3. 파일 및 파일 시스템 관리
  4. 장치 입출력
  5. 보호
  6. 네트워킹

프로그램에서 가장 자주 요구하는 서비스는 입/출력입니다. 다음으로 write 시스템 콜에 대해 논의할 것입니다.

프로그램은 write 시스템 호출을 통해 일부 장치에 쓸 기본 운영 체제를 요청합니다.

write 호출로 이동하기 전에 파일 설명자에 대한 아이디어를 얻는 것이 중요합니다.

파일 설명자

Unix 및 Unix 기반 운영 체제에서 파일 설명자는 소켓이나 파이프와 같은 파일 또는 기타 IO 리소스를 고유하게 식별하는 번호입니다.

일반적으로 파일 설명자는 음수가 아닌 정수 값입니다. 프로그램은 파일 설명자를 통해 IO용 파일에 액세스합니다.

라이브러리 함수는 IO를 처리하고 파일 설명자를 매개변수로 사용합니다.

첫 번째 단계는 IO용 파일에 액세스하기 위해 이름(파일이 프로그램의 폴더에 없는 경우 절대/상대 경로)으로 파일을 여는 것입니다.

open 기능이 파일을 성공적으로 열면(즉, 동일한 이름의 파일이 존재하고 사용자에게 필요한 권한이 있는 경우) 파일 설명자를 반환합니다.

int fd = open("abc.txt", O_RDONLY | O_CREAT);

open 기능에는 두 개의 매개변수가 있습니다. 첫 번째 매개변수는 파일 이름이고 두 번째 매개변수는 읽기 모드(예: 읽기 전용 모드, 쓰기 전용 등)입니다.

파일에 대한 후속 IO 작업은 파일 설명자를 통해 수행됩니다.

C++에서 쓰기 시스템 호출

write 시스템 호출은 운영 체제 커널에서 제공하는 가장 기본적인 루틴 중 하나입니다. 기본 메모리(버퍼)의 데이터를 파일(일부 하드웨어 장치에 저장됨)에 기록합니다.

write() 시스템 호출은 buf가 가리키는 메모리 버퍼에서 파일 설명자가 참조하는 파일에 최대 count 바이트를 씁니다.

바이트만 이해할 수 있는 저수준 함수입니다. write 호출은 클래스와 같은 레코드를 쓰는 데 사용할 수 없습니다.

따라서 복잡한 I/O를 수행하려면 더 높은 수준의 입출력 함수(printf()와 같은)가 불가피합니다.

먼저 데이터를 파일에 쓰는 데 사용되는 write 시스템 호출의 구문을 살펴보겠습니다.

ssize_t write(int fd, const void *buf, size_t count);

쓰기 기능의 세 가지 매개변수 세부 정보는 다음과 같습니다.

  1. 파일 설명자 fd는 파일 열기 호출에서 가져옵니다. 정수 값입니다. 값 0, 12는 각각 표준 입력, 표준 출력 및 표준 오류에 대해 제공될 수도 있습니다.
  2. 데이터가 기본 메모리에 저장되는 메모리의 버퍼 buf에 대한 포인터.
  3. 버퍼 buf에서 fd가 가리키는 파일에 쓰기 위해 count로 지정된 바이트 수.

ssize_tsize_t 유형은 각각 stddef.h에 정의된 부호 있는 정수 데이터 유형과 부호 없는 정수 데이터 유형입니다.

반환 값

쓰기 기능은 부호 있는 값을 반환합니다. 성공하면 파일에 성공적으로 기록된 바이트 수를 반환하며 때로는 지정된 count보다 작을 수 있습니다.

총 쓰기 바이트가 count보다 적을 수 있는 가능한 이유는 출력 장치 메모리가 가득 차거나 소스 쓰기 버퍼에 count에 지정된 수보다 쓸 chars 수가 적기 때문일 수 있습니다.

오류 시 write 시스템 호출은 -1을 반환하고 errno는 발생한 오류를 나타내도록 설정됩니다.

여기에 write 시스템 호출을 사용하여 파일에 쓸 수 있는 완전한 프로그램이 있습니다.

#include <errno.h>
#include <fcntl.h>

#include <iostream>

extern int errno;

using namespace std;

int main() {
  int fd, count;
  fd = open("abc.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
  cout << "File descriptor = " << fd << '\n';
  if (fd == -1) {
    // print which type of error have in a code
    printf("Error Number % d\n", errno);
    // print program detail "Success or failure"
    perror("Program");
  }
  char buff[] = "This is a test program to check write system call.";
  count = write(fd, buff, 50);
  if (count == -1)
    cout << "Error writing in file";
  else
    cout << "Number of bytes written to the file: " << count << '\n';
  close(fd);
  return 0;
}

첫 번째 헤더 파일 fcntl.h에는 write 시스템 호출이 있습니다. 두 번째 헤더 파일에는 오류 기능이 있습니다.

open 함수 호출에서 쓰기 모드에서 abc.txt라는 새 파일 이름을 만듭니다. 이전에 파일이 존재할 수 있지만 O_TRUNC를 사용하면 이전 내용이 제거되고 새로운 빈 파일이 생성됩니다.

0644 코드는 파일 권한을 나타냅니다. 다음으로 if 조건은 파일이 성공적으로 열렸는지 여부를 확인합니다.

실패한 경우 오류 메시지가 표시됩니다.

다음으로 샘플 텍스트로 문자 배열(버퍼로 사용)을 만들었습니다. 마지막으로 파일에 씁니다.

세 번째 매개변수는 50이며 buff 배열에서 쓸 문자 수를 나타냅니다.

countwrite() API 호출에서 반환된 정수 값입니다. 실패한 경우 값은 -1입니다. 따라서 카운트를 확인하고 그에 따라 오류 메시지를 인쇄합니다.

성공적인 쓰기 작업의 경우 count의 양수 값을 가지며 if 조건은 파일에 성공적으로 기록된 총 바이트 수를 표시합니다.

시스템 호출 쓰기

첫 번째 출력 값 3은 파일이 성공적으로 열렸음을 보여줍니다. 두 번째 줄에서 50은 50바이트가 모두 성공적으로 기록되었음을 나타냅니다.

다음으로 open 문을 수정했습니다.

fd = open("abc.txt", O_RDONLY | O_CREAT | O_TRUNC, 0644);

O_WRONLYO_RDONLY로 바꾸었고 그 결과 출력은 다음과 같습니다.

File descriptor = -1
Error Number  13
Program: Permission denied
Error writing in file

내용을 잘라 읽기 모드에서 기존 파일을 여는 것이 불가능하기 때문에 열기 작업이 실패했습니다.

실패 결과 파일 디스크립터가 -1임을 알 수 있습니다. 또한 쓰기 작업이 실패합니다.

write 시스템 호출 전에 파일을 닫으면 결과는 write 시스템 호출에 의해 실패한 작업이 됩니다. 이 경우 출력은 다음과 같아야 합니다.

File descriptor = 3
Error writing in file

여기서 파일 디스크립터는 -1이 아니지만 파일이 닫힙니다. 따라서 쓰기 시스템 호출이 실패합니다.

write 시스템 호출에 의해 반환된 값은 -1입니다. 따라서 오류 메시지가 인쇄됩니다.