<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>REAKWON</title>
    <link>https://reakwon.tistory.com/</link>
    <description>와나진짜</description>
    <language>ko</language>
    <pubDate>Sun, 19 Apr 2026 19:54:39 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>REAKWON</managingEditor>
    <image>
      <title>REAKWON</title>
      <url>https://t1.daumcdn.net/cfile/tistory/9996CC405BF2C94130</url>
      <link>https://reakwon.tistory.com</link>
    </image>
    <item>
      <title>[openssl] Server - Client 인증서 검증과 통신 소스 코드</title>
      <link>https://reakwon.tistory.com/240</link>
      <description>&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;CA를 통한 인증서 검증과 Server - Client 통신&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CA를 활용한 클라이언트 인증서 검증을 하기 위해서 CA의 인증서와 CA 서명된 Client인증서, Server 인증서가 필요합니다. 아래의 포스팅을 참고하면 CA, Server, Client의 키 쌍들과 CA 인증서와 Server, Client 인증서를 생성할 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://reakwon.tistory.com/239&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://reakwon.tistory.com/239&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1696314201214&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;openssl CA를 통한 Server - Client 인증서 검증 및 대칭키 공유 과정&quot; data-og-description=&quot;CA 인증서로 상대방의 인증서 확인 방법 디렉토리 구조 디렉토리 구조는 아래와 같으며 각각 인증서를 생성하는 과정에서 여러 키와 인증서가 생성이 될 겁니다. # ls CA Client Server CA : Root CA로 CA&quot; data-og-host=&quot;reakwon.tistory.com&quot; data-og-source-url=&quot;https://reakwon.tistory.com/239&quot; data-og-url=&quot;https://reakwon.tistory.com/239&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/yW3R6/hyT53HxxtC/m2fS2JTGAQXxF5BwZ77jPK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/gQIex/hyT5WaAz9x/Ni2IT8vXIKvOijNR4ACkV0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://reakwon.tistory.com/239&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://reakwon.tistory.com/239&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/yW3R6/hyT53HxxtC/m2fS2JTGAQXxF5BwZ77jPK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/gQIex/hyT5WaAz9x/Ni2IT8vXIKvOijNR4ACkV0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;openssl CA를 통한 Server - Client 인증서 검증 및 대칭키 공유 과정&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;CA 인증서로 상대방의 인증서 확인 방법 디렉토리 구조 디렉토리 구조는 아래와 같으며 각각 인증서를 생성하는 과정에서 여러 키와 인증서가 생성이 될 겁니다. # ls CA Client Server CA : Root CA로 CA&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;reakwon.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하면 디렉토리의 구조는 아래와 같게 됩니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1696313675519&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# ls
Client  RootCA  Server&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Server/server.c&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;
&lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-9615403369038266&quot; data-ad-slot=&quot;6888174260&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;!-- 광고 2개짜리 --&gt;
&lt;pre id=&quot;code_1696313596122&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;memory.h&amp;gt;
#include &amp;lt;errno.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;netinet/in.h&amp;gt;
#include &amp;lt;arpa/inet.h&amp;gt;
#include &amp;lt;netdb.h&amp;gt;
 
#include &amp;lt;openssl/rsa.h&amp;gt;    
#include &amp;lt;openssl/crypto.h&amp;gt;
#include &amp;lt;openssl/x509.h&amp;gt;
#include &amp;lt;openssl/pem.h&amp;gt;
#include &amp;lt;openssl/ssl.h&amp;gt;
#include &amp;lt;openssl/err.h&amp;gt;
 
#define CHK_NULL(x) if((x) == NULL) exit(1);
#define CHK_ERR(err, s) if((err) == -1) { perror(s); exit(1); }
#define CHK_SSL(err) if((err) == -1) { ERR_print_errors_fp(stderr); exit(2); }
static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx){

    char *str;
    X509 *cert = X509_STORE_CTX_get_current_cert(ctx);

    if (cert) {
        printf(&quot;Cert depth %d\n&quot;, X509_STORE_CTX_get_error_depth(ctx));
                
        str = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
        CHK_NULL(str);
        printf(&quot;\t subject : %s\n&quot;, str);
        OPENSSL_free(str);

        str = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
        CHK_NULL(str);
        printf(&quot;\t issuer : %s\n&quot;, str);
        OPENSSL_free(str);
    }

    return preverify_ok;
}
 
