root/maint/gnulib/lib/mknodat.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rpl_mknodat
  2. mknodat

   1 /* Create an inode relative to an open directory.
   2    Copyright (C) 2009-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 /* written by Eric Blake */
  18 
  19 #include <config.h>
  20 
  21 /* Specification.  */
  22 #include <sys/stat.h>
  23 
  24 #include <stdlib.h>
  25 
  26 #if HAVE_MKNODAT
  27 
  28 # include <errno.h>
  29 # include <fcntl.h>
  30 # include <string.h>
  31 
  32 int
  33 rpl_mknodat (int fd, char const *file, mode_t mode, dev_t dev)
     /* [previous][next][first][last][top][bottom][index][help] */
  34 #undef mknodat
  35 {
  36   /* Use the original mknodat(), but correct the trailing slash handling.  */
  37   size_t len = strlen (file);
  38   if (len && file[len - 1] == '/')
  39     {
  40       struct stat st;
  41 
  42       if (fstatat (fd, file, &st, AT_SYMLINK_NOFOLLOW) < 0)
  43         {
  44           if (errno == EOVERFLOW)
  45             /* It's surely a file, not a directory.  */
  46             errno = ENOTDIR;
  47         }
  48       else
  49         {
  50           /* It's a directory, otherwise fstatat() would have reported an error
  51              ENOTDIR.  */
  52           errno = EEXIST;
  53         }
  54       return -1;
  55     }
  56 
  57   return mknodat (fd, file, mode, dev);
  58 }
  59 
  60 #else
  61 
  62 # if !HAVE_MKNOD
  63 
  64 #  include <errno.h>
  65 
  66 /* Mingw lacks mknod, so this wrapper is trivial.  */
  67 
  68 int
  69 mknodat (_GL_UNUSED int fd, _GL_UNUSED char const *path,
     /* [previous][next][first][last][top][bottom][index][help] */
  70          _GL_UNUSED mode_t mode, _GL_UNUSED dev_t dev)
  71 {
  72   errno = ENOSYS;
  73   return -1;
  74 }
  75 
  76 # else
  77 
  78 /* Create a file system node FILE relative to directory FD, with
  79    access permissions and file type in MODE, and device type in DEV.
  80    Usually, non-root applications can only create named fifos, with
  81    DEV set to 0.  If possible, create the node without changing the
  82    working directory.  Otherwise, resort to using save_cwd/fchdir,
  83    then mknod/restore_cwd.  If either the save_cwd or the restore_cwd
  84    fails, then give a diagnostic and exit nonzero.  */
  85 
  86 #  define AT_FUNC_NAME mknodat
  87 #  define AT_FUNC_F1 mknod
  88 #  define AT_FUNC_POST_FILE_PARAM_DECLS , mode_t mode, dev_t dev
  89 #  define AT_FUNC_POST_FILE_ARGS        , mode, dev
  90 #  include "at-func.c"
  91 #  undef AT_FUNC_NAME
  92 #  undef AT_FUNC_F1
  93 #  undef AT_FUNC_POST_FILE_PARAM_DECLS
  94 #  undef AT_FUNC_POST_FILE_ARGS
  95 
  96 # endif
  97 
  98 #endif

/* [previous][next][first][last][top][bottom][index][help] */