[리눅스 시스템 네트워크 프로그래밍] 1. 프로세스

rhkr9080·2023년 10월 7일
0

임베디드

목록 보기
5/8

⚠️ 주의사항

"Advanced! 리눅스 시스템 네트워크 프로그래밍"
위의 책은 내용의 간소화를 위해 include를 포함하여 코드의 일부를 생략하였다. 따라서 아래 내용은 코드를 실제로 동작하도록 구현해 실행결과를 확인하는 것을 목표로 한다. 또한, 다른 독자들이 편하게 코드를 작성하고자 한다면 참고하면 좋을 것이다.
내용은 직접 책을 읽어 확인할 것!

fork

fork 예제

#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

int main()
{
        int i = 0;
        pid_t ret;

        for(i = 0 ; i < 3 ; i++)
        {
                ret = fork();
                printf("[%d] PID(%d) PPID(%d)\n", i, getpid(), getppid());
#ifndef OMIT_SWITCH
                switch(ret) {
                        case 0:
                                pause(); /* causes the process(or thread) to sleep  */
                                return 0;
                        case 1:
                                break;
                        default:
                                break;

                }
#endif
        }
        wait(NULL); /* suspends execution of the calling thread  */
        return 0;
}

exec

exec 예제

#include <stdio.h>
#include <unistd.h>

int main()
{
		// if (execl("/bin/ls", "ls -al", NULL) == -1)
        if(execl("/bin/ls", "ls", "-al", NULL) == -1) 
        {
                perror("execl");
        }
        printf("+ after execl \n");
        return 0;
}

❓execl에서 "ls -al"로 한번에 인수를 전달하면 어떻게 될까?

if (execl("/bin/ls", "ls -al", NULL) == -1)

위와 같이 작성하면 ls -al에서 앞부분의 "ls"만 추출되어 실행된다.

fork-exec

forkexec_parent.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>

int main()
{
        pid_t pid_child; /* (sys/types.h) */

        printf("Parent[%d]: Start\n", getpid());

        int fd = open("forkexec.log", O_WRONLY|O_CREAT|O_APPEND, 0644); /* (fcntl.h) */
        if(fd == -1)
        {
                perror("FAIL:open"); /* (stdio.h) produecs a message on standard error  */
                exit(EXIT_FAILURE); /* (stdlib.h) causes normal process termination */
        }
        dprintf(fd, "Parent[%d]: Open Log File(fd=%d)\n", getpid(), fd); /* print to file descriptor  */
#ifdef MY_FD_CLOEXEC
// #ifdef APPLY_FD_CLOEXEC
        int ret_fcntl;
        if( (ret_fcntl = fcntl(fd, F_SETFD, FD_CLOEXEC)) == -1) /* (fctnl.h) control file descriptor  */
        {
                perror("FAIL:fcntl(F_SETFD, FD_CLOEXEC)");
                exit(EXIT_FAILURE);
        }
#endif
        /* fork-exec mode */
        char *argv_exec[] = { "forkexec_child", (char *)NULL };
        switch(pid_child = fork())
        {
                case 0:
                        execv( argv_exec[0], argv_exec ); /* (unistd.h) replace the current process image with a new process image  */
                        break;
                case 1:
                        perror("FAIL : FORK");
                        break;
                default:
                        wait(NULL);
                        break;
        }
        printf("Parent[%d] : Exit\n", getpid());

        return (0);
}

forkexec_child.c

#include <stdio.h>
#include <unistd.h>

int main()
{
        dprintf(STDOUT_FILENO, "Child[%d]: Start\n", getpid());
        dprintf(3, "Child[%d]: fd(3): Test fd.\n", getpid());
        close(3);
        dprintf(STDOUT_FILENO, "Child[%d]: Exit\n", getpid());

        return 0;
}

posix_spawn 계열 함수

posix_spawn.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <spawn.h>
#include <fcntl.h>

int main()
{
        int ret_err = 0;
        pid_t pid_child;
        char buf_err[64];
        posix_spawn_file_actions_t posix_faction; /* (spwan.h) */
        char *argv_child[] = {"forkexec_child", NULL};

        printf("Parent[%d]: Start\n", getpid());

        if ((ret_err = posix_spawn_file_actions_init(&posix_faction)) != 0)
        {
                strerror_r(ret_err, buf_err, sizeof(buf_err));
                fprintf(stderr, "Fail: file_actions_init: %s\n", buf_err);
                exit(EXIT_FAILURE);
        }

        if ((ret_err = posix_spawn_file_actions_addopen(&posix_faction,
                                        3, "pspawn.log", O_WRONLY|O_CREAT|O_APPEND, 0664)) != 0) /* (fcntl.h)  */
        {
                strerror_r(ret_err, buf_err, sizeof(buf_err));
                fprintf(stderr, "Fail: file_actions_addopen: %s\n", buf_err);
                exit(EXIT_FAILURE);
        }

        ret_err = posix_spawn( &pid_child,
                                argv_child[0],
                                &posix_faction,
                                NULL,
                                argv_child,
                                NULL);

        if ((ret_err = posix_spawn_file_actions_destroy(&posix_faction)) != 0)
        {
                strerror_r(ret_err, buf_err, sizeof(buf_err));
                fprintf(stderr, "Fail : file_actions_destroy : %s\n", buf_err);
                exit(EXIT_FAILURE);
        }
        printf("Parent[%d] : Wait for child(%d) \n", getpid(), (int)pid_child);
        (void)wait(NULL);
        printf("Parent[%d] : Exit \n", getpid());

        return (0);
}
profile
공부방

0개의 댓글