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 2 of the License, or
+ 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,
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, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
};
+/* File descriptors 0, 1, and 2 should not be closed. fd_closed[]
+ tracks whether these descriptors have been closed in do_close()
+ below. */
+
+static int fd_closed[3];
+
+/* Check for some occurrences of bad file descriptors. We only check
+ whether fd 0, 1, or 2 are "closed". By "closed" we mean that these
+ descriptors aren't actually closed, but are considered to be closed
+ by this layer.
+
+ Other checks are performed by the underlying OS call. */
+
+static int
+fdbad (int fd)
+{
+ if (fd >=0 && fd <= 2 && fd_closed[fd])
+ {
+ errno = EBADF;
+ return -1;
+ }
+ return 0;
+}
+
static void
do_unix_exit(os_emul_data *emul,
unsigned call,
/* check if buffer exists by reading it */
emul_read_buffer(scratch_buffer, buf, nbytes, processor, cia);
+ status = fdbad (d);
/* read */
- status = read (d, scratch_buffer, nbytes);
+ if (status == 0)
+ status = read (d, scratch_buffer, nbytes);
emul_write_status(processor, status, errno);
if (status > 0)
emul_write_buffer(scratch_buffer, buf, status, processor, cia);
- zfree(scratch_buffer);
+ free(scratch_buffer);
}
emul_read_buffer(scratch_buffer, buf, nbytes,
processor, cia);
+ status = fdbad (d);
/* write */
- status = write(d, scratch_buffer, nbytes);
+ if (status == 0)
+ status = write(d, scratch_buffer, nbytes);
emul_write_status(processor, status, errno);
- zfree(scratch_buffer);
+ free(scratch_buffer);
flush_stdoutput();
}
if (WITH_TRACE && ppc_trace[trace_os_emul])
printf_filtered ("%d", d);
- status = close(d);
+ status = fdbad (d);
+ if (status == 0)
+ {
+ /* Do not close stdin, stdout, or stderr. GDB may still need access to
+ these descriptors. */
+ if (d == 0 || d == 1 || d == 2)
+ {
+ fd_closed[d] = 1;
+ status = 0;
+ }
+ else
+ status = close(d);
+ }
+
emul_write_status(processor, status, errno);
}
unsigned_word cia)
{
int oldd = cpu_registers(processor)->gpr[arg0];
- int status = dup(oldd);
+ int status = (fdbad (oldd) < 0) ? -1 : dup(oldd);
int err = errno;
if (WITH_TRACE && ppc_trace[trace_os_emul])
{
int oldd = cpu_registers(processor)->gpr[arg0];
int newd = cpu_registers(processor)->gpr[arg0+1];
- int status = dup2(oldd, newd);
+ int status = (fdbad (oldd) < 0) ? -1 : dup2(oldd, newd);
int err = errno;
if (WITH_TRACE && ppc_trace[trace_os_emul])
if (WITH_TRACE && ppc_trace[trace_os_emul])
printf_filtered ("%d %ld %d", fildes, (long)offset, whence);
- status = lseek(fildes, offset, whence);
+ status = fdbad (fildes);
+ if (status == 0)
+ status = lseek(fildes, offset, whence);
emul_write_status(processor, (int)status, errno);
}
#endif
int elf_binary;
os_emul_data *data;
device *vm;
+ char *filename;
/* merge any emulation specific entries into the device tree */
(unsigned long)(top_of_stack - stack_size));
tree_parse(vm, "./nr-bytes 0x%x", stack_size);
+ filename = tree_quote_property (bfd_get_filename(image));
tree_parse(root, "/openprom/vm/map-binary/file-name %s",
- bfd_get_filename(image));
+ filename);
+ free (filename);
/* finish the init */
tree_parse(root, "/openprom/init/register/pc 0x%lx",
#ifdef HAVE_SYS_STAT_H
#define SOLARIS_ST_FSTYPSZ 16 /* array size for file system type name */
+/* AIX 7.1 defines st_pad[123] to st_[amc]tim.tv_pad, respectively */
+#undef st_pad1
+#undef st_pad2
+#undef st_pad3
+
struct solaris_stat {
solaris_dev_t st_dev;
signed32 st_pad1[3]; /* reserved for network id */
target.st_mtim.tv_sec = H2T_4(host->st_mtime);
target.st_mtim.tv_usec = 0;
- for (i = 0; i < sizeof (target.st_pad1) / sizeof (target.st_pad1[0]); i++)
+ for (i = 0; i < ARRAY_SIZE (target.st_pad1); i++)
target.st_pad1[i] = 0;
- for (i = 0; i < sizeof (target.st_pad2) / sizeof (target.st_pad2[0]); i++)
+ for (i = 0; i < ARRAY_SIZE (target.st_pad2); i++)
target.st_pad2[i] = 0;
target.st_pad3 = 0;
- for (i = 0; i < sizeof (target.st_pad4) / sizeof (target.st_pad4[0]); i++)
+ for (i = 0; i < ARRAY_SIZE (target.st_pad4); i++)
target.st_pad4[i] = 0;
/* For now, just punt and always say it is a ufs file */
if (WITH_TRACE && ppc_trace[trace_os_emul])
printf_filtered ("%d, 0x%lx", fildes, (long)stat_pkt);
- status = fstat (fildes, &buf);
+ status = fdbad (fildes);
+ if (status == 0)
+ status = fstat (fildes, &buf);
if (status == 0)
convert_to_solaris_stat (stat_pkt, &buf, processor, cia);
#endif
#endif
+ status = fdbad (fildes);
+ if (status != 0)
+ goto done;
+
switch (request)
{
case 0: /* make sure we have at least one case */
#endif /* HAVE_TERMIOS_STRUCTURE */
}
+done:
emul_write_status(processor, status, errno);
if (WITH_TRACE && ppc_trace[trace_os_emul])
static emul_syscall emul_solaris_syscalls = {
solaris_descriptors,
- sizeof(solaris_descriptors) / sizeof(solaris_descriptors[0]),
+ ARRAY_SIZE (solaris_descriptors),
solaris_error_names,
- sizeof(solaris_error_names) / sizeof(solaris_error_names[0]),
+ ARRAY_SIZE (solaris_error_names),
solaris_signal_names,
- sizeof(solaris_signal_names) / sizeof(solaris_signal_names[0]),
+ ARRAY_SIZE (solaris_signal_names),
};
emul_solaris_init(os_emul_data *emul_data,
int nr_cpus)
{
- /* nothing yet */
+ fd_closed[0] = 0;
+ fd_closed[1] = 0;
+ fd_closed[2] = 0;
}
static void
if (WITH_TRACE && ppc_trace[trace_os_emul])
printf_filtered ("%d, 0x%lx", fildes, (long)stat_pkt);
- status = fstat (fildes, &buf);
+ status = fdbad (fildes);
+ if (status == 0)
+ status = fstat (fildes, &buf);
if (status == 0)
convert_to_linux_stat (stat_pkt, &buf, processor, cia);
#endif
#endif
+ status = fdbad (fildes);
+ if (status != 0)
+ goto done;
+
switch (request)
{
case 0: /* make sure we have at least one case */
#endif /* HAVE_TERMIOS_STRUCTURE */
}
+done:
emul_write_status(processor, status, errno);
if (WITH_TRACE && ppc_trace[trace_os_emul])
static emul_syscall emul_linux_syscalls = {
linux_descriptors,
- sizeof(linux_descriptors) / sizeof(linux_descriptors[0]),
+ ARRAY_SIZE (linux_descriptors),
linux_error_names,
- sizeof(linux_error_names) / sizeof(linux_error_names[0]),
+ ARRAY_SIZE (linux_error_names),
linux_signal_names,
- sizeof(linux_signal_names) / sizeof(linux_signal_names[0]),
+ ARRAY_SIZE (linux_signal_names),
};
emul_linux_init(os_emul_data *emul_data,
int nr_cpus)
{
- /* nothing yet */
+ fd_closed[0] = 0;
+ fd_closed[1] = 0;
+ fd_closed[2] = 0;
}
static void