전체 구조 intmain(int argc, char **argv, char **envp) { t_infoloc; if (argc != 5) error("argument error\\n"); loc.infile = open(argv[1], O_RDONLY); if (loc.infile == -1) perror("infile error"); loc.outfile = open(argv[4], O_RDWR | O_CREAT | O_TRUNC, 0644); if (loc.outfile == -1) error("outfile error"); loc.path = find_path(envp); loc.argv_command_one = ft_split(argv[2], ' '); loc.argv_command_two = ..
42Seoul/pipex
우리가 터미널에서 입력을 받기 위해 argc, argv를 사용함 ex) #include int main(int argc, char *argv[]) { printf("인자 개수: %d\\n", argc); for (int i = 0; i < argc; i++) { printf("인자 %d: %s\\n", i, argv[i]); } printf("\\n환경 변수:\\n"); return 0; } 환경 변수 들고 오기 #include int main(int argc, char *argv[], char *envp[]) { printf("인자 개수: %d\\n", argc); for (int i = 0; i < argc; i++) { printf("인자 %d: %s\\n", i, argv[i]); } printf..
모든 명령어는 종료 상태(exit status)를 리턴한다. 명령어가 성공시에는 0을 리턴하고 실패시에는 에러코드로 해석될 수 있는 non-zero(1~255)를 리턴한다. 유닉스 관례를 잘 따르는 프로그램들은 함수의 가장 마지막에 실행된 명령어가 종료 상태를 결정한다. $?변수는 제일 마지막 명령의 종료 상태 코드를 가진다. echo $? 종료 상태 코드(exit status code) 몇몇 종료 상태 코드들은 예약되어 있기 때문에 사용자가 임의로 exit의 매개변수로 쓰면 안된다. → 흔히 프로그램에서 에러 발생시 종료를 흔히 exit1을 쓰는데, 이는 다양한 에러를 나타내기 때문에 맞는 사용이기도 하지만 ,다른 면에서 보면 에러에 대한 유용한 정보를 나타내지 않는 것도 의미함. 종료 코드 뜻 에러메..
#include void perror(const char *string); perror 함수는 오류 메세지를 stderr로 출력한다. string이 NULL이 아니고 널 문자를 가리키지 않는 경우, string에서 지정된 스트링은 표준 오류 스트림으로 출력되고 콜론과 간격이 이어진다. errno의 값과 연관된 메세지가 출력된 다음 줄 바꾸기 문자가 이어진다. errno의 값 값의미 EBADDATA메세지 데이터는 유효하지 않습니다. EBUSY레코드 또는 파일은 사용 중입니다. ENOENT파일 또는 라이브러리를 찾을 수 없습니다. EPERM액세스에 불충분한 권한 부여. ENOREC레코드를 찾을 수 없습니다. EIOERROR 회복 불가능한 I/O 오류가 발생했습니다. EIORECERR회복 가능한 I/O 오류가..
waitpid 함수는 wait 함수처럼 자식 프로세스를 기다릴때 사용하는 함수 자식 프로세스의 종료상태를 회수할 때 사용 waitpid 함수는 자식 프로세스가 종료될 때 까지 차단되는 것을 원하지 않을 경우, 옵션을 사용하여 차단을 방지 가능 #include pid_t waitpid(pid_t pid, int *statloc , int options); 성공 : 프로세스 ID 반환 오류 : -1 첫 번째 인자 pid가 -1 일 경우 (pid == -1) 임의의 자식 프로세스를 기다림 pid가 0 보다 클 경우 (pid > 0) 프로세스 ID가 pid인 자식 프로세스를 기다림 pid가 -1 보다 작을 경우 (pid < -1) 프로세스 그룹 ID가 pid의 절댓값과 같은 자식 프로세스를 기다림 pid가 0일..
fork()는 현재 실행되는 프로세스에 대해 복사본 프로세스를 생성 헤더: unistd.h 형태: pid_t fork(void) 인수: - 반환: pid_t -1 : 실패0 == 자식 프로세스, 새로 생성된 프로세스임0 < 생성된 자식 프로세스 PID → 하나의 프로그램이 fork()함수를 만나는 순간 복제본이 생성 프로세스란 디스크에 있던 프로그램 파일이 메모리에 올려지고 시스템의 스케줄에 따라 실행이 되는 실행 단위. #include #include #include int main() { pid_t pid = fork(); if (pid == 0) { // 자식 프로세스 printf("자식 프로세스 실행\\n"); printf("자식 프로세스 ID: %d\\n", getpid()); printf("자..
프로레스끼리 통신을 하기 위해 파이프라는 함수를 제공해줌. 원형 #include int pipe(int fd[2]); fd[0] : 함수 호출 후 fd[0]에 데이터를 입력 받을 수 있는 파일 디스크립터가 담김 → buffer에서 read fd[1] : 함수 호출 후 데이터를 출력할 수 있는 파일 디스크립터가 담김 → buffer에 write를 할 수가 있음. # include # include # include # include # define BUFSIZE 100 int main() { int fd[2]; char buffer[BUFSIZE]; pid_t pid; int state; state = pipe(fd); if (state == -1) { puts("error"); exit(1); } pid..
c 언어에서 ‘access()’ 함수는 파일 시스템에서 파일이나 디렉토리에 대한 접근 권한을 확인하는 데 사용됨. 헤더 파일 → 인수 파일 경로 접근 모드 F_OK : 파일의 존재 여부를 확인. R_OK : 파일의 읽기 권한을 확인. W_OK : 파일의 쓰기 권한을 확인. X_OK : 파일의 실행 권환을 확인. 결과 → access() 함수는 성공적으로 수행되면 0을 반환하며, 실패한 경우 -1을 반환합니다. 실패 시, 오류의 원인은 errno 변수를 통해 확인할 수 있다. 이 예는 access함수를 이용해서 example.txt의 존재 여부를 확인. #include #include int main() { char *filename = "example.txt"; if (access(filename, F_..
파일 서술자 복제 함수 dup, dup2 파일 서술자(file descriptor)를 복사함 헤더는 unistd.h dup → dup는 fd로 전달받은 파일 서술자를 복제하여 반환. dup가 돌려주는 파일 서술자는 가장 낮은 서술자를 반환. 성공시 새 파일 서술자 오류시 -1 반환 #include int dup(int fd); 예제 #include #include #include int main() { int old_fd = open("file.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644); printf("Old file descriptor: %d\\n", old_fd); // dup() 함수를 사용하여 새로운 파일 디스크립터 생성 int new_fd = dup(old_fd)..
exec() → system()함수는 OS가 명령 문자열을 보고 프로그램을 실행하는 함수인데 보안이 허술해 악의적인 사용자가 명령 문자열을 악의적으로 조작이 가능했고, 그리하여 나온 것이 exec()계열 함수다. exec()는 현재 실행중인 프로세스를 종료하고 해당 프로세스를 대체하여 실행한다. unistd.h에 선언되어 있다. exec() 계열 함수를 호출하면 새 프로세스(외부 프로그램이)가 실행되고 해당 프로세스는 종료된다. exec() 함수들은 -1을 반환하며, errno 변수를 설정하여 발생한 오류를 알려준다. 오류는 프로그램 파일이 없는 경우, 실행 권한이 없는 경우, 메모리 부족 등의 이유로 발생할 수 있다. exec() 함수는 프로세스 간의 통신이나 프로그램 실행 중 동적으로 다른 프로그램을..