* RFA: Add 'target |' support for MinGW
@ 2006-04-12 7:04 Jim Blandy
2006-04-12 7:52 ` Eli Zaretskii
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Jim Blandy @ 2006-04-12 7:04 UTC (permalink / raw)
To: gdb-patches
src/gdb/ChangeLog:
2006-04-11 Jim Blandy <jimb@codesourcery.com>
Add support for 'target remote |' on MinGW.
* ser-mingw.c (struct pipe_state): New structure.
(make_pipe_state, free_pipe_state, cleanup_pipe_state)
(pipe_windows_open, pipe_windows_close, pipe_windows_read)
(pipe_windows_write, pipe_wait_handle): New functions.
(_initialize_ser_windows): Register a "pipe" interface based on
them.
Index: src/gdb/ser-mingw.c
===================================================================
--- src.orig/gdb/ser-mingw.c 2006-03-23 16:36:31.472949000 -0800
+++ src/gdb/ser-mingw.c 2006-04-11 23:41:01.999940000 -0700
@@ -571,6 +571,217 @@
return NULL;
}
+struct pipe_state
+{
+ /* Since we use the pipe_select_thread for our select emulation,
+ we need to place the state structure it requires at the front
+ of our state. */
+ struct ser_console_state wait;
+
+ /* The pex obj for our (one-stage) pipeline. */
+ struct pex_obj *pex;
+
+ /* Streams for the pipeline's input and output. */
+ FILE *input, *output;
+};
+
+static struct pipe_state *
+make_pipe_state (void)
+{
+ struct pipe_state *ps = XMALLOC (struct pipe_state);
+
+ memset (ps, 0, sizeof (*ps));
+ ps->wait.read_event = INVALID_HANDLE_VALUE;
+ ps->wait.except_event = INVALID_HANDLE_VALUE;
+ ps->wait.start_select = INVALID_HANDLE_VALUE;
+ ps->wait.stop_select = INVALID_HANDLE_VALUE;
+
+ return ps;
+}
+
+static void
+free_pipe_state (struct pipe_state *ps)
+{
+ int saved_errno = errno;
+
+ if (ps->wait.read_event != INVALID_HANDLE_VALUE)
+ CloseHandle (ps->wait.read_event);
+ if (ps->wait.except_event != INVALID_HANDLE_VALUE)
+ CloseHandle (ps->wait.except_event);
+ if (ps->wait.start_select != INVALID_HANDLE_VALUE)
+ CloseHandle (ps->wait.start_select);
+
+ /* If we have a select thread running, let the select thread free
+ the stop event. */
+ if (ps->wait.stop_select != INVALID_HANDLE_VALUE)
+ SetEvent (ps->wait.stop_select);
+
+ /* Close the pipe to the child. We must close the pipe before
+ calling pex_free because pex_free will wait for the child to exit
+ and the child will not exit until the pipe is closed. */
+ if (ps->input)
+ fclose (ps->input);
+ if (ps->pex)
+ pex_free (ps->pex);
+ /* pex_free closes ps->output. */
+
+ xfree (ps);
+
+ errno = saved_errno;
+}
+
+static void
+cleanup_pipe_state (void *untyped)
+{
+ struct pipe_state *ps = untyped;
+
+ free_pipe_state (ps);
+}
+
+static int
+pipe_windows_open (struct serial *scb, const char *name)
+{
+ char **argv = buildargv (name);
+ struct cleanup *back_to = make_cleanup_freeargv (argv);
+ if (! argv[0] || argv[0][0] == '\0')
+ error ("missing child command");
+
+ struct pipe_state *ps = make_pipe_state ();
+ make_cleanup (cleanup_pipe_state, ps);
+
+ ps->pex = pex_init (PEX_USE_PIPES, "target remote pipe", NULL);
+ if (! ps->pex)
+ goto fail;
+ ps->input = pex_input_pipe (ps->pex, 1);
+ if (! ps->input)
+ goto fail;
+
+ {
+ int err;
+ const char *err_msg
+ = pex_run (ps->pex, PEX_SEARCH | PEX_BINARY_INPUT | PEX_BINARY_OUTPUT,
+ argv[0], argv, NULL, NULL,
+ &err);
+
+ if (err_msg)
+ {
+ /* Our caller expects us to return -1, but all they'll do with
+ it generally is print the message based on errno. We have
+ all the same information here, plus err_msg provided by
+ pex_run, so we just raise the error here. */
+ if (err)
+ error ("error starting child process '%s': %s: %s",
+ name, err_msg, safe_strerror (err));
+ else
+ error ("error starting child process '%s': %s",
+ name, err_msg);
+ }
+ }
+
+ ps->output = pex_read_output (ps->pex, 1);
+ if (! ps->output)
+ goto fail;
+
+ scb->fd = fileno (ps->output);
+ scb->state = (void *) ps;
+
+ discard_cleanups (back_to);
+ return 0;
+
+ fail:
+ do_cleanups (back_to);
+ return -1;
+}
+
+
+static void
+pipe_windows_close (struct serial *scb)
+{
+ struct pipe_state *ps = scb->state;
+
+ /* In theory, we should try to kill the subprocess here, but the pex
+ interface doesn't give us enough information to do that. Usually
+ closing the input pipe will get the message across. */
+
+ free_pipe_state (ps);
+}
+
+
+static int
+pipe_windows_read (struct serial *scb, size_t count)
+{
+ HANDLE pipeline_out = (HANDLE) _get_osfhandle (scb->fd);
+ if (pipeline_out == INVALID_HANDLE_VALUE)
+ return -1;
+
+ DWORD available;
+ if (! PeekNamedPipe (pipeline_out, NULL, 0, NULL, &available, NULL))
+ return -1;
+
+ if (count > available)
+ count = available;
+
+ DWORD bytes_read;
+ if (! ReadFile (pipeline_out, scb->buf, count, &bytes_read, NULL))
+ return -1;
+
+ return bytes_read;
+}
+
+
+static int
+pipe_windows_write (struct serial *scb, const void *buf, size_t count)
+{
+ struct pipe_state *ps = scb->state;
+ int pipeline_in_fd = fileno (ps->input);
+ if (pipeline_in_fd < 0)
+ return -1;
+
+ HANDLE pipeline_in = (HANDLE) _get_osfhandle (pipeline_in_fd);
+ if (pipeline_in == INVALID_HANDLE_VALUE)
+ return -1;
+
+ DWORD written;
+ if (! WriteFile (pipeline_in, buf, count, &written, NULL))
+ return -1;
+
+ return written;
+}
+
+
+static void
+pipe_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
+{
+ struct pipe_state *ps = scb->state;
+
+ /* Have we allocated our events yet? */
+ if (ps->wait.read_event == INVALID_HANDLE_VALUE)
+ {
+ DWORD threadId;
+
+ /* Create auto reset events to wake and terminate the select thread. */
+ ps->wait.start_select = CreateEvent (0, FALSE, FALSE, 0);
+ ps->wait.stop_select = CreateEvent (0, FALSE, FALSE, 0);
+
+ /* Create our own events to report read and exceptions separately.
+ The exception event is currently never used. */
+ ps->wait.read_event = CreateEvent (0, FALSE, FALSE, 0);
+ ps->wait.except_event = CreateEvent (0, FALSE, FALSE, 0);
+
+ /* Start the select thread. */
+ CreateThread (NULL, 0, pipe_select_thread, scb, 0, &threadId);
+ }
+
+ ResetEvent (ps->wait.read_event);
+ ResetEvent (ps->wait.except_event);
+
+ SetEvent (ps->wait.start_select);
+
+ *read = ps->wait.read_event;
+ *except = ps->wait.except_event;
+}
+
+
struct net_windows_state
{
HANDLE read_event;
@@ -763,6 +974,34 @@
serial_add_interface (ops);
+ /* The pipe interface. */
+
+ ops = XMALLOC (struct serial_ops);
+ memset (ops, 0, sizeof (struct serial_ops));
+ ops->name = "pipe";
+ ops->next = 0;
+ ops->open = pipe_windows_open;
+ ops->close = pipe_windows_close;
+ ops->readchar = ser_base_readchar;
+ ops->write = ser_base_write;
+ ops->flush_output = ser_base_flush_output;
+ ops->flush_input = ser_base_flush_input;
+ ops->send_break = ser_base_send_break;
+ ops->go_raw = ser_base_raw;
+ ops->get_tty_state = ser_base_get_tty_state;
+ ops->set_tty_state = ser_base_set_tty_state;
+ ops->print_tty_state = ser_base_print_tty_state;
+ ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
+ ops->setbaudrate = ser_base_setbaudrate;
+ ops->setstopbits = ser_base_setstopbits;
+ ops->drain_output = ser_base_drain_output;
+ ops->async = ser_base_async;
+ ops->read_prim = pipe_windows_read;
+ ops->write_prim = pipe_windows_write;
+ ops->wait_handle = pipe_wait_handle;
+
+ serial_add_interface (ops);
+
/* If WinSock works, register the TCP/UDP socket driver. */
if (WSAStartup (MAKEWORD (1, 0), &wsa_data) != 0)
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: RFA: Add 'target |' support for MinGW
2006-04-12 7:04 RFA: Add 'target |' support for MinGW Jim Blandy
@ 2006-04-12 7:52 ` Eli Zaretskii
2006-04-12 18:39 ` Jim Blandy
2006-04-18 18:01 ` Jim Blandy
2006-04-25 18:02 ` Jim Blandy
2 siblings, 1 reply; 8+ messages in thread
From: Eli Zaretskii @ 2006-04-12 7:52 UTC (permalink / raw)
To: Jim Blandy; +Cc: gdb-patches
> From: Jim Blandy <jimb@codesourcery.com>
> Date: Wed, 12 Apr 2006 00:04:44 -0700
>
> src/gdb/ChangeLog:
> 2006-04-11 Jim Blandy <jimb@codesourcery.com>
>
> Add support for 'target remote |' on MinGW.
> * ser-mingw.c (struct pipe_state): New structure.
> (make_pipe_state, free_pipe_state, cleanup_pipe_state)
> (pipe_windows_open, pipe_windows_close, pipe_windows_read)
> (pipe_windows_write, pipe_wait_handle): New functions.
> (_initialize_ser_windows): Register a "pipe" interface based on
> them.
Thanks.
> + const char *err_msg
> + = pex_run (ps->pex, PEX_SEARCH | PEX_BINARY_INPUT | PEX_BINARY_OUTPUT,
> + argv[0], argv, NULL, NULL,
> + &err);
> [...]
> + DWORD bytes_read;
> + if (! ReadFile (pipeline_out, scb->buf, count, &bytes_read, NULL))
> + return -1;
> [...]
> + DWORD written;
> + if (! WriteFile (pipeline_in, buf, count, &written, NULL))
> + return -1;
Do we really want binary I/O in _all_ situations? Can it be that,
depending on the command on the other side of the pipe, someone would
like the CR characters to be stripped from the EOLs in the incoming
stuff? The way you wrote it, AFAICS, binary I/O is always used, no
matter what.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: RFA: Add 'target |' support for MinGW
2006-04-12 7:52 ` Eli Zaretskii
@ 2006-04-12 18:39 ` Jim Blandy
2006-04-13 8:10 ` Eli Zaretskii
0 siblings, 1 reply; 8+ messages in thread
From: Jim Blandy @ 2006-04-12 18:39 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: gdb-patches
Eli Zaretskii <eliz@gnu.org> writes:
>> From: Jim Blandy <jimb@codesourcery.com>
>> Date: Wed, 12 Apr 2006 00:04:44 -0700
>>
>> src/gdb/ChangeLog:
>> 2006-04-11 Jim Blandy <jimb@codesourcery.com>
>>
>> Add support for 'target remote |' on MinGW.
>> * ser-mingw.c (struct pipe_state): New structure.
>> (make_pipe_state, free_pipe_state, cleanup_pipe_state)
>> (pipe_windows_open, pipe_windows_close, pipe_windows_read)
>> (pipe_windows_write, pipe_wait_handle): New functions.
>> (_initialize_ser_windows): Register a "pipe" interface based on
>> them.
>
> Thanks.
>
>> + const char *err_msg
>> + = pex_run (ps->pex, PEX_SEARCH | PEX_BINARY_INPUT | PEX_BINARY_OUTPUT,
>> + argv[0], argv, NULL, NULL,
>> + &err);
>> [...]
>> + DWORD bytes_read;
>> + if (! ReadFile (pipeline_out, scb->buf, count, &bytes_read, NULL))
>> + return -1;
>> [...]
>> + DWORD written;
>> + if (! WriteFile (pipeline_in, buf, count, &written, NULL))
>> + return -1;
>
> Do we really want binary I/O in _all_ situations? Can it be that,
> depending on the command on the other side of the pipe, someone would
> like the CR characters to be stripped from the EOLs in the incoming
> stuff? The way you wrote it, AFAICS, binary I/O is always used, no
> matter what.
Well, the pipe is carrying the GDB remote protocol, which is happier
with binary.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: RFA: Add 'target |' support for MinGW
2006-04-12 18:39 ` Jim Blandy
@ 2006-04-13 8:10 ` Eli Zaretskii
2006-04-13 8:21 ` Jim Blandy
0 siblings, 1 reply; 8+ messages in thread
From: Eli Zaretskii @ 2006-04-13 8:10 UTC (permalink / raw)
To: Jim Blandy; +Cc: gdb-patches
> Cc: gdb-patches@sources.redhat.com
> From: Jim Blandy <jimb@codesourcery.com>
> Date: Wed, 12 Apr 2006 11:38:55 -0700
>
> > Do we really want binary I/O in _all_ situations? Can it be that,
> > depending on the command on the other side of the pipe, someone would
> > like the CR characters to be stripped from the EOLs in the incoming
> > stuff? The way you wrote it, AFAICS, binary I/O is always used, no
> > matter what.
>
> Well, the pipe is carrying the GDB remote protocol, which is happier
> with binary.
Do we never ask the remote to list text files, for example?
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: RFA: Add 'target |' support for MinGW
2006-04-13 8:10 ` Eli Zaretskii
@ 2006-04-13 8:21 ` Jim Blandy
2006-04-13 19:49 ` Michael Snyder
0 siblings, 1 reply; 8+ messages in thread
From: Jim Blandy @ 2006-04-13 8:21 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: Jim Blandy, gdb-patches
On 4/13/06, Eli Zaretskii <eliz@gnu.org> wrote:
> > Cc: gdb-patches@sources.redhat.com
> > From: Jim Blandy <jimb@codesourcery.com>
> > Date: Wed, 12 Apr 2006 11:38:55 -0700
> >
> > > Do we really want binary I/O in _all_ situations? Can it be that,
> > > depending on the command on the other side of the pipe, someone would
> > > like the CR characters to be stripped from the EOLs in the incoming
> > > stuff? The way you wrote it, AFAICS, binary I/O is always used, no
> > > matter what.
> >
> > Well, the pipe is carrying the GDB remote protocol, which is happier
> > with binary.
>
> Do we never ask the remote to list text files, for example?
No, we don't. Text is always encoded in hex, to avoid any munging of
this sort. And for goodness' sake, we wouldn't want line ending
conversion happening magically in the protocol's transport layer!
That should be done explicitly in GDB.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: RFA: Add 'target |' support for MinGW
2006-04-13 8:21 ` Jim Blandy
@ 2006-04-13 19:49 ` Michael Snyder
0 siblings, 0 replies; 8+ messages in thread
From: Michael Snyder @ 2006-04-13 19:49 UTC (permalink / raw)
To: Jim Blandy; +Cc: Eli Zaretskii, Jim Blandy, gdb-patches
Jim Blandy wrote:
> On 4/13/06, Eli Zaretskii <eliz@gnu.org> wrote:
>
>>>Cc: gdb-patches@sources.redhat.com
>>>From: Jim Blandy <jimb@codesourcery.com>
>>>Date: Wed, 12 Apr 2006 11:38:55 -0700
>>>
>>>
>>>>Do we really want binary I/O in _all_ situations? Can it be that,
>>>>depending on the command on the other side of the pipe, someone would
>>>>like the CR characters to be stripped from the EOLs in the incoming
>>>>stuff? The way you wrote it, AFAICS, binary I/O is always used, no
>>>>matter what.
>>>
>>>Well, the pipe is carrying the GDB remote protocol, which is happier
>>>with binary.
>>
>>Do we never ask the remote to list text files, for example?
>
>
> No, we don't. Text is always encoded in hex, to avoid any munging of
> this sort. And for goodness' sake, we wouldn't want line ending
> conversion happening magically in the protocol's transport layer!
> That should be done explicitly in GDB.
Jim's right -- the gdb protocol should be regarded as a binary
protocol, even though a lot of it looks like ASCII. We never
send text "in the clear". Even when we're simulating stdout,
we send the strings encoded. And part of the msg traffic is
definitely *not* ascii, so CR/LF conversion would be a very
bad thing.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: RFA: Add 'target |' support for MinGW
2006-04-12 7:04 RFA: Add 'target |' support for MinGW Jim Blandy
2006-04-12 7:52 ` Eli Zaretskii
@ 2006-04-18 18:01 ` Jim Blandy
2006-04-25 18:02 ` Jim Blandy
2 siblings, 0 replies; 8+ messages in thread
From: Jim Blandy @ 2006-04-18 18:01 UTC (permalink / raw)
To: gdb-patches
If folks don't have any further comments on this, I'll commit tomorrow.
Jim Blandy <jimb@codesourcery.com> writes:
> src/gdb/ChangeLog:
> 2006-04-11 Jim Blandy <jimb@codesourcery.com>
>
> Add support for 'target remote |' on MinGW.
> * ser-mingw.c (struct pipe_state): New structure.
> (make_pipe_state, free_pipe_state, cleanup_pipe_state)
> (pipe_windows_open, pipe_windows_close, pipe_windows_read)
> (pipe_windows_write, pipe_wait_handle): New functions.
> (_initialize_ser_windows): Register a "pipe" interface based on
> them.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: RFA: Add 'target |' support for MinGW
2006-04-12 7:04 RFA: Add 'target |' support for MinGW Jim Blandy
2006-04-12 7:52 ` Eli Zaretskii
2006-04-18 18:01 ` Jim Blandy
@ 2006-04-25 18:02 ` Jim Blandy
2 siblings, 0 replies; 8+ messages in thread
From: Jim Blandy @ 2006-04-25 18:02 UTC (permalink / raw)
To: gdb-patches
I've committed this.
Jim Blandy <jimb@codesourcery.com> writes:
> src/gdb/ChangeLog:
> 2006-04-11 Jim Blandy <jimb@codesourcery.com>
>
> Add support for 'target remote |' on MinGW.
> * ser-mingw.c (struct pipe_state): New structure.
> (make_pipe_state, free_pipe_state, cleanup_pipe_state)
> (pipe_windows_open, pipe_windows_close, pipe_windows_read)
> (pipe_windows_write, pipe_wait_handle): New functions.
> (_initialize_ser_windows): Register a "pipe" interface based on
> them.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2006-04-25 18:02 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-04-12 7:04 RFA: Add 'target |' support for MinGW Jim Blandy
2006-04-12 7:52 ` Eli Zaretskii
2006-04-12 18:39 ` Jim Blandy
2006-04-13 8:10 ` Eli Zaretskii
2006-04-13 8:21 ` Jim Blandy
2006-04-13 19:49 ` Michael Snyder
2006-04-18 18:01 ` Jim Blandy
2006-04-25 18:02 ` Jim Blandy
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox