(root)/
m4-1.4.19/
tests/
creat.c
       1  /* Create a file.
       2     Copyright (C) 2007-2021 Free Software Foundation, Inc.
       3  
       4     This program is free software: you can redistribute it and/or modify
       5     it under the terms of the GNU General Public License as published by
       6     the Free Software Foundation; either version 3 of the License, or
       7     (at your option) any later version.
       8  
       9     This program 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 General Public License for more details.
      13  
      14     You should have received a copy of the GNU 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  }