18dffb485Schristos /* Duplicate an open file descriptor. 28dffb485Schristos 3*4b169a6bSchristos Copyright (C) 2011-2022 Free Software Foundation, Inc. 48dffb485Schristos 5*4b169a6bSchristos This file is free software: you can redistribute it and/or modify 6*4b169a6bSchristos it under the terms of the GNU Lesser General Public License as 7*4b169a6bSchristos published by the Free Software Foundation; either version 2.1 of the 8*4b169a6bSchristos License, or (at your option) any later version. 98dffb485Schristos 10*4b169a6bSchristos This file is distributed in the hope that it will be useful, 118dffb485Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 128dffb485Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13*4b169a6bSchristos GNU Lesser General Public License for more details. 148dffb485Schristos 15*4b169a6bSchristos You should have received a copy of the GNU Lesser General Public License 168dffb485Schristos along with this program. If not, see <https://www.gnu.org/licenses/>. */ 178dffb485Schristos 188dffb485Schristos #include <config.h> 198dffb485Schristos 208dffb485Schristos /* Specification. */ 218dffb485Schristos #include <unistd.h> 228dffb485Schristos 238dffb485Schristos #include <errno.h> 248dffb485Schristos 258dffb485Schristos #if HAVE_MSVC_INVALID_PARAMETER_HANDLER 268dffb485Schristos # include "msvc-inval.h" 278dffb485Schristos #endif 288dffb485Schristos 298dffb485Schristos #undef dup 308dffb485Schristos 31*4b169a6bSchristos #if defined _WIN32 && !defined __CYGWIN__ 328dffb485Schristos # if HAVE_MSVC_INVALID_PARAMETER_HANDLER 338dffb485Schristos static int dup_nothrow(int fd)348dffb485Schristosdup_nothrow (int fd) 358dffb485Schristos { 368dffb485Schristos int result; 378dffb485Schristos 388dffb485Schristos TRY_MSVC_INVAL 398dffb485Schristos { 40*4b169a6bSchristos result = _dup (fd); 418dffb485Schristos } 428dffb485Schristos CATCH_MSVC_INVAL 438dffb485Schristos { 448dffb485Schristos result = -1; 458dffb485Schristos errno = EBADF; 468dffb485Schristos } 478dffb485Schristos DONE_MSVC_INVAL; 488dffb485Schristos 498dffb485Schristos return result; 508dffb485Schristos } 51*4b169a6bSchristos # else 52*4b169a6bSchristos # define dup_nothrow _dup 53*4b169a6bSchristos # endif 548dffb485Schristos #elif defined __KLIBC__ 558dffb485Schristos # include <fcntl.h> 568dffb485Schristos # include <sys/stat.h> 578dffb485Schristos 588dffb485Schristos # include <InnoTekLIBC/backend.h> 598dffb485Schristos 608dffb485Schristos static int dup_nothrow(int fd)618dffb485Schristosdup_nothrow (int fd) 628dffb485Schristos { 638dffb485Schristos int dupfd; 648dffb485Schristos struct stat sbuf; 658dffb485Schristos 668dffb485Schristos dupfd = dup (fd); 678dffb485Schristos if (dupfd == -1 && errno == ENOTSUP \ 688dffb485Schristos && !fstat (fd, &sbuf) && S_ISDIR (sbuf.st_mode)) 698dffb485Schristos { 708dffb485Schristos char path[_MAX_PATH]; 718dffb485Schristos 728dffb485Schristos /* Get a path from fd */ 738dffb485Schristos if (!__libc_Back_ioFHToPath (fd, path, sizeof (path))) 748dffb485Schristos dupfd = open (path, O_RDONLY); 758dffb485Schristos } 768dffb485Schristos 778dffb485Schristos return dupfd; 788dffb485Schristos } 798dffb485Schristos #else 808dffb485Schristos # define dup_nothrow dup 818dffb485Schristos #endif 828dffb485Schristos 838dffb485Schristos int rpl_dup(int fd)848dffb485Schristosrpl_dup (int fd) 858dffb485Schristos { 868dffb485Schristos int result = dup_nothrow (fd); 878dffb485Schristos #if REPLACE_FCHDIR 888dffb485Schristos if (result >= 0) 898dffb485Schristos result = _gl_register_dup (fd, result); 908dffb485Schristos #endif 918dffb485Schristos return result; 928dffb485Schristos } 93