1 /* Create a file. 2 Copyright (C) 2007-2021 Free Software Foundation, Inc. 3 4 This file is free software: you can redistribute it and/or modify 5 it under the terms of the GNU Lesser General Public License as 6 published by the Free Software Foundation; either version 2.1 of the 7 License, or (at your option) any later version. 8 9 This file is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU Lesser General Public License for more details. 13 14 You should have received a copy of the GNU Lesser General Public License 15 along with this program. If not, see <https://www.gnu.org/licenses/>. */ 16 17 /* If the user's config.h happens to include <fcntl.h>, let it include only 18 the system's <fcntl.h> here, so that orig_creat doesn't recurse to 19 rpl_creat. */ 20 #define __need_system_fcntl_h 21 #include <config.h> 22 23 /* Get the original definition of creat. It might be defined as a macro. */ 24 #include <fcntl.h> 25 #include <sys/types.h> 26 #undef __need_system_fcntl_h 27 28 static int 29 orig_creat (const char *filename, mode_t mode) /* */ 30 { 31 #if defined _WIN32 && !defined __CYGWIN__ 32 return _creat (filename, mode); 33 #else 34 return creat (filename, mode); 35 #endif 36 } 37 38 /* Specification. */ 39 /* Write "fcntl.h" here, not <fcntl.h>, otherwise OSF/1 5.1 DTK cc eliminates 40 this include because of the preliminary #include <fcntl.h> above. */ 41 #include "fcntl.h" 42 43 #include <errno.h> 44 #include <string.h> 45 #include <sys/types.h> 46 47 int 48 creat (const char *filename, mode_t mode) /* */ 49 { 50 #if OPEN_TRAILING_SLASH_BUG 51 /* Fail if the filename ends in a slash, 52 as POSIX says such a filename must name a directory 53 <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13>: 54 "A pathname that contains at least one non-<slash> character and that 55 ends with one or more trailing <slash> characters shall not be resolved 56 successfully unless the last pathname component before the trailing 57 <slash> characters names an existing directory" 58 creat() is defined as being equivalent to open() with flags 59 O_CREAT | O_TRUNC | O_WRONLY. Therefore: 60 If the named file already exists as a directory, then creat() must fail 61 with errno = EISDIR. 62 If the named file does not exist or does not name a directory, then 63 creat() must fail since creat() cannot create directories. */ 64 { 65 size_t len = strlen (filename); 66 if (len > 0 && filename[len - 1] == '/') 67 { 68 errno = EISDIR; 69 return -1; 70 } 71 } 72 #endif 73 74 #if defined _WIN32 && !defined __CYGWIN__ 75 /* Remap the 'x' bits to the 'r' bits. */ 76 mode = (mode & ~0111) | ((mode & 0111) << 2); 77 #endif 78 79 return orig_creat (filename, mode); 80 }