Back to index

glibc  2.9
tcsetattr.c
Go to the documentation of this file.
00001 /* Copyright (C) 1991, 1993, 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 
00023 #include "bsdtty.h"
00024 
00025 
00026 const speed_t __bsd_speeds[] =
00027   {
00028     0,
00029     50,
00030     75,
00031     110,
00032     134,
00033     150,
00034     200,
00035     300,
00036     600,
00037     1200,
00038     1800,
00039     2400,
00040     4800,
00041     9600,
00042     19200,
00043     38400,
00044   };
00045 
00046 
00047 /* Set the state of FD to *TERMIOS_P.  */
00048 int
00049 tcsetattr (fd, optional_actions, termios_p)
00050      int fd;
00051      int optional_actions;
00052      const struct termios *termios_p;
00053 {
00054   struct sgttyb buf;
00055   struct tchars tchars;
00056   struct ltchars ltchars;
00057   int local;
00058 #ifdef TIOCGETX
00059   int extra;
00060 #endif
00061   size_t i;
00062 
00063   if (__ioctl (fd, TIOCGETP, &buf) < 0 ||
00064       __ioctl (fd, TIOCGETC, &tchars) < 0 ||
00065       __ioctl (fd, TIOCGLTC, &ltchars) < 0 ||
00066 #ifdef TIOCGETX
00067       __ioctl (fd, TIOCGETX, &extra) < 0 ||
00068 #endif
00069       __ioctl (fd, TIOCLGET, &local) < 0)
00070     return -1;
00071 
00072   if (termios_p == NULL)
00073     {
00074       __set_errno (EINVAL);
00075       return -1;
00076     }
00077   switch (optional_actions)
00078     {
00079     case TCSANOW:
00080       break;
00081     case TCSADRAIN:
00082       if (tcdrain (fd) < 0)
00083        return -1;
00084       break;
00085     case TCSAFLUSH:
00086       if (tcflush (fd, TCIFLUSH) < 0)
00087        return -1;
00088       break;
00089     default:
00090       __set_errno (EINVAL);
00091       return -1;
00092     }
00093 
00094   buf.sg_ispeed = buf.sg_ospeed = -1;
00095   for (i = 0; i <= sizeof (__bsd_speeds) / sizeof (__bsd_speeds[0]); ++i)
00096     {
00097       if (__bsd_speeds[i] == termios_p->__ispeed)
00098        buf.sg_ispeed = i;
00099       if (__bsd_speeds[i] == termios_p->__ospeed)
00100        buf.sg_ospeed = i;
00101     }
00102   if (buf.sg_ispeed == -1 || buf.sg_ospeed == -1)
00103     {
00104       __set_errno (EINVAL);
00105       return -1;
00106     }
00107 
00108   buf.sg_flags &= ~(CBREAK|RAW);
00109   if (!(termios_p->c_lflag & ICANON))
00110     buf.sg_flags |= (termios_p->c_cflag & ISIG) ? CBREAK : RAW;
00111 #ifdef LPASS8
00112   if (termios_p->c_oflag & CS8)
00113     local |= LPASS8;
00114   else
00115     local &= ~LPASS8;
00116 #endif
00117   if (termios_p->c_lflag & _NOFLSH)
00118     local |= LNOFLSH;
00119   else
00120     local &= ~LNOFLSH;
00121   if (termios_p->c_oflag & OPOST)
00122     local &= ~LLITOUT;
00123   else
00124     local |= LLITOUT;
00125 #ifdef TIOCGETX
00126   if (termios_p->c_lflag & ISIG)
00127     extra &= ~NOISIG;
00128   else
00129     extra |= NOISIG;
00130   if (termios_p->c_cflag & CSTOPB)
00131     extra |= STOPB;
00132   else
00133     extra &= ~STOPB;
00134 #endif
00135   if (termios_p->c_iflag & ICRNL)
00136     buf.sg_flags |= CRMOD;
00137   else
00138     buf.sg_flags &= ~CRMOD;
00139   if (termios_p->c_iflag & IXOFF)
00140     buf.sg_flags |= TANDEM;
00141   else
00142     buf.sg_flags &= ~TANDEM;
00143 
00144   buf.sg_flags &= ~(ODDP|EVENP);
00145   if (!(termios_p->c_cflag & PARENB))
00146     buf.sg_flags |= ODDP | EVENP;
00147   else if (termios_p->c_cflag & PARODD)
00148     buf.sg_flags |= ODDP;
00149   else
00150     buf.sg_flags |= EVENP;
00151 
00152   if (termios_p->c_lflag & _ECHO)
00153     buf.sg_flags |= ECHO;
00154   else
00155     buf.sg_flags &= ~ECHO;
00156   if (termios_p->c_lflag & ECHOE)
00157     local |= LCRTERA;
00158   else
00159     local &= ~LCRTERA;
00160   if (termios_p->c_lflag & ECHOK)
00161     local |= LCRTKIL;
00162   else
00163     local &= ~LCRTKIL;
00164   if (termios_p->c_lflag & _TOSTOP)
00165     local |= LTOSTOP;
00166   else
00167     local &= ~LTOSTOP;
00168 
00169   buf.sg_erase = termios_p->c_cc[VERASE];
00170   buf.sg_kill = termios_p->c_cc[VKILL];
00171   tchars.t_eofc = termios_p->c_cc[VEOF];
00172   tchars.t_intrc = termios_p->c_cc[VINTR];
00173   tchars.t_quitc = termios_p->c_cc[VQUIT];
00174   ltchars.t_suspc = termios_p->c_cc[VSUSP];
00175   tchars.t_startc = termios_p->c_cc[VSTART];
00176   tchars.t_stopc = termios_p->c_cc[VSTOP];
00177 
00178   if (__ioctl (fd, TIOCSETP, &buf) < 0 ||
00179       __ioctl (fd, TIOCSETC, &tchars) < 0 ||
00180       __ioctl (fd, TIOCSLTC, &ltchars) < 0 ||
00181 #ifdef TIOCGETX
00182       __ioctl (fd, TIOCSETX, &extra) < 0 ||
00183 #endif
00184       __ioctl (fd, TIOCLSET, &local) < 0)
00185     return -1;
00186   return 0;
00187 }
00188 libc_hidden_def (tcsetattr)