(ex1_argc.c 파일)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <unistd.h>
char* usage = "Usage : Directory Suffix\n";
int my_double_ls(const char*, char*);
int match(const char*, const char*);
int main(int argc, char** argv) {
if (argc != 3) {
fprintf(stderr, usage);
exit(1);
}
my_double_ls(argv[1], argv[2]);
exit(0);
return 0;
}
int my_double_ls(const char* name, char* suffix) {
struct dirent* d;
DIR* dp;
if ((dp = opendir(name)) == NULL) {
return -1;
}
while (d = readdir(dp)) {
if (d->d_ino != 0) {
printf("%s\n", d->d_name);
}
if (match(d->d_name, suffix)) {
printf("***Matched %s\n", d->d_name);
}
}
closedir(dp);
return 0;
}
int match(const char* s1, const char* s2) {
int diff = strlen(s1) - strlen(s2);
if (strlen(s1) > strlen(s2)) {
return (strcmp(&s1[diff], s2) == 0);
}
else {
return 0;
}
}
ex1. 현재 디렉터리에서. c로 끝나는 모든 파일들을 출력하는 프로그램을 exec 시스템 호출을 이용하여 실행하라
(In ex1.c)
argv[0] = “ex1_argc”; argv[1] = “.”; argv[2] = “.c”; argv[3] = NULL;
execv(“./ex1_argc”, argv)
.....
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
char* argv[4];
printf("--> Before exec function\n");
argv[0] = "ex1_argc";
argv[1] = ".";
argv[2] = ".c";
argv[3] = NULL;
if (execv("./ex1_argc", argv) == -1) {
perror("execve");
exit(1);
}
printf("--> After exec function\n");
return 0;
}
ex2. 부모 프로세스에서 개방된 파일은 자식 프로세스에서도 개방되어 있고, 자식은 각 파일과 연관하여 자신의 파일 기술자(fd)의 복제를 유지하고 있다. 이와 관련된 사항을 확인하는 코드를 다음과 같은 차례로 작성하라
- 데이터 파일을 open
- 10bytes을 읽고, 현재 파일 위치를 출력
- fork() 호출
- 자식은 10bytes를 읽고, 현재 파일 위치를 출력
- 부모는 wait((int*)0)로 자식이 종료하기를 기다린 후, 현재 파일 위치를 출력
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
int printpos(const char* string, int filedes);
int main() {
int fd;
int nread;
pid_t pid;
char buf[10];
if ((fd = open("testdata", O_RDONLY)) == -1) {
perror("open failed");
}
read(fd, buf, 10);
printpos("Before fork", fd);
switch(pid = fork()) {
case -1:
perror("fork failed");
break;
case 0:
printpos("Child before read", fd);
read(fd, buf, 10);
printpos("Child after read", fd);
close (fd);
break;
default:
wait((int*)0);
printpos("Parent after wait", fd);
if ((nread = read(fd, buf, 10)) <= 0) {
perror("file read error");
}
}
return 0;
}
int printpos(const char* string, int filedes) {
off_t pos;
if ((pos = lseek(filedes, 0, SEEK_CUR)) == -1) {
perror ("lseek failed");
}
printf("%s:%ld\n", string, pos);
}
- Before fork: 부모 프로세스가 fork() 호출 전, read()를 한 번 수행하여 파일 포인터가 10바이트만큼 이동한 상태를 출력
- Child before read: 자식 프로세스는 fork() 이후에도 부모와 동일한 파일 디스크립터(fd)를 사용하고, 같은 파일 포인터(fp) 위치(10바이트)를 공유
- Child after read: 자식 프로세스가 10바이트를 더 읽은 후, 파일 포인터(fp) 위치가 20바이트로 이동.
- Parent after wait: 부모 프로세스는 자식이 종료한 후에 20바이트 위치에서부터 추가로 파일을 읽으려 시도.
참고 및 출처: 시스템 프로그래밍 리눅스&유닉스(이종원)
'Computer Science > UNIX & Linux' 카테고리의 다른 글
[UNIX/Linux] ep8+) 시그널 함수 실습 (1) | 2024.10.24 |
---|---|
[UNIX/Linux] ep8) 시그널 (0) | 2024.10.23 |
[UNIX/Linux] ep7) 프로세스 생성과 실행 (1) | 2024.10.21 |
[UNIX/Linux] ep6+) 프로세스 정보 함수 실습 (1) | 2024.10.14 |
[UNIX/Linux] ep6) 프로세스 정보 (4) | 2024.10.12 |