mirror of
https://sourceware.org/git/glibc.git
synced 2025-01-03 00:10:10 +00:00
* io/Makefile (routines): Add mknodat, xmknodat, mkdirat, mkfifoat.
(static-only-routines): Add mknodat. * io/Versions [GLIBC_2.4]: Add mkdirat, mkfifoat, __xmknodat. * io/sys/stat.h: Declare mkditat, mknodat, mkfifoat, __xmknodat. Define mknodat inline function. * include/sys/stat.h: Add hidden proto for __xmknodat. * sysdeps/generic/mkdirat.c: New file. * sysdeps/generic/mkfifoat.c: New file. * sysdeps/generic/mknodat.c: New file. * sysdeps/generic/xmknodat.c: New file. * sysdeps/unix/mkfifoat.c: New file. * sysdeps/unix/sysv/linux/mkdirat.c: New file. * sysdeps/unix/sysv/linux/xmknodat.c: New file. * sysdeps/generic/xmknod.c: Add one more parameter check.
This commit is contained in:
parent
975407d507
commit
e186c703dc
18
ChangeLog
18
ChangeLog
@ -1,3 +1,21 @@
|
||||
2005-12-02 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* io/Makefile (routines): Add mknodat, xmknodat, mkdirat, mkfifoat.
|
||||
(static-only-routines): Add mknodat.
|
||||
* io/Versions [GLIBC_2.4]: Add mkdirat, mkfifoat, __xmknodat.
|
||||
* io/sys/stat.h: Declare mkditat, mknodat, mkfifoat, __xmknodat.
|
||||
Define mknodat inline function.
|
||||
* include/sys/stat.h: Add hidden proto for __xmknodat.
|
||||
* sysdeps/generic/mkdirat.c: New file.
|
||||
* sysdeps/generic/mkfifoat.c: New file.
|
||||
* sysdeps/generic/mknodat.c: New file.
|
||||
* sysdeps/generic/xmknodat.c: New file.
|
||||
* sysdeps/unix/mkfifoat.c: New file.
|
||||
* sysdeps/unix/sysv/linux/mkdirat.c: New file.
|
||||
* sysdeps/unix/sysv/linux/xmknodat.c: New file.
|
||||
|
||||
* sysdeps/generic/xmknod.c: Add one more parameter check.
|
||||
|
||||
2005-11-28 Andreas Jaeger <aj@suse.de>
|
||||
|
||||
* sysdeps/unix/sysv/linux/mips/bits/mman.h (MREMAP_FIXED): Added,
|
||||
|
4
NEWS
4
NEWS
@ -1,4 +1,4 @@
|
||||
GNU C Library NEWS -- history of user-visible changes. 2005-11-11
|
||||
GNU C Library NEWS -- history of user-visible changes. 2005-12-02
|
||||
Copyright (C) 1992-2002,2003,2004,2005 Free Software Foundation, Inc.
|
||||
See the end for copying conditions.
|
||||
|
||||
@ -28,7 +28,7 @@ Version 2.4
|
||||
recommend using the stable 2.3 branch.
|
||||
|
||||
* New interfaces: fdopendir, openat, fstatat, fchownat, futimesat, renameat,
|
||||
unlinkat.
|
||||
unlinkat, mkdirat, mkfifoat, mknodat.
|
||||
|
||||
Version 2.3.6
|
||||
|
||||
|
@ -29,6 +29,7 @@ extern __inline__ int __mknod (__const char *__path, __mode_t __mode,
|
||||
{
|
||||
return __xmknod (_MKNOD_VER, __path, __mode, &__dev);
|
||||
}
|
||||
libc_hidden_proto (__xmknodat)
|
||||
|
||||
|
||||
/* The `stat', `fstat', `lstat' functions have to be handled special since
|
||||
|
13
io/Makefile
13
io/Makefile
@ -28,13 +28,14 @@ headers := sys/stat.h bits/stat.h sys/statfs.h bits/statfs.h sys/vfs.h \
|
||||
|
||||
routines := \
|
||||
utime \
|
||||
mkfifo \
|
||||
stat fstat lstat mknod stat64 fstat64 lstat64 fstatat fstatat64 \
|
||||
xstat fxstat lxstat xmknod xstat64 fxstat64 lxstat64 \
|
||||
mkfifo mkfifoat \
|
||||
stat fstat lstat stat64 fstat64 lstat64 fstatat fstatat64 \
|
||||
xstat fxstat lxstat xstat64 fxstat64 lxstat64 \
|
||||
mknod mknodat xmknod xmknodat \
|
||||
fxstatat fxstatat64 \
|
||||
statfs fstatfs statfs64 fstatfs64 \
|
||||
statvfs fstatvfs statvfs64 fstatvfs64 \
|
||||
umask chmod fchmod lchmod mkdir \
|
||||
umask chmod fchmod lchmod mkdir mkdirat \
|
||||
open open64 openat openat64 close \
|
||||
read write lseek lseek64 access euidaccess \
|
||||
fcntl flock lockf lockf64 \
|
||||
@ -54,8 +55,8 @@ routines := \
|
||||
# These routines will be omitted from the libc shared object.
|
||||
# Instead the static object files will be included in a special archive
|
||||
# linked against when the shared library will be used.
|
||||
static-only-routines = stat fstat lstat mknod stat64 fstat64 lstat64 \
|
||||
fstatat fstatat64
|
||||
static-only-routines = stat fstat lstat stat64 fstat64 lstat64 \
|
||||
fstatat fstatat64 mknod mknodat
|
||||
|
||||
others := pwd
|
||||
test-srcs := ftwtest
|
||||
|
@ -100,6 +100,7 @@ libc {
|
||||
GLIBC_2.4 {
|
||||
fchownat;
|
||||
__fxstatat; __fxstatat64;
|
||||
mkdirat; mkfifoat; __xmknodat;
|
||||
openat; openat64;
|
||||
unlinkat;
|
||||
}
|
||||
|
@ -305,6 +305,14 @@ extern __mode_t getumask (void) __THROW;
|
||||
extern int mkdir (__const char *__path, __mode_t __mode)
|
||||
__THROW __nonnull ((1));
|
||||
|
||||
#ifdef __USE_GNU
|
||||
/* Like mkdir, create a new directory with permission bits MODE. But
|
||||
interpret relative PATH names relative to the directory associated
|
||||
with FD. */
|
||||
extern int mkdirat (int __fd, __const char *__path, __mode_t __mode)
|
||||
__THROW __nonnull ((2));
|
||||
#endif
|
||||
|
||||
/* Create a device file named PATH, with permission and special bits MODE
|
||||
and device number DEV (which can be constructed from major and minor
|
||||
device numbers with the `makedev' macro above). */
|
||||
@ -313,10 +321,26 @@ extern int mknod (__const char *__path, __mode_t __mode, __dev_t __dev)
|
||||
__THROW __nonnull ((1));
|
||||
#endif
|
||||
|
||||
#ifdef __USE_GNU
|
||||
/* Like mknod, create a new device file with permission bits MODE and
|
||||
device number DEV. But interpret relative PATH names relative to
|
||||
the directory associated with FD. */
|
||||
extern int mknodat (int __fd, __const char *__path, __mode_t __mode,
|
||||
__dev_t __dev) __THROW __nonnull ((2));
|
||||
#endif
|
||||
|
||||
|
||||
/* Create a new FIFO named PATH, with permission bits MODE. */
|
||||
extern int mkfifo (__const char *__path, __mode_t __mode)
|
||||
__THROW __nonnull ((1));
|
||||
|
||||
#ifdef __USE_GNU
|
||||
/* Like mkfifo, create a new FIFO with permission bits MODE. But
|
||||
interpret relative PATH names relative to the directory associated
|
||||
with FD. */
|
||||
extern int mkfifoat (int __fd, __const char *__path, __mode_t __mode)
|
||||
__THROW __nonnull ((2));
|
||||
#endif
|
||||
|
||||
/* To allow the `struct stat' structure and the file type `mode_t'
|
||||
bits to vary without changing shared library major version number,
|
||||
@ -388,6 +412,10 @@ extern int __fxstatat64 (int __ver, int __fildes, __const char *__filename,
|
||||
extern int __xmknod (int __ver, __const char *__path, __mode_t __mode,
|
||||
__dev_t *__dev) __THROW __nonnull ((2, 4));
|
||||
|
||||
extern int __xmknodat (int __ver, int __fd, __const char *__path,
|
||||
__mode_t __mode, __dev_t *__dev)
|
||||
__THROW __nonnull ((3, 5));
|
||||
|
||||
#if defined __GNUC__ && __GNUC__ >= 2
|
||||
/* Inlined versions of the real stat and mknod functions. */
|
||||
|
||||
@ -428,6 +456,15 @@ __NTH (mknod (__const char *__path, __mode_t __mode, __dev_t __dev))
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifdef __USE_GNU
|
||||
extern __inline__ int
|
||||
__NTH (mknodat (int __fd, __const char *__path, __mode_t __mode,
|
||||
__dev_t __dev))
|
||||
{
|
||||
return __xmknodat (_MKNOD_VER, __fd, __path, __mode, &__dev);
|
||||
}
|
||||
# endif
|
||||
|
||||
# if defined __USE_LARGEFILE64 \
|
||||
&& (! defined __USE_FILE_OFFSET64 \
|
||||
|| (defined __REDIRECT_NTH && defined __OPTIMIZE__))
|
||||
|
58
sysdeps/generic/mkdirat.c
Normal file
58
sysdeps/generic/mkdirat.c
Normal file
@ -0,0 +1,58 @@
|
||||
/* Copyright (C) 1991, 1995, 1996, 1997, 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stddef.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
|
||||
/* Create a directory named PATH relative to FD with protections MODE. */
|
||||
int
|
||||
mkdirat (fd, path, mode)
|
||||
int fd;
|
||||
const char *path;
|
||||
mode_t mode;
|
||||
{
|
||||
if (path == NULL)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fd != AT_FDCWD && path[0] != '/')
|
||||
{
|
||||
/* Check FD is associated with a directory. */
|
||||
struct stat64 st;
|
||||
if (__fxstat64 (_STAT_VER, fd, &st) != 0)
|
||||
return -1;
|
||||
|
||||
if (!S_ISDIR (st.st_mode))
|
||||
{
|
||||
__set_errno (ENOTDIR);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
__set_errno (ENOSYS);
|
||||
return -1;
|
||||
}
|
||||
stub_warning (mkdirat)
|
||||
|
||||
#include <stub-tag.h>
|
60
sysdeps/generic/mkfifoat.c
Normal file
60
sysdeps/generic/mkfifoat.c
Normal file
@ -0,0 +1,60 @@
|
||||
/* Copyright (C) 1991, 1995, 1996, 1997, 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stddef.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
|
||||
/* Create a named pipe (FIFO) named PATH relative to FD with
|
||||
protections MODE. */
|
||||
int
|
||||
mkfifoat (fd, path, mode)
|
||||
int fd;
|
||||
const char *path;
|
||||
mode_t mode;
|
||||
{
|
||||
if (path == NULL)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fd != AT_FDCWD && path[0] != '/')
|
||||
{
|
||||
/* Check FD is associated with a directory. */
|
||||
struct stat64 st;
|
||||
if (__fxstat64 (_STAT_VER, fd, &st) != 0)
|
||||
return -1;
|
||||
|
||||
if (!S_ISDIR (st.st_mode))
|
||||
{
|
||||
__set_errno (ENOTDIR);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
__set_errno (ENOSYS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
stub_warning (mkfifoat)
|
||||
#include <stub-tag.h>
|
60
sysdeps/generic/mknodat.c
Normal file
60
sysdeps/generic/mknodat.c
Normal file
@ -0,0 +1,60 @@
|
||||
/* Copyright (C) 1995, 1996, 2001, 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
In addition to the permissions in the GNU Lesser General Public
|
||||
License, the Free Software Foundation gives you unlimited
|
||||
permission to link the compiled version of this file with other
|
||||
programs, and to distribute those programs without any restriction
|
||||
coming from the use of this file. (The GNU Lesser General Public
|
||||
License restrictions do apply in other respects; for example, they
|
||||
cover modification of the file, and distribution when not linked
|
||||
into another program.)
|
||||
|
||||
Note that people who make modified versions of this file are not
|
||||
obligated to grant this special exception for their modified
|
||||
versions; it is their choice whether to do so. The GNU Lesser
|
||||
General Public License gives permission to release a modified
|
||||
version without this exception; this exception also makes it
|
||||
possible to release a modified version which carries forward this
|
||||
exception.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* This definition is only used if inlining fails for this function; see
|
||||
the last page of <sys/stat.h>. The real work is done by the `x'
|
||||
function which is passed a version number argument. We arrange in the
|
||||
makefile that when not inlined this function is always statically
|
||||
linked; that way a dynamically-linked executable always encodes the
|
||||
version number corresponding to the data structures it uses, so the `x'
|
||||
functions in the shared library can adapt without needing to recompile
|
||||
all callers. */
|
||||
|
||||
int
|
||||
mknodat (int fd, const char *path, mode_t mode, dev_t dev)
|
||||
{
|
||||
return __xmknodat (_MKNOD_VER, fd, path, mode, &dev);
|
||||
}
|
||||
|
||||
|
||||
/* Hide the symbol so that no definition but the one locally in the
|
||||
executable or DSO is used. */
|
||||
#ifdef HAVE_DOT_HIDDEN
|
||||
asm (".hidden\tmknodat");
|
||||
#endif
|
63
sysdeps/generic/xmknodat.c
Normal file
63
sysdeps/generic/xmknodat.c
Normal file
@ -0,0 +1,63 @@
|
||||
/* Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* Create a device file named PATH relative to FD, with permission and
|
||||
special bits MODE and device number DEV (which can be constructed
|
||||
from major and minor device numbers with the `makedev' macro
|
||||
above). */
|
||||
int
|
||||
__xmknodat (int vers, int fd, const char *path, mode_t mode, dev_t *dev)
|
||||
{
|
||||
if (vers != _MKNOD_VER)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (path == NULL)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fd != AT_FDCWD && path[0] != '/')
|
||||
{
|
||||
/* Check FD is associated with a directory. */
|
||||
struct stat64 st;
|
||||
if (__fxstat64 (_STAT_VER, fd, &st) != 0)
|
||||
return -1;
|
||||
|
||||
if (!S_ISDIR (st.st_mode))
|
||||
{
|
||||
__set_errno (ENOTDIR);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
__set_errno (ENOSYS);
|
||||
return -1;
|
||||
}
|
||||
stub_warning (__xmknodat)
|
||||
|
||||
libc_hidden_def (__xmknodat)
|
||||
#include <stub-tag.h>
|
32
sysdeps/unix/mkfifoat.c
Normal file
32
sysdeps/unix/mkfifoat.c
Normal file
@ -0,0 +1,32 @@
|
||||
/* Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
||||
/* Create a new FIFO with permission bits MODE. But interpret
|
||||
relative PATH names relative to the directory associated with FD. */
|
||||
int
|
||||
mkfifoat (fd, file, mode)
|
||||
int fd;
|
||||
const char *file;
|
||||
mode_t mode;
|
||||
{
|
||||
dev_t dev = 0;
|
||||
return __xmknodat (_MKNOD_VER, fd, file, mode | S_IFIFO, &dev);
|
||||
}
|
66
sysdeps/unix/sysv/linux/mkdirat.c
Normal file
66
sysdeps/unix/sysv/linux/mkdirat.c
Normal file
@ -0,0 +1,66 @@
|
||||
/* Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sysdep-cancel.h>
|
||||
|
||||
|
||||
/* Create a new directory with permission bits MODE. But interpret
|
||||
relative PATH names relative to the directory associated with FD. */
|
||||
int
|
||||
mkdirat (fd, file, mode)
|
||||
int fd;
|
||||
const char *file;
|
||||
mode_t mode;
|
||||
{
|
||||
char *buf = NULL;
|
||||
|
||||
if (fd != AT_FDCWD && file[0] != '/')
|
||||
{
|
||||
size_t filelen = strlen (file);
|
||||
static const char procfd[] = "/proc/self/fd/%d/%s";
|
||||
/* Buffer for the path name we are going to use. It consists of
|
||||
- the string /proc/self/fd/
|
||||
- the file descriptor number
|
||||
- the file name provided.
|
||||
The final NUL is included in the sizeof. A bit of overhead
|
||||
due to the format elements compensates for possible negative
|
||||
numbers. */
|
||||
size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
|
||||
buf = alloca (buflen);
|
||||
|
||||
__snprintf (buf, buflen, procfd, fd, file);
|
||||
file = buf;
|
||||
}
|
||||
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
int res = INTERNAL_SYSCALL (mkdir, err, 2, file, mode);
|
||||
|
||||
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (res, err), 0))
|
||||
{
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (res, err), fd, buf);
|
||||
res = -1;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
75
sysdeps/unix/sysv/linux/xmknodat.c
Normal file
75
sysdeps/unix/sysv/linux/xmknodat.c
Normal file
@ -0,0 +1,75 @@
|
||||
/* Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysmacros.h>
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <bp-checks.h>
|
||||
|
||||
/* Create a device file named PATH relative to FD, with permission and
|
||||
special bits MODE and device number DEV (which can be constructed
|
||||
from major and minor device numbers with the `makedev' macro above). */
|
||||
int
|
||||
__xmknodat (int vers, int fd, const char *file, mode_t mode, dev_t *dev)
|
||||
{
|
||||
if (vers != _MKNOD_VER)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *buf = NULL;
|
||||
|
||||
if (fd != AT_FDCWD && file[0] != '/')
|
||||
{
|
||||
size_t filelen = strlen (file);
|
||||
static const char procfd[] = "/proc/self/fd/%d/%s";
|
||||
/* Buffer for the path name we are going to use. It consists of
|
||||
- the string /proc/self/fd/
|
||||
- the file descriptor number
|
||||
- the file name provided.
|
||||
The final NUL is included in the sizeof. A bit of overhead
|
||||
due to the format elements compensates for possible negative
|
||||
numbers. */
|
||||
size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
|
||||
buf = alloca (buflen);
|
||||
|
||||
__snprintf (buf, buflen, procfd, fd, file);
|
||||
file = buf;
|
||||
}
|
||||
|
||||
/* We must convert the value to dev_t type used by the kernel. */
|
||||
unsigned long long int k_dev = (*dev) & ((1ULL << 32) - 1);
|
||||
if (k_dev != *dev)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return INLINE_SYSCALL (mknod, 3, CHECK_STRING (file), mode,
|
||||
(unsigned int) k_dev);
|
||||
}
|
||||
|
||||
libc_hidden_def (__xmknodat)
|
Loading…
Reference in New Issue
Block a user