xref: /netbsd-src/external/gpl3/gdb/dist/gnulib/import/dup.c (revision 4b169a6ba595ae283ca507b26b15fdff40495b1c)
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)348dffb485Schristos dup_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)618dffb485Schristos dup_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)848dffb485Schristos rpl_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