/* termios.cc: termios for WIN32.

   Written by Doug Evans and Steve Chamberlain of Cygnus Support
   dje@cygnus.com, sac@cygnus.com

This file is part of Cygwin.

This software is a copyrighted work licensed under the terms of the
Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
details. */

#include "winsup.h"
#include "cygwin/version.h"
#include <stdlib.h>
#include "cygerrno.h"
#include "security.h"
#include "path.h"
#include "fhandler.h"
#include "dtable.h"
#include "cygheap.h"
#include "perprocess.h"
#include "cygtls.h"

/* tcsendbreak: POSIX 7.2.2.1 */
extern "C" int
tcsendbreak (int fd, int duration)
{
  int res = -1;

  cygheap_fdget cfd (fd);
  if (cfd < 0)
    goto out;

  if (!cfd->is_tty ())
    set_errno (ENOTTY);
  else if ((res = cfd->bg_check (-SIGTTOU)) > bg_eof)
    res = cfd->tcsendbreak (duration);

out:
  syscall_printf ("%R = tcsendbreak(%d, %d)", res, fd, duration);
  return res;
}

/* tcdrain: POSIX 7.2.2.1 */
extern "C" int
tcdrain (int fd)
{
  pthread_testcancel ();

  int res = -1;

  termios_printf ("tcdrain");

  cygheap_fdget cfd (fd);
  if (cfd < 0)
    goto out;

  if (!cfd->is_tty ())
    set_errno (ENOTTY);
  else if ((res = cfd->bg_check (-SIGTTOU)) > bg_eof)
    res = cfd->tcdrain ();

out:
  syscall_printf ("%R = tcdrain(%d)", res, fd);
  return res;
}

/* tcflush: POSIX 7.2.2.1 */
extern "C" int
tcflush (int fd, int queue)
{
  int res = -1;

  cygheap_fdget cfd (fd);
  if (cfd < 0)
    goto out;

  if (!cfd->is_tty ())
    set_errno (ENOTTY);
  else if (queue != TCIFLUSH && queue != TCOFLUSH && queue != TCIOFLUSH)
      set_errno (EINVAL);
  else if ((res = cfd->bg_check (-SIGTTOU)) > bg_eof)
    res = cfd->tcflush (queue);

out:
  termios_printf ("%R = tcflush(%d, %d)", res, fd, queue);
  return res;
}

/* tcflow: POSIX 7.2.2.1 */
extern "C" int
tcflow (int fd, int action)
{
  int res = -1;

  cygheap_fdget cfd (fd);
  if (cfd < 0)
    goto out;

  if (!cfd->is_tty ())
    set_errno (ENOTTY);
  else if ((res = cfd->bg_check (-SIGTTOU)) > bg_eof)
    res = cfd->tcflow (action);

out:
  syscall_printf ("%R = tcflow(%d, %d)", res, fd, action);
  return res;
}

/* tcsetattr: POSIX96 7.2.1.1 */
extern "C" int
tcsetattr (int fd, int a, const struct termios *t)
{
  int res;
  t = __tonew_termios (t);
  int e = get_errno ();

  while (1)
    {
      res = -1;
      cygheap_fdget cfd (fd);
      if (cfd < 0)
	{
	  e = get_errno ();
	  break;
	}

      if (!cfd->is_tty ())
	{
	  e = ENOTTY;
	  break;
	}

      res = cfd->bg_check (-SIGTTOU);

      switch (res)
	{
	case bg_eof:
	  e = get_errno ();
	  break;
	case bg_ok:
	  if (cfd.isopen ())
	    res = cfd->tcsetattr (a, t);
	  e = get_errno ();
	  break;
	case bg_signalled:
	  if (_my_tls.call_signal_handler ())
	    continue;
	  res = -1;
	  /* fall through intentionally */
	default:
	  e = get_errno ();
	  break;
	}
      break;
    }

  set_errno (e);
  termios_printf ("iflag %y, oflag %y, cflag %y, lflag %y, VMIN %d, VTIME %d",
	t->c_iflag, t->c_oflag, t->c_cflag, t->c_lflag, t->c_cc[VMIN],
	t->c_cc[VTIME]);
  termios_printf ("%R = tcsetattr(%d, %d, %p)", res, fd, a, t);
  return res;
}

