Back to index

glibc  2.9
tcsetattr.c
Go to the documentation of this file.
00001 /* Copyright (C) 1993,1996,1997,1998,2002,2003 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 <string.h>
00021 #include <termios.h>
00022 #include <sys/ioctl.h>
00023 #include <sys/types.h>
00024 #include <sysdep.h>
00025 
00026 /* The difference here is that the termios structure used in the
00027    kernel is not the same as we use in the libc.  Therefore we must
00028    translate it here.  */
00029 #include <kernel_termios.h>
00030 
00031 
00032 /* This is a gross hack around a kernel bug.  If the cfsetispeed functions
00033    is called with the SPEED argument set to zero this means use the same
00034    speed as for output.  But we don't have independent input and output
00035    speeds and therefore cannot record this.
00036 
00037    We use an unused bit in the `c_iflag' field to keep track of this
00038    use of `cfsetispeed'.  The value here must correspond to the one used
00039    in `speed.c'.  */
00040 #define IBAUD0       020000000000
00041 
00042 
00043 /* Set the state of FD to *TERMIOS_P.  */
00044 int
00045 tcsetattr (fd, optional_actions, termios_p)
00046      int fd;
00047      int optional_actions;
00048      const struct termios *termios_p;
00049 {
00050   struct __kernel_termios k_termios;
00051   unsigned long int cmd;
00052 
00053   switch (optional_actions)
00054     {
00055     case TCSANOW:
00056       cmd = TCSETS;
00057       break;
00058     case TCSADRAIN:
00059       cmd = TCSETSW;
00060       break;
00061     case TCSAFLUSH:
00062       cmd = TCSETSF;
00063       break;
00064     default:
00065       __set_errno (EINVAL);
00066       return -1;
00067     }
00068 
00069   k_termios.c_iflag = termios_p->c_iflag & ~IBAUD0;
00070   k_termios.c_oflag = termios_p->c_oflag;
00071   k_termios.c_cflag = termios_p->c_cflag;
00072   k_termios.c_lflag = termios_p->c_lflag;
00073   k_termios.c_line = termios_p->c_line;
00074 #if defined _HAVE_C_ISPEED && defined _HAVE_STRUCT_TERMIOS_C_ISPEED
00075   k_termios.c_ispeed = termios_p->c_ispeed;
00076 #endif
00077 #if defined _HAVE_C_OSPEED && defined _HAVE_STRUCT_TERMIOS_C_OSPEED
00078   k_termios.c_ospeed = termios_p->c_ospeed;
00079 #endif
00080   memcpy (&k_termios.c_cc[0], &termios_p->c_cc[0],
00081          __KERNEL_NCCS * sizeof (cc_t));
00082 
00083   return INLINE_SYSCALL (ioctl, 3, fd, cmd, &k_termios);
00084 }
00085 libc_hidden_def (tcsetattr)