X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=sim%2Fppc%2Femul_netbsd.c;h=9b80fc25dc812ab4317de3a7481b34a31199cc07;hb=0394eed15c5bf24943850f356785152c3d65ab94;hp=f81c9cb250330033d77bd12b4f56b1411f655183;hpb=01f0fe5e0450edf168c1f612feb93cf588e4e7ea;p=deliverable%2Fbinutils-gdb.git diff --git a/sim/ppc/emul_netbsd.c b/sim/ppc/emul_netbsd.c index f81c9cb250..9b80fc25dc 100644 --- a/sim/ppc/emul_netbsd.c +++ b/sim/ppc/emul_netbsd.c @@ -4,7 +4,7 @@ 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, @@ -13,8 +13,7 @@ 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 . */ @@ -258,7 +257,7 @@ write_direntries(unsigned_word addr, nbytes -= in->d_reclen; addr += in->d_reclen; buf += in->d_reclen; - zfree(out); + free(out); } } #endif @@ -293,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, @@ -340,13 +364,15 @@ 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) emul_write_buffer(scratch_buffer, buf, status, processor, cia); - zfree(scratch_buffer); + free(scratch_buffer); } @@ -375,9 +401,12 @@ 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); - zfree(scratch_buffer); + free(scratch_buffer); flush_stdoutput(); } @@ -441,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); } @@ -550,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]) @@ -641,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 @@ -682,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]) @@ -712,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 @@ -797,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) @@ -850,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); } @@ -916,7 +965,7 @@ do_getdirentries(os_emul_data *emul, if (status > 0) write_direntries(buf_addr, buf, status, processor, cia); if (buf != NULL) - zfree(buf); + free(buf); } #endif @@ -952,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 { @@ -1362,11 +1413,11 @@ static char *(netbsd_signal_names[]) = { static emul_syscall emul_netbsd_syscalls = { netbsd_descriptors, - sizeof(netbsd_descriptors) / sizeof(netbsd_descriptors[0]), + ARRAY_SIZE (netbsd_descriptors), netbsd_error_names, - sizeof(netbsd_error_names) / sizeof(netbsd_error_names[0]), + ARRAY_SIZE (netbsd_error_names), netbsd_signal_names, - sizeof(netbsd_signal_names) / sizeof(netbsd_signal_names[0]), + ARRAY_SIZE (netbsd_signal_names), }; @@ -1451,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