Back to index

glibc  2.9
tcsetattr.c
Go to the documentation of this file.
00001 /* Copyright (C) 1992, 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003 
00004    The GNU C Library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Lesser General Public
00006    License as published by the Free Software Foundation; either
00007    version 2.1 of the License, or (at your option) any later version.
00008 
00009    The GNU C Library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Lesser General Public License for more details.
00013 
00014    You should have received a copy of the GNU Lesser General Public
00015    License along with the GNU C Library; if not, write to the Free
00016    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00017    02111-1307 USA.  */
00018 
00019 #include <errno.h>
00020 #include <stddef.h>
00021 #include <termios.h>
00022 #include <sys/ioctl.h>
00023 
00024 #include <sysv_termio.h>
00025 
00026 
00027 const speed_t __unix_speeds[] =
00028   {
00029     0,
00030     50,
00031     75,
00032     110,
00033     134,
00034     150,
00035     200,
00036     300,
00037     600,
00038     1200,
00039     1800,
00040     2400,
00041     4800,
00042     9600,
00043     19200,
00044     38400,
00045   };
00046 
00047 
00048 /* Set the state of FD to *TERMIOS_P.  */
00049 int
00050 tcsetattr (fd, optional_actions, termios_p)
00051      int fd;
00052      int optional_actions;
00053      const struct termios *termios_p;
00054 {
00055   struct __sysv_termio buf;
00056   int ioctl_function;
00057   size_t i;
00058 
00059   if (termios_p == NULL)
00060     {
00061       __set_errno (EINVAL);
00062       return -1;
00063     }
00064   switch (optional_actions)
00065     {
00066     case TCSANOW:
00067       ioctl_function = _TCSETA;
00068       break;
00069     case TCSADRAIN:
00070       ioctl_function = _TCSETAW;
00071       break;
00072     case TCSAFLUSH:
00073       ioctl_function = _TCSETAF;
00074       break;
00075     default:
00076       __set_errno (EINVAL);
00077       return -1;
00078     }
00079 
00080   if (termios_p->__ispeed != termios_p->__ospeed)
00081     {
00082       __set_errno (EINVAL);
00083       return -1;
00084     }
00085   buf.c_cflag = -1;
00086   for (i = 0; i <= sizeof (__unix_speeds) / sizeof (__unix_speeds[0]); ++i)
00087     {
00088       if (__unix_speeds[i] == termios_p->__ispeed)
00089        buf.c_cflag = i;
00090     }
00091   if (buf.c_cflag == -1)
00092     {
00093       __set_errno (EINVAL);
00094       return -1;
00095     }
00096 
00097   buf.c_iflag = 0;
00098   if (termios_p->c_iflag & IGNBRK)
00099     buf.c_iflag |= _SYSV_IGNBRK;
00100   if (termios_p->c_iflag & BRKINT)
00101     buf.c_iflag |= _SYSV_BRKINT;
00102   if (termios_p->c_iflag & IGNPAR)
00103     buf.c_iflag |= _SYSV_IGNPAR;
00104   if (termios_p->c_iflag & PARMRK)
00105     buf.c_iflag |= _SYSV_PARMRK;
00106   if (termios_p->c_iflag & INPCK)
00107     buf.c_iflag |= _SYSV_INPCK;
00108   if (termios_p->c_iflag & ISTRIP)
00109     buf.c_iflag |= _SYSV_ISTRIP;
00110   if (termios_p->c_iflag & INLCR)
00111     buf.c_iflag |= _SYSV_INLCR;
00112   if (termios_p->c_iflag & IGNCR)
00113     buf.c_iflag |= _SYSV_IGNCR;
00114   if (termios_p->c_iflag & ICRNL)
00115     buf.c_iflag |= _SYSV_ICRNL;
00116   if (termios_p->c_iflag & IXON)
00117     buf.c_iflag |= _SYSV_IXON;
00118   if (termios_p->c_iflag & IXOFF)
00119     buf.c_iflag |= _SYSV_IXOFF;
00120   if (termios_p->c_iflag & IXANY)
00121     buf.c_iflag |= _SYSV_IXANY;
00122   if (termios_p->c_iflag & IMAXBEL)
00123     buf.c_iflag |= _SYSV_IMAXBEL;
00124 
00125   buf.c_oflag = 0;
00126   if (termios_p->c_oflag & OPOST)
00127     buf.c_oflag |= _SYSV_OPOST;
00128   if (termios_p->c_oflag & ONLCR)
00129     buf.c_oflag |= _SYSV_ONLCR;
00130 
00131   /* So far, buf.c_cflag contains the speed in CBAUD.  */
00132   if (termios_p->c_cflag & CSTOPB)
00133     buf.c_cflag |= _SYSV_CSTOPB;
00134   if (termios_p->c_cflag & CREAD)
00135     buf.c_cflag |= _SYSV_CREAD;
00136   if (termios_p->c_cflag & PARENB)
00137     buf.c_cflag |= _SYSV_PARENB;
00138   if (termios_p->c_cflag & PARODD)
00139     buf.c_cflag |= _SYSV_PARODD;
00140   if (termios_p->c_cflag & HUPCL)
00141     buf.c_cflag |= _SYSV_HUPCL;
00142   if (termios_p->c_cflag & CLOCAL)
00143     buf.c_cflag |= _SYSV_CLOCAL;
00144   switch (termios_p->c_cflag & CSIZE)
00145     {
00146     case CS5:
00147       buf.c_cflag |= _SYSV_CS5;
00148       break;
00149     case CS6:
00150       buf.c_cflag |= _SYSV_CS6;
00151       break;
00152     case CS7:
00153       buf.c_cflag |= _SYSV_CS7;
00154       break;
00155     case CS8:
00156       buf.c_cflag |= _SYSV_CS8;
00157       break;
00158     }
00159 
00160   buf.c_lflag = 0;
00161   if (termios_p->c_lflag & ISIG)
00162     buf.c_lflag |= _SYSV_ISIG;
00163   if (termios_p->c_lflag & ICANON)
00164     buf.c_lflag |= _SYSV_ICANON;
00165   if (termios_p->c_lflag & ECHO)
00166     buf.c_lflag |= _SYSV_ECHO;
00167   if (termios_p->c_lflag & ECHOE)
00168     buf.c_lflag |= _SYSV_ECHOE;
00169   if (termios_p->c_lflag & ECHOK)
00170     buf.c_lflag |= _SYSV_ECHOK;
00171   if (termios_p->c_lflag & ECHONL)
00172     buf.c_lflag |= _SYSV_ECHONL;
00173   if (termios_p->c_lflag & NOFLSH)
00174     buf.c_lflag |= _SYSV_NOFLSH;
00175   if (termios_p->c_lflag & TOSTOP)
00176     buf.c_lflag |= _SYSV_TOSTOP;
00177   if (termios_p->c_lflag & ECHOCTL)
00178     buf.c_lflag |= _SYSV_ECHOCTL;
00179   if (termios_p->c_lflag & ECHOPRT)
00180     buf.c_lflag |= _SYSV_ECHOPRT;
00181   if (termios_p->c_lflag & ECHOKE)
00182     buf.c_lflag |= _SYSV_ECHOKE;
00183   if (termios_p->c_lflag & FLUSHO)
00184     buf.c_lflag |= _SYSV_FLUSHO;
00185   if (termios_p->c_lflag & PENDIN)
00186     buf.c_lflag |= _SYSV_PENDIN;
00187   if (termios_p->c_lflag & IEXTEN)
00188     buf.c_lflag |= _SYSV_IEXTEN;
00189 
00190   buf.c_cc[_SYSV_VINTR] = termios_p->c_cc[VINTR];
00191   buf.c_cc[_SYSV_VQUIT] = termios_p->c_cc[VQUIT];
00192   buf.c_cc[_SYSV_VERASE] = termios_p->c_cc[VERASE];
00193   buf.c_cc[_SYSV_VKILL] = termios_p->c_cc[VKILL];
00194   if (buf.c_lflag & _SYSV_ICANON)
00195     {
00196       buf.c_cc[_SYSV_VEOF] = termios_p->c_cc[VEOF];
00197       buf.c_cc[_SYSV_VEOL] = termios_p->c_cc[VEOL];
00198     }
00199   else
00200     {
00201       buf.c_cc[_SYSV_VMIN] = termios_p->c_cc[VMIN];
00202       buf.c_cc[_SYSV_VTIME] = termios_p->c_cc[VTIME];
00203     }
00204   buf.c_cc[_SYSV_VEOL2] = termios_p->c_cc[VEOL2];
00205 
00206   if (__ioctl (fd, ioctl_function, &buf) < 0)
00207     return -1;
00208   return 0;
00209 }
00210 libc_hidden_def (tcsetattr)