¿©±âÀÇ ¸ðµç ¿¹Á¦´Â miniterm.c¿¡¼ µû¿Ô´Ù. Canonical ÀԷ ó¸®¿¡¼
ó¸®ÇÒ ¼ö ÀÖ´Â ÃÖ´ë ±æÀÌÀÇ ¹®ÀÚ´Â 255°³(<linux/limits.h>
ȤÀº <posix1_lim.h>¿¡ Á¤ÀǵÊ) ·Î¼ ¹öÆÛÀÇ ÃÖ´ë ±æÀÌ´Â
255·Î Á¦ÇѵȴÙ.
¿©·¯ ÀԷ ó¸® ¸ðµåÀÇ »ç¿ë¹ý¿¡ ´ëÇÑ ¼³¸íÀ» ¿øÇϸé ÄÚµå ³»ÀÇ comment¸¦ ÂüÁ¶Ç϶ó. Äڵ尡 ÀÌÇØÇϱ⠽±±â¸¦ ¹Ù¶õ´Ù. Canonical ÀԷ ó¸® ¸ðµåÀÇ ¿¹Á¦´Â comment¸¦ °¡Àå Àß ÇØ³õ¾Ò´Ù. ´Ù¸¥ ¿¹Á¦´Â canonical ¸ðµå ¿¹Á¦¿Í ´Ù¸¥ ºÎºÐ¿¡¸¸ comment¸¦ ´Þ¾Ò´Ù.
¼³¸íÀÌ ¿Ïº®ÇÏÁø ¾ÊÁö¸¸, ÀÌ ¿¹Á¦·Î Á÷Á¢ Å×½ºÆ®¸¦ ÇØº¸¸é ´ç½ÅÀÇ ÇÁ·Î±×·¥¿¡ Àû¿ëÇÒ ¶§ ÃÖÀûÀÇ ¹æ¹ýÀ» ãÀ» ¼ö ÀÖÀ» °ÍÀÌ´Ù.
½Ã¸®¾ó Æ÷Æ® ÀåÄ¡ ÆÄÀÏÀÇ ¼±ÅÃÀ» Á¦´ë·Î Çߴ°¡¸¦ ´Ù½Ã ÇÑ ¹ø È®ÀÎÇϰí, ÆÄÀÏ Á¢±Ù
Çã°¡´Â Á¦´ë·Î µÇ¾î ÀÖ´ÂÁö º¸±â¸¦ ¹Ù¶õ´Ù.
(¿¹: chmod a+rw /dev/ttyS1)
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <fcntl.h>
  #include <termios.h>
  #include <stdio.h>
  /* Baudrate ¼³Á¤Àº <asm/termbits.h>¿¡ Á¤ÀǵǾî ÀÖ´Ù.
  /* <asm/termbits.h>´Â <termios.h>¿¡¼ includeµÈ´Ù. */
  #define BAUDRATE B38400
  /* ¿©±âÀÇ Æ÷Æ® ÀåÄ¡ ÆÄÀÏÀ» ¹Ù²Û´Ù. COM1="/dev/ttyS1, COM2="/dev/ttyS2 */
  #define MODEMDEVICE "/dev/ttyS1"
  #define _POSIX_SOURCE 1 /* POSIX ȣȯ ¼Ò½º */
  #define FALSE 0
  #define TRUE 1
  volatile int STOP=FALSE;
  main()
  {
    int fd,c, res;
    struct termios oldtio,newtio;
    char buf[255];
  /* Àбâ/¾²±â ¸ðµå·Î ¸ðµ© ÀåÄ¡¸¦ ¿¬´Ù.(O_RDWR)
     µ¥ÀÌÅÍ Àü¼Û ½Ã¿¡ <CTRL>-C ¹®ÀÚ°¡ ¿À¸é ÇÁ·Î±×·¥ÀÌ Á¾·áµÇÁö ¾Êµµ·Ï
     Çϱâ À§ÇØ controlling tty°¡ ¾ÈµÇµµ·Ï ÇÑ´Ù.(O_NOCTTY)
  */
   fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
   if (fd <0) {perror(MODEMDEVICE); exit(-1); }
   tcgetattr(fd,&oldtio); /* save current serial port settings */
   bzero(&newtio, sizeof(newtio)); /* clear struct for new port settings */
  /*
    BAUDRATE: Àü¼Û ¼Óµµ. cfsetispeed() ¹× cfsetospeed() ÇÔ¼ö·Îµµ ¼¼ÆÃ °¡´É
    CRTSCTS : Çϵå¿þ¾î È帧 Á¦¾î. (½Ã¸®¾ó ÄÉÀ̺íÀÌ ¸ðµç ÇÉ¿¡ ¿¬°áµÇ¾î ÀÖ´Â
              °æ¿ì¸¸ »ç¿ëÇϵµ·Ï ÇÑ´Ù. Serial-HOWTOÀÇ 7ÀåÀ» ÂüÁ¶ÇÒ °Í.)
    CS8     : 8N1 (8bit, no parity, 1 stopbit)
    CLOCAL  : Local connection. ¸ðµ© Á¦¾î¸¦ ÇÏÁö ¾Ê´Â´Ù.
    CREAD   : ¹®ÀÚ ¼ö½ÅÀ» °¡´ÉÇÏ°Ô ÇÑ´Ù.
  */
   newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
  /*
   IGNPAR   : Parity ¿¡·¯°¡ ÀÖ´Â ¹®ÀÚ ¹ÙÀÌÆ®¸¦ ¹«½ÃÇÑ´Ù.
   ICRNL    : CR ¹®ÀÚ¸¦ NL ¹®ÀÚ·Î º¯È¯ ó¸®ÇÑ´Ù. (ÀÌ ¼³Á¤À» ¾ÈÇÏ¸é ´Ù¸¥
              ÄÄÇ»ÅÍ´Â CR ¹®ÀÚ¸¦ ÇÑ ÁÙÀÇ Á¾·á¹®ÀÚ·Î ÀνÄÇÏÁö ¾ÊÀ» ¼ö ÀÖ´Ù.)
    otherwise make device raw (no other input processing)
  */
   newtio.c_iflag = IGNPAR | ICRNL;
  /*
   Raw output.
  */
   newtio.c_oflag = 0;
   ICANON   : canonical ÀÔ·ÂÀ» °¡´ÉÇÏ°Ô ÇÑ´Ù.
    disable all echo functionality, and don't send signals to calling program
  */
   newtio.c_lflag = ICANON;
  /*
    ¸ðµç Á¦¾î ¹®ÀÚµéÀ» ÃʱâÈÇÑ´Ù.
    µðÆúÆ® °ªÀº <termios.h> Çì¾î ÆÄÀÏ¿¡¼ ãÀ» ¼ö ÀÖ´Ù. ¿©±â comment¿¡µµ
    Ãß°¡·Î ´Þ¾Æ³õ¾Ò´Ù.
  */
   newtio.c_cc[VINTR]    = 0;     /* Ctrl-c */
   newtio.c_cc[VQUIT]    = 0;     /* Ctrl-\ */
   newtio.c_cc[VERASE]   = 0;     /* del */
   newtio.c_cc[VKILL]    = 0;     /* @ */
   newtio.c_cc[VEOF]     = 4;     /* Ctrl-d */
   newtio.c_cc[VTIME]    = 0;     /* inter-character timer unused */
   newtio.c_cc[VMIN]     = 1;     /* blocking read until 1 character arrives */
   newtio.c_cc[VSWTC]    = 0;     /* '\0' */
   newtio.c_cc[VSTART]   = 0;     /* Ctrl-q */
   newtio.c_cc[VSTOP]    = 0;     /* Ctrl-s */
   newtio.c_cc[VSUSP]    = 0;     /* Ctrl-z */
   newtio.c_cc[VEOL]     = 0;     /* '\0' */
   newtio.c_cc[VREPRINT] = 0;     /* Ctrl-r */
   newtio.c_cc[VDISCARD] = 0;     /* Ctrl-u */
   newtio.c_cc[VWERASE]  = 0;     /* Ctrl-w */
   newtio.c_cc[VLNEXT]   = 0;     /* Ctrl-v */
   newtio.c_cc[VEOL2]    = 0;     /* '\0' */
  /*
    ÀÌÁ¦ modem ¶óÀÎÀ» ÃʱâÈÇÏ°í Æ÷Æ® ¼¼ÆÃÀ» ¸¶Ä£´Ù.
  */
   tcflush(fd, TCIFLUSH);
   tcsetattr(fd,TCSANOW,&newtio);
  /*
    Å͹̳Π¼¼ÆÃÀÌ ³¡³µ°í, ÀÌÁ¦´Â ÀÔ·ÂÀ» ó¸®ÇÑ´Ù.
    ÀÌ ¿¹Á¦¿¡¼´Â ÇÑ ÁÙÀÇ ¸Ç ù ¹®ÀÚ¸¦ 'z'·Î ÇßÀ» ¶§ ÇÁ·Î±×·¥À»
    Á¾·áÇÑ´Ù.
  */
   while (STOP==FALSE) {     /* Á¾·á Á¶°Ç(STOP==TRUE)°¡ µÉ ¶§±îÁö ·çÇÁ */
   /* read()´Â ¶óÀÎ Á¾·á ¹®ÀÚ°¡ ³ª¿Ã ¶§±îÁö 255 ¹®ÀÚ¸¦ ³Ñ¾î°¡´õ¶óµµ
      block µÈ´Ù. read ÇϰíÀÚ ÇÏ´Â ¹®ÀÚ °³¼ö°¡ ÀÔ·Â °¡´ÉÇÑ ¹®ÀÚ °³¼öº¸´Ù
      ÀûÀº °æ¿ì¿¡´Â ¶Ç ÇѹøÀÇ read¸¦ ÇÏ¿© ³ª¸ÓÁö¸¦ Àо ¼ö ÀÖ´Ù.
      res´Â read¿¡ ÀÇÇØ¼ ½ÇÁ¦·Î ÀÐÇôÁø ¹®ÀÚÀÇ °³¼ö¸¦ °®°Ô µÈ´Ù. */
      
      res = read(fd,buf,255);
      buf[res]=0;             /* set end of string, so we can printf */
      printf(":%s:%d\n", buf, res);
      if (buf[0]=='z') STOP=TRUE;
   }
   /* restore the old port settings */
   tcsetattr(fd,TCSANOW,&oldtio);
  }
