#ifndef _SYS_TERMIOS_H_
#define _SYS_TERMIOS_H_

#include <core/termios.h>
#include <sys/cdefs.h>

/****************************************************************************************************************
 *
 * Prototypes
 *
 */
__BEGIN_DECLS
int tcflow(int, int);
void cfmakeraw(struct termios *tio);
__END_DECLS

/****************************************************************************************************************/

#include <sys/ioctl.h>

__attribute__((__always_inline__)) static inline speed_t cfgetispeed(const struct termios *tio) {
  return tio->c_ispeed;
}

__attribute__((__always_inline__)) static inline speed_t cfgetospeed(const struct termios *tio) {
  return tio->c_ospeed;
}

__attribute__((__always_inline__)) static inline int cfsetispeed(struct termios *tio, speed_t s) {
  tio->c_ispeed = s;
  return 0;
}

__attribute__((__always_inline__)) static inline int cfsetospeed(struct termios *tio, speed_t s) {
  tio->c_ospeed = s;
  return 0;
}

__attribute__((__always_inline__)) static inline int cfsetspeed(struct termios *tio, speed_t s)  {
  tio->c_ispeed = tio->c_ospeed = s;
  return 0;
}

/****************************************************************************************************************/

__attribute__((__always_inline__)) static inline int tcgetattr(int fd, struct termios *tio) {
  return ioctl(fd, TCGETS, tio);
}

/****************************************************************************************************************/

int __tcsetattr(int fd, int how, const struct termios *tio);

__attribute__((__always_inline__)) static inline int tcsetattr(int fd, int how, const struct termios *tio) {
  if (__builtin_constant_p(how)) {
    switch(how) {
    case TCSADRAIN: return ioctl(fd, TCSETSW, tio);
    case TCSAFLUSH: return ioctl(fd, TCSETSF, tio);
    default:        return ioctl(fd, TCSETS,  tio);
    }
  } else {
    return __tcsetattr(fd, how, tio);
  }
}

/****************************************************************************************************************/

__attribute__((__always_inline__)) static inline int tcdrain(int fd)            { return ioctl(fd, TCSBRK, 0);   }
__attribute__((__always_inline__)) static inline int tcflush(int fd, int how)   { return ioctl(fd, TCFLSH, how); }
__attribute__((__always_inline__)) static inline int tcsendbreak(int fd, int t) { return ioctl(fd, TCSBRKP, t);  }

/****************************************************************************************************************/
#endif
