diff options
Diffstat (limited to 'sim/ppc/emul_netbsd.c')
-rw-r--r-- | sim/ppc/emul_netbsd.c | 78 |
1 files changed, 66 insertions, 12 deletions
diff --git a/sim/ppc/emul_netbsd.c b/sim/ppc/emul_netbsd.c index 6bef370..12dfb21 100644 --- a/sim/ppc/emul_netbsd.c +++ b/sim/ppc/emul_netbsd.c @@ -292,6 +292,31 @@ write_rusage(unsigned_word addr, } #endif + +/* 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_exit(os_emul_data *emul, unsigned call, @@ -339,7 +364,9 @@ do_read(os_emul_data *emul, status = -1; } #endif - status = read (d, scratch_buffer, nbytes); + status = fdbad (d); + if (status == 0) + status = read (d, scratch_buffer, nbytes); emul_write_status(processor, status, errno); if (status > 0) @@ -374,7 +401,10 @@ do_write(os_emul_data *emul, processor, cia); /* write */ - status = write(d, scratch_buffer, nbytes); + status = fdbad (d); + if (status == 0) + status = write(d, scratch_buffer, nbytes); + emul_write_status(processor, status, errno); free(scratch_buffer); @@ -440,8 +470,20 @@ do_close(os_emul_data *emul, SYS(close); - /* Can't combine these statements, cuz close sets errno. */ - 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); } @@ -549,7 +591,7 @@ do_dup(os_emul_data *emul, 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]) @@ -640,7 +682,9 @@ do_ioctl(os_emul_data *emul, || dir & IOC_OUT || !(dir & IOC_VOID)) error("do_ioctl() read or write of parameter not implemented\n"); - status = ioctl(d, request, NULL); + status = fdbad (d); + if (status == 0) + status = ioctl(d, request, NULL); emul_write_status(processor, status, errno); #endif @@ -681,7 +725,7 @@ do_dup2(os_emul_data *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]) @@ -711,7 +755,9 @@ do_fcntl(os_emul_data *emul, printf_filtered ("%d, %d, %d", fd, cmd, arg); SYS(fcntl); - status = fcntl(fd, cmd, arg); + status = fdbad (fd); + if (status == 0) + status = fcntl(fd, cmd, arg); emul_write_status(processor, status, errno); } #endif @@ -796,7 +842,9 @@ do_fstatfs(os_emul_data *emul, printf_filtered ("%d, 0x%lx", fd, (long)buf_addr); SYS(fstatfs); - status = fstatfs(fd, (buf_addr == 0 ? NULL : &buf)); + status = fdbad (fd); + if (status == 0) + status = fstatfs(fd, (buf_addr == 0 ? NULL : &buf)); emul_write_status(processor, status, errno); if (status == 0) { if (buf_addr != 0) @@ -849,7 +897,9 @@ do_fstat(os_emul_data *emul, SYS(fstat); #endif /* Can't combine these statements, cuz fstat sets errno. */ - status = fstat(fd, &buf); + status = fdbad (fd); + if (status == 0) + status = fstat(fd, &buf); emul_write_status(processor, status, errno); write_stat(stat_buf_addr, buf, processor, cia); } @@ -951,7 +1001,9 @@ do_lseek(os_emul_data *emul, int whence = cpu_registers(processor)->gpr[arg0+4]; off_t status; SYS(lseek); - status = lseek(fildes, offset, whence); + status = fdbad (fildes); + if (status == 0) + status = lseek(fildes, offset, whence); if (status == -1) emul_write_status(processor, -1, errno); else { @@ -1450,7 +1502,9 @@ static void emul_netbsd_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 |