Non-Canonical ÀԷ ó¸® ¸ðµå¿¡¼´Â ÀÔ·ÂÀÌ ÇÑ ÁÙ ´ÜÀ§·Î 󸮵ÇÁö ¾Ê´Â´Ù.
erase, kill, delete µîÀÇ ÀԷ ó¸®µµ ¼öÇàµÇÁö ¾Ê´Â´Ù. ÀÌ ¸ðµå¿¡¼ ¼³Á¤ÇÏ´Â
ÆÄ¶ó¹ÌÅÍ´Â c_cc[VTIME]°ú c_cc[VMIN] µÎ °¡ÁöÀÌ´Ù.
c_cc[VTIME]Àº ŸÀ̸ÓÀÇ ½Ã°£À» ¼³Á¤Çϰí, c_cc[VMIN]Àº
readÇÒ ¶§ ¸®ÅϵDZâ À§ÇÑ ÃÖ¼ÒÀÇ ¹®ÀÚ °³¼ö¸¦ ÁöÁ¤ÇÑ´Ù.
MINÀº read°¡ ¸®ÅϵDZâ À§ÇÑ ÃÖ¼ÒÇÑÀÇ ¹®ÀÚ °³¼ö.
TIMEÀÌ 0À̸é ŸÀ̸Ӵ »ç¿ëµÇÁö ¾Ê´Â´Ù.(¹«ÇÑ´ë·Î
±â´Ù¸°´Ù.)
TIMEÀº time-out °ªÀ¸·Î »ç¿ëµÈ´Ù. Time-out °ªÀº
TIME * 0.1 ÃÊÀÌ´Ù. Time-outÀÌ ÀϾ±â Àü¿¡
ÇÑ ¹®ÀÚ¶óµµ µé¾î¿À¸é read´Â ¸®ÅϵȴÙ. 
TIMEÀº time-outÀÌ ¾Æ´Ñ inter-character ŸÀ̸ӷΠµ¿ÀÛÇÑ´Ù. ÃÖ¼Ò MIN °³ÀÇ ¹®ÀÚ°¡ µé¾î¿À°Å³ª µÎ ¹®ÀÚ »çÀÌÀÇ ½Ã°£ÀÌ TIME °ªÀ» ³ÑÀ¸¸é ¸®ÅϵȴÙ. ¹®ÀÚ°¡ óÀ½ µé¾î¿Ã ¶§ ŸÀ̸Ӵ µ¿ÀÛÀ» ½ÃÀÛÇϰí ÀÌÈÄ ¹®ÀÚ°¡ µé¾î¿Ã ¶§¸¶´Ù Àç½ÃÀ۵ȴÙ.
read´Â Áï½Ã ¸®ÅϵȴÙ. ÇöÀç ÀÐÀ» ¼ö ÀÖ´Â ¹®ÀÚÀÇ °³¼ö³ª
¿äûÇÑ ¹®ÀÚ °³¼ö°¡ ¹ÝȯµÈ´Ù. Antonino¾¾¿¡ ÀÇÇϸé
readÇϱâ Àü¿¡ fcntl(fd, F_SETFL, FNDELAY); ¸¦
È£ÃâÇÏ¸é ¶È°°Àº °á°ú¸¦ ¾òÀ» ¼ö ÀÖ´Ù.
newtio.c_cc[VTIME]°ú newtio.c_cc[VMIN]À»
¼öÁ¤ÇÏ¿© À§ ³× °¡Áö ¹æ½ÄÀ» Å×½ºÆ® ÇÒ ¼ö ÀÖ´Ù.
       #include <sys/types.h>
       #include <sys/stat.h>
       #include <fcntl.h>
       #include <termios.h>
       #include <stdio.h>
       #define BAUDRATE B38400
       #define MODEMDEVICE "/dev/ttyS1"
       #define _POSIX_SOURCE 1 /* POSIX compliant source */
       #define FALSE 0
       #define TRUE 1
       volatile int STOP=FALSE;
       main()
       {
         int fd,c, res;
         struct termios oldtio,newtio;
         char buf[255];
        fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
        if (fd <0) {perror(MODEMDEVICE); exit(-1); }
        tcgetattr(fd,&oldtio); /* ÇöÀç ¼³Á¤À» oldtio¿¡ ÀúÀå */
        bzero(&newtio, sizeof(newtio));
        newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
        newtio.c_iflag = IGNPAR;
        newtio.c_oflag = 0;
        /* set input mode (non-canonical, no echo,...) */
        newtio.c_lflag = 0;
        newtio.c_cc[VTIME]    = 0;   /* ¹®ÀÚ »çÀÌÀÇ timer¸¦ disable */
        newtio.c_cc[VMIN]     = 5;   /* ÃÖ¼Ò 5 ¹®ÀÚ ¹ÞÀ» ¶§±îÁø blocking */
        tcflush(fd, TCIFLUSH);
        tcsetattr(fd,TCSANOW,&newtio);
        while (STOP==FALSE) {       /* loop for input */
          res = read(fd,buf,255);   /* ÃÖ¼Ò 5 ¹®ÀÚ¸¦ ¹ÞÀ¸¸é ¸®ÅÏ */
          buf[res]=0;               /* '\0' Á¾·á ¹®ÀÚ¿(printf¸¦ Çϱâ À§ÇØ) */
          printf(":%s:%d\n", buf, res);
          if (buf[0]=='z') STOP=TRUE;
        }
        tcsetattr(fd,TCSANOW,&oldtio);
       }
  #include <termios.h>
  #include <stdio.h>
  #include <unistd.h>
  #include <fcntl.h>
  #include <sys/signal.h>
  #include <sys/types.h>
  #define BAUDRATE B38400
  #define MODEMDEVICE "/dev/ttyS1"
  #define _POSIX_SOURCE 1 /* POSIX compliant source */
  #define FALSE 0
  #define TRUE 1
  volatile int STOP=FALSE;
  void signal_handler_IO (int status);   /* signal handler ÇÔ¼ö Á¤ÀÇ */
  int wait_flag=TRUE;                    /* signalÀ» ¹ÞÁö ¾ÊÀº µ¿¾ÈÀº TRUE */
  main()
  {
    int fd,c, res;
    struct termios oldtio,newtio;
    struct sigaction saio;           /* signal actionÀÇ Á¤ÀÇ */
    char buf[255];
    /* Non-blocking ¸ðµå·Î ½Ã¸®¾ó ÀåÄ¡¸¦ ¿¬´Ù(read ÇÔ¼ö È£Ãâ ÈÄ Áï°¢ ¸®ÅÏ) */
    fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
    if (fd <0) {perror(MODEMDEVICE); exit(-1); }
    /* install the signal handler before making the device asynchronous */
    /* ÀåÄ¡¸¦ ºñµ¿±â ¸ðµå·Î ¸¸µé±â Àü¿¡ signal handler */
    saio.sa_handler = signal_handler_IO;
    saio.sa_mask = 0;
    saio.sa_flags = 0;
    saio.sa_restorer = NULL;
    sigaction(SIGIO,&saio,NULL);
    /* SIGIO signalÀ» ¹ÞÀ» ¼ö ÀÖµµ·Ï ÇÑ´Ù. */
    fcntl(fd, F_SETOWN, getpid());
    /* file descriptor¸¦ ºñµ¿±â·Î ¸¸µç´Ù. (manual page¸¦ º¸¸é
       O_APPEND ¿Í O_NONBLOCK¸¸ÀÌ F_SETFL¿¡ »ç¿ëÇÒ ¼ö ÀÖ´Ù°í µÇ¾î ÀÖ´Ù.) */
    fcntl(fd, F_SETFL, FASYNC);
    tcgetattr(fd,&oldtio); /* save current port settings */
    /* canonical ÀÔ·Â󸮸¦ À§ÇÑ Æ÷Æ® ¼¼ÆÃ */
    newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
    newtio.c_iflag = IGNPAR | ICRNL;
    newtio.c_oflag = 0;
    newtio.c_lflag = ICANON;
    newtio.c_cc[VMIN]=1;
    newtio.c_cc[VTIME]=0;
    tcflush(fd, TCIFLUSH);
    tcsetattr(fd,TCSANOW,&newtio);
    /* loop while waiting for input. normally we would do something
       useful here */
    while (STOP==FALSE) {
      printf(".\n");usleep(100000);
      /* after receiving SIGIO, wait_flag = FALSE, input is available
         and can be read */
      if (wait_flag==FALSE) {
        res = read(fd,buf,255);
        buf[res]=0;
        printf(":%s:%d\n", buf, res);
        if (res==1) STOP=TRUE; /* stop loop if only a CR was input */
        wait_flag = TRUE;      /* wait for new input */
      }
    }
    /* restore old port settings */
    tcsetattr(fd,TCSANOW,&oldtio);
  }
  /***************************************************************************
  * signal handler. sets wait_flag to FALSE, to indicate above loop that     *
  * characters have been received.                                           *
  ***************************************************************************/
  void signal_handler_IO (int status)
  {
    printf("received SIGIO signal.\n");
    wait_flag = FALSE;
  }
