/* Copyright (C) 2016 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #include #include #include #include #include #include #include #include #include int dup2(int fd, int newfd) { __dpmi_regs r = {0}; if (newfd < 0 || newfd >= getdtablesize() || _get_dev_info(fd) == -1) { errno = EBADF; return -1; } if (fd == newfd) return newfd; /* Reset the text/binary modes, the fsext, and the properties, since DOS function 46h closes newfd. */ __file_handle_set(newfd, __file_handle_modes[fd] ^ (O_BINARY|O_TEXT)); __FSEXT_set_function(newfd, 0); r.h.ah = 0x46; r.x.bx = fd; r.x.cx = newfd; __dpmi_int(0x21, &r); if (r.x.flags & 1) { errno = __doserr_to_errno(r.x.ax); return -1; } /* The properties may be cleared only after the file has been forcibly closed because the file associated with the descriptor may be deleted if it has the temporary attribute and if newfd is the last reference to it. */ if (__has_fd_properties(newfd)) __clear_fd_properties(newfd); /* Copy the fsext hook, the handle modes, and the properties. */ __FSEXT_set_function(newfd, __FSEXT_get_function(fd)); setmode(newfd, __file_handle_modes[fd]); if (__has_fd_properties(fd)) __dup_fd_properties(fd, newfd); return newfd; }