/* Serial interface for a selectable event.
   Copyright (C) 2016-2024 Free Software Foundation, Inc.

   This file is part of GDB.

   This program 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 3 of the License, or
   (at your option) any later version.

   This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "ser-event.h"
#include "serial.h"
#include "gdbsupport/filestuff.h"
#include "gdbsupport/eintr.h"

/* On POSIX hosts, a serial_event is basically an abstraction for the
   classical self-pipe trick.

   On Windows, a serial_event is a wrapper around a native Windows
   event object.  Because we want to interface with gdb_select, which
   takes file descriptors, we need to wrap that Windows event object
   in a file descriptor.  As _open_osfhandle can not be used with
   event objects, we instead create a dummy file wrap that in a file
   descriptor with _open_osfhandle, and pass that as selectable
   descriptor to callers.  As Windows' gdb_select converts file
   descriptors back to Windows handles by calling serial->wait_handle,
   nothing ever actually waits on that file descriptor.  */

struct serial_event_state
  {
#ifdef USE_WIN32API
    /* The Windows event object, created with CreateEvent.  */
    HANDLE event;
#else
    /* The write side of the pipe.  The read side is in
       serial->fd.  */
    int write_fd;
#endif
  };

/* Open a new serial event.  */

static void
serial_event_open (struct serial *scb, const char *name)
{
  struct serial_event_state *state;

  state = XNEW (struct serial_event_state);
  scb->state = state;

#ifndef USE_WIN32API
  {
    int fds[2];

    if (gdb_pipe_cloexec (fds) == -1)
      internal_error ("creating serial event pipe failed.");

    gdb::fcntl (fds[0], F_SETFL, O_NONBLOCK);
    gdb::fcntl (fds[1], F_SETFL, O_NONBLOCK);

    scb->fd = fds[0];
    state->write_fd = fds[1];
  }
#else
  {
    /* A dummy file object that can be wrapped in a file descriptor.
       We don't need to store this handle because closing the file
       descriptor automatically closes this.  */
    HANDLE dummy_file;

    /* A manual-reset event.  */
    state->event = CreateEvent (0, TRUE, FALSE, 0);

    /* The dummy file handle.  Created just so we have something
       wrappable in a file descriptor.  */
    dummy_file = CreateFile ("nul", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
    scb->fd = _open_osfhandle ((intptr_t) dummy_file, 0);
  }
#endif
}

static void
serial_event_close (struct serial *scb)
{
  struct serial_event_state *state = (struct serial_event_state *) scb->state;

  gdb::close (scb->fd);
#ifndef USE_WIN32API
  gdb::close (state->write_fd);
#else
  CloseHandle (state->event);
#endif

  scb->fd = -1;

  xfree (state);
  scb->state = NULL;
}

#ifdef USE_WIN32API

/* Implementation of the wait_handle method.  Returns the native
   Windows event object handle.  */

static void
serial_event_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
{
  struct serial_event_state *state = (struct serial_event_state *) scb->state;

  *read = state->event;
}

#endif

/* The serial_ops for struct serial_event objects.  Note we never
   register this serial type with serial_add_interface, because this
   is internal implementation detail never to be used by remote
   targets for protocol transport.  */

static const struct serial_ops serial_event_ops =
{
  "event",
  serial_event_open,
  serial_event_close,
  NULL, /* fdopen */
  NULL, /* readchar */
  NULL, /* write */
  NULL, /* flush_output */
  NULL, /* flush_input */
  NULL, /* send_break */
  NULL, /* go_raw */
  NULL, /* get_tty_state */
  NULL, /* copy_tty_state */
  NULL, /* set_tty_state */
  NULL, /* print_tty_state */
  NULL, /* setbaudrate */
  NULL, /* setstopbits */
  NULL, /* setparity */
  NULL, /* drain_output */
  NULL, /* async */
  NULL, /* read_prim */
  NULL, /* write_prim */
  NULL, /* avail */
#ifdef USE_WIN32API
  serial_event_wait_handle,
#endif
};

/* See ser-event.h.  */

struct serial_event *
make_serial_event (void)
{
  return (struct serial_event *) serial_open_ops (&serial_event_ops);
}

/* See ser-event.h.  */

int
serial_event_fd (struct serial_event *event)
{
  struct serial *ser = (struct serial *) event;

  return ser->fd;
}

/* See ser-event.h.  */

void
serial_event_set (struct serial_event *event)
{
  struct serial *ser = (struct serial *) event;
  struct serial_event_state *state = (struct serial_event_state *) ser->state;
#ifndef USE_WIN32API
  char c = '+';		/* Anything.  */

  gdb::write (state->write_fd, &c, 1);
#else
  SetEvent (state->event);
#endif
}

/* See ser-event.h.  */

void
serial_event_clear (struct serial_event *event)
{
  struct serial *ser = (struct serial *) event;
#ifndef USE_WIN32API
  int r;

  do
    {
      char c;

      r = gdb::read (ser->fd, &c, 1);
    }
  while (r > 0);
#else
  struct serial_event_state *state = (struct serial_event_state *) ser->state;
  ResetEvent (state->event);
#endif
}