ÀÌ ¼½¼ÇÀº °£·«ÇÑ ¼³¸í¸¸À» ÇϰڴÙ. ¾î¶»°Ô ÇÏ´Â Áö¿¡ ´ëÇÑ °£´ÜÇÑ ÈùÆ®¸¸À» ÁÖ±â À§ÇÑ °ÍÀ̹ǷΠªÀº ¿¹Á¦ Äڵ常À» ´ã¾Ò´Ù. ÀÌ ¹æ¹ýÀº ½Ã¸®¾ó Æ÷Æ®¿¡¸¸ Àû¿ëµÇ´Â °ÍÀÌ ¾Æ´Ï¶ó file descriptor¸¦ »ç¿ëÇÏ´Â ¸ðµç ÀÔÃâ·Â¿¡ »ç¿ëÇÒ ¼ö ÀÖ´Ù.
select() ½Ã½ºÅÛ È£Ãâ ÇÔ¼ö¿Í ÇØ´çÇÏ´Â ¸ÅÅ©·Î ÇÔ¼öµéÀº
fd_setÀ» »ç¿ëÇÑ´Ù. fd_set´Â bit array·Î¼
file descriptorÀÇ bit entry·Î ÀÛ¿ëÇÑ´Ù.
select()´Â ÇØ´çÇÏ´Â file descriptorÀÇ bitµéÀ» ¼¼ÆÃÇÑ
fd_setÀ» ÀÔ·Â ÆÄ¶ó¹ÌÅÍ·Î ¹Þ¾Æ¼ ÀÔ·Â, Ãâ·Â ȤÀº
¿¹¿Ü ¹ß»ýÀÌ ÀÏ¾î³ °æ¿ì ¸®ÅÏÇÑ´Ù. fd_setÀº
FD_·Î ½ÃÀÛÇÏ´Â ¸ÅÅ©·Î ÇÔ¼öµéÀ» ÅëÇØ¼ °ü¸®ÇÑ´Ù.
select(2)ÀÇ man page¸¦ ÂüÁ¶Ç϶ó.
  #include <sys/time.h>
  #include <sys/types.h>
  #include <unistd.h>
  main()
  {
     int    fd1, fd2;  /* input sources 1 and 2 */
     fd_set readfs;    /* file descriptor set */
     int    maxfd;     /* maximum file desciptor used */
     int    loop=1;    /* loop while TRUE */
     /* open_input_source opens a device, sets the port correctly, and
        returns a file descriptor */
     fd1 = open_input_source("/dev/ttyS1");   /* COM2 */
     if (fd1<0) exit(0);
     fd2 = open_input_source("/dev/ttyS2");   /* COM3 */
     if (fd2<0) exit(0);
     maxfd = MAX (fd1, fd2)+1;  /* maximum bit entry (fd) to test */
     /* loop for input */
     while (loop) {
       FD_SET(fd1, &readfs);  /* set testing for source 1 */
       FD_SET(fd2, &readfs);  /* set testing for source 2 */
       /* block until input becomes available */
       select(maxfd, &readfs, NULL, NULL, NULL);
       if (FD_ISSET(fd1, &readfs))     /* input from source 1 available */
         handle_input_from_source1();
       if (FD_ISSET(fd2, &readfs))     /* input from source 2 available */
         handle_input_from_source2();
     }
  }