int main(void){

    int err, listen_fd, socket_fd;
    struct sockaddr_in server, client;
    size_t client_len;
   
    // SSL 관련 객체 
    SSL_CTX *ctx;
    SSL *ssl;
    X509 *client_cert;
    SSL_METHOD  *meth;
    
    char *str;
    char buf[128];
   
    printf(&quot;Server start!\n&quot;);

    // SSL 초기 셋팅 
    SSL_load_error_strings();
    SSLeay_add_ssl_algorithms();
    meth = SSLv23_server_method();
    ctx = SSL_CTX_new(meth);  
   
    if(!ctx) {
        ERR_print_errors_fp(stderr);
        exit(-1);
    }
   
    // 서버의 인증서 설정 
    if(SSL_CTX_use_certificate_file(ctx, &quot;./Server.crt&quot;, SSL_FILETYPE_PEM) &amp;lt;= 0) {
        ERR_print_errors_fp(stderr);
        exit(-1);
    }
   
    // 서버의 개인키 설정 
    if(SSL_CTX_use_PrivateKey_file(ctx, &quot;./privkey-Server.pem&quot;, SSL_FILETYPE_PEM) &amp;lt;= 0) {
        ERR_print_errors_fp(stderr);
        exit(-1);
    }

    // 개인키 사용 가능성 체크
    if(!SSL_CTX_check_private_key(ctx)) {
        fprintf(stderr, &quot;private key is not matched to public key.\n&quot;);
        exit(-1);
    }
    // 사용할 CA의 인증서 설정
    if(!SSL_CTX_load_verify_locations(ctx, &quot;../RootCA/CA.crt&quot;, NULL)) {
        ERR_print_errors_fp(stderr);
        exit(-1);
    }

    // Client의 인증서를 검증하기 위한 설정, CA는 하나만 있다고 가정-&amp;gt; depth = 1
    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, verify_callback);
    SSL_CTX_set_verify_depth(ctx, 1); 
   
    // TCP socket 생성 이후 bind, listen, accept
    listen_fd = socket(AF_INET, SOCK_STREAM, 0);
    CHK_ERR(listen_fd, &quot;socket&quot;);
   
    memset(&amp;amp;server, 0x00, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons(12340); 
 
    err = bind(listen_fd, (struct sockaddr*)&amp;amp;server, sizeof(server));
    CHK_ERR(err, &quot;bind&quot;);
   
    err = listen(listen_fd, 5);
    CHK_ERR(err, &quot;listen&quot;);
    
    client_len = sizeof(client);
    socket_fd = accept(listen_fd, (struct sockaddr*)&amp;amp;client, &amp;amp;client_len);
    CHK_ERR(socket_fd, &quot;accept&quot;);
    close(listen_fd);
    
    // SSL 세션 생성 
    ssl = SSL_new(ctx);
    CHK_NULL(ssl);

    // SSL 접속 대기 , SSL_accept 완료 = SSL handshake 완료
    SSL_set_fd(ssl, socket_fd);
    err = SSL_accept(ssl);    
    CHK_SSL(err);
   
    // 사용하는 Cipher 
    printf(&quot;SSL is using cipher %s\n&quot;, SSL_get_cipher(ssl));
   
    // 클라이언트의 인증서를 받고 검증
    client_cert = SSL_get_peer_certificate(ssl);
    CHK_NULL(client_cert);


    if(SSL_get_verify_result(ssl) == X509_V_OK){
        printf(&quot;verify cert OK\n&quot;);
        X509_free(client_cert);
    } else {
        printf(&quot;verify cert Failed\n&quot;);
    }

   
    // 클라이언트로부터 메시지 수신
    err = SSL_read(ssl, buf, sizeof(buf)-1);
    CHK_SSL(err);
    buf[err] = 0;
    printf(&quot;From Client '%s'\n&quot;, buf);
   
    err = SSL_write(ssl, &quot;Hello, Client!&quot;, strlen(&quot;Hello, Client!&quot;));
    CHK_SSL(err);
   
    //자원 해제 
    close(socket_fd);
    SSL_free(ssl);
    SSL_CTX_free(ctx);
   
    return(0);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;!-- 광고 2개짜리 --&gt; &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-client=&quot;ca-pub-9615403369038266&quot; data-ad-slot=&quot;2573768191&quot; data-ad-format=&quot;auto&quot; data-full-width-responsive=&quot;true&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;SSL Context&lt;/b&gt; : Context는 cipher, TLS 버전, 인증서 및 암호 파라미터들의 모음입니다. 이를 기반으로 SSL session이 생성됩니다.&amp;nbsp; 그러니까 인증서나 키 등의 세션들이 공통적으로 사용하는 데이터를 미리 설정해둠에 따라 세션이 만들어질때마다 이런 데이터를 미리 준비하는 과정이 없어집니다. 그 말은 즉, 시간이 줄어든다는 뜻입니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;SSL Session&lt;/b&gt; : Session은 Server와 Client간의 연결이 실제 이루어진 것을 의미합니다. 이 세션에서 데이터의 전송이 이루어집니다. Server나 Client간의 세션이 없다면 만들어지고, 만들어져있다면 세션을 다시 재활용하는 것도 가능합니다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;인증서 검증&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Client의 인증서를 검증하기 위해서는 SSL_CTX_set_verify, 그리고 SSL_CTX_set_verify_depth를 지정&lt;/b&gt;해야합니다. SSL_CTX_set_verify에 SSL_VERIFY_PEER 옵션 지정 후 verify_callback 함수를 통해서 커스텀한 검증을 할 수 있는데, verify_callback함수에 preverify_ok라는 인자는 이전에 검증 과정의 결과를 알려줍니다. depth에 따라서 여러번 호출이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 verify_callback 함수는 &lt;b&gt;SSL_CTX_set_verify_depth에 의해서 depth를 지정해 줄 수 있는데, depth에 따라 인증서를 어느 수준까지 인증할 것이냐를 정의해줄 수 있습니다.&lt;/b&gt; 예를 들어 depth가 1이면 Client(depth 0)와 그 인증서를 발행한 CA(depth 1)의 인증서를 검증하게 되는 것이구요. depth가 2일 경우에는 위 단계에서 CA의 인증서를 발생한 상위의 CA(depth 2)의 인증서를 검증합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 잘 검증되었는지를 확인하는&lt;b&gt; SSL_get_verify_result&lt;/b&gt; 함수를 이용해 문제없이 인증서가 검증되었는지 확인할 수 있습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Client/client.c&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;!-- 광고 2개짜리 --&gt; &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-client=&quot;ca-pub-9615403369038266&quot; data-ad-slot=&quot;2573768191&quot; data-ad-format=&quot;auto&quot; data-full-width-responsive=&quot;true&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1696313627703&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;memory.h&amp;gt;
#include &amp;lt;errno.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;netinet/in.h&amp;gt;
#include &amp;lt;arpa/inet.h&amp;gt;
#include &amp;lt;netdb.h&amp;gt;
 
#include &amp;lt;openssl/crypto.h&amp;gt;
#include &amp;lt;openssl/x509.h&amp;gt;
#include &amp;lt;openssl/pem.h&amp;gt;
#include &amp;lt;openssl/ssl.h&amp;gt;
#include &amp;lt;openssl/err.h&amp;gt;
 
#define CHK_NULL(x) if((x) == NULL) exit(1);
#define CHK_ERR(err, s) if((err) == -1) { perror(s); exit(1); }
#define CHK_SSL(err) if((err) == -1) { ERR_print_errors_fp(stderr); exit(2); }
 
int main(void)
{
    int err, socket_fd;
    struct sockaddr_in server;
   
    SSL_CTX *ctx;
    SSL *ssl;
    X509 *server_cert;
    char *str;
    char buf[128];
    SSL_METHOD    *method;
   
    //초기 세팅
    SSL_load_error_strings();
    SSLeay_add_ssl_algorithms();
    method = SSLv23_client_method();
    ctx = SSL_CTX_new(method);
    CHK_NULL(ctx);
   
    // Context에서 사용할 인증서 설정
    if(SSL_CTX_use_certificate_file(ctx, &quot;./Client.crt&quot;, SSL_FILETYPE_PEM) &amp;lt;= 0) {    
        ERR_print_errors_fp(stderr);
        exit(-1);
    }
   
    // Context에서 사용할 개인키 설정
    if(SSL_CTX_use_PrivateKey_file(ctx, &quot;./privkey-Client.pem&quot;, SSL_FILETYPE_PEM) &amp;lt;= 0) {
        ERR_print_errors_fp(stderr);
        exit(-1);
    }
   
    // 개인키 사용가능성 확인
    if(!SSL_CTX_check_private_key(ctx)) {
        fprintf(stderr, &quot;Private key is not matched to public key\n&quot;);
        exit(-1);
    }
   
    // Socket의 Connect까지 설정하는 과정
    socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    CHK_ERR(socket_fd, &quot;socket error &quot;);
   
    memset(&amp;amp;server, 0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = inet_addr(&quot;127.0.0.1&quot;);
    server.sin_port = htons(12340); 
   
    err = connect(socket_fd, (struct sockaddr*)&amp;amp;server, sizeof(server));
    CHK_ERR(err, &quot;connect error &quot;);
   
    //SSL 세션 객체 생성
    ssl = SSL_new(ctx); 
    CHK_NULL(ssl);
   
    //SSL객체에 socket fd를 설정
    SSL_set_fd(ssl, socket_fd);
    err = SSL_connect(ssl); 
    CHK_NULL(err);
   
    printf(&quot;SSL is using cipher %s\n&quot;, SSL_get_cipher(ssl));
   
    // 서버의 인증서를 가져옴
    server_cert = SSL_get_peer_certificate(ssl);
    CHK_NULL(server_cert);

    printf(&quot;Server certificate:\n&quot;);
   
    //인증서의 몇가지 정보를 출력
    str = X509_NAME_oneline(X509_get_subject_name(server_cert), 0, 0);
    CHK_NULL(str);
    printf(&quot;\t subject: %s\n&quot;, str);
    OPENSSL_free(str);
   
    /* 인증서의 issuer를 출력한다. */
    str = X509_NAME_oneline(X509_get_issuer_name(server_cert), 0, 0);
    CHK_NULL(str);
    printf(&quot;\t issuer: %s\n&quot;, str);
    OPENSSL_free(str);
   
    X509_free(server_cert);
   
    // 서버에게 메시지를 전송
    err = SSL_write(ssl, &quot;Hello World!&quot;, strlen(&quot;Hello World!&quot;));
    CHK_SSL(err);
   
    // 서버로부터 메시지 수신
    err = SSL_read(ssl, buf, sizeof(buf)-1);
    CHK_SSL(err);
    
    buf[err] = 0;
    printf(&quot;From Server : '%s'\n&quot;, buf);

   
    // 세션 종료 및 ssl, ctx 자원 해제
    SSL_shutdown(ssl);   
    close(socket_fd);
    SSL_free(ssl);
    SSL_CTX_free(ctx);
   
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;결과화면&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;
&lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-9615403369038266&quot; data-ad-slot=&quot;6888174260&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인증서를 대충만들었기 때문에 구분이 잘 안가실텐데, 아래의 depth 1은 CA 인증서, depth 0은 Client 인증서의 정보를 나타냅니다. CA의 인증서를 보면 subject와 issuer가 같은 것을 알 수 있죠. 자기 자신의 인증서를 자신이 사이닝했습니다.&lt;/p&gt;
&lt;!-- 광고 2개짜리 --&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style7&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: left;&quot;&gt;&lt;b&gt;Server&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: left;&quot;&gt;# ./server &lt;br /&gt;Server start! &lt;br /&gt;Cert depth 1 &lt;br /&gt;&amp;nbsp; &amp;nbsp; subject : /C=KR/ST=Some-State/O=CA/OU=CA/CN=CA/emailAddress=no &lt;br /&gt;&amp;nbsp; &amp;nbsp; issuer : /C=KR/ST=Some-State/O=CA/OU=CA/CN=CA/emailAddress=no &lt;br /&gt;Cert depth 0 &lt;br /&gt;&amp;nbsp; &amp;nbsp; subject : /C=KR/ST=Some-State/O=Internet Widgits Pty Ltd/CN=Client/emailAddress=client@dd.com &lt;br /&gt;&amp;nbsp; &amp;nbsp; issuer : /C=KR/ST=Some-State/O=CA/OU=CA/CN=CA/emailAddress=no &lt;br /&gt;SSL is using cipher TLS_AES_256_GCM_SHA384 &lt;br /&gt;verify cert OK &lt;br /&gt;From Client 'Hello World!'&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: left;&quot;&gt;&lt;b&gt;Client&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: left;&quot;&gt;# ./client &lt;br /&gt;SSL is using TLS_AES_256_GCM_SHA384 &lt;br /&gt;Server certificate: &lt;br /&gt;&amp;nbsp; &amp;nbsp; subject: /C=KR/ST=Some-State/O=Internet Widgits Pty Ltd/CN=Server/emailAddress=server@dd.com &lt;br /&gt;&amp;nbsp; &amp;nbsp; issuer: /C=KR/ST=Some-State/O=CA/OU=CA/CN=CA/emailAddress=no &lt;br /&gt;From Server : 'Hello, Client!'&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;참고한 자료&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSL Server - Client 코드 : &lt;a href=&quot;http://pchero21.com/?p=603&quot;&gt;http://pchero21.com/?p=603&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CA, Server, Client 인증서 생성 : &lt;a href=&quot;https://www.cs.toronto.edu/~arnold/427/19s/427_19S/tool/ssl/notes.pdf&quot;&gt;https://www.cs.toronto.edu/~arnold/427/19s/427_19S/tool/ssl/notes.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인증서 검증 : &lt;a href=&quot;https://tribal1012.tistory.com/m/213&quot;&gt;https://tribal1012.tistory.com/m/213&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category> 컴퓨터/운영체제(주로 리눅스)</category>
      <category>openssl Client</category>
      <category>openssl Context</category>
      <category>openssl Server</category>
      <category>openssl session</category>
      <category>openssl 통신 코드</category>
      <category>SSL_CTX_set_verify</category>
      <category>SSL_CTX_set_verify_depth</category>
      <category>SSL_get_peer_certificate</category>
      <category>SSL_read</category>
      <category>SSL_write</category>
      <author>REAKWON</author>
      <guid isPermaLink="true">https://reakwon.tistory.com/240</guid>
      <comments>https://reakwon.tistory.com/240#entry240comment</comments>
      <pubDate>Tue, 3 Oct 2023 16:10:57 +0900</pubDate>
    </item>
    <item>
      <title>openssl CA를 통한 Server - Client 인증서 검증 및 대칭키 공유 과정</title>
      <link>https://reakwon.tistory.com/239</link>
      <description>&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;CA 인증서로 상대방의 인증서 확인 방법&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;디렉토리 구조&amp;nbsp;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디렉토리 구조는 아래와 같으며 각각 인증서를 생성하는 과정에서 여러 키와 인증서가 생성이 될 겁니다.&lt;/p&gt;
&lt;pre id=&quot;code_1696247011087&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# ls
CA  Client  Server&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CA : Root CA로 CA의 개인키, 공개키, 인증서가 저장됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Client : Client의 개인키, 공개키, CSR, 인증서가 저장됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Server : Server의 개인키, 공개키, CSR, 인증서가 저장됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;CA의 인증서 생성 절차&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Root CA라고 가정하고 자신의 인증서를 생성하는 절차입니다.&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. private key 생성&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;!-- 광고 2개짜리 --&gt; &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-client=&quot;ca-pub-9615403369038266&quot; data-ad-slot=&quot;2573768191&quot; data-ad-format=&quot;auto&quot; data-full-width-responsive=&quot;true&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1696243175853&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:5 -out privkey-CA.pem&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;암호 알고리즘은 RSA를 사용하며 2048비트의 rsa 키 길이를 사용하는 개인키를 생성합니다. 추가로 rsa_keygen_pubexp로 exponent를 지정할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. public key 생성&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1696243133730&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# openssl pkey -in privkey-CA.pem -pubout -out pubkey-CA.pem&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;생성된 private key의 쌍인 public key를 생성합니다.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3.&amp;nbsp; Self-Sign한 인증서 생성&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1696243218107&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# openssl req -x509 -new -nodes -key privkey-CA.pem -sha256 -days 365 -out CA.crt
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:KR
State or Province Name (full name) [Some-State]:State
Locality Name (eg, city) []:city
Organization Name (eg, company) [Internet Widgits Pty Ltd]:CA  
Organizational Unit Name (eg, section) []:CA
Common Name (e.g. server FQDN or YOUR name) []:CA
Email Address []:no&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Server 인증서 생성&amp;nbsp;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버의 인증서를 CA의 개인키로 서명하는 절차입니다. 개인키, 공개키를 생성하는 절차는 CA와 같습니다.&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. private key 생성&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1696245810632&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:3 -out privkey-Server.pem&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. public key 생성&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1696245872206&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# openssl pkey -in privkey-Server.pem -pubout -out pubkey-Server.pem&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. CSR 생성&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1696246017374&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# openssl req -new -key privkey-Server.pem -out Server-req.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:KR
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:Seoul
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Server
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:no

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. CA 서명된 인증서 Server 생성&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1696246214729&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# openssl x509 -req -in Server-req.csr -CA ../CA/CA.crt -CAkey ../CA/privkey-CA.pem -CAcreateserial -out Server.crt -days 500 -sha256
Certificate request self-signature ok
subject=C = KR, ST = Some-State, L = Seoul, O = Server, emailAddress = no&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Client 인증서 생성&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Client의 개인키, 공개키를 생성하고 CA의 개인키로 서명합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. private key 생성&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1696246410921&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:3 -out privkey-Client.pem&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. public key 생성&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1696246453514&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# openssl pkey -in privkey-Client.pem -pubout -out pubkey-Client.pem&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. CSR 생성&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;
&lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-9615403369038266&quot; data-ad-slot=&quot;6888174260&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1696246509120&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# openssl req -new -key privkey-Client.pem -out Client-req.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:KR
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:Seoul
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Client
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:no

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4.&amp;nbsp; CA 서명된 Client 인증서 생성&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1696246585737&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# openssl x509 -req -in Client-req.csr -CA ../CA/CA.crt -CAkey ../CA/privkey-CA.pem -CAcreateserial -out Client.crt -days 500 -sha256
Certificate request self-signature ok
subject=C = KR, ST = Some-State, L = Seoul, O = Client, emailAddress = no&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;인증서 검증&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;클라이언트에서 서버 인증서 검증&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1696246680005&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# cd Client
# openssl verify -CAfile ../CA/CA.crt ../Server/Server.crt
../Server/Server.crt: OK&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;서버에서 클라이언트 인증서 검증&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1696246712855&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# cd Server
# openssl verify -CAfile ../CA/CA.crt ../Client/Client.crt 
../Client/Client.crt: OK&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;공개키 추출&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;서버 인증서에서 서버 공개키 추출&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1696246883405&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# cd Client
# cp ../Server/Server.crt .
# openssl x509 -pubkey -in Server.crt -noout &amp;gt; pubkey-Server.pem&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;클라이언트 인증서에서 클라이언트 공개키 추출&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1696246924656&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# cd Server
# cp ../Client/Client.crt .
# openssl x509 -pubkey -in Client.crt -noout &amp;gt; pubkey-Client.pem&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;대칭키&amp;nbsp; 공유&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;클라이언트에서 랜덤한 대칭키 생성 후 Server의 공개키로 암호화&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1696247545062&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# cd Client
# openssl rand -out symkey.pem -base64 32
# hexdump -C symkey.pem 
00000000  51 4f 31 67 6d 5a 63 5a  6e 36 76 47 48 31 36 37  |QO1gmZcZn6vGH167|
00000010  39 47 47 72 68 58 35 43  69 69 6f 4b 33 64 34 41  |9GGrhX5CiioK3d4A|
00000020  2b 6f 38 67 4a 4c 49 4a  64 65 38 3d 0a           |+o8gJLIJde8=.|
0000002d
# openssl pkeyutl -encrypt -in symkey.pem -pubin -inkey pubkey-Server.pem -out symkey.enc&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;클라이언트의 개인키로 서명&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1696247810553&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# openssl dgst -sha1 -sign privkey-Client.pem -out signature.bin symkey.pem&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서버에서 암호화된 대칭키 복호화 후 검증&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;!-- 광고 2개짜리 --&gt; &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-client=&quot;ca-pub-9615403369038266&quot; data-ad-slot=&quot;2573768191&quot; data-ad-format=&quot;auto&quot; data-full-width-responsive=&quot;true&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1696247952413&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# cp ../Client/signature.bin .
# cp ../Server/symkey.enc .
# hexdump -C symkey.pem 
00000000  51 4f 31 67 6d 5a 63 5a  6e 36 76 47 48 31 36 37  |QO1gmZcZn6vGH167|
00000010  39 47 47 72 68 58 35 43  69 69 6f 4b 33 64 34 41  |9GGrhX5CiioK3d4A|
00000020  2b 6f 38 67 4a 4c 49 4a  64 65 38 3d 0a           |+o8gJLIJde8=.|
0000002d
# openssl dgst -sha1 -verify pubkey-Client.pem -signature signature.bin symkey.pem
Verified OK&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 이 대칭키를 가지고 암복호화 통신을 하면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category> 컴퓨터/운영체제(주로 리눅스)</category>
      <category>CA</category>
      <category>openssl</category>
      <category>openssl 인증서</category>
      <category>PKI</category>
      <category>인증서 검증</category>
      <category>인증서 생성</category>
      <author>REAKWON</author>
      <guid isPermaLink="true">https://reakwon.tistory.com/239</guid>
      <comments>https://reakwon.tistory.com/239#entry239comment</comments>
      <pubDate>Mon, 2 Oct 2023 21:05:35 +0900</pubDate>
    </item>
    <item>
      <title>[리눅스] 알면 도움되는 dd 명령어 사용 방법과 사용 예들</title>
      <link>https://reakwon.tistory.com/238</link>
      <description>&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;dd 명령어&amp;nbsp;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;dd 명령어는 파일을 복사하거나 sdcard 같은 저장장치에 데이터를 쓸 수 있게 해주거나, 혹은 반대로 저장장치나 파일로부터 데이터를 복사해올 수 있게 만들어주는 유용한 명령어입니다.&lt;/b&gt; 그래서 블록(Block)이라는 단위를 통해서 파일의 내용을 다른 파일이나 저장 장치로 쓸 수 있습니다. 이제부터 저장장치도 파일이라고 간주하고 설명하도록 하겠습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;사용법 1&amp;nbsp; :&amp;nbsp; 파일 전체를 복사&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 dd 명령어는 아래와 같은 input file과 output file을 가지게 됩니다. 옵션이 아무것도 없죠. 이런 경우에는 파일의 전체를 복사합니다. 아래의 명령어는 /home/image.ext4 파일을 /dev/mmcblk0p2 파일로 복사합니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1696236521909&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# dd if=/home/image.ext4 of=/dev/mmcblk0p2&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;if : input file의 약자로 복사할 파일을 지정합니다.&lt;/li&gt;
&lt;li&gt;of : output file의 약자로 출력이 될 파일을 지정합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;사용법2 : input의 내용을 output의 일부분으로 복사&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 명령어는 기존 output의 내용이 있던 없던 간에 무조건 input의 내용으로만 복사가 되었습니다. 하지만 &lt;b&gt;output의 내용의 일부분만 input의 내용으로 복사할 경우나 추가할 경우에는 conv 옵션에 notrunc 값을 지정&lt;/b&gt;해야합니다. 참고로 여기서 conv는 convert의 줄임말입니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1696238007587&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# dd if=size512.bin of=size1024.bin conv=notrunc&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;conv=notrunc : output 파일의 내용을 자르지 않는다는 의미입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;사용법3 :&amp;nbsp; 블록 사이즈 지정하고 원하는 바이트만큼 복사&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블록사이즈는 사용자가 지정하기 나름인데 기본적으로 설정되어있는 블록 사이즈는 512바이트입니다. 블록 사이즈나 블록의 갯수를 지정하여 원하는 양의 크기대로 복사할 수 있습니다. &lt;b&gt;bs 옵션은 block size의 의미로 블록의 크기를 지정&lt;/b&gt;하는데 사용됩니다. 만약 512바이트가 아닌 블록 사이즈가 1024바이트이길 원한다면 bs의 옵션에 1024를 지정해주면 됩니다. 그리고 그 &lt;b&gt;블록을 몇개 복사할 것이냐를 지정할때는 count옵션을 사용&lt;/b&gt;하면 됩니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같은 경우는 block size가 1이며 512의 블록을 output.bin으로 복사합니다. 이럴 경우에는 단순히 512바이트 만큼 복사가 되겠네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;!-- 광고 2개짜리 --&gt; &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-client=&quot;ca-pub-9615403369038266&quot; data-ad-slot=&quot;2573768191&quot; data-ad-format=&quot;auto&quot; data-full-width-responsive=&quot;true&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1696238384736&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# dd if=/dev/vda1 of=output.bin bs=1 count=512&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;bs : block size의 의미로 블록의 크기&lt;/li&gt;
&lt;li&gt;count : input file의 블록을 몇개 복사할 것인지를 지정&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;사용법4 : input 파일의 내용을 일부 건너 뛰고 복사&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;input 파일에서 처음부터가 아닌 몇 블록을 건너 뛴 다음에 복사하고 싶을때는 skip 옵션을 사용하시면 됩니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1696238974449&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# dd if=size1024.bin  of=size512.bin bs=128 skip=1 count=1&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;skip : input 파일에서 건너 뛸 블록의 갯수를 의미합니다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 예에서는 블록 사이즈를 128바이트로 지정한뒤 한 블록을 건너 뛰어서 1개의 블록을 복사하는 예입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블록의 갯수가 아니고 skip을 단순히 바이트 단위로 건너 뛰고 싶을 경우 iflag에 skip_bytes를 지정하면 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1696239892968&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# dd if=size1024.bin of=size512.bin skip=128 iflag=skip_bytes bs=128 count=1&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;iflag=skip_bytes : skip을 블록 단위가 아닌 바이트 단위로 인식하여 input의 내용을 건너 뜁니다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 위의 두 예제는 같은 결과를 보여줍니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;사용법5 : output 파일의 내용을 일부 건너 뛰어 복사&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;skip옵션과 마찬가지로 output 파일의 블록을 건너 뛸 수도 있습니다. seek 옵션을 사용하면 됩니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1696239241903&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# dd if=size1024.bin of=size512.bin bs=128 seek=1 count=1&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;seek : 건너 뛸 output 파일의 블록 갯수를 지정합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 예에서는 블록의 크기가 128바이트이며, size1024.bin의 블록 하나를 복사합니다. 이때 seek=1을 사용해 size512.bin의 블록 하나를 건너 뛴 자리에 복사가 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;역시 seek을 블록 단위가 아닌 바이트 단위로 인식시키려면 oflag에 seek_bytes를 지정하면 됩니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1696240068400&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# dd if=size1024.bin of=size512.bin bs=128 seek=128 count=1 oflag=seek_bytes&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;oflag=seek_bytes : seek을 블록 단위가 아닌 바이트 단위로 변경합니다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 두 예제는 같은 결과를 보여줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;사용법6 : 출력 파일이 존재할 때만 실행&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력 파일이 있어야만 실행해야할 경우에는 아래와 같은 명령어를 사용하면 됩니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1696240298494&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# dd if=size1024.bin of=size512.bin conv=nocreat
dd: failed to open 'size512.bin': No such file or directory&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;conv=nocreat : output 파일이 있을 경우에만 dd 명령어를 수행합니다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 파일이 존재하지 않는다면 위의 결과와 같이 output 파일이 존재하지 않는다는 오류를 발생시키고 명령어를 수행하지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;dd명령은 이정도만 사용하면 무난하게 리눅스에서 사용하실 수 있을 겁니다.&amp;nbsp;&lt;/p&gt;</description>
      <category>dd seek</category>
      <category>dd skip</category>
      <category>dd명령어</category>
      <category>dd사용법</category>
      <category>리눅스 dd</category>
      <category>블록파일복사</category>
      <category>파일복사</category>
      <author>REAKWON</author>
      <guid isPermaLink="true">https://reakwon.tistory.com/238</guid>
      <comments>https://reakwon.tistory.com/238#entry238comment</comments>
      <pubDate>Mon, 2 Oct 2023 19:00:13 +0900</pubDate>
    </item>
    <item>
      <title>[리눅스] Datagram Socket 통신 - 간단 server - client C 소스 코드</title>
      <link>https://reakwon.tistory.com/237</link>
      <description>&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Datagram Socket 통신&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Stream Socket은 연결 지향형이고 &lt;b&gt;Datagram은 비연결형의 Socket 통신 방법&lt;/b&gt;입니다. &lt;b&gt;신뢰성은 그만큼 떨어지지만&amp;nbsp;단순하고 빠른 전송을 위한 것으로 UDP 프로토콜&lt;/b&gt;을 사용합니다. Stream Socket과는 다르게 Datagram 소켓을 사용하여 간단히 Server - Client 통신 소스코드를 짜보도록 합시다. Stream Socket은 서버와 클라이언트 사이에 연결을 맺어주느라 소스 코드의 길이가 길지요. &lt;b&gt;지금 볼 datagram socket은 이러한 연결(Connection) 과정이 생략&lt;/b&gt;이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니까 Stream Socket과는 다르게 listen, accept를 datagram socket에서 사용할 필요가 없어졌습니다. 그래서 다행이라고 할까요? Stream socket보다는 코드의 길이가 짧습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;서버 코드&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래에서 구현한 소스코드는 client의 메시지를 받아서 그대로 client쪽으로 돌려주는 echo 서버의 소스코드입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1695542065562&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//dgram-server.c
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;netinet/in.h&amp;gt;
#include &amp;lt;arpa/inet.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;

#define PORT 12346
#define BUF_SIZE 128

void err_exit(const char *err){
        perror(err);
        exit(1);
}

int main(void){
        int socket_fd, n;
        struct sockaddr_in host_addr, client_addr;
        socklen_t size;
        char buffer[BUF_SIZE] = {0,};

        //Datagram socket 생성
        socket_fd=socket(PF_INET,SOCK_DGRAM,0);
        if(socket_fd &amp;lt; 0) err_exit(&quot;socket error &quot;);

        //server ip와 bind하기 위해 주소 설정
        memset(&amp;amp;host_addr, 0, sizeof(host_addr));
        host_addr.sin_family=AF_INET;
        host_addr.sin_port=htons(PORT); 
        host_addr.sin_addr.s_addr=0;    //자신의 주소로 자동으로 설정 

        //socket과 host_addr과 bind
        if(bind(socket_fd,(struct sockaddr *)&amp;amp;host_addr,sizeof(struct sockaddr)) &amp;lt; 0)
                err_exit(&quot;bind error &quot;);

        //Client의 메시지를 그대로 다시 돌려준다. 
        memset(&amp;amp;client_addr, 0, sizeof(struct sockaddr));
        while(1){
                size = sizeof(struct sockaddr);

                //accept에서 client_addr을 얻어온 stream socket방식과 다르게
                //accept가 없는 datagram socket은 
                //recvfrom에서 client 정보를 얻어올 수 있다. 
                n = recvfrom(socket_fd, buffer, BUF_SIZE, 0,
                                (struct sockaddr*)&amp;amp;client_addr, &amp;amp;size);

                if(n &amp;lt; 0) err_exit(&quot;recvfrom error &quot;);

                //Client의 접속 정보를 출력
                printf(&quot;Client Info : IP %s, Port %d\n&quot;, 
                        inet_ntoa(client_addr.sin_addr),
                        ntohs(client_addr.sin_port));


                //quit라는 메시지를 받으면 종료 
                if(!strcmp(buffer,&quot;quit&quot;) || n == 0) break;

                //보낼 client_addr 객체까지 있어야 전달 가능
                n = sendto(socket_fd, buffer, n, 0,
                                (struct sockaddr*)&amp;amp;client_addr, sizeof(struct sockaddr));
                if(n &amp;lt; 0)err_exit(&quot;send error &quot;);

        }

        shutdown(socket_fd, SHUT_RDWR);
        return 0;

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 stream socket과 다른 점이 있다면, SOCK_STREAM이 아닌 &lt;b&gt;SOCK_DGRAM을 사용&lt;/b&gt;한다는 점입니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;
&lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-9615403369038266&quot; data-ad-slot=&quot;6888174260&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1695542170713&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;socket_fd=socket(PF_INET,SOCK_DGRAM,0);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;stream socket은 send, recv를 사용하였는데, Datagram socket에서는 sendto, recvfrom을 사용하는 것을 알 수 있네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 두 함수들의 끝 2개는 sockaddr의 구조체와 크기입니다. Server는 accept과정이 없기 때문에 client의 주소를 알 방법이 없습니다. 그래서 다시 echo할 주소가 없다는 거죠. &lt;b&gt;recvfrom은 메시지를 받을때 송신자의 주소를 가져오기 위해서 사용&lt;/b&gt;합니다. &lt;b&gt;sendto도 마찬가지로 보낼 곳을 지정&lt;/b&gt;할때 사용합니다. 이 주소 정보가 없다면 아래와 같은 관계가 성립됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1695542182056&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;send(sockfd, buf, len, flags) -&amp;gt; sendto(sockfd, buf, len, flags, NULL, 0)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1695542189978&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;recv(sockfd, buf, len, flags) -&amp;gt;  recvfrom(sockfd, buf, len, flags, NULL, NULL)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;클라이언트 코드&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이에 대응하는 client의 소스코드입니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1695542354836&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//dgram-client.c
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;netinet/in.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;errno.h&amp;gt;
#include &amp;lt;arpa/inet.h&amp;gt; 

#define BUF_SIZE 128

void err_exit(const char *err){
        perror(err);
        exit(1);
}

int main(int argc, char *argv[])
{
        int sockfd = 0, n = 0;
        uint16_t port;
        char buffer[BUF_SIZE] = {0,};
        struct sockaddr_in server_addr;
        int size; 

        if(argc != 3){
                printf(&quot;\n Usage: %s server_ip port \n&quot;,argv[0]);
                return 1;
        } 

        port = atoi(argv[2]);

        //Internet용 socket(Datagram)을 연다.
        if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) &amp;lt; 0)
                err_exit(&quot;socket error &quot;);

        //server_addr의 구조체를 깔끔히 0으로 도배 
        memset(&amp;amp;server_addr, 0, sizeof(server_addr)); 
        server_addr.sin_family = AF_INET;
        server_addr.sin_port = htons(port); 
        //127.0.0.1은 본인의 IP이다. 
        inet_aton(argv[1], (struct in_addr*)&amp;amp;server_addr.sin_addr);


        while(1){
                while(1){
                        printf(&quot;message:&quot;);
                        fgets(buffer, BUF_SIZE, stdin);
                        if(strlen(buffer) &amp;gt;= 100)
                                printf(&quot;message too large\n&quot;);
                        else break;

                };
                // \n을 \0로 처리 
                buffer[strlen(buffer)-1] = '\0';

                size = sizeof(struct sockaddr);
                //서버에게 메시지 전송
                //connect 콜이 없어서 server ip로 직접 보낸다.
                n = sendto(sockfd, buffer, strlen(buffer)+1, 0,
                                (struct sockaddr*)&amp;amp;server_addr, sizeof(struct sockaddr));
                
                if(n &amp;lt; 0) err_exit(&quot;send error &quot;);
                if(!strcmp(buffer, &quot;quit&quot;)) break;

                //서버로부터 에코된 메시지를 받음
                n = recvfrom(sockfd, buffer, BUF_SIZE, 0,
                                (struct sockaddr*)&amp;amp;server_addr, &amp;amp;size);

                if(n &amp;lt; 0) err_exit(&quot;recv error &quot;);

                printf(&quot;%s\n&quot;, buffer);


        }

        shutdown(sockfd, SHUT_RDWR);
        return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;!-- 광고 2개짜리 --&gt; &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-client=&quot;ca-pub-9615403369038266&quot; data-ad-slot=&quot;2573768191&quot; data-ad-format=&quot;auto&quot; data-full-width-responsive=&quot;true&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;결과 화면&lt;/b&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 34px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style15&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 16px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 16px;&quot;&gt;Server&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 16px;&quot;&gt;Client&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 18px; text-align: left;&quot;&gt;# ./server &lt;br /&gt;Client Info : IP 127.0.0.1, Port 60112 &lt;br /&gt;Client Info : IP 127.0.0.1, Port 60112 &lt;br /&gt;Client Info : IP 127.0.0.1, Port 60112&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 18px; text-align: left;&quot;&gt;# ./client 127.0.0.1 12346 &lt;br /&gt;message:hello datagram server~~ &lt;br /&gt;hello datagram server~~ &lt;br /&gt;message:good good &lt;br /&gt;good good &lt;br /&gt;message:quit&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기까지 간단하게 UDP를 사용하는 server - client 통신 구현을 해보았습니다. 여러 클라이언트를 받기 위해서는 다중 프로세스, 다중 쓰레드, 다중입출력을 활용해야겠죠. 다중입출력 방식 중 하나인 epoll에 관한 설명도 저의 블로그에 있으니 확인해보세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://reakwon.tistory.com/236&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://reakwon.tistory.com/236&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1695542713372&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[LINUX] epoll의 개념과 이를 활용한 다중입출력 방식의 서버, 클라이언트&quot; data-og-description=&quot;epoll 뿐만 아닌 다중 입출력의 설명과 코드를 아래의 note에서 확인하실 수 있습니다. https://reakwon.tistory.com/233 리눅스 프로그래밍 note 배포 티스토리에 리눅스에 관한 내용을 두서없이 여지껏 포&quot; data-og-host=&quot;reakwon.tistory.com&quot; data-og-source-url=&quot;https://reakwon.tistory.com/236&quot; data-og-url=&quot;https://reakwon.tistory.com/236&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/EoAJL/hyTZcTmlaL/YP3t0n4TUpMbYV5kCxiY1K/img.png?width=800&amp;amp;height=230&amp;amp;face=0_0_800_230,https://scrap.kakaocdn.net/dn/dqDagu/hyTY1qIjH2/8Mo9NqR4hc0Kp17MIZUpf0/img.png?width=800&amp;amp;height=230&amp;amp;face=0_0_800_230,https://scrap.kakaocdn.net/dn/vkXgd/hyTYZ0KrgP/kiSkQYHXDUUj3IQoKXuK9k/img.png?width=800&amp;amp;height=230&amp;amp;face=0_0_800_230&quot;&gt;&lt;a href=&quot;https://reakwon.tistory.com/236&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://reakwon.tistory.com/236&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/EoAJL/hyTZcTmlaL/YP3t0n4TUpMbYV5kCxiY1K/img.png?width=800&amp;amp;height=230&amp;amp;face=0_0_800_230,https://scrap.kakaocdn.net/dn/dqDagu/hyTY1qIjH2/8Mo9NqR4hc0Kp17MIZUpf0/img.png?width=800&amp;amp;height=230&amp;amp;face=0_0_800_230,https://scrap.kakaocdn.net/dn/vkXgd/hyTYZ0KrgP/kiSkQYHXDUUj3IQoKXuK9k/img.png?width=800&amp;amp;height=230&amp;amp;face=0_0_800_230');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[LINUX] epoll의 개념과 이를 활용한 다중입출력 방식의 서버, 클라이언트&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;epoll 뿐만 아닌 다중 입출력의 설명과 코드를 아래의 note에서 확인하실 수 있습니다. https://reakwon.tistory.com/233 리눅스 프로그래밍 note 배포 티스토리에 리눅스에 관한 내용을 두서없이 여지껏 포&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;reakwon.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category> 컴퓨터/운영체제(주로 리눅스)</category>
      <category>Datagram</category>
      <category>DatagramSocket</category>
      <category>UDP</category>
      <category>UDP client</category>
      <category>UDP server</category>
      <author>REAKWON</author>
      <guid isPermaLink="true">https://reakwon.tistory.com/237</guid>
      <comments>https://reakwon.tistory.com/237#entry237comment</comments>
      <pubDate>Sun, 24 Sep 2023 17:07:35 +0900</pubDate>
    </item>
    <item>
      <title>[LINUX] epoll의 개념과 이를 활용한 다중입출력 방식의 서버, 클라이언트</title>
      <link>https://reakwon.tistory.com/236</link>
      <description>&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;epoll 뿐만 아닌 다중 입출력의 설명과 코드를 아래의 note에서 확인하실 수 있습니다.&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://reakwon.tistory.com/233&quot;&gt;https://reakwon.tistory.com/233&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1695531176371&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;리눅스 프로그래밍 note 배포&quot; data-og-description=&quot;티스토리에 리눅스에 관한 내용을 두서없이 여지껏 포스팅했었데요. 저도 제 포스팅을 찾기가 어렵기도 하고 티스토리에서 코드삽입을 하게 되면 이게 일자로 쭉 쓰여져있는 x같은 현상이 생겨&quot; data-og-host=&quot;reakwon.tistory.com&quot; data-og-source-url=&quot;https://reakwon.tistory.com/233&quot; data-og-url=&quot;https://reakwon.tistory.com/233&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/djRl3C/hyTY3INP16/P1tYrhnMvUiEgGGVikTJEk/img.png?width=800&amp;amp;height=847&amp;amp;face=0_0_800_847,https://scrap.kakaocdn.net/dn/f6M1O/hyTY0rNA8O/Kr7Q5NsBBYafAHKu2W0Fkk/img.png?width=800&amp;amp;height=847&amp;amp;face=0_0_800_847,https://scrap.kakaocdn.net/dn/Efp8A/hyT2qh3lrS/TdQ8evvosl2CtJnbDkVt11/img.png?width=1308&amp;amp;height=1386&amp;amp;face=0_0_1308_1386&quot;&gt;&lt;a href=&quot;https://reakwon.tistory.com/233&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://reakwon.tistory.com/233&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/djRl3C/hyTY3INP16/P1tYrhnMvUiEgGGVikTJEk/img.png?width=800&amp;amp;height=847&amp;amp;face=0_0_800_847,https://scrap.kakaocdn.net/dn/f6M1O/hyTY0rNA8O/Kr7Q5NsBBYafAHKu2W0Fkk/img.png?width=800&amp;amp;height=847&amp;amp;face=0_0_800_847,https://scrap.kakaocdn.net/dn/Efp8A/hyT2qh3lrS/TdQ8evvosl2CtJnbDkVt11/img.png?width=1308&amp;amp;height=1386&amp;amp;face=0_0_1308_1386');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;리눅스 프로그래밍 note 배포&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;티스토리에 리눅스에 관한 내용을 두서없이 여지껏 포스팅했었데요. 저도 제 포스팅을 찾기가 어렵기도 하고 티스토리에서 코드삽입을 하게 되면 이게 일자로 쭉 쓰여져있는 x같은 현상이 생겨&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;reakwon.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;epoll&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;epoll은 poll과 비슷한 방식으로 동작하지만 전체 파일 디스크립터가 아닌 이벤트가 발생한 객체만 되돌려줍니다. 그리고 두 가지 이벤트 트리거 방식을 선택하여 동작할 수 있는데, &lt;b&gt;Level Trigger&lt;/b&gt; 방식과&lt;b&gt; Edge Trigger&lt;/b&gt; 방식입니다. 이 둘을 줄여서 LT, ET라고 하겠습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;&lt;u&gt;이번 글에서는 epoll에 대한 개념을 설명한 후에 Level Trigger 방식의 에코 서버, Edge Trigger 방식의 에코서버의 예제코드를 작성해보도록 하겠습니다. 서버의 소스코드나 클라이언트 소스코드가 길게 느껴질 수 있는데, 한줄 한줄 읽어보면 진짜 별거없습니다!&lt;/u&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; Level Trigger&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LT방식은 어떤 일이 일어났을 때 상태에 따라서 트리거를 지속 시킵니다. 예를 들어서 입력 버퍼가 채워져있는 상태를 1, 아닌 상태를 0으로 놓고, 입력 버퍼가 채워져있는 상태는 계속 1인 상태이기 때문에 이벤트가 지속된다는 뜻입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;230&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkH4YK/btsvoYKF2ZE/Oc8gaEm3KPWfVVVtLl5KkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkH4YK/btsvoYKF2ZE/Oc8gaEm3KPWfVVVtLl5KkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkH4YK/btsvoYKF2ZE/Oc8gaEm3KPWfVVVtLl5KkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkH4YK%2FbtsvoYKF2ZE%2FOc8gaEm3KPWfVVVtLl5KkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;230&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;230&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 그림에서도 볼 수 있듯이 1인 상태는 버퍼가 채워져있는 상태로 정의하고, 빨간색 부분에 대해서 지속적으로 이벤트 발생을 알려줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Edge Trigger&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 ET방식은 사건이 발생한 시점에 딱 한번 트리거 됩니다. 그러니까 버퍼가 채워지는 그 시점에만 이벤트가 발생한다는 뜻입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;
&lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-9615403369038266&quot; data-ad-slot=&quot;6888174260&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;230&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ntXPx/btsvoXZiqZp/BbGcI6k03p2q4FFZ7sPgO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ntXPx/btsvoXZiqZp/BbGcI6k03p2q4FFZ7sPgO1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ntXPx/btsvoXZiqZp/BbGcI6k03p2q4FFZ7sPgO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FntXPx%2FbtsvoXZiqZp%2FBbGcI6k03p2q4FFZ7sPgO1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;230&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;230&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 LT, ET 방식인지에 따라서 잠시 후에 나올 epoll_wait 함수가 다음 이벤트까지 기다리는 시점이 달라집니다. 이제 epoll을 다루기 위한 세가지 함수를 소개합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. epoll_create&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1695466144289&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;sys/epoll.h&amp;gt;
int epoll_create(int size);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;epol l객체를 생성합니다. 커널 2.6.8 버전부터 이 size라는 인자는 무시되며 그냥 0보다 큰 값으로 설정만 해주면 됩니다. 실패시에는 -1을 반환하고 정상 반환일때는 0보다 큰 값이 반환됩니다. 이 반환 값을 파일 디스크립터입니다. 그래서 close로 닫을 수 있습니다. 이렇게 나오는 epoll의 파일 디스크립터는 제어, 이벤트 대기시에 사용이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. epoll_ctl &lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1695466168430&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;sys/epoll.h&amp;gt;
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;epoll_ctl 함수는 epfd라는 epoll 파일 디스크립터에의해 참조되는 관심 리스트(interest list)에 fd를 더할지, 변경할지, 삭제할지를 도와주는 함수입니다. event는 그 fd에 대해서 관심있게 주시할 event를 설정해줍니다. poll과 유사합니다. event에는 아까 소개한 ET 방식도 설정할 수 있습니다. operation을 뜻하는 op는 아래의 표와 같이 세가지가 있습니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 26.9767%;&quot;&gt;&lt;b&gt;Op&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 73.0233%;&quot;&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 26.9767%;&quot;&gt;&lt;b&gt;EPOLL_CTL_ADD&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 73.0233%;&quot;&gt;epfd의 관심 리스트에 entry를 더해줍니다. entry는 관심있게 볼 파일 디스크립터 fd와 주시할 event를 포함한 개념이라고 보시면 됩니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 26.9767%;&quot;&gt;&lt;b&gt;EPOLL_CTL_MOD&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 73.0233%;&quot;&gt;관심 리스트의 fd와 연관된 세팅을 변경합니다. 여기서 fd는 전달받은 인자인 event로 새롭게 세팅 됩니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 26.9767%;&quot;&gt;&lt;b&gt;EPOLL_CTL_DEL&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 73.0233%;&quot;&gt;관심 리스트에 fd를 등록 해제합니다. 여기서 인자 event는 무시되니까 NULL을 전달하면 됩니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;epoll_event 구조체는 아래와 같이 정의되어있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1695466635172&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;typedef union epoll_data {
        void        *ptr;
        int          fd;
        uint32_t     u32;
        uint64_t     u64;
} epoll_data_t;

struct epoll_event {
        uint32_t     events;      /* Epoll events */
        epoll_data_t data;        /* User data variable */
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;events&lt;/b&gt;의&amp;nbsp;설정할 수 있는 이벤트들은 poll과 비슷합니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25.1163%;&quot;&gt;&lt;b&gt;Event&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 74.8837%;&quot;&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25.1163%;&quot;&gt;&lt;b&gt;EPOLLIN&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 74.8837%;&quot;&gt;데이터를 읽을 수 있는 event를 설정합니다. fd에 대해서 데이터를 읽을 수 있을 때 event가 발생됩니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25.1163%;&quot;&gt;&lt;b&gt;EPOLLOUT&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 74.8837%;&quot;&gt;데이터를 쓸 수 있는 event를 설정합니다. 데이터를 쓸 수 있을때 event가 발생됩니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25.1163%;&quot;&gt;&lt;b&gt;EPOLLRDHUP&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 74.8837%;&quot;&gt;커널 2.6.17부터 생긴 이벤트인데, 스트림 소켓이 커넥션이 닫혔거나 shutdown 됐을때 이벤트를 발생시킵니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25.1163%;&quot;&gt;&lt;b&gt;EPOLLPRI&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 74.8837%;&quot;&gt;POLLPRI와 같아 high priority 자료를 바로 읽을 수 있는 이벤트입니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25.1163%;&quot;&gt;&lt;b&gt;EPOLLERR&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 74.8837%;&quot;&gt;파일 디스크립터에 에러가 발생했을때 이벤트가 발생됩니다. 예외적인 이벤트이므로 이러한 이벤트는 사용자가 설정할 필요없습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25.1163%;&quot;&gt;&lt;b&gt;EPOLLHUP&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 74.8837%;&quot;&gt;파일 디스크립터가 끊겼을 때 발생합니다. 역시 사용자가 일부러 이벤트를 지정할 필요없습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25.1163%;&quot;&gt;&lt;b&gt;EPOLLET&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 74.8837%;&quot;&gt;Edge Trigger 방식으로 이벤트 트리거 방식을 변경시킵니다. epoll은 기본적으로 Level Trigger 방식을 사용하고 있습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25.1163%;&quot;&gt;&lt;b&gt;EPOLLONESHOT&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 74.8837%;&quot;&gt;파일 디스크립터에 대한 이벤트를 한번만 발생시키고자 할 때 이 이벤트를 지정하면 됩니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. epoll_wait&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1695466816045&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;sys/epoll.h&amp;gt;
int epoll_wait(int epfd, struct epoll_event *events,
                      int maxevents, int timeout);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;epfd에 대해서 이벤트가 발생함을 기다리는 역할을 합니다. Event에는 발생한 event들이 있습니다. 최대 기다릴 events수를 maxevents에 넣을 수 있습니다. Timeout에 따라서 epoll_wait이 계속 기다릴지, 특정 시간 동안 기다릴지, 바로 반환할 지를 정해줄 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;timeout = -1 : 이벤트 발생시까지 무한히 대기합니다.&lt;/li&gt;
&lt;li&gt;timeout = 0 : 곧 장 반환합니다.&lt;/li&gt;
&lt;li&gt;timeout &amp;gt; 0 : ms만큼 대기하다가 반환됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;예제 코드 - Level Trigger Epoll &lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 Level Trigger 방식의 epoll 에코 서버의 예제입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;server&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;
&lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-9615403369038266&quot; data-ad-slot=&quot;6888174260&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1695466892849&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//epoll_server-level.c
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;netinet/in.h&amp;gt;
#include &amp;lt;arpa/inet.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/epoll.h&amp;gt;

#FD_MAX 1024
#define PORT 12346
#define BUF_SIZE 1

const char *welcome_message = &quot;Welcome!\n&quot;;

void err_exit(const char *err){
        perror(err);
        exit(1);
}

void clear_fd(const int epoll_fd, const int fd){
        epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL);
        close(fd);
}
int main(void){
        int socket_fd, accepted_fd;
        struct sockaddr_in host_addr, client_addr;
        socklen_t size;
        int epoll_fd, i, n, ret; 
        char buffer[BUF_SIZE] = {0,};
        struct epoll_event events[FD_MAX];
        int pos = 0;

        //STREAM socket 생성
        socket_fd=socket(PF_INET,SOCK_STREAM,0);
        if(socket_fd &amp;lt; 0) err_exit(&quot;socket error &quot;);

        //server ip와 bind하기 위해 주소 설정
        memset(&amp;amp;host_addr, 0, sizeof(host_addr));
        host_addr.sin_family=AF_INET;
        host_addr.sin_port=htons(PORT); 
        host_addr.sin_addr.s_addr = 0;  //자신의 주소로 자동으로 설정 

        //socket과 host_addr과 bind
        if(bind(socket_fd,(struct sockaddr *)&amp;amp;host_addr,sizeof(struct sockaddr)) &amp;lt; 0)
                err_exit(&quot;bind error &quot;);

        //접속 대기
        if(listen(socket_fd,3) &amp;lt; 0)
                err_exit(&quot;listen error &quot;);

        for(i = 0; i &amp;lt; FD_MAX; i++)
                events[i].data.fd = -1;


        //그냥 0보다 크면 된다.
        epoll_fd = epoll_create(1024); 
        if(epoll_fd &amp;lt; 0) err_exit(&quot;epoll_create error &quot;);

        struct epoll_event event;
        event.data.fd = socket_fd;
        event.events = EPOLLIN;

        if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, socket_fd, &amp;amp;event) &amp;lt; 0)
                err_exit(&quot;epoll_ctl error &quot;);

        while(1){

                ret = epoll_wait(epoll_fd, events, FD_MAX, -1);
                //-1은 이벤트가 발생할때까지 무한정 대기
                if(ret == -1) err_exit(&quot;epoll_wait error &quot;);
                //ret는 이벤트가 발생한 entry의 갯수, events는 발생한 events의 배열이 저장된다.
                for(i = 0; i &amp;lt; ret; i++){
                        //accept할 것이 있는가?
                        if(events[i].data.fd == socket_fd &amp;amp;&amp;amp; events[i].events &amp;amp; EPOLLIN){
                                size = sizeof(struct sockaddr_in);

                                //Client가 connect할때까지 기디린다. 
                                accepted_fd = 
                                        accept(socket_fd,(struct sockaddr *)&amp;amp;client_addr,&amp;amp;size);

                                if(accepted_fd  &amp;lt; 0)
                                        err_exit(&quot;accept error &quot;);

                                struct epoll_event client;
                                client.data.fd = accepted_fd;
client.events = EPOLLIN;


                                if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, accepted_fd, &amp;amp;client) &amp;lt; 0)
                                        err_exit(&quot;epoll_ctl error &quot;);
                                //Client의 접속 정보를 출력하고 접속 잘됐다고 메시지 전송
                                printf(&quot;Client Info : IP %s, Port %d\n&quot;, 
                                                inet_ntoa(client_addr.sin_addr),
                                                ntohs(client_addr.sin_port));

                                n = send(accepted_fd, welcome_message, strlen(welcome_message), 0);
                                if(n &amp;lt; 0) err_exit(&quot;send error &quot;);
                                continue;
                        } 

                        if(events[i].events &amp;amp; EPOLLIN){

                                n = recv(events[i].data.fd, &amp;amp;buffer[pos], BUF_SIZE, 0);

                                if(n &amp;lt; 0) err_exit(&quot;recv error &quot;);

                                //n == 0일 경우에 epoll_fd 관심 리스트에서 비워준다. 
                                if(n == 0) {
                                        clear_fd(epoll_fd, events[i].data.fd);
                                        pos = 0;
                                        continue;
                                }

                                if(buffer[pos] == '\0'){
                                        printf(&quot;rcv msg : %s\n&quot;, buffer);
                                        //quit라는 메시지를 받으면 종료
                                        if(!strcmp(buffer,&quot;quit&quot;)){
                                                clear_fd(epoll_fd, events[i].data.fd);
                                                pos = 0;
                                                continue;
                                        }

                                        n = send(events[i].data.fd, buffer, pos, 0);
                                        if(n &amp;lt; 0) err_exit(&quot;send error &quot;);
                                        pos = 0;
                                } else 
                                        pos++;
                        }

                }

        }
        printf(&quot;end\n&quot;);
        shutdown(socket_fd, SHUT_RDWR);

        return 0;

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;client&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1695468554794&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//client.c
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;netinet/in.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;errno.h&amp;gt;
#include &amp;lt;arpa/inet.h&amp;gt; 

