/* Ioctl calls for terminals
   Copyright (C) 1991 Free Software Foundation

This file is part of the GNU Hurd.

The GNU Hurd is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.

The GNU Hurd is distributed in the hope that it will be useful, 
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with the GNU Hurd; see the file COPYING.  If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */

/* Written by Michael I. Bushnell.  */

#define DOBIT(fromname, toname, from, to) \
  if ((from) & (fromname)) (to) |= (toname)

error_t
process_ioctl (int code,
	       void *data,
	       struct term_io_data *termdata)
{
  int stopped;
  
  switch (code)
    {
    case TIOCGETATTR:		/* right name? */
      if (ctty_check (termdata, SIGTTOU) == STOPPED)
	return MIG_NO_REPLY;

      *(struct termios *)data = termstat;
      return POSIX_SUCCESS;

    case TIOCSETATTR:		/* right name? */
      if (ctty_check (termdata, SIGTTOU) == STOPPED)
	return MIG_NO_REPLY;
      
      termstat = *(struct termios *)data;
      return POSIX_SUCCESS;
      
    case TIOCMODG:		/* get modem control state */
      if (inline)
	*(int *)data = modem_state;
      else
	{
	  int machstat;
	  int machstatcnt = TTY_MODEM_COUNT;
	  int stat = 0;

	  device_get_status (termdev, TTY_MODEM, &machstat, &machstatcnt);

#define DOONE(name) DOBIT(TM_ ## name, TIOCM_ ## name, machstat, stat)
	  DOONE (LE);
	  DOONE (DTR);
	  DOONE (RTS);
	  DOONE (ST);
	  DOONE (SR);
	  DOONE (CTS);
	  DOONE (CAR);
	  DOONE (RNG);
	  DOONE (DSR);
#undef DOONE
	  
	  *(int *)data = stat;
	}
      return POSIX_SUCCESS;
      
    case TIOCMODS:		/* set modem control state */
      if (inline)
	modem_state = *(int *)data;
      else
	{
	  int machstat = 0;
	  int machstatcnt = TTY_MODEM_COUNT;
	  int stat = *(int *)data;
	  
#define DOONE(name) DOBIT(TIOCM_ ## name, TM_ ## name, stat, machstat)
	  DOONE (LE);
	  DOONE (DTR);
	  DOONE (RTS);
	  DOONE (ST);
	  DOONE (SR);
	  DOONE (CTS);
	  DOONE (CAR);
	  DOONE (RNG);
	  DOONE (DSR);
#undef DOONE
	  
	  device_set_status (termdev, TTY_MODEM, &machstat, &machstatcnt);
	  return POSIX_SUCCESS:
	}

    case TIOCEXCL:		/* set exclusive access */
      exclusive = 1;
      return POSIX_SUCCESS;
    case TIOCNXCL:		/* clear exclusive access */
      exclusive = 0;
      return POSIX_SUCCESS;
    }
}