À§ÀÇ ¿¹Á¦ ÄÚµå´Â ÀÔ·ÂÀÌ µé¾î¿Ã ¶§±îÁö °è¼Ó block µÇ´Â µ¿ÀÛÀ» º¸¿©ÁØ´Ù. Time-outÀÌ ÇÊ¿äÇÏ´Ù¸é, ´ÙÀ½°ú °°ÀÌ ¹Ù²Û´Ù.
       int res;
       struct timeval Timeout;
       /* set timeout value within input loop */
       Timeout.tv_usec = 0;  /* milliseconds */
       Timeout.tv_sec  = 1;  /* seconds */
       res = select(maxfd, &readfs, NULL, NULL, &Timeout);
       if (res==0)
       /* number of file descriptors with input = 0, timeout occurred. */
ÀÌ ¿¹Á¦´Â 1ÃÊ ÈÄ¿¡ time-outÀÌ µÇ´Â °ÍÀ» º¸¿©ÁØ´Ù. Time-outÀÌ ÀϾ¸é
select()´Â 0À» ¹ÝȯÇÑ´Ù. ¿©±â¼ ÁÖÀÇÇÒ Á¡Àº,
¼³Á¤ÇÑ Timeout °ªÀº select()¿¡ ÀÇÇØ¼ °¨¼ÒÇϱ⠶§¹®¿¡
´Ù½Ã select()¸¦ È£ÃâÇÑ´Ù¸é Timeout.tv_usec°ú
Timeout.tv_sec °ªÀ» ´Ù½Ã ¼³Á¤ÇØ¾ß ÇÑ´Ù.
Timeout °ªÀÌ 0ÀÌ µÇ¸é time-outÀÌ ¹ß»ýÇϰí
select()´Â Áï½Ã ¸®ÅϵȴÙ.