#define BUF_SIZE 128

void err_exit(const char *err){
        perror(err);
        exit(1);
}

int main(int argc, char *argv[])
{
        int sockfd = 0, n = 0;
        uint16_t port;
        char buffer[BUF_SIZE] = {0,};
        struct sockaddr_in server_addr; 

        if(argc != 3){
                printf(&quot;\n Usage: %s server_ip port \n&quot;,argv[0]);
                return 1;
        } 

        port = atoi(argv[2]);

        //Internet용 socket을 연다.
        if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) &amp;lt; 0)
                err_exit(&quot;socket error &quot;);

        //server_addr의 구조체를 깔끔히 0으로 도배 
        memset(&amp;amp;server_addr, 0, sizeof(server_addr)); 
        server_addr.sin_family = AF_INET;
        server_addr.sin_port = htons(port); 
        //127.0.0.1은 본인의 IP이다. 
        inet_aton(argv[1], (struct in_addr*)&amp;amp;server_addr.sin_addr);

        //client는 서버의 ip, port, protocol 설정후 connect로 서버에게
        //바로 연결한다.
        if(connect(sockfd, (struct sockaddr *)&amp;amp;server_addr, sizeof(server_addr)) &amp;lt; 0)
                err_exit(&quot;connect error &quot;);


        while(1){
                //서버로부터 에코된 메시지를 받음
                n = recv(sockfd, buffer, BUF_SIZE, 0);

                if(n &amp;lt; 0) err_exit(&quot;recv error &quot;);

                printf(&quot;%s\n&quot;, buffer);

                while(1){
                        printf(&quot;message:&quot;);
                        fgets(buffer, BUF_SIZE, stdin);
                        if(strlen(buffer) &amp;gt;= 100)
                                printf(&quot;message too large\n&quot;);
                        else break;

                };
                // \n을 \0로 처리 
                buffer[strlen(buffer)-1] = '\0';

                //서버에게 메시지 전송
                n = send(sockfd, buffer, strlen(buffer)+1, 0);
                if(n &amp;lt; 0) err_exit(&quot;send error &quot;);

        }

        shutdown(sockfd, SHUT_RDWR);
        return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Level Trigger 방식의 결과화면입니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style7&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: left;&quot; colspan=&quot;2&quot;&gt;Server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: left;&quot; colspan=&quot;2&quot;&gt;# ./server &lt;br /&gt;Client Info : IP 127.0.0.1, Port 42872 &lt;br /&gt;rcv msg : hello epoll server &lt;br /&gt;Client Info : IP 127.0.0.1, Port 46286 &lt;br /&gt;rcv msg : This is level trigger &lt;br /&gt;rcv msg : good bye~~~~~ &lt;br /&gt;rcv msg : quit &lt;br /&gt;rcv msg : GOOD BYE ^C&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: left;&quot;&gt;Client1&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: left;&quot;&gt;Client2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: left;&quot;&gt;# ./client 127.0.0.1 12346 &lt;br /&gt;Welcome! &lt;br /&gt;message:hello epoll server &lt;br /&gt;hello epoll server &lt;br /&gt;message: GOOD BYE &lt;br /&gt;GOOD BYE &lt;br /&gt;message:^C&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: left;&quot;&gt;# ./client 127.0.0.1 12346 &lt;br /&gt;Welcome! &lt;br /&gt;message:This is level trigger &lt;br /&gt;This is level trigger &lt;br /&gt;message: good bye~~~~~ &lt;br /&gt;good bye~~~~~ &lt;br /&gt;message:quit &lt;br /&gt;quit &lt;br /&gt;message:&lt;br /&gt;message:&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;예제 코드 - Edge Trigger Epoll &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 LT방식은 ET방식으로 바꿔볼까요? event에다가 EPOLLET를 추가하시면 ET방식으로 동작하게 됩니다. accepted_fd를 EPOLLET event를 같이 추가해서 실행해보세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;
&lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-9615403369038266&quot; data-ad-slot=&quot;6888174260&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1695467652908&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;struct epoll_event client;
client.data.fd = accepted_fd;
client.events = EPOLLIN | EPOLLET;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그 후 실행하게 되면 에코가 되지 않습니다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style7&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: left;&quot; colspan=&quot;2&quot;&gt;&lt;b&gt;Server&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: left;&quot; colspan=&quot;2&quot;&gt;# ./server &lt;br /&gt;Client Info : IP 127.0.0.1, Port 43596 &lt;br /&gt;Client Info : IP 127.0.0.1, Port 43600&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: left;&quot;&gt;&lt;b&gt;Client1&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: left;&quot;&gt;&lt;b&gt;Client2&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: left;&quot;&gt;# ./client 127.0.0.1 12346 &lt;br /&gt;Welcome! &lt;br /&gt;message:Hello! epoll ET server&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: left;&quot;&gt;# ./client 127.0.0.1 12346 &lt;br /&gt;Welcome! message:Hell;;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜 이런 결과가 나올까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 구현한 방식은 한 글자씩 버퍼에서 읽어옵니다. 이는 epoll_wait이 반환된 후에 읽을 수가 있죠. &lt;b&gt;LT방식일때는 버퍼에 데이터가 남아있으면 epoll_wait에 의해서 반환&lt;/b&gt;되게 됩니다. 하지만 &lt;b&gt;ET방식은 버퍼가 채워지는 이벤트 순간 한번만 epoll_wait이 반환&lt;/b&gt;되기 때문에 버퍼에서 한글자만 읽고 대기하게 되는 겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 여기서 질문, select와 poll은 어떤 방식을 쓰고 있는 걸까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 현상을 보게 되면 버퍼가 남이있다면 select와 poll은 return됩니다. 이런 결과를 봐서 &lt;b&gt;우리는 select와 poll은 LT방식&lt;/b&gt;인 것을 알 수 있습니다. &lt;b&gt;이러한 문제를 해결하기 위해서는 non-blocking 방식의 read를 해야합니다.&lt;/b&gt;즉, 더 이상 버퍼에 남아있는 데이터가 없어서 오류를 발생할때까지 읽어야합니다. 이때 남아있는 데이터가 없으면 EAGAIN 에러를 발생하게 됩니다. 그래서 이런 방식으로 수정해야합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;비차단 모드로 설정&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1695467917953&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//NON-BLOCKING 모드로 전환
int flags = fcntl(accepted_fd, F_GETFL);
flags |= O_NONBLOCK;
if(fcntl(accepted_fd, F_SETFL, flags) &amp;lt; 0) 
    err_exit(&quot;fcntl error &quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;read에서 EAGAIN 오류를 만날때까지 읽기&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1695467931965&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;while(1){
    n = recv(events[i].data.fd, &amp;amp;buffer[pos], BUF_SIZE, 0);

    if(n &amp;lt; 0) 
        if(errno == EAGAIN) break;
    if(n == 0) {
        clear_fd(epoll_fd, events[i].data.fd);
        pos = 0;
        break;
    }

    pos++;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체 풀 소스코드는 아래와 같습니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1695467988205&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//epoll_server-edge.c
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;netinet/in.h&amp;gt;
#include &amp;lt;arpa/inet.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/epoll.h&amp;gt;
#include &amp;lt;errno.h&amp;gt;
#include &amp;lt;fcntl.h&amp;gt;

#define PORT 12346
#define BUF_SIZE 1

const char *welcome_message = &quot;Welcome!\n&quot;;

void err_exit(const char *err){
        perror(err);
        exit(1);
}

void clear_fd(const int epoll_fd, const int fd){
        epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL);
        close(fd);
}
int main(void){
        int socket_fd, accepted_fd;
        struct sockaddr_in host_addr, client_addr;
        socklen_t size;
        int epoll_fd, i, n, ret; 
        char buffer[BUF_SIZE] = {0,};
        struct epoll_event events[FD_MAX];
        int pos = 0;

        //STREAM socket 생성
        socket_fd=socket(PF_INET,SOCK_STREAM,0);
        if(socket_fd &amp;lt; 0) err_exit(&quot;socket error &quot;);

        //server ip와 bind하기 위해 주소 설정
        memset(&amp;amp;host_addr, 0, sizeof(host_addr));
        host_addr.sin_family=AF_INET;
        host_addr.sin_port=htons(PORT); 
        host_addr.sin_addr.s_addr = 0;  //자신의 주소로 자동으로 설정 

        //socket과 host_addr과 bind
        if(bind(socket_fd,(struct sockaddr *)&amp;amp;host_addr,sizeof(struct sockaddr)) &amp;lt; 0)
                err_exit(&quot;bind error &quot;);

        //접속 대기
        if(listen(socket_fd,3) &amp;lt; 0)
                err_exit(&quot;listen error &quot;);

        for(i = 0; i &amp;lt; FD_MAX; i++)
                events[i].data.fd = -1;


        //그냥 0보다 크면 된다.
        epoll_fd = epoll_create(1024); 
        if(epoll_fd &amp;lt; 0) err_exit(&quot;epoll_create error &quot;);

        struct epoll_event event;
        event.data.fd = socket_fd;
        event.events = EPOLLIN;
        //event.events = EPOLLIN | EPOLLET;

        if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, socket_fd, &amp;amp;event) &amp;lt; 0)
                err_exit(&quot;epoll_ctl error &quot;);

        while(1){

                ret = epoll_wait(epoll_fd, events, FD_MAX, -1);
                //-1은 이벤트가 발생할때까지 무한정 대기
                if(ret == -1) err_exit(&quot;epoll_wait error &quot;);
                //ret는 이벤트가 발생한 entry의 갯수, events는 발생한 events의 배열이 저장된다.
                for(i = 0; i &amp;lt; ret; i++){
                        //accept할 것이 있는가?
                        if(events[i].data.fd == socket_fd &amp;amp;&amp;amp; events[i].events &amp;amp; EPOLLIN){
                                size = sizeof(struct sockaddr_in);

                                //Client가 connect할때까지 기디린다. 
                                accepted_fd = 
                                        accept(socket_fd,(struct sockaddr *)&amp;amp;client_addr,&amp;amp;size);

                                if(accepted_fd  &amp;lt; 0)
                                        err_exit(&quot;accept error &quot;);

                                struct epoll_event client;
                                client.data.fd = accepted_fd;
                                client.events = EPOLLIN | EPOLLET;

                                //NON-BLOCKING 모드로 전환
                                int flags = fcntl(accepted_fd, F_GETFL);
                                flags |= O_NONBLOCK;
                                if(fcntl(accepted_fd, F_SETFL, flags) &amp;lt; 0) 
                                        err_exit(&quot;fcntl error &quot;);


                                if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, accepted_fd, &amp;amp;client) &amp;lt; 0)
                                        err_exit(&quot;epoll_ctl error &quot;);
                                //Client의 접속 정보를 출력하고 접속 잘됐다고 메시지 전송
                                printf(&quot;Client Info : IP %s, Port %d\n&quot;, 
                                                inet_ntoa(client_addr.sin_addr),
                                                ntohs(client_addr.sin_port));

                                n = send(accepted_fd, welcome_message, strlen(welcome_message), 0);
                                if(n &amp;lt; 0) err_exit(&quot;send error &quot;);
                                continue;
                        } 

                        if(events[i].events &amp;amp; EPOLLIN){
                                while(1){
                                        n = recv(events[i].data.fd, &amp;amp;buffer[pos], BUF_SIZE, 0);

                                        if(n &amp;lt; 0) 
                                                if(errno == EAGAIN) break;
                                        if(n == 0) {
                                                clear_fd(epoll_fd, events[i].data.fd);
                                                pos = 0;
                                                break;
                                        }

                                        pos++;
                                }

                                //quit라는 메시지를 받으면 종료
                                if(!strcmp(buffer,&quot;quit&quot;) || n == 0){
                                        clear_fd(epoll_fd, events[i].data.fd);
                                        pos = 0;
                                        continue;
                                }
                                printf(&quot;rcv msg : %s\n&quot;, buffer);

                                n = send(events[i].data.fd, buffer, pos, 0);
                                if(n &amp;lt; 0) err_exit(&quot;send error &quot;);
                                pos = 0;
                        }

                }

        }
        printf(&quot;end\n&quot;);
        shutdown(socket_fd, SHUT_RDWR);

        return 0;

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;!-- 광고 2개짜리 --&gt; &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-client=&quot;ca-pub-9615403369038266&quot; data-ad-slot=&quot;2573768191&quot; data-ad-format=&quot;auto&quot; data-full-width-responsive=&quot;true&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style7&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: left;&quot; colspan=&quot;2&quot;&gt;&lt;b&gt;Server&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: left;&quot; colspan=&quot;2&quot;&gt;# ./server &lt;br /&gt;Client Info : IP 127.0.0.1, Port 34820 &lt;br /&gt;Client Info : IP 127.0.0.1, Port 34832 &lt;br /&gt;rcv msg : hello! epoll ET server &lt;br /&gt;rcv msg : HI HI ~~~~ &lt;br /&gt;rcv msg : BYE!!! &lt;br /&gt;rcv msg : edge trigger~~~~ &lt;br /&gt;rcv msg : GOOD &lt;br /&gt;Client Info : IP 127.0.0.1, Port 60190 &lt;br /&gt;rcv msg : I'm back &lt;br /&gt;rcv msg : Bye&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: left;&quot;&gt;&lt;b&gt;Client1&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: left;&quot;&gt;&lt;b&gt;Client2&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: left;&quot;&gt;# ./client 127.0.0.1 12346 &lt;br /&gt;Welcome! &lt;br /&gt;message:hello! epoll ET server &lt;br /&gt;hello! epoll ET server &lt;br /&gt;message:edge trigger~~~~ &lt;br /&gt;edge trigger~~~~ &lt;br /&gt;message:GOOD &lt;br /&gt;GOOD &lt;br /&gt;message:^C &lt;br /&gt;# ./client 127.0.0.1 12346 &lt;br /&gt;Welcome! &lt;br /&gt;message:I'm back &lt;br /&gt;I'm back &lt;br /&gt;message:Bye Bye &lt;br /&gt;message:^C&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: left;&quot;&gt;# ./client 127.0.0.1 12346 &lt;br /&gt;Welcome! &lt;br /&gt;message:HI HI ~~~~ &lt;br /&gt;HI HI ~~~~ &lt;br /&gt;message:BYE!!! BYE!!! &lt;br /&gt;message:quit &lt;br /&gt;quit &lt;br /&gt;message: &lt;br /&gt;message:&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이상으로 epoll에 관한 설명을 마칩니다.&lt;/p&gt;</description>
      <category> 컴퓨터/운영체제(주로 리눅스)</category>
      <category>EdgeTrigger</category>
      <category>epoll</category>
      <category>epoll 서버</category>
      <category>epoll 클라이언트</category>
      <category>epoll개념</category>
      <category>LevelTrigger</category>
      <author>REAKWON</author>
      <guid isPermaLink="true">https://reakwon.tistory.com/236</guid>
      <comments>https://reakwon.tistory.com/236#entry236comment</comments>
      <pubDate>Sat, 23 Sep 2023 20:31:35 +0900</pubDate>
    </item>
    <item>
      <title>임베디드 시큐어부트 기본 적인 개념과 다루는 기술들 - Trust Chain</title>
      <link>https://reakwon.tistory.com/235</link>
      <description>&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;시큐어부트(Secure Boot)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시큐어부트(Secure Boot)는 말 그대로 안전한 부팅을 의미합니다. 시큐어 부팅은 ROM으로부터 시작되는 부팅의 시작부터 파일 시스템이 얹어지는 부팅 완료까지 안전하게 부팅을 하는 절차입니다. 주로 세 단계의 인증을 거치게 됩니다. 맨 처음 부팅의 시작인 부트로더들의 인증, 그리고 부트로더에 의해 커널 이미지가 올라오게 되면 커널 이미지를 인증, 이후 커널에 의해 파일 시스템이 마운트되기 전에 파일 시스템의 인증을 거치게 됩니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;결론은 부트 로더 인증 -&amp;gt; 커널 인증 -&amp;gt; 파일 시스템 인증 순으로 이어지게 된다는 것이죠.&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;부트 로더 인증&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;임베디드 시스템에서 Boot Loader는 한 가지만 존재하지 않습니다. ROM에서 시작되는 부트 로더1부터 시작해 부트로더2, 부트로더 3 등이 있으며, 여기서도 부트로더 순서대로 인증하는 CoT(Chain Of Trust)라는 기술이 존재하지만 이 포스팅에는 부트로더와 다른 Firmware 이미지들을 한 꺼번에 인증하는 FIP 인증을 다룹니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;FIP(Firmware Image Package)라고하는 펌웨어 이미지 바이너리를 인증&lt;/b&gt;합니다. FIP는 단순히 부트로더들의 모임이라고 생각하시면 되고, FIP를 서명한 서명값이 FIP끝에 달리게 됩니다. 이때 인증은 각 SoC 업체의 Firmware를 사용하여 인증을 하게 되는데요. NXP사의 s32g 칩의 경우에는 &lt;b&gt;HSE(Hardware Security Engine)&lt;/b&gt;이라는 펌웨어가 그 역할을 하게 되지요.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;311&quot; data-origin-height=&quot;151&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6Iwaw/btsvapWh89O/bH8FgCeE2LcgLj3wAjM9gK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6Iwaw/btsvapWh89O/bH8FgCeE2LcgLj3wAjM9gK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6Iwaw/btsvapWh89O/bH8FgCeE2LcgLj3wAjM9gK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6Iwaw%2FbtsvapWh89O%2FbH8FgCeE2LcgLj3wAjM9gK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;311&quot; height=&quot;151&quot; data-origin-width=&quot;311&quot; data-origin-height=&quot;151&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인증을 하는 경우에는 공개키가 있어야겠죠? 이 공개키는 어딘가에 저장이 되어야하는데 nxp s32g의 경우 FAT 파일 시스템을 통해서 특정 파티션에 저장하고 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;커널 인증&amp;nbsp;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부트로더 인증이 되었다면 그 이후 커널 인증을 거쳐야합니다. 커널 인증은 커널이 변조되었는지 아닌지를 판별하게 됩니다. 커널 인증을 하는 대표적인 방법은 Verified Boot라는 건데요. U-boot에서 사용하는 커널 인증 방법으로 FIT(Flattened Image Tree)를 이용합니다. 이 &lt;b&gt;FIT는 아래와 같은 형식의 .its라는 파일을 가지고 생성&lt;/b&gt;되어 집니다. its는 FIT에 대한 정보를 갖고 있는 소스 파일입니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;
&lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-9615403369038266&quot; data-ad-slot=&quot;6888174260&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1695306739869&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/dts-v1/;
/ {
    description = &quot;Verified boot FIT Image&quot;;
    #address-cells = &amp;lt;2&amp;gt;;
    images {
        kernel-1 {
            description = &quot;FIT kernel Image&quot;;
            data = /incbin/(&quot;Image&quot;);
            type = &quot;kernel&quot;;
            arch = &quot;arm64&quot;;
            os = &quot;linux&quot;;
            compression = &quot;none&quot;;
            load =  &amp;lt;0x00080000&amp;gt;;
            entry = &amp;lt;0x00080000&amp;gt;;
            hash@1 {
                algo = &quot;sha256&quot;;
            };
        };
        tee-1 {
            description = &quot;Arm Trusted Firmware&quot;;
            data = /incbin/(&quot;optee.bin&quot;);
            type = &quot;standalone&quot;;
            arch = &quot;arm64&quot;;
            compression = &quot;none&quot;;
            load =  &amp;lt;0x08400000&amp;gt;;
            entry = &amp;lt;0x08400000&amp;gt;;
            hash@1 {
                algo = &quot;sha256&quot;;
            };
        };
        fdt-1 {
            description = &quot;FIT device tree&quot;;
            data = /incbin/(&quot;fit-linux-kernel.dtb&quot;);
            type = &quot;flat_dt&quot;;
            arch = &quot;arm64&quot;;
            compression = &quot;none&quot;;
            hash@1 {
                algo = &quot;sha256&quot;;
            };
        };
    };
    configurations {
        default = &quot;config-1&quot;;
        config-1 {
            description = &quot;verified boot FIT configuration&quot;;
            kernel = &quot;kernel-1&quot;;
            loadables = &quot;tee-1&quot;;
            fdt = &quot;fdt-1&quot;;
            signature-1 {
                algo = &quot;sha256,rsa2048&quot;;
                key-name-hint = &quot;dev&quot;;
                sign-images = &quot;fdt&quot;, &quot;kernel&quot;, &quot;loadables&quot;;
            };
        };
    };
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막 configurations에서 signature-1을 보시면 FIT 인증을 위한 정보들이 저장이 됩니다. 이 its를 가지고 mkimage라는 u-boot의 툴을 통해서 FIT를 아래와 같은 방법으로 만들어냅니다.&lt;/p&gt;
&lt;pre id=&quot;code_1695306900014&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;./u-boot/tools/mkimage -f fit-image.its -K u-boot.dtb -k keys -r image.fit&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;-f : its의 파일 이름&lt;/li&gt;
&lt;li&gt;-K : 그렇다면 공개키는 어디 있을까요? 공개키는 앞서 인증한 FIP의 커널을 부팅하는 부터로더인 U-boot의 dtb에 존재합니다. 그 dtb 파일의 이름을 -K 옵션으로 정해주면 이 dtb 파일에 공개키가 삽입이 됩니다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;-k : 서명할 키와 인증서가 있는 디렉토리를 정해줍니다. keys라는 디렉토리에 위치해있으며 openssl이든 다른 키 생성 툴이든 사용하여 키와 인증서를 만들어야합니다. 위의 예시에는 키에 대한 정보(key-name-hint)가 dev입니다.&lt;/li&gt;
&lt;li&gt;-r : 인증이 필수라는 뜻으로 인증을 강제합니다. 이 옵션을 정해줌으로써 인증이 실패한 커널은 부팅하지 않습니다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;image.fit : 최종적으로 나오는 fit 이미지의 이름을 정해줍니다. input이 아닙니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 FIT 이미지는 U-boot의 bootm 부팅 커맨드로만 동작이 가능하며 u-boot에서 iminfo 라는 명령을 통해서 이미지의 정보를 확인할 수도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자세한 사용 방법은 아래를 참고하시면 될 것 같네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://blog.crysys.hu/2018/06/verified-boot-on-the-raspberry-pi/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://blog.crysys.hu/2018/06/verified-boot-on-the-raspberry-pi/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1695305962678&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Verified boot on the Raspberry Pi &amp;ndash; CrySyS Blog&quot; data-og-description=&quot;This blog post, written by Istv&amp;aacute;n Telek, is the third post in a series of blog posts on transforming the Raspberry Pi into a security enhanced IoT platform. It describes how you can implement a verified boot process on the Raspberry pi. Introduction Secur&quot; data-og-host=&quot;blog.crysys.hu&quot; data-og-source-url=&quot;https://blog.crysys.hu/2018/06/verified-boot-on-the-raspberry-pi/&quot; data-og-url=&quot;https://blog.crysys.hu/2018/06/verified-boot-on-the-raspberry-pi/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://blog.crysys.hu/2018/06/verified-boot-on-the-raspberry-pi/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://blog.crysys.hu/2018/06/verified-boot-on-the-raspberry-pi/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Verified boot on the Raspberry Pi &amp;ndash; CrySyS Blog&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;This blog post, written by Istv&amp;aacute;n Telek, is the third post in a series of blog posts on transforming the Raspberry Pi into a security enhanced IoT platform. It describes how you can implement a verified boot process on the Raspberry pi. Introduction Secur&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blog.crysys.hu&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;파일 시스템 인증&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;
&lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-9615403369038266&quot; data-ad-slot=&quot;6888174260&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자, 이제 마지막 인증 과정입니다. 바로 실제 데이터들이 존재하는 파일 시스템을 마운트하기전 파일 시스템을 인증하는 과정이 필요하게 되지요. 파일 시스템을 인증하는 대표적인 기술로 사용되는 것이 dm-verity라는 기술입니다. dm-verity는 파일 시스템 이미지의 원본 블록 을 1차로 나온 Hash 데이터를 다시 2차 Hash를 가하고, 이후 n 번의 Hash를 가하게 되면 결국 마지막 나오는 hash값을 갖고 파일 시스템의 무결성을 검증합니다. 하지만 인증을 위해서는 이 hash값을 서명해야됩니다. 결국 우리는 파일 시스템 원본 이미지 + 해쉬 블록을 미리 생성하고, &lt;b&gt;root hash까지 미리 생성하여 안전하게 보관&lt;/b&gt;해야합니다. 이때 hash가 계산되는 모습을 보면 트리 형태로 보여지는데 이를 merkle Tree 라고합니다. 결과적으로 나온&amp;nbsp;&lt;b&gt;root hash는 노출되어서는 안돼요.&lt;/b&gt; 부팅이 되고 마운트될때 파일 시스템의 이미지를 root hash로 만들어서 갖고 있는 root hash와 같다면 인증에 성공합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1764&quot; data-origin-height=&quot;1072&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rBEt7/btsu7OoFRU1/HlkK99cAAg5qIFv7KhC0v1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rBEt7/btsu7OoFRU1/HlkK99cAAg5qIFv7KhC0v1/img.png&quot; data-alt=&quot;https://www.timesys.com/security/dm-verity-without-an-initramfs/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rBEt7/btsu7OoFRU1/HlkK99cAAg5qIFv7KhC0v1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrBEt7%2Fbtsu7OoFRU1%2FHlkK99cAAg5qIFv7KhC0v1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;617&quot; height=&quot;375&quot; data-origin-width=&quot;1764&quot; data-origin-height=&quot;1072&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://www.timesys.com/security/dm-verity-without-an-initramfs/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;한가지 중요한 것은 파일 시스템의 쓰기가 발생하면 안된다는 점&lt;/b&gt;입니다. 쓰기가 일어나면 인증은 다음 부팅때 당연히 실패합니다. 그래서 파일 시스템은 read-only 파일 시스템에서만 dm-verity가 사용이 가능합니다. 이 dm-verity에 관한 내용과 파일 시스템 인증에 관한 방법은 아래의 페이지에서 세세하게 다루고 있으니 이 페이지를 참고하시기 바랍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.timesys.com/security/dm-verity-without-an-initramfs/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.timesys.com/security/dm-verity-without-an-initramfs/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1695306453990&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;DM-Verity Without an Initramfs - Timesys&quot; data-og-description=&quot;Learn how you can implement file system verification on your embedded system without the use of an initramfs. This can significantly save boot time and storage requirements in many situations.&quot; data-og-host=&quot;www.timesys.com&quot; data-og-source-url=&quot;https://www.timesys.com/security/dm-verity-without-an-initramfs/&quot; data-og-url=&quot;https://www.timesys.com/security/dm-verity-without-an-initramfs/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dvqo3q/hyTY14DTPn/3XIM9DSoRVuASMfuBKkhn1/img.jpg?width=1000&amp;amp;height=625&amp;amp;face=0_0_1000_625&quot;&gt;&lt;a href=&quot;https://www.timesys.com/security/dm-verity-without-an-initramfs/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.timesys.com/security/dm-verity-without-an-initramfs/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dvqo3q/hyTY14DTPn/3XIM9DSoRVuASMfuBKkhn1/img.jpg?width=1000&amp;amp;height=625&amp;amp;face=0_0_1000_625');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;DM-Verity Without an Initramfs - Timesys&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Learn how you can implement file system verification on your embedded system without the use of an initramfs. This can significantly save boot time and storage requirements in many situations.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.timesys.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이상으로 시큐어부팅에 관한 포스팅을 마치도록 하겠습니다.&lt;/p&gt;</description>
      <category> 컴퓨터/보안 기술</category>
      <category>Dm-verity</category>
      <category>fit</category>
      <category>u-boot</category>
      <category>Verified Boot</category>
      <category>부팅 과정</category>
      <category>시큐어부트</category>
      <category>커널인증</category>
      <category>파일시스템인증</category>
      <author>REAKWON</author>
      <guid isPermaLink="true">https://reakwon.tistory.com/235</guid>
      <comments>https://reakwon.tistory.com/235#entry235comment</comments>
      <pubDate>Thu, 21 Sep 2023 23:43:45 +0900</pubDate>
    </item>
    <item>
      <title>[리눅스] 코드로 이해하는 저장된 사용자 ID(Saved UID)가 있는 이유</title>
      <link>https://reakwon.tistory.com/234</link>
      <description>&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;저장된 사용자 ID - Saved UID&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Saved UID를 이해하기 위해서는 실제 사용자 ID(Real UID)와 유효 사용자 ID(Effective UID)에 대한 이해가 깔려있어야합니다. 아직 개념이 안잡혀있다면 아래의 포스팅을 먼저 보고 오시면 좋겠습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://reakwon.tistory.com/228&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://reakwon.tistory.com/228&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1692193427300&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[리눅스] 코드로 알아보는 uid(real uid, effective uid, saved uid) 관계&quot; data-og-description=&quot;아래 포스팅보다 더 많은 정보와 예제를 담은 리눅스 교재를 배포했습니다. 아래의 페이지에서 리눅스 교재를 받아가세요. https://reakwon.tistory.com/233 리눅스 프로그래밍 note 배포 티스토리에 리눅&quot; data-og-host=&quot;reakwon.tistory.com&quot; data-og-source-url=&quot;https://reakwon.tistory.com/228&quot; data-og-url=&quot;https://reakwon.tistory.com/228&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b40myG/hyTFa743Hw/qcrhg6GQ4tGFpmxuMXNFDK/img.png?width=676&amp;amp;height=368&amp;amp;face=0_0_676_368,https://scrap.kakaocdn.net/dn/mfXMZ/hyTFeCDWeE/SSYVa9fquKdkedJKg7Wxdk/img.png?width=676&amp;amp;height=368&amp;amp;face=0_0_676_368,https://scrap.kakaocdn.net/dn/b4KQKB/hyTFfBy8xA/Ok6XKHYdcLYWlzQH8ZRwaK/img.png?width=676&amp;amp;height=368&amp;amp;face=0_0_676_368&quot;&gt;&lt;a href=&quot;https://reakwon.tistory.com/228&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://reakwon.tistory.com/228&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b40myG/hyTFa743Hw/qcrhg6GQ4tGFpmxuMXNFDK/img.png?width=676&amp;amp;height=368&amp;amp;face=0_0_676_368,https://scrap.kakaocdn.net/dn/mfXMZ/hyTFeCDWeE/SSYVa9fquKdkedJKg7Wxdk/img.png?width=676&amp;amp;height=368&amp;amp;face=0_0_676_368,https://scrap.kakaocdn.net/dn/b4KQKB/hyTFfBy8xA/Ok6XKHYdcLYWlzQH8ZRwaK/img.png?width=676&amp;amp;height=368&amp;amp;face=0_0_676_368');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[리눅스] 코드로 알아보는 uid(real uid, effective uid, saved uid) 관계&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;아래 포스팅보다 더 많은 정보와 예제를 담은 리눅스 교재를 배포했습니다. 아래의 페이지에서 리눅스 교재를 받아가세요. https://reakwon.tistory.com/233 리눅스 프로그래밍 note 배포 티스토리에 리눅&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;reakwon.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Saved UID가 없다고 생각하고 Real UID와 Effective UID만 있다고 가정 해보세요. 그리고 setresuid 역시 suid를 설정하는 함수이니 없다고 가정해보세요. 권한이 확장된 프로그램에서의 euid를 권한이 확장된 euid라고 부르겠습니다. &lt;b&gt;다른 사용자의 권한을 얻은 상태에서 다시 권한을 축소 시켜야할때, 그러니까 실사용자 ruid로 돌려야할 상황이 생길 때 단순히 ruid로만 돌리면 나중에 다시 유효 사용자 권한이 필요할 때 돌아올 방법이 없습니다. 그러니까 euid, ruid를 왔다리 갔다리 유도리있게 스위칭할수가 없다는 뜻입니다.&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;setuid를 통해서 권한이 확장된&amp;nbsp;euid로 다시 바꿀 수 있을까요?&amp;nbsp;현재&amp;nbsp;ruid=euid입니다. suid는 없다고 가정했으니, ruid로만 변경될 수 있는데,&amp;nbsp;이는 권한이 확장된&amp;nbsp;euid가 아니잖아요. setuid로는 바꿀 수 없습니다.&lt;/li&gt;
&lt;li&gt;seteuid&amp;nbsp;역시 마찬가지인데요. ruid&amp;nbsp;혹은&amp;nbsp;suid로 돌아갈 수 있는데 지금은&amp;nbsp;suid가 없다고 가정했으니 역시&amp;nbsp;setuid의 결과와 같습니다.&amp;nbsp;바꿀 수 없죠. &amp;nbsp;&lt;/li&gt;
&lt;li&gt;setreuid도 마찬가지입니다. ruid가 현재&amp;nbsp;euid이기 때문이죠. setreuid는 현재의&amp;nbsp;ruid&amp;nbsp;혹은&amp;nbsp;euid로만 변경되는데,&amp;nbsp;지금 상황은&amp;nbsp;ruid가&amp;nbsp;euid와 같죠.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 저장된 사용자 ID가 없이 ruid와 euid만 존재하면&amp;nbsp;&lt;b&gt;현재&amp;nbsp;ruid = euid가 생길 때&amp;nbsp;다시 확장된 권한의&amp;nbsp;euid로 돌아갈 방법이 없다&lt;/b&gt;는 뜻입니다. 그래서 &lt;b&gt;따로 그러한 확장된 권한의&amp;nbsp;euid를 저장해 놓아야하는데, 이를 위한&amp;nbsp;uid가 바로&amp;nbsp;saved-user id&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 이전 지난 포스팅에 suid가 초기의 euid와 같다는 점을 주시하라고 한겁니다. 저의 큰 그림 아시겠어요? 이제 saved라는 의미가 왜 붙었는지 아시겠죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, root 권한의 프로그램에서 잠시 root 권한을 뺄 때를 생각해봅시다. 위와 같은 상황은 발생하겠죠. 아무리 root가 프로그램 사용권한을 자신의 것으로 쓰게 끔 허락했어도 특정 파일에 대한 접근 권한을 막을 상황이 생길겁니다. 이런 경우 seteuid를 사용자의 ruid로 돌려줍니다. 현재 ruid = 실 사용자 id, 현재 euid = 실 사용자 id 그러다가 그 후 다시 root 권한으로 작업해야할 때는 seteuid를 다시 root로 돌려야하겠죠. 그런데 현재 상황에서 ruid는 실 사용자의 id, 그리고 euid도 실 사용자 id인데, 어떻게 돌릴 수 있죠? suid는 아까 봤듯이 euid와 같았죠. 네, suid 덕분에 다시 유효사용자 id를 root로 돌릴 수 있게 됩니다.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래의 코드는 root.txt라는 root만든 텍스트 파일을 euid를 변경해가며 읽는 소스 코드입니다. 실행하면서 어떤 현상이 발생하는지 관찰해보면 suid가 왜 쓰이는지 알 수 있을 겁니다.&lt;/p&gt;
&lt;pre id=&quot;code_1692193011399&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//savedUID.c
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;errno.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

void readfile(){
        int n;
        char buf[32]={0,};
        int fd = open(&quot;root.txt&quot;, O_RDWR);
        if(fd &amp;lt; 0){
                printf(&quot;open error(%s)\n&quot;, strerror(errno));
                return;
        }


        n = read(fd, buf, 32);
        if(n &amp;lt; 0){
                printf(&quot;read error(%s)\n&quot;, strerror(errno));
                close(fd);
                return;
        }
        printf(&quot;%s&quot;, buf);
        close(fd);


}
void pr_resuid(){
        int ruid, euid, suid;
        if(getresuid(&amp;amp;ruid, &amp;amp;euid, &amp;amp;suid) &amp;lt; 0){
                printf(&quot;setresuid error\n&quot;);
                exit(0);
        }
        printf(&quot;ruid:%d, euid:%d, suid:%d\n&quot;,
                ruid, euid, suid);
}
int main(){

        printf(&quot;초기 uid\n&quot;);
        pr_resuid();

        printf(&quot;file 읽기 시도 &amp;gt; &quot;);
        readfile();
        printf(&quot;\n&quot;);

        printf(&quot;euid를 %d로 전환\n&quot;, getuid());
        if(seteuid(getuid()) &amp;lt; 0){
                printf(&quot;seteuid error\n&quot;);
                return 1;
        }
        pr_resuid();

        printf(&quot;file 읽기 시도 &amp;gt; &quot;);
        readfile();
        printf(&quot;\n&quot;);

        printf(&quot;euid를 root로 전환\n&quot;);
        seteuid(0);

        printf(&quot;file 읽기 시도 &amp;gt; &quot;);
        readfile();
        pr_resuid();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;
&lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-9615403369038266&quot; data-ad-slot=&quot;6888174260&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선&amp;nbsp;root의 유효사용자&amp;nbsp;id를&amp;nbsp;root로 돌려야하기 때문에 권한을 줘야겠군요. gcc&amp;nbsp;경고에 대한 문구는 가볍게 쌩까도록 합시다.&amp;nbsp;아참,&amp;nbsp;그리고&amp;nbsp;root권한의 파일을 하나 만들어야겠네요. root.txt를 읽어야하잖아요.&lt;/p&gt;
&lt;pre id=&quot;code_1692193046823&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;root# gcc savedUID.c 
savedUID.c: In function &amp;lsquo;pr_resuid&amp;rsquo;:
savedUID.c:32:12: warning: implicit declaration of function &amp;lsquo;getresuid&amp;rsquo;; did you mean &amp;lsquo;setreuid&amp;rsquo;? [-Wimplicit-function-declaration]
   32 |         if(getresuid(&amp;amp;ruid, &amp;amp;euid, &amp;amp;suid) &amp;lt; 0){
      |            ^~~~~~~~~
      |            setreuid
root# chmod u+s a.out
root# echo &quot;this is a file made by root&quot; &amp;gt; root.txt&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;계정을&amp;nbsp;ubuntu로 전환하고 파일을 실행하면 어떤 결과가 나올까요?&lt;/p&gt;
&lt;pre id=&quot;code_1692193093745&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;root# su ubuntu
ubuntu$ ./a.out 
초기 uid
ruid:1000, euid:0, suid:0
file 읽기 시도 &amp;gt; this is a file made by root

euid를 1000로 전환
ruid:1000, euid:1000, suid:0
file 읽기 시도 &amp;gt; open error(Permission denied)

euid를 root로 전환
file 읽기 시도 &amp;gt; this is a file made by root
ruid:1000, euid:0, suid:0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;euid를 잠시 ubuntu로 전환하고 파일을 읽을 땐 파일을 읽을 수 없습니다. 여기서 알 수 있는 것은 permission denied로 권한이 축소되었음을 알 수 있습니다. 그 후에는 euid를 root로 전환하여 파일을 읽을 수 있게 되었습니다. &lt;b&gt;euid를 0으로 되돌릴 수 있는 이유는 suid가 0이기 때문&lt;/b&gt;이고 만약 suid 마저도 다른 uid로 변경되었다면 seteuid는 에러를 발생시킵니다.&lt;/p&gt;</description>
      <category> 컴퓨터/운영체제(주로 리눅스)</category>
      <category>savedUID</category>
      <category>setresuid</category>
      <category>리눅스 UID</category>
      <category>저장된사용자ID</category>
      <author>REAKWON</author>
      <guid isPermaLink="true">https://reakwon.tistory.com/234</guid>
      <comments>https://reakwon.tistory.com/234#entry234comment</comments>
      <pubDate>Wed, 16 Aug 2023 22:45:51 +0900</pubDate>
    </item>
    <item>
      <title>리눅스 프로그래밍 note 배포</title>
      <link>https://reakwon.tistory.com/233</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;티스토리에 리눅스에 관한 내용을 두서없이 여지껏 포스팅했었데요. 저도 제 포스팅을 찾기가 어렵기도 하고 티스토리에서 코드삽입을 하게 되면 이게 일자로 쭉 쓰여져있는 x같은 현상이 생겨서 문서로 배포하도록 결정했습니다.&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1308&quot; data-origin-height=&quot;1386&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HewoT/btsp2abyD95/iVBnFLP0OOwH6bqbMz7cJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HewoT/btsp2abyD95/iVBnFLP0OOwH6bqbMz7cJK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HewoT/btsp2abyD95/iVBnFLP0OOwH6bqbMz7cJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHewoT%2Fbtsp2abyD95%2FiVBnFLP0OOwH6bqbMz7cJK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;502&quot; height=&quot;532&quot; data-origin-width=&quot;1308&quot; data-origin-height=&quot;1386&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;차례대로 설명이 되어 있으므로, 찾아보셔도 되고, 입문자분들께서는 부족하지만 처음부터 보셔도 됩니다.&amp;nbsp;&amp;nbsp;&lt;br&gt;현재 초기단계의 배포라서 오타, 오류 등이 있을텐데, 차차 수정하면서 버전을 올려서 다시 배포하도록 하겠습니다. 제가 원래는 좋아요와 댓글 구걸은 하지 않는데, 얼마나 문서를 다운 받으셨는지, 오류 내용이 무엇인지 확인하기 위해서&amp;nbsp; &lt;b&gt;좋아요! 댓글!&amp;nbsp;&lt;/b&gt; 남겨주시면 감사하겠습니다.&lt;br&gt;아래의 구글 드라이브를 통해서 다운받으실 수 있습니다.&amp;nbsp;&lt;/p&gt;&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;a href=&quot;https://drive.google.com/file/d/1WyVSbAeKxgtaeMjxQB7nzAKF-hw4bysw/view?usp=sharing&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;linux_note_v1.0&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;목차는 아래와 같습니다.&lt;/span&gt;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;a href=&quot;#linux&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;리눅스&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#linux_1_history&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;리눅스&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;역사&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1.1 &lt;a href=&quot;#linux_1_1_systemv&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;System V&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;i&gt; &lt;/i&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.2 &lt;/span&gt;&lt;a href=&quot;#linux_1_2_BSD&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;BSD&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.3 &lt;/span&gt;&lt;a href=&quot;#linux_1_3_linux&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;LINUX&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.4 &lt;/span&gt;&lt;a href=&quot;#linux_1_4_POSIX&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;POSIX&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.5 &lt;/span&gt;&lt;a href=&quot;#linux_1_5_GNU&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;GNU&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#linux_2_distro&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;리눅스&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;배포판&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2.1 &lt;a href=&quot;#linux_2_1_debian&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Debian&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.2 &lt;/span&gt;&lt;a href=&quot;#linux_2_2_ubuntu&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Ubuntu&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.3 &lt;/span&gt;&lt;a href=&quot;#linux_2_3_centos&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;CentOS&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.4 &lt;/span&gt;&lt;a href=&quot;#linux_2_4_kali&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Kali&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#linux_3_feature&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;리눅스&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;특징&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#liux_4_boot_to_login&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;부팅에서&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;로그인&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4.1 &lt;a href=&quot;#linux_4_1_boot_process_old&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;부팅&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;과정&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4.2 &lt;/span&gt;&lt;a href=&quot;#linux_4_2_latest_boot_process&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;최신&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;기기에서&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;부팅&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;과정&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4.3 &lt;/span&gt;&lt;a href=&quot;#linux_4_3_login_process&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;로그인&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;과정&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#linux_4_structure&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;리눅스&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;운영체제의&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;구조&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;5.1 &lt;/span&gt;&lt;a href=&quot;#linux_4_1_application_systemcall_flow&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;어플리케이션&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;실행&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;흐름&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;a href=&quot;#system_handling&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;시스템&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다루기&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#system_handling_2_limit&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;한계&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1.1 &lt;a href=&quot;#system_handling_2_1_limit_at_compile&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;컴파일&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;시점&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;한계&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.2 &lt;/span&gt;&lt;a href=&quot;#system_handling_2_2_limit_at_runtime_sys&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;실행&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;시점&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;한계&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; - sysconf&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.3 &lt;/span&gt;&lt;a href=&quot;#system_handling_2_3_limit_at_runtime_pat&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;실행&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;시점&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;한계&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – pathconf, fpathconf&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.4 &lt;/span&gt;&lt;a href=&quot;#system_handling_2_4_exam_limit_read&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;한계&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;알아보기&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2 &lt;/span&gt;&lt;a href=&quot;#system_handling_3_env_var&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;환경변수&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2.1 &lt;a href=&quot;#system_handling_3_1_general_env_var&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;일반적인&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;환경변수&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.2 &lt;/span&gt;&lt;a href=&quot;#system_handling_3_2_env_var_set&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;환경변수&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;설정&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2.2.1&lt;/span&gt;&lt;a href=&quot;#system_handling_3_2_1_export&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; export &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;명령어&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2.2.2 &lt;/span&gt;&lt;a href=&quot;#system_handling_3_2_2_env_var_character&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;환경변수&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;특성&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2.3 &lt;/span&gt;&lt;a href=&quot;#system_handling_3_3_env_functions&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;환경변수&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;함수&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2.3.1 &lt;/span&gt;&lt;a href=&quot;#system_handling_3_3_1_setenv&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;setenv, unsetenv&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2.3.2 &lt;/span&gt;&lt;a href=&quot;#system_handling_3_3_2_putenv&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;putenv&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2.3.3 &lt;/span&gt;&lt;a href=&quot;#system_handling_3_3_3_getenv&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;getenv&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.3.4 &lt;/span&gt;&lt;a href=&quot;#system_handling_3_3_4_exam_setenv&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;환경변수&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;설정하기&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;a href=&quot;#FILE&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파일&lt;/span&gt;&lt;/span&gt;&lt;/a&gt; &lt;/b&gt;&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.1&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#파일입출력&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파일입출력&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1.1 &lt;i&gt;&lt;a href=&quot;#open&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;open&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/i&gt;&lt;i&gt; &lt;/i&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.2 &lt;/span&gt;&lt;i&gt;&lt;a href=&quot;#close&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;close&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/i&gt;&lt;i&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;/i&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.3 &lt;/span&gt;&lt;i&gt;&lt;a href=&quot;#read&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;read&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/i&gt;&lt;i&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;/i&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.4 &lt;/span&gt;&lt;i&gt;&lt;a href=&quot;#write&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;write&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/i&gt;&lt;i&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;/i&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.5 &lt;/span&gt;&lt;i&gt;&lt;a href=&quot;#lseek&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;lseek&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/i&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.6 &lt;/span&gt;&lt;a href=&quot;#실습파일쓰기읽기&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제-&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파일&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;쓰기, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;읽기&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.7 &lt;/span&gt;&lt;a href=&quot;#리다이렉션&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;리다이렉션&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1.7.1 &lt;/span&gt;&lt;a href=&quot;#입력Redirection&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;입력 Redirection&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1.7.2 &lt;/span&gt;&lt;a href=&quot;#출력Redirection&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;출력&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; Redirection&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1.7.3 &lt;/span&gt;&lt;a href=&quot;#에러Redirection&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;에러&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; Redirection&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1.7.4 &lt;/span&gt;&lt;a href=&quot;#파일FDRedirection&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파일로&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; Redirection&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1.7.5 &lt;/span&gt;&lt;a href=&quot;#AppendRedirection&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Append&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1.7.6 &lt;/span&gt;&lt;a href=&quot;#redirection예&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Redirection&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;의&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.8 &lt;/span&gt;&lt;a href=&quot;#파이프&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파이프&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2 &lt;/span&gt;&lt;a href=&quot;#파일제어&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파일제어&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.1 &lt;/span&gt;&lt;a href=&quot;#파일접근권한&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파일&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;권한&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.1.1 &lt;/span&gt;&lt;a href=&quot;#파일특수권한&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;특수&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;권한&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; SUID, SGID&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.1.2 &lt;/span&gt;&lt;a href=&quot;#특수권한Sticky&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;특수&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;권한&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; Stiky&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.1.3 &lt;/span&gt;&lt;a href=&quot;#umask&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;umask&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.2 &lt;/span&gt;&lt;a href=&quot;#링크&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;링크&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.2.1 &lt;/span&gt;&lt;a href=&quot;#HardLink&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;하드&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;링크&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.2.2 &lt;/span&gt;&lt;a href=&quot;#SymbolicLink&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;심볼릭&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;링크&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.2.3 &lt;/span&gt;&lt;a href=&quot;#LinkCommandImplementation&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;링크&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;커맨드&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;구현&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.3 &lt;/span&gt;&lt;a href=&quot;#FileStatus&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파일&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;상태&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.3.1 &lt;/span&gt;&lt;a href=&quot;#FileStatusExam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파일&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;상태&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;확인&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.4 &lt;/span&gt;&lt;a href=&quot;#fcntl&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파일&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;컨트롤 - fcntl&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.4.1 &lt;/span&gt;&lt;a href=&quot;#fcntlBasicExam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파일&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;속성&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;조회, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;변경&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.4.2 &lt;/span&gt;&lt;a href=&quot;#NON_BLOCK예제&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;비차단(NON-Block) &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;모드&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.4.3 &lt;/span&gt;&lt;a href=&quot;#CloexecBasic&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – CLOEXEC &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이해&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.5 &lt;/span&gt;&lt;a href=&quot;#FileDuplication&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파일&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;서술자&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;복제&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.5.1 &lt;/span&gt;&lt;a href=&quot;#dup&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;dup&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.5.2 &lt;/span&gt;&lt;a href=&quot;#dup2&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;dup2&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.5.3 &lt;/span&gt;&lt;a href=&quot;#FileDupExam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파일&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;서술자&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;복제1&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.5.4 &lt;/span&gt;&lt;a href=&quot;#FileDupExam2&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파일&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;서술자&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;복제2&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.6 &lt;/span&gt;&lt;a href=&quot;#Directory&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;디렉토리&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다루기&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.6.1 &lt;/span&gt;&lt;a href=&quot;#opendir&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;opendir&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.6.2 &lt;/span&gt;&lt;a href=&quot;#readdir&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;readdir&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.6.3 &lt;/span&gt;&lt;a href=&quot;#closedir&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;closedir&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.6.4 &lt;/span&gt;&lt;a href=&quot;#readdirExam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;디렉토리&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파일&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;리스트&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;출력&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.6.5 &lt;/span&gt;&lt;a href=&quot;#recursiveReadDirExam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;하위&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;디렉토리&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;읽기&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3 &lt;/span&gt;&lt;a href=&quot;#file_3_standardIO&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;표준입출력&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;라이브러리&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.1 &lt;/span&gt;&lt;a href=&quot;#file_3_1_file_type&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파일의&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;종류&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;텍스트&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파일, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이진파일&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.2 &lt;/span&gt;&lt;a href=&quot;#file_3_2_stream&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;스트림&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &amp;nbsp;&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.3 &lt;/span&gt;&lt;a href=&quot;#file_3_3_C_stdio_func&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;표준&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; C &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;함수&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.3.5 &lt;/span&gt;&lt;a href=&quot;#file_3_3_5_C_exam_test_data_read_write&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;텍스트&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파일&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;쓰기, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;읽기&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.3.8 &lt;/span&gt;&lt;a href=&quot;#file_3_3_8_C_exam_bin_data_read_write&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이진&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데이터&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;쓰기, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;읽기&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.3.9 &lt;/span&gt;&lt;a href=&quot;#file_3_3_9_random_access&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;임의&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;접근(Random Access)&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.3.9.4 &lt;/span&gt;&lt;a href=&quot;#file_3_3_9_4_exam_query_students_info&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;특정&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;학생&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;정보&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;가져오기&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.4 &lt;/span&gt;&lt;a href=&quot;#file_3_4_buffer&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;버퍼&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.4.1 &lt;/span&gt;&lt;a href=&quot;#file_3_4_1_buffer_flush_ways&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;버퍼를&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;비우는&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;방법&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.4.2 &lt;/span&gt;&lt;a href=&quot;#file_3_4_2_buffering_methods&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;버퍼링&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;방식&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.4.2.4 &lt;/span&gt;&lt;a href=&quot;#file_3_4_2_4_get_buffering_info&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;버퍼링&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;정보&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;가져오기&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.4.2.5 &lt;/span&gt;&lt;a href=&quot;#file_3_4_2_5_setbuf&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;버퍼&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;설정&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;함수&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – setbuf&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.4.2.6 &lt;/span&gt;&lt;a href=&quot;#file_3_4_2_6_setvbuf&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;버퍼&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;설정&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;함수&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; - setvbuf&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;a href=&quot;#유저&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;유저&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#사용자관리&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사용자관리&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1.1 &lt;a href=&quot;#etcPasswd&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;/etc/passwd&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.2 &lt;/span&gt;&lt;a href=&quot;#etcShadow&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;/etc/shadow&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.3 &lt;/span&gt;&lt;a href=&quot;#etcGroup&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;/etc/group&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.4 &lt;/span&gt;&lt;a href=&quot;#pwdAPI&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사용자&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;정보&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;조회&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – pwd API&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.4.1 &lt;/span&gt;&lt;a href=&quot;#getpwduid&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;getpwuid, getpwnam&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.4.2 &lt;/span&gt;&lt;a href=&quot;#setpwent&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;setpwent, getpwent, endpwent&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.4.3 &lt;/span&gt;&lt;a href=&quot;#pwdExam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사용자&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;정보&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;조회&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.5 &lt;/span&gt;&lt;a href=&quot;#shadowAPI&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;비밀&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;번호&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;관련&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; API&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.5.1 &lt;/span&gt;&lt;a href=&quot;#getspnam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;getspnam, setspent, getspent, endspent&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#RuidEuidSuid&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사용자&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; UID(RUID, EUID, SUID)&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;와&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그룹&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; ID(RGID, EGID, SGID)&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2.1 &lt;a href=&quot;#getuidFunctions&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;uid &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;조회&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;함수들&lt;/span&gt;&lt;/span&gt;&lt;/a&gt; &lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.1.1 &lt;/span&gt;&lt;a href=&quot;#getuid&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;getuid, geteuid, getresuid&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.1.2 &lt;/span&gt;&lt;a href=&quot;#printuids&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사용자&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; UID &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;조회&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;2.2 &lt;a href=&quot;#uidSettingFunctions&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;uid &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;설정&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;함수들&lt;/span&gt;&lt;/span&gt;&lt;/a&gt; &lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.2.1 &lt;/span&gt;&lt;a href=&quot;#SetuidSetGid&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;setuid, getgid&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.2.2 &lt;/span&gt;&lt;a href=&quot;#setuidExam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – setuid &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;특징&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.2.3 &lt;/span&gt;&lt;a href=&quot;#SetreuidSetregid&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;setreuid, setregid&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.2.4 &lt;/span&gt;&lt;a href=&quot;#SetresuidSetresgid&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;setresuid, setresgid&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.2.5 &lt;/span&gt;&lt;a href=&quot;#setuidsAndPrint&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – uid &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;설정&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;함수들&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;관찰&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.3 &lt;/span&gt;&lt;a href=&quot;#SavedUserIDObject&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Saved User ID&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;의&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;쓰임새&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.3.1 &lt;/span&gt;&lt;a href=&quot;#SavedUserIDExam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – Saved User ID &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;활용&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.4 &lt;/span&gt;&lt;a href=&quot;#myLoginExam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;실습&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;간단&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; login &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로그램&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;구현&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;a href=&quot;#프로세스&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로세스&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1 &lt;/span&gt;&lt;a href=&quot;#processStatus&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로세스&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;상태&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;1.1 &lt;a href=&quot;#linuxProcessStatus&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;리눅스&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로세스&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;상태&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.2 &lt;/span&gt;&lt;a href=&quot;#processStatusCheckExam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;실습&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로세스&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;상태&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;확인&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2 &lt;/span&gt;&lt;a href=&quot;#process_run&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로세스&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;실행&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3 &lt;/span&gt;&lt;a href=&quot;#process_exit&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로세스&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;종료exit &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;함수&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.1 &lt;a href=&quot;#exit_func&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;exit &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;함수&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.1.1 &lt;/span&gt;&lt;a href=&quot;#exit_flush&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파일&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;디스크립터&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;방출&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.2.2 &lt;/span&gt;&lt;a href=&quot;#exit_atexit&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;atexit &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;호출&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.2.2 &lt;/span&gt;&lt;a href=&quot;#exit_exit&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;_exit &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;호출&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4 &lt;/span&gt;&lt;a href=&quot;#nonlocal_jump&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;비국소(nonlocal) &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;분기&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4.1 &lt;a href=&quot;#setjmp_longjmp&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;setjmp, longjmp&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4.2 &lt;/span&gt;&lt;a href=&quot;#setjmp_longjmpExam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – setjmp, longjmp &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;활용&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;5 &lt;/span&gt;&lt;a href=&quot;#process_fork&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로세스&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;생성&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5.1 &lt;a href=&quot;#child_process_creation&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자식&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로세스&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;생성&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – fork&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5.1.1 &lt;/span&gt;&lt;a href=&quot;#orphan_process&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;고아&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로세스&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;5.1.2 &lt;/span&gt;&lt;a href=&quot;#wait&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;wait&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;5.1.3 &lt;/span&gt;&lt;a href=&quot;#zomebie_process&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;좀비&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로세스&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;5.1.4 &lt;/span&gt;&lt;a href=&quot;#wait_using_SIGCHLD&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SIGCHLD&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;를&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이용한&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; wait&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;5.1.5 &lt;/span&gt;&lt;a href=&quot;#wait_multiChildren_Exam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;실습&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다수의&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자식&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로세스&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; wait&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;5.1.6 &lt;/span&gt;&lt;a href=&quot;#exit_status_child&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자식&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로세스&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;종료&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;상태&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;알아오기&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;5.1.7 &lt;/span&gt;&lt;a href=&quot;#waitpid&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;waitpid&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5.1.7.1 &lt;/span&gt;&lt;a href=&quot;#waitpid_exam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – waitpid &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사용&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5.1.7.2 &lt;/span&gt;&lt;a href=&quot;#waitpid_nonblock_exam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;비차단&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; waitpid&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;6 &lt;/span&gt;&lt;a href=&quot;#exec_function&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;exec &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;함수들&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 6.1 &lt;a href=&quot;#exec_methods&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;exec &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;기본&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사용방법&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;6.2 &lt;/span&gt;&lt;a href=&quot;#exec_spec&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;exec &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;특징&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;6.2.1&lt;/span&gt;&lt;a href=&quot;#exec_CLOEXEC&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; CLOEXEC&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;6.3 &lt;/span&gt;&lt;a href=&quot;#simple_shell_exam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;간단&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; shell&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;7 &lt;/span&gt;&lt;a href=&quot;#process_group&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로세스&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그룹&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 7.1 &lt;a href=&quot;#process_groupID_get&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로세스&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그룹&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; Id&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;를&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;가져오는&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; API&lt;/span&gt;&lt;/span&gt;&lt;/a&gt; &lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;7.1.1 &lt;/span&gt;&lt;a href=&quot;#getpgrp&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;getpgrp&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;7.1.2 &lt;/span&gt;&lt;a href=&quot;#getpgid&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;getpgid&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;7.2 &lt;/span&gt;&lt;a href=&quot;#process_group_cases&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로세스&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그룹&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사례들&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;7.2.1 &lt;/span&gt;&lt;a href=&quot;#process_group_cases_shell&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사례&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 1 – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;쉘&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;스크립트&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;7.2.2 &lt;/span&gt;&lt;a href=&quot;#process_group_cases_fork&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사례&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 2 – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자식&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로세스&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;7.2.3 &lt;/span&gt;&lt;a href=&quot;#process_group_cases_pipe&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사례&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 3 – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파이프&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;7.3 &lt;/span&gt;&lt;a href=&quot;#process_group_set&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로세스&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그룹&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; ID &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;설정 API&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;7.3.1 &lt;/span&gt;&lt;a href=&quot;#process_group_id_change_Exam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로세스&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그룹&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; ID &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;설정&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;후&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;현상&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;관찰&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;8 &lt;/span&gt;&lt;a href=&quot;#session&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;세션&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;a href=&quot;#daemon_process&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데몬&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로세스&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1 &lt;/span&gt;&lt;a href=&quot;#daemon_process_spec&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데몬&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로세스&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;특징&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2 &lt;/span&gt;&lt;a href=&quot;#daemon_process_imple&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데몬&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로세스&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;구현&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3 &lt;/span&gt;&lt;a href=&quot;#log&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;로그&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.1 &lt;/span&gt;&lt;a href=&quot;#log_api&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;로그&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; API&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.1.1 &lt;/span&gt;&lt;a href=&quot;#openlog&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;openlog&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.2.2 &lt;/span&gt;&lt;a href=&quot;#syslog&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;syslog&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.3.3 &lt;/span&gt;&lt;a href=&quot;#log_save_sep_exam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;로그&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;별도&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;저장&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4 &lt;/span&gt;&lt;a href=&quot;#system_daemon&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;시스템&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데몬&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4.1 &lt;/span&gt;&lt;a href=&quot;#system_daemon_use&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;시스템&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데몬&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사용&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4.1.1 &lt;/span&gt;&lt;a href=&quot;#system_daemon_use_exefile&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;시스템&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데몬&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;실행&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파일&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;생성&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4.1.2 &lt;/span&gt;&lt;a href=&quot;#system_daemon_use_unit&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;시스템&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데몬&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; Unit &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;작성&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4.1.2.1 &lt;/span&gt;&lt;a href=&quot;#system_daemon_use_unit_section&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;시스템&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데몬&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; unit &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;섹션&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4.1.2.2 &lt;/span&gt;&lt;a href=&quot;#system_daemon_use_service_section&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;시스템&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데몬&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; service &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;섹션&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4.1.2.3 &lt;/span&gt;&lt;a href=&quot;#system_daemon_use_install_section&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;시스템&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데몬&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; install &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;섹션&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4.1.3 &lt;/span&gt;&lt;a href=&quot;#systemctl_daeon_ctl&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;systemctl&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이용한&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데몬&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;제어&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4.1.3.1 &lt;/span&gt;&lt;a href=&quot;#system_daemon_service_exe&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데몬&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;실행&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4.1.3.2 &lt;/span&gt;&lt;a href=&quot;#system_daemon_service_stat&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데몬&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;상태&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;확인&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4.1.3.3 &lt;/span&gt;&lt;a href=&quot;#system_daemon_service_stop&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데몬&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;중지&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4.1.3.4 &lt;/span&gt;&lt;a href=&quot;#system_daemon_service_restart&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데몬&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;재시작&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4.1.3.5 &lt;/span&gt;&lt;a href=&quot;#system_daemon_service_enable&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;부팅&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;시&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데몬&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;실행&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;a href=&quot;#신호&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;신호&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#signal_send&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;신호보내기&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.1 &lt;/span&gt;&lt;a href=&quot;#kill_command&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;kill &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;명령어&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.2 &lt;/span&gt;&lt;a href=&quot;#kill_raise&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;kill, raise API&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;2 &lt;a href=&quot;#signalTypes&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;신호&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;종류&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3 &lt;/span&gt;&lt;a href=&quot;#signalFunction&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;signal &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;함수와&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;시그널&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;특징&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.1&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#sigint&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SIGINT&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.2&lt;/span&gt;&lt;a href=&quot;#sigtstp&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; SIGTSTP&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.3 &lt;/span&gt;&lt;a href=&quot;#sigstop&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SIGSTOP&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.4 &lt;/span&gt;&lt;a href=&quot;#SIGCHLDExam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SIGCHLD&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.5 &lt;/span&gt;&lt;a href=&quot;#sighup&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SIGSHUP&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.6 &lt;/span&gt;&lt;a href=&quot;#SWInterrupt&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SW interrupt &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;특징&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.7 &lt;/span&gt;&lt;a href=&quot;#signalSlowSyscall&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;느린&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;시스템&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;콜에서&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;신호&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4 &lt;/span&gt;&lt;a href=&quot;#signalControl&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;시그널&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;제어&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4.1&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#sigset&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;시그널&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;집합&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4.1.1&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#sigfillsetSigemptyset&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;sigemptyset, sigfillset&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4.1.2 &lt;/span&gt;&lt;a href=&quot;#sigaddsetSigdelset&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;sigaddset, sigdelset&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4.1.3 &lt;/span&gt;&lt;a href=&quot;#sigismember&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;sigismember&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4.2&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#signalBlock&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;시그널&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;차단&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4.2.1 &lt;/span&gt;&lt;a href=&quot;#sigprocmask&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;sigprocmask&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4.2.2 &lt;/span&gt;&lt;a href=&quot;#sigprocmask1Exam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – sigprocmask1&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4.2.3 &lt;/span&gt;&lt;a href=&quot;#sigprocmask2Exam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – sigprocmask2 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;시그널&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;차단&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4.2.4 &lt;/span&gt;&lt;a href=&quot;#sigpending&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;sigpending&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4.2.5 &lt;/span&gt;&lt;a href=&quot;#sigsuspend&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;sigsuspend&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4.3&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#sigaction&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;sigaction&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4.3.1 &lt;/span&gt;&lt;a href=&quot;#sigactionExam1&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – sigaction&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;으로&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; signal &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;구현&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4.3.2 &lt;/span&gt;&lt;a href=&quot;#sigactionExam2&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – sigaction&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;으로&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; SIGCHLD &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;제어&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;a href=&quot;#쓰레드&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;스레드&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#linux_thread&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;리눅스&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;스레드&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.1&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#pthread_create&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;pthread_create&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.2&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#pthread_join&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;pthread_join&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.3 &lt;/span&gt;&lt;a href=&quot;#pthread_detach&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;pthread_detach&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2 &lt;/span&gt;&lt;a href=&quot;#thread_sync&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;동기화&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.1&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#critical_section&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;임계영역&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.2 &lt;/span&gt;&lt;a href=&quot;#mutex_concept&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;뮤텍스(Mutex)&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.1.1 &lt;/span&gt;&lt;a href=&quot;#pthread_mutex_init&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;pthread_mutex_init&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.1.2 &lt;/span&gt;&lt;a href=&quot;#pthread_mutex_lock_unlock&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;pthread_mutex_lock, pthread_mutex_unlock&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.1.3 &lt;/span&gt;&lt;a href=&quot;#pthread_mutex_destroy&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;pthread_mutex_destroy&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.1.5 &lt;/span&gt;&lt;a href=&quot;#sysvshmexam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – system v &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;공유메모리&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사용&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.3 &lt;/span&gt;&lt;a href=&quot;#semaphore&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;세마포어(Semaphore)&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.3.1 &lt;/span&gt;&lt;a href=&quot;#semaphore_P&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;P&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;연산&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.3.2 &lt;/span&gt;&lt;a href=&quot;#semaphore_V&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;V &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;연산&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.3.3 &lt;/span&gt;&lt;a href=&quot;#semaphore_API&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;세마포어&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; API&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.3.3.1 &lt;/span&gt;&lt;a href=&quot;#semget&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;semget&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.3.3.2 &lt;/span&gt;&lt;a href=&quot;#semctl&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;semctl&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.3.3.3 &lt;/span&gt;&lt;a href=&quot;#semop&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;semop&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.3.3.4 &lt;/span&gt;&lt;a href=&quot;#non_semaphore_exam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;세마포어&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;적용&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;쓰레드&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.4&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#conditional_value&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;조건변수&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.4.1 &lt;/span&gt;&lt;a href=&quot;#conditional_value_API&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;조건변수&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; API&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.4.1.1 &lt;/span&gt;&lt;a href=&quot;#pthread_cond_init&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;pthread_cond_init&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.4.1.2 &lt;/span&gt;&lt;a href=&quot;#pthread_cond_wait&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;pthread_cond_wait&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.4.1.3 &lt;/span&gt;&lt;a href=&quot;#pthread_cond_signal&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;pthread_cond_signal&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.4.1.4 &lt;/span&gt;&lt;a href=&quot;#condition_variable_basic_exam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;조건&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;변수&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; API &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사용&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.4.1.5 &lt;/span&gt;&lt;a href=&quot;#producer_consumer&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;생산자&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;소비자&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;문제&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3 &lt;/span&gt;&lt;a href=&quot;#dead_lock&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;교착상태(DeadLock)&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.1&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#dead_lock_condition&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;교착상태&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;발생&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;조건&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.1.1 &lt;/span&gt;&lt;a href=&quot;#dead_lock_mutual_execlusion&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;상호&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;배제&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.2.2 &lt;/span&gt;&lt;a href=&quot;#daed_lock_hold_and_wait&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;점유와&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;대기&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.2.3 &lt;/span&gt;&lt;a href=&quot;#dead_lock_non_preemptive&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;비선점&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;조건&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.1.2 &lt;/span&gt;&lt;a href=&quot;#dead_lock_circle_wait&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;환형&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;대기&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.2 &lt;/span&gt;&lt;a href=&quot;#dead_lock_exam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;교착상태&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;발생&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로그램&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.3&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#dead_lock_solve&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;교착상태&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;해결&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.3.1 &lt;/span&gt;&lt;a href=&quot;#dead_lock_solve_prevention&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;교착상태&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예방&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.3.2 &lt;/span&gt;&lt;a href=&quot;#dead_lock_solve_회피&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;교착상태&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;회피&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.3.3 &lt;/span&gt;&lt;a href=&quot;#dead_lock_restore&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;교착상태&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;회복&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;a href=&quot;#IPC&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;IPC&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#pipe&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파이프(Pipe)&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.1&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#pipeExam1&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파이프&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사용1&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.2&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#pipeExam2&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파이프&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사용2&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2 &lt;/span&gt;&lt;a href=&quot;#sharedmemory&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;공유메모리&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.1&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#sysvshm&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;System V &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;공유&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;메모리&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.1.1 &lt;/span&gt;&lt;a href=&quot;#shmget&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;shmget&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.1.2 &lt;/span&gt;&lt;a href=&quot;#shmat&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;shmat&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.1.3 &lt;/span&gt;&lt;a href=&quot;#shmdt&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;shmdt&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.1.4 &lt;/span&gt;&lt;a href=&quot;#shmctl&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;shmctl&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.1.5 &lt;/span&gt;&lt;a href=&quot;#sysvshmexam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – system v &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;공유메모리&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사용&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.2&lt;/span&gt;&lt;a href=&quot;#POSIXshm&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; POSIX &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;공유&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;메모리&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.2.1 &lt;/span&gt;&lt;a href=&quot;#shmopen&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;shm_open&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.2.2 &lt;/span&gt;&lt;a href=&quot;#ftruncate&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;ftruncate&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.2.3 &lt;/span&gt;&lt;a href=&quot;#shm_unlink&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;shm_unlink&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.2.4 &lt;/span&gt;&lt;a href=&quot;#POSIXshmExam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – POSIX &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;공유메모리&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사용&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3 &lt;/span&gt;&lt;a href=&quot;#MessageQueue&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;메시지&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;큐&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.1&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#SysVMQ&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;System V &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;메시지&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;큐&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.1.1&lt;/span&gt;&lt;a href=&quot;#msgget&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; msgget&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.1.2 &lt;/span&gt;&lt;a href=&quot;#msgsend&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;msgsnd&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.1.3 &lt;/span&gt;&lt;a href=&quot;#msgrcv&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;msgrcv&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.1.4&lt;/span&gt;&lt;a href=&quot;#msgctl&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; msgctl&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.1.5 &lt;/span&gt;&lt;a href=&quot;#sysMQExam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – System V &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;메시지큐&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사용&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.2&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#POSIXMQ&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;POSIX &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;메시지&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;큐&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.2.1 &lt;/span&gt;&lt;a href=&quot;#mqOpen&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;mq_open&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.2.2 &lt;/span&gt;&lt;a href=&quot;#mqSend&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;mq_send&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;#mqSend&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, mq_timedsend&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.2.3 &lt;/span&gt;&lt;a href=&quot;#mqReceive&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;mq_receive&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;#mqReceive&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, mq_timedreceive&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.2.4 &lt;/span&gt;&lt;a href=&quot;#mqClose&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;mq_close&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.2.5 &lt;/span&gt;&lt;a href=&quot;#mq_unlink&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;mq_unlink&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.2.6&lt;/span&gt;&lt;a href=&quot;#POSIXMQExam&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – POSIX &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;메시지&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;큐&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사용&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;a href=&quot;#네트워크&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;네트워크&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#OSI7Layer&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;OSI 7 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;계층&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2 &lt;/span&gt;&lt;a href=&quot;#tcpip&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;TCP/IP&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.1&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#TCP_UDP&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;전송&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로토콜&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – TCP, UDP&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.2&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#TPC_InternetProtocol&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;네트워크&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로토콜&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; - IP&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3 &amp;nbsp;&lt;/span&gt;&lt;a href=&quot;#Socket&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;소켓&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.1&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#networkFunctions&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;네크워크&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;관련&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; API&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.1.1 &lt;/span&gt;&lt;a href=&quot;#socketFunc&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;socket&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.1.2 &lt;/span&gt;&lt;a href=&quot;#bind&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;bind&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.1.3 &lt;/span&gt;&lt;a href=&quot;#listen&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;listen&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.1.4 &lt;/span&gt;&lt;a href=&quot;#accept&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;accept&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.1.5 &lt;/span&gt;&lt;a href=&quot;#connect&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;connect&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.1.6 &lt;/span&gt;&lt;a href=&quot;#send&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;send&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.1.7 &lt;/span&gt;&lt;a href=&quot;#recv&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;recv&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.1.8 &lt;/span&gt;&lt;a href=&quot;#shutdown&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;shutdown&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.1.9 &lt;/span&gt;&lt;a href=&quot;#byte_order_change&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;바이트&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;순서&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;변환&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.1.10 &lt;/span&gt;&lt;a href=&quot;#internet_address_change&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;인터넷&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;주소&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;변환&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.2&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;#server_client_communications&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;서버&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;클라이언트&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;통신&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;구현&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.2.1 &lt;/span&gt;&lt;a href=&quot;#server_single_client&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;단일&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;클라이언트&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;처리&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;서버, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;클라이언트&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;코드&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.2.2 &lt;/span&gt;&lt;a href=&quot;#multiprocess_server&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;멀티&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로세스&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;서버&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.2.3 &lt;/span&gt;&lt;a href=&quot;#multithread_server&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;멀티&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;스레드&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;서버&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.2.4 &lt;/span&gt;&lt;a href=&quot;#select_server&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다중입출력&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – select &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;활용&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.2.5 &lt;/span&gt;&lt;a href=&quot;#poll_server&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다중입출력&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; – poll &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;활용&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.2.6 &lt;/span&gt;&lt;a href=&quot;#epoll_server&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다중입출력&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; epoll &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;활용&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.2.6.1 &lt;/span&gt;&lt;a href=&quot;#epoll_level_trigger&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Level Trigger&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.2.6.2 &lt;/span&gt;&lt;a href=&quot;#epoll_edge_trigger&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Edge Trigger&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.2.6.3 &lt;/span&gt;&lt;a href=&quot;#epoll_create&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;epoll_create&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.2.6.4 &lt;/span&gt;&lt;a href=&quot;#epoll_ctl&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;epoll_ctl&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.2.6.5 &lt;/span&gt;&lt;a href=&quot;#epoll_wait&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;epoll_wait&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.2.6.6 &lt;/span&gt;&lt;a href=&quot;#epoll_level_server&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Level Trigger &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;서버&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.2.6.7 &lt;/span&gt;&lt;a href=&quot;#epoll_edge_server&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Edge Trigger &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;서버&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3.3 &lt;/span&gt;&lt;a href=&quot;#datagram_socket&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Datagram &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;소켓&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;서버&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category> 컴퓨터/리눅스 note</category>
      <category>linux_note</category>
      <category>reakwon</category>
      <category>ubuntu</category>
      <author>REAKWON</author>
      <guid isPermaLink="true">https://reakwon.tistory.com/233</guid>
      <comments>https://reakwon.tistory.com/233#entry233comment</comments>
      <pubDate>Thu, 3 Aug 2023 17:08:53 +0900</pubDate>
    </item>
    <item>
      <title>[리눅스] 환경 변수 개념과 환경 변수를 다루는 방법 - 환경 변수는 어쩌면 맛있는게 아닐까?</title>
      <link>https://reakwon.tistory.com/232</link>
      <description>&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;리눅스 시스템의 더 많은 정보와 예제를 담은 리눅스 교재를 배포했습니다. 아래의 페이지에서 리눅스 교재를 받아가세요.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://reakwon.tistory.com/233&quot;&gt;https://reakwon.tistory.com/233&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1691052063832&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;리눅스 프로그래밍 note 배포&quot; data-og-description=&quot;티스토리에 리눅스에 관한 내용을 두서없이 여지껏 포스팅했었데요. 저도 제 포스팅을 찾기가 어렵기도 하고 티스토리에서 코드삽입을 하게 되면 이게 일자로 쭉 쓰여져있는 x같은 현상이 생겨&quot; data-og-host=&quot;reakwon.tistory.com&quot; data-og-source-url=&quot;https://reakwon.tistory.com/233&quot; data-og-url=&quot;https://reakwon.tistory.com/233&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cN2yHU/hyTxZSIeE6/Q9VuhsVauuLcHQwEbDzifK/img.png?width=800&amp;amp;height=847&amp;amp;face=0_0_800_847,https://scrap.kakaocdn.net/dn/tlBlx/hyTwhtWkQR/GAoTiXMEt0FUanBkraAid1/img.png?width=800&amp;amp;height=847&amp;amp;face=0_0_800_847,https://scrap.kakaocdn.net/dn/bEWgFd/hyTxXm3UOF/HLjLnAkSLbVcxIjFxKifi1/img.png?width=1308&amp;amp;height=1386&amp;amp;face=0_0_1308_1386&quot;&gt;&lt;a href=&quot;https://reakwon.tistory.com/233&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://reakwon.tistory.com/233&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cN2yHU/hyTxZSIeE6/Q9VuhsVauuLcHQwEbDzifK/img.png?width=800&amp;amp;height=847&amp;amp;face=0_0_800_847,https://scrap.kakaocdn.net/dn/tlBlx/hyTwhtWkQR/GAoTiXMEt0FUanBkraAid1/img.png?width=800&amp;amp;height=847&amp;amp;face=0_0_800_847,https://scrap.kakaocdn.net/dn/bEWgFd/hyTxXm3UOF/HLjLnAkSLbVcxIjFxKifi1/img.png?width=1308&amp;amp;height=1386&amp;amp;face=0_0_1308_1386');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;리눅스 프로그래밍 note 배포&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;티스토리에 리눅스에 관한 내용을 두서없이 여지껏 포스팅했었데요. 저도 제 포스팅을 찾기가 어렵기도 하고 티스토리에서 코드삽입을 하게 되면 이게 일자로 쭉 쓰여져있는 x같은 현상이 생겨&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;reakwon.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span&gt;환경 변수&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;컴퓨터 시스템에서 사용되는 동적인 값을 저장하는 변수&lt;/span&gt;&lt;/b&gt;&lt;span&gt;로&lt;span&gt;, &lt;/span&gt;프로그램들이 시스템 설정과 상호작용하는 데 사용됩니다&lt;span&gt;. &lt;/span&gt;환경변수는 텍스트 형식으로 저장되며&lt;span&gt;, &lt;/span&gt;특정 이름과 그에 해당하는 값으로 구성됩니다&lt;span&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;i&gt;&lt;span&gt;이름 &lt;span&gt;= &lt;/span&gt;값&lt;/span&gt;&lt;/i&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;시스템 전체에서 공유되거나 특정 프로세스 내에서만 유효한 변수들이 있을 수 있습니다&lt;span&gt;. &lt;/span&gt;환경변수는 주로 다음과 같은 용도로 사용됩니다&lt;span&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;시스템 설정 및 구성 정보 저장 시스템의 설정 정보를 저장하여 다른 프로그램들이 해당 정보를 활용할 수 있게 합니다. 예를 들어, 시스템의 언어, 시간대, 기본 디렉토리 등을 환경변수로 설정하여 시스템 전반에 적용할 수 있습니다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;프로그램 실행 시 동작 옵션 설정 프로그램이 동작할 때 필요한 옵션을 환경변수로 설정하여 해당 프로그램이 이를 인식하고 적용하게 할 수 있습니다. 이를 통해 특정 프로그램의 동작을 조정하거나 사용자 맞춤 설정을 지원할 수 있습니다.&lt;/li&gt;
&lt;li&gt;실행 환경 설정 프로그램이 실행되는 환경을 설정하는 데 사용됩니다. 예를 들어, 실행 파일들을 찾는 경로를 설정하거나 라이브러리의 위치를 지정하는데 환경변수를 활용할 수 있습니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;우리는 &lt;b&gt;&lt;span style=&quot;color: #00b050;&quot;&gt;현재 쉘에서 환경 변수&lt;/span&gt;&lt;/b&gt;를 설정한적은 없죠&lt;span&gt;. &lt;/span&gt;그런데 로그인 할 때 기본적으로 설정되어 있는 환경 변수들이 있습니다&lt;span&gt;(&lt;/span&gt;여기서는 &lt;span&gt;bash &lt;/span&gt;쉘만 보겠습니다&lt;span&gt;.) printenv &lt;/span&gt;명령&lt;span&gt;(&lt;/span&gt;혹은 &lt;span&gt;env)&lt;/span&gt;을 통해서 &lt;b&gt;&lt;span style=&quot;color: #00b050;&quot;&gt;현재 쉘&lt;/span&gt;&lt;/b&gt;에 어떤 환경변수가 설정되어있는지 확인해볼까요&lt;span&gt;?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1691032063479&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# printenv
SHELL=/bin/bash
PWD=/root
LOGNAME=ubuntu
//...
HOME=/root
LANG=en_US.UTF-8
//...
USER=ubuntu
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
MAIL=/var/mail/root
SSH_TTY=/dev/pts/0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;제가 있는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #00b050;&quot;&gt;현재 &lt;span&gt;bash &lt;/span&gt;쉘의 환경변수&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;는 이렇게 설정되어있습니다&lt;span&gt;. &lt;/span&gt;&lt;b&gt;환경 변수도 변수이기 때문에 그 값을 변경하거나 없애거나 할 수 있습니다&lt;span&gt;. &lt;/span&gt;&lt;/b&gt;그런데 보통 기본적으로 설정되어있는 환경 변수는 건드리지 않는 편이 좋습니다&lt;span&gt;. &lt;/span&gt;예를 들어 &lt;span&gt;PATH&lt;/span&gt;를 건드리게 되면 명령어 실행을 못할 수도 있습니다&lt;span&gt;. &lt;/span&gt;여기서는 알아두면 좋을 환경 변수들을 설명하고 환경 변수를 설정하는 방법과 프로그램에서 어떻게 환경 변수를 읽어오고 설정하는지 확인해보도록 하겠습니다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1. 일반적인 환경 변수들&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;아래의 환경 변수들은 기본적으로 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #00b050;&quot;&gt;현재 쉘&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;에 설정되어있을 수 있는 환경 변수들입니다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #b4c6e7;&quot; width=&quot;113&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;환경변수&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #b4c6e7;&quot; width=&quot;488&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;설명&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ebebeb;&quot; width=&quot;113&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #555555;&quot;&gt;USER&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; width=&quot;488&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #555555;&quot;&gt;현재 로그인한 사용자입니다&lt;span&gt;.&lt;/span&gt; UID(&lt;/span&gt;숫자&lt;span&gt;)&lt;/span&gt;가 아닌 계정명으로 나타납니다&lt;span&gt;.&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ebebeb;&quot; width=&quot;113&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #555555;&quot;&gt;HOME&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; width=&quot;488&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #555555;&quot;&gt;현재 사용자의 홈 디렉토리입니다&lt;span&gt;.&lt;/span&gt; &lt;/span&gt;로그인하면 이 디렉토리로 자동으로 위치가 됩니다&lt;span&gt;.&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ebebeb;&quot; width=&quot;113&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #555555;&quot;&gt;EDITER&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; width=&quot;488&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #555555;&quot;&gt;사용할 기본 파일 편집기입니다&lt;span&gt;. &lt;/span&gt;터미널에&lt;span&gt; edit&lt;/span&gt;를 입력할 때 사용할 편집기입니다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ebebeb;&quot; width=&quot;113&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #555555;&quot;&gt;LANG&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; width=&quot;488&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #555555;&quot;&gt;현재 로컬 언어 설정을 보여줍니다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ebebeb;&quot; width=&quot;113&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #555555;&quot;&gt;TERM&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; width=&quot;488&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #555555;&quot;&gt;현재 터미널 에뮬레이션입니다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ebebeb;&quot; width=&quot;113&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #555555;&quot;&gt;MAIL&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; width=&quot;488&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #555555;&quot;&gt;현재 사용자의 메일이 저장되는 위치입니다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ebebeb;&quot; width=&quot;113&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #555555;&quot;&gt;PATH&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; width=&quot;488&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #555555;&quot;&gt;명령어를 실행할 때 검색할 디렉토리들입니다&lt;span&gt;. &lt;/span&gt;여러 디렉토리가 있을 수 있기 때문에 &lt;span&gt;:(&lt;/span&gt;콜론&lt;span&gt;)&lt;/span&gt;으로 구분이 됩니다&lt;span&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span style=&quot;color: #555555;&quot;&gt;여러분이 명령어를 아무데서나 칠 수 있는 이유는 바로 이 &lt;span&gt;PATH&lt;/span&gt;변수 때문입니다&lt;span&gt;. &lt;/span&gt;이 변수가 없다면 &lt;span&gt;ls &lt;/span&gt;명령을 칠 때 전체 경로를 넣어서 &lt;span&gt;/bin/ls&lt;/span&gt;를 쳐야하지만 &lt;span&gt;PATH&lt;/span&gt;에 &lt;span&gt;/bin &lt;/span&gt;디렉토리가 있기 때문에 &lt;span&gt;ls&lt;/span&gt;만 쳐서 명령을 칠 수 있는 것입니다&lt;span&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ebebeb;&quot; width=&quot;113&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #555555;&quot;&gt;SHELL&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; width=&quot;488&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #555555;&quot;&gt;현재 사용자의 로그인 쉘입니다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ebebeb;&quot; width=&quot;113&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #555555;&quot;&gt;PWD&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; width=&quot;488&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #555555;&quot;&gt;현재 사용자가 있는 디렉토리입니다&lt;span&gt;.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.&amp;nbsp; 환경 변수 설정&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;우선 일반적으로 쉘에서 단순 변수는 아래와 같이 설정할 수 있습니다&lt;span&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;span style=&quot;color: #000000;&quot;&gt;변수명&lt;span&gt;=&lt;/span&gt;값&lt;/span&gt;&lt;/i&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그 변수를 참조할 때는 변수명 앞에 &lt;span&gt;$&lt;/span&gt;를 사용하여 확인할 수 있습니다&lt;span&gt;. &lt;/span&gt;며칠전에 달라로 &lt;span&gt;500&lt;/span&gt;만원을 환전했는데 개떡락을 하더군요 &lt;span&gt;--;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1691032224678&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# VAL=&quot;hello, world&quot;
# echo $VAL
hello, world&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그런데 이건 이 쉘에서만 유효한 변수일 뿐이지 환경 변수는 아닙니다&lt;span&gt;. printenv&lt;/span&gt;나 &lt;span&gt;env &lt;/span&gt;명령을 통해서 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #00b050;&quot;&gt;현재 쉘에 설정된 환경 변수&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #00b050;&quot;&gt;를 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;확인해보세요&lt;span&gt;. &lt;/span&gt;환경변수는 아니라는 것을 알 수 있습니다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1691032239117&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# printenv | grep VAL
아무 결과도 나오지 않음&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;대신에 현재 쉘 환경의 환경 변수를 포함한 모든 변수&lt;span&gt;, &lt;/span&gt;함수 등을 출력하는 &lt;span&gt;set &lt;/span&gt;명령을 통해 확인하면 변수가 설정되어있는 것은 알 수 있습니다&lt;span&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1691032254365&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# set | grep VAL
VAL='hello world'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그렇다면 환경 변수를 설정하려면 어떻게 해야 할까요&lt;span&gt;? &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;export 명령&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;export &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;명령&lt;span&gt;, &lt;/span&gt;일명 내보내기 명령을 통해서 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #00b050;&quot;&gt;현재 쉘&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;의 환경 변수로 변수를 등록할 수 있습니다&lt;span&gt;. &lt;/span&gt;이때 변수명 앞 &lt;span&gt;$&lt;/span&gt;는 생략해야합니다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;
&lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-9615403369038266&quot; data-ad-slot=&quot;6888174260&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;i&gt;&lt;span style=&quot;color: #000000;&quot;&gt;export &lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span style=&quot;color: #000000;&quot;&gt;변수명&lt;/span&gt;&lt;/i&gt;&lt;/u&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1691032292108&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# VAL=&quot;hello world&quot;
# export VAL
# printenv | grep VAL
VAL=hello world&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;혹은 한번에 값을 지정해서 내보낼 수도 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;i&gt;&lt;span style=&quot;color: #000000;&quot;&gt;export &lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span style=&quot;color: #000000;&quot;&gt;변수명&lt;span&gt;=&lt;/span&gt;값&lt;/span&gt;&lt;/i&gt;&lt;/u&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1691032313690&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# export APPLE=&quot;Mac Book&quot;
# printenv | grep APPLE
APPLE=Mac Book&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이제 환경 변수로 등록되었다는 것을 알 수 있습니다&lt;span&gt;. &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;환경 변수나 변수를 해제하려면 &lt;span&gt;unset &lt;/span&gt;명령어를 통해서 해제할 수 있습니다&lt;span&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;i&gt;&lt;span style=&quot;color: #000000;&quot;&gt;unset &lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span style=&quot;color: #000000;&quot;&gt;변수명&lt;/span&gt;&lt;/i&gt;&lt;/u&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1691032339899&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# printenv |grep VAL
VAL=hello world
# unset VAL
# printenv | grep VAL
# printenv | grep APPLE
APPLE=Mac Book
# unset APPLE
# printenv | grep APPLE&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이런 환경 변수는 &lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;color: #00b050;&quot;&gt;현재 수행되는 쉘&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 유지되는 동안만 유효&lt;span&gt;(&lt;/span&gt;사실 더 정확하게는 환경변수를 설정한 프로세스가 유지되는 동안 유효&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;합니다&lt;span&gt;. &lt;/span&gt;무슨 말이냐구요&lt;span&gt;? &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. 환경변수의 특성&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;계속 주구장창 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #00b050;&quot;&gt;현재 쉘&lt;span&gt;, &lt;/span&gt;현재 쉘&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이라는 말을 썼는데요&lt;span&gt;. &lt;/span&gt;여러분들이 놓치실까봐 초록색으로 표시했습니다&lt;span&gt;. &lt;/span&gt;그림으로 보면 더욱 이해가 빠르실텐데요&lt;span&gt;. &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;처음 로그인 쉘인 &lt;span&gt;(1) /bin/bash&lt;/span&gt;에서 &lt;span&gt;export&lt;/span&gt;를 이용해서 &lt;span&gt;HELLO&lt;/span&gt;를 환경 변수로 등록하고 &lt;span&gt;sh&lt;/span&gt;로 새로운 쉘을 시작합니다&lt;span&gt;. &lt;/span&gt;이때 &lt;span&gt;(2)/bin/sh&lt;/span&gt;로 실행되는 환경이 바뀌게 됩니다&lt;span&gt;. &lt;/span&gt;여기서도 &lt;span&gt;export&lt;/span&gt;를 이용해서 &lt;span&gt;WORLD&lt;/span&gt;를 환경 변수로 등록하고 다시 새로운 &lt;span&gt;(3)bash &lt;/span&gt;쉘을 실행시켜서 실행 환경을 바꿉니다&lt;span&gt;. &lt;/span&gt;여기서 &lt;span&gt;BYE&lt;/span&gt;라는 환경 변수를 등록합니다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;512&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHzgFg/btspTJF9lEe/vWqkLHatKSSwKWMzBRJRa1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHzgFg/btspTJF9lEe/vWqkLHatKSSwKWMzBRJRa1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHzgFg/btspTJF9lEe/vWqkLHatKSSwKWMzBRJRa1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHzgFg%2FbtspTJF9lEe%2FvWqkLHatKSSwKWMzBRJRa1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;700&quot; height=&quot;512&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;512&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그러면 맨 오른쪽 &lt;span&gt;(3)bash &lt;/span&gt;쉘을 사용하고 있을때 &lt;span&gt;HELLO, WORLD, BYE&lt;/span&gt;라는 환경변수는 다 살아있을까요&lt;span&gt;? &lt;/span&gt;네&lt;span&gt;, &lt;/span&gt;살아있습니다&lt;span&gt;. &lt;/span&gt;맨처음 &lt;span&gt;(1)/bin/bash&lt;/span&gt;도&lt;span&gt;, &lt;/span&gt;그 다음 &lt;span&gt;(2)/bin/sh&lt;/span&gt;도 실행중이니까요&lt;span&gt;. &lt;/span&gt;이제 &lt;span&gt;exit&lt;/span&gt;으로 &lt;span&gt;(3)bash&lt;/span&gt;를 끝내게 되어도 세 환경 변수 &lt;span&gt;HELLO, WORLD, BYE&lt;/span&gt;는 살아있을까요&lt;span&gt;? BYE&lt;/span&gt;는 &lt;span&gt;(3)bash&lt;/span&gt;가 &lt;span&gt;exit&lt;/span&gt;을 종료했기 때문에 더 이상 존재하지 않습니다&lt;span&gt;. &lt;/span&gt;그래서 &lt;span&gt;HELLO, WORLD&lt;/span&gt;만 남아있게 됩니다&lt;span&gt;. (2)/bin/sh&lt;/span&gt;를 끝냈을때&lt;span&gt;, &lt;/span&gt;이때 &lt;span&gt;(1)/bin/bash&lt;/span&gt;만 수행되는 상태겠죠&lt;span&gt;. &lt;/span&gt;그러면 &lt;span&gt;HELLO&lt;/span&gt;만 환경 변수로 유효하게 되는 겁니다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;아래는 테스트 결과입니다&lt;span&gt;. &lt;/span&gt;헷갈리지 않도록 앞에 프롬프트를 추가했습니다&lt;span&gt;. &lt;/span&gt;참고로 전 쉘에서 설정한 변수를 다음 쉘에서 이용하려면 &lt;span&gt;export&lt;/span&gt;를 이용해 환경변수로 등록이 되어야 가능합니다&lt;span&gt;. &lt;/span&gt;그러니까 &lt;span&gt;(1)/bin/bash&lt;/span&gt;에서 설정한 &lt;span&gt;HELLO&lt;/span&gt;를 &lt;span&gt;(2)/bin/sh&lt;/span&gt;의 &lt;span&gt;echo&lt;/span&gt;로 출력하려면 &lt;span&gt;export&lt;/span&gt;되어있어야 된다는 겁니다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1691032425203&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;(1)/bin/bash# export HELLO=&quot;hello!&quot;
(1)/bin/bash# sh
(2)/bin/sh# export WORLD=&quot;world!&quot;   
(2)/bin/sh# bash
(3)/bin/bash# export BYE=&quot;GOOD BYE~&quot;
(3)/bin/bash# echo $HELLO $WORLD $BYE
hello! world! GOOD BYE~
(3)/bin/bash# exit
exit
(2)/bin/sh# echo $HELLO $WORLD $BYE
hello! world!
(2)/bin/sh# exit
(1)/bin/bash# echo $HELLO $WORLD $BYE
hello!&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이런 특성을 모른다면 이런 실수 많이들 하실겁니다&lt;span&gt;. &lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;아래는 간단한 &lt;span&gt;bash &lt;/span&gt;쉘 스크립트를 작성한겁니다&lt;span&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1691032442799&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#!/bin/bash

#현재 프로세스 ID 출력 
echo $$

export HELLO=&quot;hello &quot;
export WORLD=&quot;world!&quot;
export BYE=&quot;good bye!&quot;

echo $HELLO $WORLD $BYE&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;스크립트를 몰라도 맨위의 첫줄은 &lt;span&gt;bash &lt;/span&gt;스크립트를 알려주는 한줄이니까 그냥 그렇게 쓰는구나 묻지도 따지지지도 말고 흡수하시면 됩니다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1691032466240&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#!/bin/bash&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그 다음 줄을 좀 눈여겨 봐야하는데&lt;span&gt;, &lt;b&gt;$$&lt;/b&gt;&lt;/span&gt;&lt;b&gt;는 현재 프로세스의 &lt;span&gt;ID&lt;/span&gt;&lt;/b&gt;를 의미합니다&lt;span&gt;. &lt;/span&gt;그래서 &lt;span&gt;echo&lt;/span&gt;를 통해서 출력하는 것이구요&lt;span&gt;. &lt;/span&gt;그냥 간단히 현재 실행되는 프로그램의 &lt;span&gt;ID&lt;/span&gt;라고 생각하세요&lt;span&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1691032491992&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#현재 프로세스 ID 출력 
echo $$&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그리고 우리가 배운 &lt;span&gt;export&lt;/span&gt;와 명령을 출력하는 &lt;span&gt;echo&lt;/span&gt;가 다입니다&lt;span&gt;. &lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;위 스크립트의 의도는 &lt;span&gt;$HELLO, $WORLD, $BYE&lt;/span&gt;를 환경 변수로 설정해서 편하게 쓰려는 의도입니다&lt;span&gt;. &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;실행권한을 주고 실행하면 쉘 스크&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;립트는 잘 실행되지만 스크립트가 끝난 이후 환경 변수를 불러오고자 한다면 이렇게 빈 공백만 출력이 됩니다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1691032521037&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# chmod 777 setmyenv.sh
# ./setmyenv.sh 
6968
hello world! good bye!
# echo $$
3196
# echo $HELLO

# echo $WORLD

# echo $BYE&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그런데 제가 명령어를 수행하는 프로그램의 &lt;span&gt;ID&lt;/span&gt;가 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #0070c0;&quot;&gt;3196&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이고&lt;span&gt;, , ./setmyenv.sh&lt;/span&gt;라는 쉘 스크립트가 실행되는 프로그램 &lt;span&gt;ID&lt;/span&gt;는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #7030a0;&quot;&gt;6968&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;로 다르네요&lt;span&gt;. &lt;/span&gt;결국 이런 상황입니다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;576&quot; data-origin-height=&quot;484&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biY8CJ/btspUoO705X/HMMcBKnKjnRqmmipp2GPDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biY8CJ/btspUoO705X/HMMcBKnKjnRqmmipp2GPDK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biY8CJ/btspUoO705X/HMMcBKnKjnRqmmipp2GPDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiY8CJ%2FbtspUoO705X%2FHMMcBKnKjnRqmmipp2GPDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;576&quot; height=&quot;484&quot; data-origin-width=&quot;576&quot; data-origin-height=&quot;484&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;방금 전 언급한 그 상황이 발생했습니다&lt;span&gt;. &lt;/span&gt;그러면 새로운 실행을 낳지 않고&lt;span&gt;, &lt;/span&gt;현재 있는 쉘에서 그대로 스크립트를 수행하면 될 것 같습니다&lt;span&gt;. &lt;/span&gt;그런 목적을 달성할 명령이 바로 &lt;span&gt;source &lt;/span&gt;명령입니다&lt;span&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;위의 스크립트를 &lt;span&gt;source&lt;/span&gt;를 이용해서 실행해봅시다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;
&lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-9615403369038266&quot; data-ad-slot=&quot;6888174260&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1691032549422&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# source setmyenv.sh 
3196
hello world! good bye!
# echo $HELLO
hello
# echo $WORLD
world!
r# echo $BYE
good bye!
# echo $$
3196&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;보세요&lt;span&gt;. &lt;/span&gt;쉘 스크립트가 그대로 &lt;span&gt;3196&lt;/span&gt;에서 실행이 되었죠&lt;span&gt;? &lt;/span&gt;그리고 환경 변수가 설정되어서 현재 쉘에서 사용할 수도 있습니다&lt;span&gt;. &lt;/span&gt;우리가 원하는 목적을 달성할 수 있었습니다&lt;span&gt;. source&lt;/span&gt;는 쉘 스크립트를 현재 쉘에서 실행하게 해주는 명령어입니다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4. 환경 변수 함수&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이젠 리눅스에서 프로그램이 어떻게 환경 변수를 다룰 수 있는 지 볼까요&lt;span&gt;? &lt;/span&gt;환경 변수를 설정하는 함수는 &lt;span&gt;setenv, putenv&lt;/span&gt;가 있으며 환경 변수를 해제하려면 &lt;span&gt;unsetenv&lt;/span&gt;함수를 사용할 수 있습니다&lt;span&gt;. &lt;/span&gt;환경 변수의 어떤 값을 읽어올 경우에는 &lt;span&gt;getenv &lt;/span&gt;함수를 이용하면 됩니다&lt;span&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4.1 setenv, unsetenv&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1691032601158&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdlib.h&amp;gt;
int setenv(const char *name, const char *value, int overwrite);
int unsetenv(const char *name);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;setenv &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;함수는 &lt;span&gt;name&lt;/span&gt;에 해당하는 &lt;span&gt;value&lt;/span&gt;를 갖는 환경 변수를 설정해줍니다&lt;span&gt;. overwrite&lt;/span&gt;가 &lt;span&gt;1&lt;/span&gt;이라면 기존에 환경 변수값이 있을 때 현재 값으로 덮어쓰고&lt;span&gt;, 0&lt;/span&gt;이라면 덮어쓰지 않습니다&lt;span&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;unsetenv &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;함수는 &lt;span&gt;name&lt;/span&gt;에 해당하는 환경 변수를 해제합니다&lt;span&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;성공시 &lt;span&gt;0, &lt;/span&gt;실패시 &lt;span&gt;-1&lt;/span&gt;을 반환합니다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;4.2 putenv&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1691032632268&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdlib.h&amp;gt;
int putenv(char *string);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;putenv&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;는 &lt;span&gt;&amp;ldquo;&lt;/span&gt;이름&lt;span&gt;=&lt;/span&gt;값&lt;span&gt;&amp;rdquo; &lt;/span&gt;형식으로 넘겨줌으로써 환경 변수를 설정할 수 있습니다&lt;span&gt;. &lt;/span&gt;이때 무조건 덮어쓰기가 되니 주의하세요&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;성공시 &lt;span&gt;0, &lt;/span&gt;실패시 &lt;span&gt;0&lt;/span&gt;이 아닌 값을 반환합니다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;4.3 getenv&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1691032654452&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdlib.h&amp;gt;
char *getenv(const char *name);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;getenv&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;함수는 &lt;span&gt;name&lt;/span&gt;에 해당하는 환경변수를 읽어옵니다&lt;span&gt;. &lt;/span&gt;그래서 그 값을 반환하죠&lt;span&gt;. &lt;/span&gt;만약에 해당하는 환경 변수가 없다면 &lt;span&gt;NULL&lt;/span&gt;을 반환합니다&lt;span&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4.4 환경 변수 함수 이용의 예&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;네 함수&lt;span&gt;(setenv, putenv, getenv unsetenv)&lt;/span&gt;를 다 사용하는 예제를 한번 볼까요&lt;span&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1691032694683&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//setenv.c
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;

int main(int argc, char *argv[]){

        char *name = NULL;
        char *value = NULL;
        char name_val_pair[128]={0,};
        if(argc != 3){
                printf(&quot;Usage %s NAME VALUE\n&quot;, argv[0]);
                return 1;
        }

        name = argv[1];
        value = argv[2];

        //overwrite 허용
        //setenv(name, value, 1);
        //overwrite 불가
        //setenv(name, value, 0);
        sprintf(name_val_pair, &quot;%s=%s&quot;,name,value);
        putenv(name_val_pair);

        printf(&quot;%s=%s\n&quot;,name,getenv(name));

        unsetenv(name);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;putenv&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;를 이용해서 환경 변수를 설정해보았습니다&lt;span&gt;. &lt;/span&gt;만약 여러분이 &lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;setenv&lt;/span&gt;함수를 이용해서 덮어쓸지 말지를 결정할 수도 있습니다&lt;span&gt;. &lt;/span&gt;여기서는 &lt;span&gt;putenv&lt;/span&gt;를 통해서 덮어쓰기가 가능한 환경 변수 설정을 하는 것으로 합시다&lt;span&gt;. &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다음은 환경 변수 &lt;span&gt;USER&lt;/span&gt;를 바꾸는 실행화면입니다&lt;span&gt;. &lt;/span&gt;처음에는 &lt;span&gt;ubuntu&lt;/span&gt;로 설정되어있고&lt;span&gt;, &lt;/span&gt;프로그램을 실행하니까 &lt;span&gt;kali&lt;/span&gt;로 바뀌었습니다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그런데 프로그램이 끝난 이후 &lt;span&gt;USER&lt;/span&gt;를 확인해보니 &lt;span&gt;ubuntu&lt;/span&gt;로 돌아왔네요&lt;span&gt;. &lt;/span&gt;왜 그렇죠&lt;span&gt;!? &lt;a href=&quot;#system_handling_3_2_2_env_var_character&quot;&gt;&lt;span&gt;&lt;span&gt;위&lt;span&gt;에&lt;span&gt;서&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;설&lt;span&gt;명&lt;span&gt;한&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;내&lt;span&gt;용(3 환경변수의 특성)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;을 잊지 않으셨죠&lt;span&gt;?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1691032740876&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# echo $USER
ubuntu
# ./a.out USER kali
USER=kali
# echo $USER
ubuntu&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;만약 &lt;span&gt;USER&lt;/span&gt;가 바껴지는 것을 확인하고 싶다면 &lt;span&gt;system&lt;/span&gt;함수로 다른 &lt;span&gt;shell&lt;/span&gt;을 실행시켜셔 확인해보세요&lt;span&gt;. system &lt;/span&gt;함수는 다른 명령어를 실행하는 함수로 이해하시면 됩니다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1691032752623&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//setenv.c
//&amp;hellip; 생략 &amp;hellip; //

int main(int argc, char *argv[]){
	//&amp;hellip; 생략 &amp;hellip; //
	putenv(name_val_pair);

        printf(&quot;%s=%s\n&quot;,name,getenv(name));
        system(&quot;/bin/sh&quot;);

        unsetenv(name);
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1691032762358&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# ./a.out USER kali
USER=kali
# printenv | grep USER    sh쉘로 전환
USER=kali&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로그인시 환경변수 자동 셋팅(.bashrc), 전체 사용자에 대한 환경 변수 설정(/etc/profile)에 대한 설정 방법은 아주 훌륭하신 블로거님들이 정리를 잘 해놓았으니, 여기서는 설명하지 않겠습니다.&lt;/p&gt;</description>
      <category> 컴퓨터/운영체제(주로 리눅스)</category>
      <category>Export</category>
      <category>getenv</category>
      <category>putenv</category>
      <category>setenv</category>
      <category>source명령</category>
      <category>환경변수</category>
      <category>환경변수개념</category>
      <category>환경변수함수</category>
      <author>REAKWON</author>
      <guid isPermaLink="true">https://reakwon.tistory.com/232</guid>
      <comments>https://reakwon.tistory.com/232#entry232comment</comments>
      <pubDate>Thu, 3 Aug 2023 12:23:59 +0900</pubDate>
    </item>
    <item>
      <title>[리눅스] 시스템의 한계를 구하는 방법 - sysconf, pathconf</title>
      <link>https://reakwon.tistory.com/231</link>
      <description>&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;리눅스의 전반적인 더 많은 정보와 예제를 담은 리눅스 교재를 배포했습니다. 아래의 페이지에서 리눅스 교재를 받아가세요.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://reakwon.tistory.com/233&quot;&gt;https://reakwon.tistory.com/233&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1691052048121&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;리눅스 프로그래밍 note 배포&quot; data-og-description=&quot;티스토리에 리눅스에 관한 내용을 두서없이 여지껏 포스팅했었데요. 저도 제 포스팅을 찾기가 어렵기도 하고 티스토리에서 코드삽입을 하게 되면 이게 일자로 쭉 쓰여져있는 x같은 현상이 생겨&quot; data-og-host=&quot;reakwon.tistory.com&quot; data-og-source-url=&quot;https://reakwon.tistory.com/233&quot; data-og-url=&quot;https://reakwon.tistory.com/233&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cN2yHU/hyTxZSIeE6/Q9VuhsVauuLcHQwEbDzifK/img.png?width=800&amp;amp;height=847&amp;amp;face=0_0_800_847,https://scrap.kakaocdn.net/dn/tlBlx/hyTwhtWkQR/GAoTiXMEt0FUanBkraAid1/img.png?width=800&amp;amp;height=847&amp;amp;face=0_0_800_847,https://scrap.kakaocdn.net/dn/bEWgFd/hyTxXm3UOF/HLjLnAkSLbVcxIjFxKifi1/img.png?width=1308&amp;amp;height=1386&amp;amp;face=0_0_1308_1386&quot;&gt;&lt;a href=&quot;https://reakwon.tistory.com/233&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://reakwon.tistory.com/233&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cN2yHU/hyTxZSIeE6/Q9VuhsVauuLcHQwEbDzifK/img.png?width=800&amp;amp;height=847&amp;amp;face=0_0_800_847,https://scrap.kakaocdn.net/dn/tlBlx/hyTwhtWkQR/GAoTiXMEt0FUanBkraAid1/img.png?width=800&amp;amp;height=847&amp;amp;face=0_0_800_847,https://scrap.kakaocdn.net/dn/bEWgFd/hyTxXm3UOF/HLjLnAkSLbVcxIjFxKifi1/img.png?width=1308&amp;amp;height=1386&amp;amp;face=0_0_1308_1386');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;리눅스 프로그래밍 note 배포&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;티스토리에 리눅스에 관한 내용을 두서없이 여지껏 포스팅했었데요. 저도 제 포스팅을 찾기가 어렵기도 하고 티스토리에서 코드삽입을 하게 되면 이게 일자로 쭉 쓰여져있는 x같은 현상이 생겨&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;reakwon.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;한계&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리눅스에서 프로그램을 다른 리눅스에서 실행할 수 있습니다. 혹은 다른 유닉스 계열(BSD나 솔라리스, MAC OS X 등)의 시스템에서도 동작이 될 수가 있지요. 그런데 이렇게 시스템마다 지원하는 한계라는 것이 다 제 각각이거든요. 예를 들면 어떤 시스템에서는 한 프로세스 당 열 수 있는 파일 디스크립터의 갯수가 256개를 지원하는데, 다른 시스템에서는 1024개까지 지원할 수 있는 등 시스템마다 지원할 수 있는 한계가 존재합니다. 그렇다면 어떤 시스템에서 사용자가 생성할 수 있는 자식 프로세스의 수라던가, 최대 파일 경로의 이름이라던가,&amp;nbsp; 로그인이 가능한 이름의 최대 길이라던가를 알아내면 그 프로그램이 효율적으로 동작할 수 있을 것 같은데요. 과연 어떻게 알아낼 수 있을까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한계는 세가지로 구분할 수가 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;컴파일 시점에서 한계(헤더 파일에 명시)&lt;/b&gt; : 이러한 한계들은 limits.h에 명시되어 있습니다. 시스템마다 불변하는 한계를 의미하게 됩니다. 예를 들어 POSIX를 준수하는 시스템에서는 int 자료형에서 지원가능한 값은 2,147,483,647이 적어도 만족이 되어야합니다. INT_MAX 상수로 확인이 가능합니다. 여기서는 설명하지 않겠습니다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;파일이나 디렉토리와 연관되지 않은 실행 시점의 한계(sysconf 함수)&lt;/b&gt; : 파일과 연관이 없는 시스템에서 실제 지원할 수가 있는 한계를 확인하려면 &lt;b&gt;sysconf&lt;/b&gt;함수를 이용해서 확인할 수 있습니다. 함수의 원형을 볼까요?&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1690775979290&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;unistd.h&amp;gt;

long sysconf(int name);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;sysconf의 인자인 name을 전달하게 되면 그에 따른 값이 나옵니다. name은 앞에 &lt;b&gt;_SC_&lt;/b&gt;로 시작하는 매크로 상수입니다. SC는 SysConf의 약자입니다. 아래의 소개한 매크로보다 더 다양한 name이 있습니다. 여기서는 요만큼만 설명합니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style15&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 34.3023%;&quot;&gt;매크로 상수&lt;/td&gt;
&lt;td style=&quot;width: 65.6977%;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 34.3023%;&quot;&gt;_SC_ARG_MAX&lt;/td&gt;
&lt;td style=&quot;width: 65.6977%;&quot;&gt;exec 함수의 인수 길이 최대값&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 34.3023%;&quot;&gt;_SC_CHILD_MAX&lt;/td&gt;
&lt;td style=&quot;width: 65.6977%;&quot;&gt;uid 당 동시에 실행할 수 있는 프로세스의 최대값&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 34.3023%;&quot;&gt;_SC_HOST_NAME_MAX&lt;/td&gt;
&lt;td style=&quot;width: 65.6977%;&quot;&gt;hostname의 최대 값, gethostname으로 구할 수 있습니다&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 34.3023%;&quot;&gt;_SC_LOGIN_NAMX_MAX&lt;/td&gt;
&lt;td style=&quot;width: 65.6977%;&quot;&gt;로그인 이름의 최대 길이&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 34.3023%;&quot;&gt;_SC_OPEN_MAX&lt;/td&gt;
&lt;td style=&quot;width: 65.6977%;&quot;&gt;프로세스가 열 수 있는 파일의 최대 갯수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 34.3023%;&quot;&gt;_SC_PAGE_SIZE&lt;br /&gt;_SC_PAGESIZE&lt;/td&gt;
&lt;td style=&quot;width: 65.6977%;&quot;&gt;페이지의 크기&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 34.3023%;&quot;&gt;_SC_STREAM_MAX&lt;/td&gt;
&lt;td style=&quot;width: 65.6977%;&quot;&gt;프로세스가 열 수 있는 파일 스트림의 최대 갯수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 34.3023%;&quot;&gt;_SC_TTY_NAME_MAX&lt;/td&gt;
&lt;td style=&quot;width: 65.6977%;&quot;&gt;터미널 디바이스 이름의 최대 길이&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 34.3023%;&quot;&gt;_SC_TZNAME_MAX&lt;/td&gt;
&lt;td style=&quot;width: 65.6977%;&quot;&gt;타임 존 이름의 최대 길이&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 34.3023%;&quot;&gt;_SC_LINE_MAX&lt;/td&gt;
&lt;td style=&quot;width: 65.6977%;&quot;&gt;유틸리티 프로그램에서 입력 줄로 받을 수 있는 최대 길이(stdin으로든 file으로 든)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 34.3023%;&quot;&gt;_SC_SIGQUEUE_MAX&lt;/td&gt;
&lt;td style=&quot;width: 65.6977%;&quot;&gt;한 프로세스에 신호 큐에 담을 수 있는 신호의 최대 갯수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 34.3023%;&quot;&gt;_SC_SEM_VALUE_MAX&lt;/td&gt;
&lt;td style=&quot;width: 65.6977%;&quot;&gt;세마포어의 최대값&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 34.3023%;&quot;&gt;_SC_SEM_NSEMS_MAX&lt;/td&gt;
&lt;td style=&quot;width: 65.6977%;&quot;&gt;한 프로세스가 동시에 사용할 수 있는 세마포어의 최대 개수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 34.3023%;&quot;&gt;_SC_CLK_TCK&lt;/td&gt;
&lt;td style=&quot;width: 65.6977%;&quot;&gt;1초 클록 틱 개수&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;파일이나 디렉토리와 연관된 실행 시점의 한계(pathconf 함수 혹은 fpathconf 함수)&lt;/b&gt; : 파일과 관련된 한계를 알아낼 때는 &lt;b&gt;pathconf&lt;/b&gt;와 &lt;b&gt;fpathconf&lt;/b&gt; 함수를 사용할 수 있습니다. 예를 들어 어떤 터미널에 대한 한계를 알고 싶다면 /dev/ 하위의 터미널 파일을 입력으로 주어 확인할 수 있습니다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1690777426930&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;unistd.h&amp;gt;

long fpathconf(int fd, int name);
long pathconf(const char *path, int name);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이 둘의 동작은 같습니다. 단지 파일을 알려주는 첫 인자를 파일 디스크립터로 전달하느냐(fd), 파일의 경로와 이름을 사용하여 전달하느냐(path)에 따른 것만 다르죠. name은 확인하려는 한계의 이름을 넣어주면 됩니다. 앞에 _PC_로 시작합니다. Path Config의 약자겠죠?&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 145px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style15&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 35.5814%; height: 19px;&quot;&gt;매크로 상수&lt;/td&gt;
&lt;td style=&quot;width: 64.4186%; height: 19px;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 38px;&quot;&gt;
&lt;td style=&quot;width: 35.5814%; height: 38px;&quot;&gt;_PC_LINK_MAX&lt;/td&gt;
&lt;td style=&quot;width: 64.4186%; height: 38px;&quot;&gt;파일에 최대 링크 갯수를 의미하며, 만약 파일이라면 파일에 대한 최대 링크 갯수를 가져오고, 디렉토리를 지정하면 디렉토리의 링크 최대 갯수를 가져옵니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 35.5814%; height: 19px;&quot;&gt;_PC_MAX_CANON&lt;/td&gt;
&lt;td style=&quot;width: 64.4186%; height: 19px;&quot;&gt;터미널의 서식화된 입력줄의 최대 길이로 파일을 반드시 터미널 파일을 지정해야합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 35.5814%; height: 18px;&quot;&gt;_PC_MAX_INPUT&lt;/td&gt;
&lt;td style=&quot;width: 64.4186%; height: 18px;&quot;&gt;터미널의 입력줄의 최대 길이로 반드시 터미널 파일을 지정해야합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 35.5814%; height: 17px;&quot;&gt;_PC_NAME_MAX&lt;/td&gt;
&lt;td style=&quot;width: 64.4186%; height: 17px;&quot;&gt;지정한 디렉토리에서 파일 입력의 최대 길이로 인자를 디렉토리로 주어야합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 35.5814%; height: 17px;&quot;&gt;_PC_PIPE_BUF&lt;/td&gt;
&lt;td style=&quot;width: 64.4186%; height: 17px;&quot;&gt;하나의 파이프에 원자적으로 쓸 수 있는 최대 바이트 수로 pipe나 fifo 타입의 파일, 혹은 디렉토리를 주어야합니다. 디렉토리를 주었을 때는 디렉토리 안에 생성된 임의의 fifo에 대한 한계를 가져옵니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 35.5814%; height: 17px;&quot;&gt;_PC_PATH_MAX&lt;/td&gt;
&lt;td style=&quot;width: 64.4186%; height: 17px;&quot;&gt;path나 fd가 현재 작업 디렉토리일 경우 상대 경로의 최대길이&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 세 함수(sysconf, pathconf, fpathconf)는 &lt;b&gt;실패일 경우 -1&lt;/b&gt;이 반환되지만 1&lt;b&gt;) 실제 지원하지 않는 name이라서 실패한 경우&lt;/b&gt;와 &lt;b&gt;2)확정할 수 없는 한계에 의한 실패&lt;/b&gt;가 있습니다. 지원하지 않는 실패의 경우 errno가 EINVAL로 설정되구요. 확정할 수 없는 한계에 의한 실패는 errno가 변하지 않습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;한계를 가져오는 소스 코드&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;
&lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-9615403369038266&quot; data-ad-slot=&quot;6888174260&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1690780283838&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//print_conf.c
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;limits.h&amp;gt;
#include &amp;lt;errno.h&amp;gt;

static void print_sysconf(char *str, int name){
        long val;
        errno = 0;
        printf(&quot;%s &quot;, str);

        if((val = sysconf(name)) &amp;lt; 0){ 
                if(errno != 0){
                        if(errno == EINVAL)
                                printf(&quot; (not supported)\n&quot;);
                        else printf(&quot;syconf error\n&quot;);
                }else
                        printf(&quot; (no limit)\n&quot;);

        }else 
                printf(&quot; %ld\n&quot;, val);
}

static void print_pathconf(char *str, char *path, int name){
        long val;
        printf(&quot;%s &quot;, str);
        errno = 0;
        if((val = pathconf(path,name)) &amp;lt; 0){ 
                if(errno != 0){
                        if(errno == EINVAL)
                                printf(&quot; (not supported)\n&quot;);
                        else printf(&quot;pathcon error(%s)\n&quot;, path);
                }else
                        printf(&quot; (no limit)\n&quot;);
        }else
                printf(&quot; %ld\n&quot;, val);

}
int main(int argc, char *argv[]){
        if(argc != 2){
                printf(&quot;Usage : %s &amp;lt;filename&amp;gt; \n&quot;, argv[0]);
                return 1;
        }


        printf(&quot;======== sysconf ==========\n&quot;);
#ifdef _SC_ARG_MAX
        print_sysconf(&quot;ARG_MAX :&quot;, _SC_ARG_MAX);
#endif
#ifdef _SC_CHILD_MAX
        print_sysconf(&quot;CHILD_MAX : &quot;, _SC_CHILD_MAX);
#endif
#ifdef _SC_HOST_NAME_MAX
        print_sysconf(&quot;HOST_NAME_MAX : &quot;, _SC_HOST_NAME_MAX);
#endif
#ifdef _SC_LOGIN_NAMX_MAX
        print_sysconf(&quot;LOGIN_NAMX_MAX : &quot;, _SC_LOGIN_NAMX_MAX);
#endif
#ifdef _SC_OPEN_MAX
        print_sysconf(&quot;OPEN_MAX : &quot;, _SC_OPEN_MAX);
#endif
#ifdef _SC_PAGESIZE
        print_sysconf(&quot;PAGESIZE : &quot;, _SC_PAGESIZE);
#endif
#ifdef _SC_STREAM_MAX
        print_sysconf(&quot;STREAM_MAX : &quot;, _SC_STREAM_MAX);
#endif
#ifdef _SC_TTY_NAME_MAX
        print_sysconf(&quot;TTY_NAME_MAX : &quot;, _SC_TTY_NAME_MAX);
#endif
#ifdef _SC_TZNAME_MAX
        print_sysconf(&quot;TZNAME_MAX : &quot;, _SC_TZNAME_MAX);
#endif
#ifdef _SC_LINE_MAX
        print_sysconf(&quot;LINE_MAX : &quot;, _SC_LINE_MAX);
#endif
#ifdef _SC_SIGQUEUE_MAX
        print_sysconf(&quot;SIGQUEUE_MAX : &quot;, _SC_SIGQUEUE_MAX);
#endif
#ifdef _SC_SEM_VALUE_MAX
        print_sysconf(&quot;SEM_VALUE_MAX : &quot;, _SC_SEM_VALUE_MAX);
#endif
#ifdef _SC_SEM_NSEMS_MAX
        print_sysconf(&quot;SEM_NSEMS_MAX : &quot;, _SC_SEM_NSEMS_MAX);
#endif
#ifdef _SC_CLK_TCK
        print_sysconf(&quot;CLK_TCK : &quot;, _SC_CLK_TCK);
#endif

        printf(&quot;======== pathconf ==========\n&quot;);
#ifdef _PC_LINK_MAX
        print_pathconf(&quot;LINK_MAX : &quot;, argv[1], _PC_LINK_MAX);
#endif
#ifdef _PC_MAX_CANON
        print_pathconf(&quot;MAX_CANON : &quot;, argv[1], _PC_MAX_CANON);
#endif
#ifdef _PC_MAX_INPUT
        print_pathconf(&quot;MAX_INPUT : &quot;, argv[1], _PC_MAX_INPUT);
#endif
#ifdef _PC_NAME_MAX
        print_pathconf(&quot;NAME_MAX : &quot;, argv[1], _PC_NAME_MAX);
#endif
#ifdef _PC_PIPE_BUF
        print_pathconf(&quot;PIPE_BUF : &quot;, argv[1], _PC_PIPE_BUF);
#endif
#ifdef _PC_PATH_MAX
        print_pathconf(&quot;PATH_MAX : &quot;, argv[1], _PC_PATH_MAX);
#endif

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 소스코드는 sysconf와 pathconf 함수를 사용해서 한계를 출력해주는 프로그램입니다. 다른 시스템에서는 정의되지 않은 name이 존재할 수 있으므로 #ifdef로 정의되어있는지 파악하여 사용합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실패할 경우에는 errno이 EINVAL이면 지원하지 않는 한계 이름입니다. 그런데 errno가 0으로 변하지 않았다면 불확정인 한계로 볼 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;
&lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-9615403369038266&quot; data-ad-slot=&quot;6888174260&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1690780371593&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;errno = 0;
//...
if((val = sysconf(name)) &amp;lt; 0){ 
    if(errno != 0){
            if(errno == EINVAL)
                    printf(&quot; (not supported)\n&quot;);
            else printf(&quot;syconf error\n&quot;);
    }else
            printf(&quot; (no limit)\n&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 실행 결과입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1690780833593&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# ./a.out /etc
======== sysconf ==========
ARG_MAX :  2097152
CHILD_MAX :   15044
HOST_NAME_MAX :   64
OPEN_MAX :   1024
PAGESIZE :   4096
STREAM_MAX :   16
TTY_NAME_MAX :   32
TZNAME_MAX :   (no limit)
LINE_MAX :   2048
SIGQUEUE_MAX :   15044
SEM_VALUE_MAX :   2147483647
SEM_NSEMS_MAX :   (no limit)
CLK_TCK :   100
======== pathconf ==========
LINK_MAX :   65000
MAX_CANON :   255
MAX_INPUT :   255
NAME_MAX :   255
PIPE_BUF :   4096
PATH_MAX :   4096&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category> 컴퓨터/운영체제(주로 리눅스)</category>
      <category>ARG_MAX</category>
      <category>CHILD_MAX</category>
      <category>fpathconf</category>
      <category>OPEN_MAX</category>
      <category>pathconf</category>
      <category>sysconf</category>
      <category>_SC_PAGESIZE</category>
      <category>한계</category>
      <author>REAKWON</author>
      <guid isPermaLink="true">https://reakwon.tistory.com/231</guid>
      <comments>https://reakwon.tistory.com/231#entry231comment</comments>
      <pubDate>Mon, 31 Jul 2023 14:24:10 +0900</pubDate>
    </item>
  </channel>
</rss>