static int response_needed;
static int exit_requested;
+/* --once: Exit after the first connection has closed. */
+int run_once;
+
int multi_process;
int non_stop;
{
struct vstop_notif *new_notif;
- new_notif = malloc (sizeof (*new_notif));
+ new_notif = xmalloc (sizeof (*new_notif));
new_notif->next = NULL;
new_notif->ptid = ptid;
new_notif->status = *status;
return len;
}
+/* Handle qXfer:traceframe-info:read. */
+
+static int
+handle_qxfer_traceframe_info (const char *annex,
+ gdb_byte *readbuf, const gdb_byte *writebuf,
+ ULONGEST offset, LONGEST len)
+{
+ static char *result = 0;
+ static unsigned int result_length = 0;
+
+ if (writebuf != NULL)
+ return -2;
+
+ if (!target_running () || annex[0] != '\0' || current_traceframe == -1)
+ return -1;
+
+ if (offset == 0)
+ {
+ struct buffer buffer;
+
+ /* When asked for data at offset 0, generate everything and
+ store into 'result'. Successive reads will be served off
+ 'result'. */
+ free (result);
+
+ buffer_init (&buffer);
+
+ traceframe_read_info (current_traceframe, &buffer);
+
+ result = buffer_finish (&buffer);
+ result_length = strlen (result);
+ buffer_free (&buffer);
+ }
+
+ if (offset >= result_length)
+ {
+ /* We're out of data. */
+ free (result);
+ result = NULL;
+ result_length = 0;
+ return 0;
+ }
+
+ if (len > result_length - offset)
+ len = result_length - offset;
+
+ memcpy (readbuf, result + offset, len);
+ return len;
+}
+
static const struct qxfer qxfer_packets[] =
{
{ "auxv", handle_qxfer_auxv },
{ "spu", handle_qxfer_spu },
{ "statictrace", handle_qxfer_statictrace },
{ "threads", handle_qxfer_threads },
+ { "traceframe-info", handle_qxfer_traceframe_info },
};
static int
sprintf (own_buf, "QC");
own_buf += 2;
- own_buf = write_ptid (own_buf, gdb_id);
+ write_ptid (own_buf, gdb_id);
return;
}
strcat (own_buf, ";FastTracepoints+");
strcat (own_buf, ";StaticTracepoints+");
strcat (own_buf, ";qXfer:statictrace:read+");
+ strcat (own_buf, ";qXfer:traceframe-info:read+");
+ strcat (own_buf, ";EnableDisableTracepoints+");
}
return;
if (program_argv == NULL)
{
- /* FIXME: new_argv memory leak */
write_enn (own_buf);
+ freeargv (new_argv);
return 0;
}
new_argv[0] = strdup (program_argv[0]);
if (new_argv[0] == NULL)
{
- /* FIXME: new_argv memory leak */
write_enn (own_buf);
+ freeargv (new_argv);
return 0;
}
}
" --debug Enable general debugging output.\n"
" --remote-debug Enable remote protocol debugging output.\n"
" --version Display version information and exit.\n"
- " --wrapper WRAPPER -- Run WRAPPER to start new programs.\n");
+ " --wrapper WRAPPER -- Run WRAPPER to start new programs.\n"
+ " --once Exit after the first connection has "
+ "closed.\n");
if (REPORT_BUGS_TO[0] && stream == stdout)
fprintf (stream, "Report bugs to \"%s\".\n", REPORT_BUGS_TO);
}
for_each_inferior (&all_processes, detach_or_kill_inferior_callback);
}
-static void
-join_inferiors_callback (struct inferior_list_entry *entry)
-{
- struct process_info *process = (struct process_info *) entry;
-
- /* If we are attached, then we can exit. Otherwise, we need to hang
- around doing nothing, until the child is gone. */
- if (!process->attached)
- join_inferior (ptid_get_pid (process->head.id));
-}
-
int
main (int argc, char *argv[])
{
}
}
}
+ else if (strcmp (*next_arg, "--once") == 0)
+ run_once = 1;
else
{
fprintf (stderr, "Unknown argument: %s\n", *next_arg);
exit (1);
}
- initialize_inferiors ();
initialize_async_io ();
initialize_low ();
if (target_supports_tracepoints ())
exit (1);
}
+ remote_prepare (port);
+
while (1)
{
noack_mode = 0;
getpkt to fail; close the connection and reopen it at the
top of the loop. */
- if (exit_requested)
+ if (exit_requested || run_once)
{
detach_or_kill_for_exit ();
exit (0);
/* If we are attached, then we can exit. Otherwise, we
need to hang around doing nothing, until the child is
gone. */
- for_each_inferior (&all_processes,
- join_inferiors_callback);
+ join_inferior (pid);
exit (0);
}
}