mkfifoat: new module
[gnulib.git] / lib / mkfifoat.c
1 /* Create a named fifo relative to an open directory.
2    Copyright (C) 2009 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 <http://www.gnu.org/licenses/>.  */
16
17 /* written by Eric Blake */
18
19 #include <config.h>
20
21 #include <sys/stat.h>
22
23 #include "dirname.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */
24 #include "openat.h"
25 #include "openat-priv.h"
26 #include "save-cwd.h"
27
28 #ifndef HAVE_MKFIFO
29 # define HAVE_MKFIFO 0
30 #endif
31 #ifndef HAVE_MKNOD
32 # define HAVE_MKNOD 0
33 #endif
34
35 /* For now, all known systems either have both mkfifo and mknod, or
36    neither.  If this is not true, we can implement the portable
37    aspects of one using the other (POSIX only requires mknod to create
38    fifos; all other uses of mknod are for root users and outside the
39    realm of POSIX).  */
40 #if HAVE_MKNOD != HAVE_MKFIFO
41 # error Please report this message and your system to bug-gnulib@gnu.org.
42 #endif
43
44 #if !HAVE_MKFIFO
45 /* Mingw lacks mkfifo and mknod, so this wrapper is trivial.  */
46
47 # include <errno.h>
48
49 int
50 mkfifoat (int fd _UNUSED_PARAMETER_, char const *path _UNUSED_PARAMETER_,
51           mode_t mode _UNUSED_PARAMETER_)
52 {
53   errno = ENOSYS;
54   return -1;
55 }
56
57 int
58 mknodat (int fd _UNUSED_PARAMETER_, char const *path _UNUSED_PARAMETER_,
59          mode_t mode _UNUSED_PARAMETER_, dev_t dev _UNUSED_PARAMETER_)
60 {
61   errno = ENOSYS;
62   return -1;
63 }
64
65 #else /* HAVE_MKFIFO */
66
67 /* Create a named fifo FILE relative to directory FD, with access
68    permissions in MODE.  If possible, do it without changing the
69    working directory.  Otherwise, resort to using save_cwd/fchdir,
70    then mkfifo/restore_cwd.  If either the save_cwd or the restore_cwd
71    fails, then give a diagnostic and exit nonzero.  */
72
73 # define AT_FUNC_NAME mkfifoat
74 # define AT_FUNC_F1 mkfifo
75 # define AT_FUNC_POST_FILE_PARAM_DECLS , mode_t mode
76 # define AT_FUNC_POST_FILE_ARGS        , mode
77 # include "at-func.c"
78 # undef AT_FUNC_NAME
79 # undef AT_FUNC_F1
80 # undef AT_FUNC_POST_FILE_PARAM_DECLS
81 # undef AT_FUNC_POST_FILE_ARGS
82
83 /* Create a file system node FILE relative to directory FD, with
84    access permissions and file type in MODE, and device type in DEV.
85    Usually, non-root applications can only create named fifos, with
86    DEV set to 0.  If possible, create the node without changing the
87    working directory.  Otherwise, resort to using save_cwd/fchdir,
88    then mknod/restore_cwd.  If either the save_cwd or the restore_cwd
89    fails, then give a diagnostic and exit nonzero.  */
90
91 # define AT_FUNC_NAME mknodat
92 # define AT_FUNC_F1 mknod
93 # define AT_FUNC_POST_FILE_PARAM_DECLS , mode_t mode, dev_t dev
94 # define AT_FUNC_POST_FILE_ARGS        , mode, dev
95 # include "at-func.c"
96 # undef AT_FUNC_NAME
97 # undef AT_FUNC_F1
98 # undef AT_FUNC_POST_FILE_PARAM_DECLS
99 # undef AT_FUNC_POST_FILE_ARGS
100
101 #endif /* HAVE_MKFIFO */