1 1.1 christos /* Adjust a file descriptor result so that it avoids clobbering 2 1.1 christos STD{IN,OUT,ERR}_FILENO, with specific flags. 3 1.1 christos 4 1.1.1.2 christos Copyright (C) 2005-2006, 2009-2022 Free Software Foundation, Inc. 5 1.1 christos 6 1.1 christos This program is free software: you can redistribute it and/or modify 7 1.1 christos it under the terms of the GNU General Public License as published by 8 1.1.1.2 christos the Free Software Foundation, either version 3 of the License, or 9 1.1 christos (at your option) any later version. 10 1.1 christos 11 1.1 christos This program is distributed in the hope that it will be useful, 12 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 1.1 christos GNU General Public License for more details. 15 1.1 christos 16 1.1 christos You should have received a copy of the GNU General Public License 17 1.1 christos along with this program. If not, see <https://www.gnu.org/licenses/>. */ 18 1.1 christos 19 1.1 christos /* Written by Paul Eggert and Eric Blake. */ 20 1.1 christos 21 1.1 christos #include <config.h> 22 1.1 christos 23 1.1 christos /* Specification. */ 24 1.1 christos #include "unistd-safer.h" 25 1.1 christos 26 1.1 christos #include <errno.h> 27 1.1 christos #include <unistd.h> 28 1.1 christos 29 1.1 christos /* Return FD, unless FD would be a copy of standard input, output, or 30 1.1 christos error; in that case, return a duplicate of FD, closing FD. If FLAG 31 1.1 christos contains O_CLOEXEC, the returned FD will have close-on-exec 32 1.1 christos semantics. On failure to duplicate, close FD, set errno, and 33 1.1 christos return -1. Preserve errno if FD is negative, so that the caller 34 1.1 christos can always inspect errno when the returned value is negative. 35 1.1 christos 36 1.1 christos This function is usefully wrapped around functions that return file 37 1.1 christos descriptors, e.g., fd_safer_flag (open ("file", O_RDONLY | flag), flag). */ 38 1.1 christos 39 1.1 christos int 40 1.1 christos fd_safer_flag (int fd, int flag) 41 1.1 christos { 42 1.1 christos if (STDIN_FILENO <= fd && fd <= STDERR_FILENO) 43 1.1 christos { 44 1.1 christos int f = dup_safer_flag (fd, flag); 45 1.1 christos int e = errno; 46 1.1 christos close (fd); 47 1.1 christos errno = e; 48 1.1 christos fd = f; 49 1.1 christos } 50 1.1 christos 51 1.1 christos return fd; 52 1.1 christos } 53