static char *inferior_thisrun_terminal;
-/* Nonzero if our terminal settings are in effect.
- Zero if the inferior's settings are in effect. */
+/* Nonzero if our terminal settings are in effect. Zero if the
+ inferior's settings are in effect. Ignored if !gdb_has_a_terminal
+ (). */
static int terminal_is_ours;
all!). Can't do this in _initialize_inflow because SERIAL_FDOPEN
won't work until the serial_ops_list is initialized. */
+#ifdef F_GETFL
tflags_ours = fcntl (0, F_GETFL, 0);
+#endif
gdb_has_a_terminal_flag = no;
stdin_serial = SERIAL_FDOPEN (0);
void
terminal_init_inferior ()
{
- /* Make sure that our_ttystate (etc) are initialized. */
- gdb_has_a_terminal ();
-
- /* We could just as well copy our_ttystate (if we felt like adding
- a new function SERIAL_COPY_TTY_STATE). */
- if (inferior_ttystate)
- free (inferior_ttystate);
- inferior_ttystate = SERIAL_GET_TTY_STATE (stdin_serial);
- SERIAL_SET_PROCESS_GROUP (stdin_serial, inferior_ttystate, inferior_pid);
-
- /* Make sure that next time we call terminal_inferior (which will be
- before the program runs, as it needs to be), we install the new
- process group. */
- terminal_is_ours = 1;
+ if (gdb_has_a_terminal ())
+ {
+ /* We could just as well copy our_ttystate (if we felt like adding
+ a new function SERIAL_COPY_TTY_STATE). */
+ if (inferior_ttystate)
+ free (inferior_ttystate);
+ inferior_ttystate = SERIAL_GET_TTY_STATE (stdin_serial);
+ SERIAL_SET_PROCESS_GROUP (stdin_serial, inferior_ttystate, inferior_pid);
+
+ /* Make sure that next time we call terminal_inferior (which will be
+ before the program runs, as it needs to be), we install the new
+ process group. */
+ terminal_is_ours = 1;
+ }
}
/* Put the inferior's terminal settings into effect.
{
int result;
+#ifdef F_GETFL
/* Is there a reason this is being done twice? It happens both
places we use F_SETFL, so I'm inclined to think perhaps there
is some reason, however perverse. Perhaps not though... */
result = fcntl (0, F_SETFL, tflags_inferior);
result = fcntl (0, F_SETFL, tflags_inferior);
OOPSY ("fcntl F_SETFL");
+#endif
/* Because we were careful to not change in or out of raw mode in
terminal_ours, we will not change in our out of raw mode with
signal (SIGQUIT, sigquit_ours);
}
+#ifdef F_GETFL
tflags_inferior = fcntl (0, F_GETFL, 0);
/* Is there a reason this is being done twice? It happens both
is some reason, however perverse. Perhaps not though... */
result = fcntl (0, F_SETFL, tflags_ours);
result = fcntl (0, F_SETFL, tflags_ours);
+#endif
result = result; /* lint */
}
new_tty ()
{
register int tty;
- void (*osigttou) ();
if (inferior_thisrun_terminal == 0)
return;
tty = open("/dev/tty", O_RDWR);
if (tty > 0)
{
+ void (*osigttou) ();
+
osigttou = (void (*)()) signal(SIGTTOU, SIG_IGN);
ioctl(tty, TIOCNOTTY, 0);
close(tty);
#endif
reopen_exec_file ();
+ flush_cached_frames ();
if (target_has_stack) {
set_current_frame ( create_new_frame (read_register (FP_REGNUM),
read_pc ()));
/* Select target systems and architectures at runtime for GDB.
- Copyright 1990, 1992 Free Software Foundation, Inc.
+ Copyright 1990, 1992, 1993 Free Software Foundation, Inc.
Contributed by Cygnus Support.
This file is part of GDB.
find_default_create_inferior, /* create_inferior */
0, /* mourn_inferior */
0, /* can_run */
+ 0, /* notice_signals */
dummy_stratum, 0, /* stratum, next */
0, 0, 0, 0, 0, /* all mem, mem, stack, regs, exec */
0, 0, /* section pointers */
de_fault (to_create_inferior, maybe_kill_then_create_inferior);
de_fault (to_mourn_inferior, (void (*)())noprocess);
de_fault (to_can_run, return_zero);
+ de_fault (to_notice_signals, (void (*)())ignore);
de_fault (to_next, 0);
de_fault (to_has_all_memory, 0);
de_fault (to_has_memory, 0);
{
(current_target->to_close)(0); /* Let it clean up */
current_target = current_target->to_next;
+#if 0
+ /* This will dump core if ever called--push_target expects current_target
+ to be non-NULL. But I don't think it's needed; I don't see how the
+ dummy_target could ever be removed from the stack. */
if (!current_target) /* At bottom, push dummy. */
push_target (&dummy_target);
+#endif
}
+#undef MIN
#define MIN(A, B) (((A) <= (B)) ? (A) : (B))
/* target_read_string -- read a null terminated string from MEMADDR in target.
return origlen;
}
-/* Move memory to or from the targets. Iterate until all of it has
- been moved, if necessary. The top target gets priority; anything
- it doesn't want, is offered to the next one down, etc. Note the
- business with curlen: if an early target says "no, but I have a
- boundary overlapping this xfer" then we shorten what we offer to
- the subsequent targets so the early guy will get a chance at the
- tail before the subsequent ones do.
+/* Read LEN bytes of target memory at address MEMADDR, placing the results in
+ GDB's memory at MYADDR. Returns either 0 for success or an errno value
+ if any error occurs.
- Result is 0 or errno value. */
+ If an error occurs, no guarantee is made about the contents of the data at
+ MYADDR. In particular, the caller should not depend upon partial reads
+ filling the buffer with good data. There is no way for the caller to know
+ how much good data might have been transfered anyway. Callers that can
+ deal with partial reads should call target_read_memory_partial. */
int
target_read_memory (memaddr, myaddr, len)
return target_xfer_memory (memaddr, myaddr, len, 0);
}
+/* Read LEN bytes of target memory at address MEMADDR, placing the results
+ in GDB's memory at MYADDR. Returns a count of the bytes actually read,
+ and optionally an errno value in the location pointed to by ERRNOPTR
+ if ERRNOPTR is non-null. */
+
+int
+target_read_memory_partial (memaddr, myaddr, len, errnoptr)
+ CORE_ADDR memaddr;
+ char *myaddr;
+ int len;
+ int *errnoptr;
+{
+ int nread; /* Number of bytes actually read. */
+ int errcode; /* Error from last read. */
+
+ /* First try a complete read. */
+ errcode = target_xfer_memory (memaddr, myaddr, len, 0);
+ if (errcode == 0)
+ {
+ /* Got it all. */
+ nread = len;
+ }
+ else
+ {
+ /* Loop, reading one byte at a time until we get as much as we can. */
+ for (errcode = 0, nread = 0; len > 0 && errcode == 0; nread++, len--)
+ {
+ errcode = target_xfer_memory (memaddr++, myaddr++, 1, 0);
+ }
+ /* If an error, the last read was unsuccessful, so adjust count. */
+ if (errcode != 0)
+ {
+ nread--;
+ }
+ }
+ if (errnoptr != NULL)
+ {
+ *errnoptr = errcode;
+ }
+ return (nread);
+}
+
int
target_write_memory (memaddr, myaddr, len)
CORE_ADDR memaddr;
return target_xfer_memory (memaddr, myaddr, len, 1);
}
+/* Move memory to or from the targets. Iterate until all of it has
+ been moved, if necessary. The top target gets priority; anything
+ it doesn't want, is offered to the next one down, etc. Note the
+ business with curlen: if an early target says "no, but I have a
+ boundary overlapping this xfer" then we shorten what we offer to
+ the subsequent targets so the early guy will get a chance at the
+ tail before the subsequent ones do.
+
+ Result is 0 or errno value. */
+
int
target_xfer_memory (memaddr, myaddr, len, write)
CORE_ADDR memaddr;
int curlen;
int res;
struct target_ops *t;
-
+
+ /* to_xfer_memory is not guaranteed to set errno, even when it returns
+ 0. */
+ errno = 0;
+
/* The quick case is that the top target does it all. */
res = current_target->to_xfer_memory
(memaddr, myaddr, len, write, current_target);
}
}
+/* Detach a target after doing deferred register stores. */
+
+void
+target_detach (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ /* Handle any optimized stores to the inferior. */
+#ifdef DO_DEFERRED_STORES
+ DO_DEFERRED_STORES;
+#endif
+ (current_target->to_detach) (args, from_tty);
+
+ /* It is correct to do this because the top process can never be as high
+ as process_stratum now. This is needed at least in the case where
+ we detach a corefile, and thus need to flush the frame cache. */
+ generic_mourn_inferior ();
+}
+
/* Look through the list of possible targets for a target that can
execute a run or attach command without any other data. This is
used to locate the default process stratum.
char *do_mesg;
{
struct target_ops **t;
- struct target_ops *runable;
+ struct target_ops *runable = NULL;
int count;
count = 0;
return 0;
}
+struct target_ops *
+find_core_target ()
+{
+ struct target_ops **t;
+ struct target_ops *runable = NULL;
+ int count;
+
+ count = 0;
+
+ for (t = target_structs; t < target_structs + target_struct_size;
+ ++t)
+ {
+ if ((*t)->to_stratum == core_stratum)
+ {
+ runable = *t;
+ ++count;
+ }
+ }
+
+ return(count == 1 ? runable : NULL);
+}
+
+/* Convert a normal process ID to a string. Returns the string in a static
+ buffer. */
+
+char *
+normal_pid_to_str (pid)
+ int pid;
+{
+ static char buf[30];
+
+ sprintf (buf, "process %d", pid);
+
+ return buf;
+}
+
static char targ_desc[] =
"Names of targets and files being debugged.\n\
Shows the entire stack of targets currently in use (including the exec-file,\n\