/* tcgetattr: POSIX 7.2.1.1 */
extern "C" int
tcgetattr (int fd, struct termios *in_t)
{
  int res = -1;
  struct termios *t = __makenew_termios (in_t);

  cygheap_fdget cfd (fd);
  if (cfd < 0)
    /* saw an error */;
  else if (!cfd->is_tty ())
    set_errno (ENOTTY);
  else if ((res = cfd->tcgetattr (t)) == 0)
    __toapp_termios (in_t, t);

  if (res)
    termios_printf ("%R = tcgetattr(%d, %p)", res, fd, in_t);
  else
    termios_printf ("iflag %y, oflag %y, cflag %y, lflag %y, VMIN %d, VTIME %d",
	  t->c_iflag, t->c_oflag, t->c_cflag, t->c_lflag, t->c_cc[VMIN],
	  t->c_cc[VTIME]);

  return res;
}

/* tcgetpgrp: POSIX 7.2.3.1 */
extern "C" int
tcgetpgrp (int fd)
{
  int res;

  cygheap_fdget cfd (fd);
  if (cfd < 0)
    res = -1;
  else
    res = cfd->tcgetpgrp ();

  termios_printf ("%R = tcgetpgrp(%d)", res, fd);
  return res;
}

extern "C" pid_t
tcgetsid (int fd)
{
  int res;

  cygheap_fdget cfd (fd);
  if (cfd < 0)
    res = -1;
  else
    res = cfd->tcgetsid ();

  termios_printf ("%R = tcgetsid(%d)", res, fd);
  return res;
}

/* tcsetpgrp: POSIX 7.2.4.1 */
extern "C" int
tcsetpgrp (int fd, pid_t pgid)
{
  int res = -1;

  cygheap_fdget cfd (fd);
  if (cfd < 0)
    /* saw an error */;
  else if (!cfd->is_tty ())
    set_errno (ENOTTY);
  else
    res = cfd->tcsetpgrp (pgid);

  termios_printf ("%R = tcsetpgrp(%d, %d)", res, fd, pgid);
  return res;
}

/* NIST PCTS requires not macro-only implementation */
#undef cfgetospeed
#undef cfgetispeed
#undef cfsetospeed
#undef cfsetispeed

/* cfgetospeed: POSIX96 7.1.3.1 */
extern "C" speed_t
cfgetospeed (const struct termios *tp)
{
  return __tonew_termios (tp)->c_ospeed;
}

/* cfgetispeed: POSIX96 7.1.3.1 */
extern "C" speed_t
cfgetispeed (const struct termios *tp)
{
  return __tonew_termios (tp)->c_ispeed;
}

static inline int
setspeed (speed_t &set_speed, speed_t from_speed)
{
  int res;
  switch (from_speed)
    {
    case B0:
    case B50:
    case B75:
    case B110:
    case B134:
    case B150:
    case B200:
    case B300:
    case B600:
    case B1200:
    case B1800:
    case B2400:
    case B4800:
    case B9600:
    case B19200:
    case B38400:
    case B57600:
    case B115200:
    case B128000:
    case B230400:
    case B256000:
    case B460800:
    case B500000:
    case B576000:
    case B921600:
    case B1000000:
    case B1152000:
    case B1500000:
    case B2000000:
    case B2500000:
    case B3000000:
      set_speed = from_speed;
      res = 0;
      break;
    default:
      set_errno (EINVAL);
      res = -1;
      break;
    }
  return res;
}

/* cfsetospeed: POSIX96 7.1.3.1 */
extern "C" int
cfsetospeed (struct termios *in_tp, speed_t speed)
{
  struct termios *tp = __tonew_termios (in_tp);
  int res = setspeed (tp->c_ospeed, speed);
  __toapp_termios (in_tp, tp);
  return res;
}

/* cfsetispeed: POSIX96 7.1.3.1 */
extern "C" int
cfsetispeed (struct termios *in_tp, speed_t speed)
{
  struct termios *tp = __tonew_termios (in_tp);
  int res = setspeed (tp->c_ispeed, speed);
  __toapp_termios (in_tp, tp);
  return res;
}

/* cfsetspeed: 4.4BSD */
extern "C" int
cfsetspeed (struct termios *in_tp, speed_t speed)
{
  struct termios *tp = __tonew_termios (in_tp);
  int res;
  /* errors come only from unsupported baud rates, so setspeed() would return
     identical results in both calls */
  if ((res = setspeed (tp->c_ospeed, speed)) == 0)
    setspeed (tp->c_ispeed, speed);
  __toapp_termios (in_tp, tp);
  return res;
}

extern "C" void
cfmakeraw(struct termios *tp)
{
  tp->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
		 | INLCR | IGNCR | ICRNL | IXON);
  tp->c_oflag &= ~OPOST;
  tp->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
  tp->c_cflag &= ~(CSIZE | PARENB);
  tp->c_cflag |= CS8;
}
