2025. 2. 8. 15:39ㆍ정보기술/운영체제 (OS)
5장: 시스템 콜을 직접 사용해 보기
1. 간단한 C 프로그램을 작성하여 시스템 콜 사용하기
이전 장에서 시스템 콜이 내부적으로 어떻게 동작하는지 배웠습니다. 이제 C 언어를 사용하여 시스템 콜을 직접 호출하는 프로그램을 작성하고, 파일을 읽고 쓰는 과정을 실습해 보겠습니다.
보통 printf(), fopen() 같은 라이브러리 함수들은 내부적으로 시스템 콜을 호출합니다. 이번 실습에서는 라이브러리 함수를 사용하지 않고 직접 시스템 콜을 호출하여 파일을 조작하는 방법을 배웁니다.
2. 파일을 여는 코드 (open), 데이터 읽고 쓰는 코드 (read, write)
📌 1) 파일을 여는 코드 (open)
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
int main() {
int fd;
// 파일 열기 (쓰기 모드, 없으면 생성)
fd = open("testfile.txt", O_WRONLY | O_CREAT, 0644);
if (fd == -1) {
perror("파일 열기 실패");
return 1;
}
printf("파일이 성공적으로 열렸습니다. 파일 디스크립터: %d\n", fd);
// 파일 닫기
if (close(fd) == -1) {
perror("파일 닫기 실패");
return 1;
}
return 0;
}
📌 2) 파일 권한 (0644)에 대한 자세한 설명
파일을 생성할 때 0644라는 파일 권한(Permission) 값을 지정했습니다.
🔹 파일 권한은 3자리(사용자, 그룹, 기타)로 구성됨
🔹 각 자리는 읽기(4), 쓰기(2), 실행(1) 권한의 합으로 표현됨
권한 값 | 의미 |
0644 | 사용자(6: 읽기+쓰기), 그룹(4: 읽기), 기타(4: 읽기) |
0666 | 모든 사용자에게 읽기/쓰기 허용 |
0600 | 파일 소유자만 읽기/쓰기 가능 (비밀 파일에 사용) |
0755 | 소유자는 읽기/쓰기/실행 가능, 그룹과 기타 사용자는 읽기/실행만 가능 (실행 파일에 사용) |
💡 예시: 0644 (일반적인 텍스트 파일 권한)
- 소유자(User, U): 6 → 읽기(4) + 쓰기(2) = 읽기+쓰기 가능
- 그룹(Group, G): 4 → 읽기(4) = 읽기만 가능
- 기타(Others, O): 4 → 읽기(4) = 읽기만 가능
즉, 0644는 파일 소유자는 읽고 쓸 수 있지만, 그룹과 다른 사용자들은 읽기만 가능하도록 설정합니다.
📌 3) 데이터 읽고 쓰는 코드 (write, read)
다음 프로그램은 write() 시스템 콜을 사용하여 파일에 데이터를 쓰고, read() 시스템 콜을 사용하여 데이터를 읽는 코드입니다.
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
int main() {
int fd;
char buffer[100];
ssize_t bytes_written, bytes_read;
// 파일 열기 (쓰기 모드, 없으면 생성, 기존 내용 삭제)
fd = open("testfile.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1) {
perror("파일 열기 실패");
return 1;
}
// 파일에 데이터 쓰기
bytes_written = write(fd, "Hello, System Call!\n", 20);
if (bytes_written == -1) {
perror("파일 쓰기 실패");
close(fd);
return 1;
}
close(fd); // 파일 닫기
// 파일 다시 열기 (읽기 모드)
fd = open("testfile.txt", O_RDONLY);
if (fd == -1) {
perror("파일 열기 실패");
return 1;
}
// 파일에서 데이터 읽기
bytes_read = read(fd, buffer, sizeof(buffer) - 1);
if (bytes_read == -1) {
perror("파일 읽기 실패");
close(fd);
return 1;
}
buffer[bytes_read] = '\0'; // 문자열 종료
printf("파일 내용: %s\n", buffer);
close(fd); // 파일 닫기
return 0;
}
📌 4) 에러 처리 보완
✅ 파일 시스템 콜에서 에러가 발생할 수 있는 경우
- open() 실패: 존재하지 않는 파일을 읽으려고 하거나, 권한이 없을 경우
- write() 실패: 디스크 공간 부족, 파일이 읽기 전용인 경우
- read() 실패: 파일이 존재하지 않거나, 허용되지 않은 접근
✅ perror()를 사용하여 오류 원인 출력
- perror("에러 메시지")는 errno 값을 기반으로 상세한 시스템 오류 메시지를 출력합니다.
3. 시스템 콜 확인 방법 (strace 명령어 사용)
strace를 사용하면 프로그램이 실행하는 시스템 콜을 추적할 수 있습니다.
이 도구를 활용하면 프로그램이 내부적으로 어떤 시스템 콜을 호출하는지 확인할 수 있습니다.
📌 strace 사용법
✅ strace를 사용하여 우리가 만든 프로그램(file_io)을 실행해 보겠습니다.
strace ./file_io
✅ 예상되는 strace 출력 예시
open("testfile.txt", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 3
write(3, "Hello, System Call!\n", 20) = 20
close(3) = 0
open("testfile.txt", O_RDONLY) = 3
read(3, "Hello, System Call!\n", 99) = 20
close(3) = 0
📢 strace 분석
1️⃣ 파일 열기 → open("testfile.txt", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 3
- testfile.txt 파일을 열고 파일 디스크립터 3을 반환
2️⃣ 파일에 쓰기 → write(3, "Hello, System Call!\n", 20) = 20
- 20바이트를 파일에 씀
3️⃣ 파일 닫기 → close(3) = 0
- 파일 디스크립터 3을 닫음
4️⃣ 파일 다시 열기 → open("testfile.txt", O_RDONLY) = 3
- 읽기 모드로 다시 열기
5️⃣ 파일에서 읽기 → read(3, "Hello, System Call!\n", 99) = 20
- 파일에서 20바이트 읽어 buffer에 저장
6️⃣ 파일 닫기 → close(3) = 0
- 파일 닫기 완료
🚀 정리 및 핵심 요약
✅ 파일 권한(0644)의 의미와 설정 방법 설명 추가
✅ open(), read(), write(), close() 시스템 콜을 직접 호출하는 C 코드 작성
✅ 파일을 읽고 쓰는 과정에서 perror()를 활용한 에러 처리 보강
✅ strace를 사용하여 실행되는 시스템 콜을 추적하고 결과를 분석
'정보기술 > 운영체제 (OS)' 카테고리의 다른 글
운영체제 락 개념과 동기화 기법 (1. 운영체제에서 동기화 / 1-1. 동기화(Synchronization)란?) (0) | 2025.02.26 |
---|---|
시스템 콜 (System Call) - 6. 시스템 콜의 보안과 성능 이슈 (0) | 2025.02.08 |
시스템 콜 (System Call) - 4. 시스템 콜이 동작하는 과정 (0) | 2025.02.08 |
시스템 콜 (System Call) - 3. 시스템 콜의 종류와 예제 (0) | 2025.02.08 |
시스템 콜 (System Call) - 2. 시스템 콜의 개념을 쉽게 이해하기 (0) | 2025.02.08 |