Add some more *at() system calls.
authorSascha Wildner <saw@online.de>
Fri, 6 Aug 2010 14:44:50 +0000 (16:44 +0200)
committerSascha Wildner <saw@online.de>
Fri, 6 Aug 2010 14:46:17 +0000 (16:46 +0200)
mkdirat(2), mkfifoat(2), mknodat(2), readlinkat(2), symlinkat(2)

Missing still (at least): linkat(2)

Documentation-changes-from: FreeBSD

17 files changed:
include/unistd.h
lib/libc/sys/Makefile.inc
lib/libc/sys/mkdir.2
lib/libc/sys/mkfifo.2
lib/libc/sys/mknod.2
lib/libc/sys/readlink.2
lib/libc/sys/symlink.2
sys/kern/init_sysent.c
sys/kern/syscalls.c
sys/kern/syscalls.master
sys/kern/vfs_syscalls.c
sys/sys/stat.h
sys/sys/syscall-hide.h
sys/sys/syscall.h
sys/sys/syscall.mk
sys/sys/sysproto.h
sys/sys/sysunion.h

index 8ad0c0f..16e7ba9 100644 (file)
@@ -315,15 +315,9 @@ __BEGIN_DECLS
 /* 1003.1-1990 */
 void    _exit(int) __dead2;
 int     access(const char *, int);
-#if __BSD_VISIBLE || __POSIX_VISIBLE >= 200809
-int     faccessat(int, const char *, int, int);
-#endif
 unsigned int    alarm(unsigned int);
 int     chdir(const char *);
 int     chown(const char *, uid_t, gid_t);
-#if __BSD_VISIBLE || __POSIX_VISIBLE >= 200809
-int     fchownat(int, const char *, uid_t, gid_t, int);
-#endif
 int     close(int);
 int     dup(int);
 int     dup2(int, int);
@@ -367,9 +361,6 @@ int  tcsetpgrp(int, pid_t);
 char   *ttyname(int);
 int     ttyname_r(int, char *, size_t);
 int     unlink(const char *);
-#if __BSD_VISIBLE || __POSIX_VISIBLE >= 200809
-int     unlinkat(int, const char *, int);
-#endif
 ssize_t         write(int, const void *, size_t);
 
 /* 1003.2-1992 */
@@ -429,18 +420,17 @@ int        truncate(const char *, off_t);
 #endif
 #endif /* __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE */
 
-/* XXX */
-#if 0
 #if __POSIX_VISIBLE >= 200809 || __BSD_VISIBLE
 int    faccessat(int, const char *, int, int);
 int    fchownat(int, const char *, uid_t, gid_t, int);
+#if 0
 int    fexecve(int, char *const [], char *const []);
 int    linkat(int, const char *, int, const char *, int);
+#endif
 ssize_t        readlinkat(int, const char * __restrict, char * __restrict, size_t);
 int    symlinkat(const char *, int, const char *);
 int    unlinkat(int, const char *, int);
 #endif /* __POSIX_VISIBLE >= 200809 || __BSD_VISIBLE */
-#endif
 
 /*
  * symlink() was originally in POSIX.1a, which was withdrawn after
index edd502f..11029b0 100644 (file)
@@ -134,12 +134,16 @@ MLINKS+=kqueue.2 EV_SET.2 \
 MLINKS+=lseek.2 seek.2
 MLINKS+=madvise.2 mcontrol.2 \
        madvise.2 posix_madvise.3
+MLINKS+=mkdir.2 mkdirat.2
+MLINKS+=mkfifo.2 mkfifoat.2
+MLINKS+=mknod.2 mknodat.2
 MLINKS+=mlock.2 munlock.2
 MLINKS+=modnext.2 modfnext.2
 MLINKS+=mount.2 unmount.2
 MLINKS+=open.2 openat.2
 MLINKS+=pathconf.2 fpathconf.2
 MLINKS+=read.2 pread.2 read.2 preadv.2 read.2 readv.2
+MLINKS+=readlink.2 readlinkat.2
 MLINKS+=recv.2 recvfrom.2 recv.2 recvmsg.2
 MLINKS+=rename.2 renameat.2
 MLINKS+=rtprio.2 lwp_rtprio.2
@@ -161,6 +165,7 @@ MLINKS+=shmat.2 shmdt.2
 MLINKS+=stat.2 fstat.2 stat.2 fstatat.2 stat.2 lstat.2
 MLINKS+=statfs.2 fstatfs.2
 MLINKS+=statvfs.2 fstatvfs.2
+MLINKS+=symlink.2 symlinkat.2
 MLINKS+=syscall.2 __syscall.2
 MLINKS+=tls.2 set_tls_area.2 tls.2 get_tls_area.2
 MLINKS+=truncate.2 ftruncate.2
index a6bdf60..769e0b6 100644 (file)
@@ -9,10 +9,6 @@
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)mkdir.2    8.2 (Berkeley) 12/11/93
-.\" $FreeBSD: src/lib/libc/sys/mkdir.2,v 1.9.2.6 2001/12/14 18:34:01 ru Exp $
-.\" $DragonFly: src/lib/libc/sys/mkdir.2,v 1.2 2003/06/17 04:26:47 dillon Exp $
+.\" $FreeBSD: src/lib/libc/sys/mkdir.2,v 1.28 2008/06/30 08:46:09 danger Exp $
 .\"
-.Dd December 11, 1993
+.Dd August 6, 2010
 .Dt MKDIR 2
 .Os
 .Sh NAME
-.Nm mkdir
+.Nm mkdir ,
+.Nm mkdirat
 .Nd make a directory file
 .Sh LIBRARY
 .Lb libc
 .Sh SYNOPSIS
-.In sys/types.h
 .In sys/stat.h
 .Ft int
 .Fn mkdir "const char *path" "mode_t mode"
+.Ft int
+.Fn mkdirat "int fd" "const char *path" "mode_t mode"
 .Sh DESCRIPTION
 The directory
 .Fa path
@@ -58,10 +55,33 @@ of the calling process.
 The directory's owner ID is set to the process's effective user ID.
 The directory's group ID is set to that of the parent directory in
 which it is created.
+.Pp
+The
+.Fn mkdirat
+system call is equivalent to
+.Fn mkdir
+except in the case where
+.Fa path
+specifies a relative path.
+In this case the newly created directory is created relative to the
+directory associated with the file descriptor
+.Fa fd
+instead of the current working directory.
+If
+.Fn mkdirat
+is passed the special value
+.Dv AT_FDCWD
+in the
+.Fa fd
+parameter, the current working directory is used and the behavior is
+identical to a call to
+.Fn mkdir .
 .Sh RETURN VALUES
 .Rv -std mkdir
 .Sh ERRORS
-.Fn Mkdir
+The
+.Fn mkdir
+system call
 will fail and no directory will be created if:
 .Bl -tag -width Er
 .It Bq Er ENOTDIR
@@ -77,8 +97,16 @@ or write permission is denied
 on the parent directory of the directory to be created.
 .It Bq Er ELOOP
 Too many symbolic links were encountered in translating the pathname.
+.It Bq Er EPERM
+The parent directory of the directory to be created has its immutable flag set,
+see the
+.Xr chflags 2
+manual page for more information.
 .It Bq Er EROFS
-The named file resides on a read-only file system.
+The named directory would reside on a read-only file system.
+.It Bq Er EMLINK
+The new directory cannot be created because the parent directory contains
+too many subdirectories.
 .It Bq Er EEXIST
 The named file exists.
 .It Bq Er ENOSPC
@@ -99,15 +127,50 @@ An I/O error occurred while making the directory entry or allocating the inode.
 .It Bq Er EIO
 An I/O error occurred while reading from or writing to the file system.
 .It Bq Er EFAULT
-.Fa Path
+The
+.Fa path
+argument
 points outside the process's allocated address space.
 .El
+.Pp
+In addition to the errors returned by the
+.Fn mkdir ,
+the
+.Fn mkdirat
+may fail if:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Fa path
+argument does not specify an absolute path and the
+.Fa fd
+argument is neither
+.Dv AT_FDCWD
+nor a valid file descriptor open for searching.
+.It Bq Er ENOTDIR
+The
+.Fa path
+argument is not an absolute path and
+.Fa fd
+is neither
+.Dv AT_FDCWD
+nor a file descriptor associated with a directory.
+.El
 .Sh SEE ALSO
+.Xr chflags 2 ,
 .Xr chmod 2 ,
 .Xr stat 2 ,
 .Xr umask 2
 .Sh STANDARDS
 The
 .Fn mkdir
-function call is expected to conform to
+system call is expected to conform to
 .St -p1003.1-90 .
+The
+.Fn mkdirat
+system call follows The Open Group Extended API Set 2 specification.
+.Sh HISTORY
+The
+.Fn mkdirat
+system call appeared in
+.Dx 2.7 .
index 8eedecb..5ad58d6 100644 (file)
@@ -9,10 +9,6 @@
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
 .\" SUCH DAMAGE.
 .\"
 .\"    @(#)mkfifo.2    8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/sys/mkfifo.2,v 1.9.2.6 2001/12/14 18:34:01 ru Exp $
-.\" $DragonFly: src/lib/libc/sys/mkfifo.2,v 1.2 2003/06/17 04:26:47 dillon Exp $
+.\" $FreeBSD: src/lib/libc/sys/mkfifo.2,v 1.23 2008/04/16 13:03:12 kib Exp $
 .\"
-.Dd June 4, 1993
+.Dd August 6, 2010
 .Dt MKFIFO 2
 .Os
 .Sh NAME
-.Nm mkfifo
+.Nm mkfifo ,
+.Nm mkfifoat
 .Nd make a fifo file
 .Sh LIBRARY
 .Lb libc
 .Sh SYNOPSIS
-.In sys/types.h
 .In sys/stat.h
 .Ft int
 .Fn mkfifo "const char *path" "mode_t mode"
+.Ft int
+.Fn mkfifoat "int fd" "const char *path" "mode_t mode"
 .Sh DESCRIPTION
-.Fn Mkfifo
+The
+.Fn mkfifo
+system call
 creates a new fifo file with name
 .Fa path .
 The access permissions are
@@ -60,10 +59,33 @@ of the calling process.
 The fifo's owner ID is set to the process's effective user ID.
 The fifo's group ID is set to that of the parent directory in
 which it is created.
+.Pp
+The
+.Fn mkfifoat
+system call is equivalent to
+.Fn mkfifo
+except in the case where
+.Fa path
+specifies a relative path.
+In this case the newly created FIFO is created relative to the
+directory associated with the file descriptor
+.Fa fd
+instead of the current working directory.
+If
+.Fn mkfifoat
+is passed the special value
+.Dv AT_FDCWD
+in the
+.Fa fd
+parameter, the current working directory is used and the behavior is
+identical to a call to
+.Fn mkfifo .
 .Sh RETURN VALUES
 .Rv -std mkfifo
 .Sh ERRORS
-.Fn Mkfifo
+The
+.Fn mkfifo
+system call
 will fail and no fifo will be created if:
 .Bl -tag -width Er
 .It Bq Er ENOTSUP
@@ -76,13 +98,18 @@ or an entire path name exceeded 1023 characters.
 .It Bq Er ENOENT
 A component of the path prefix does not exist.
 .It Bq Er EACCES
-Search permission is denied for a component of the path prefix.
+A component of the path prefix denies search permission, or write permission
+is denied on the parent directory of the fifo to be created.
 .It Bq Er ELOOP
 Too many symbolic links were encountered in translating the pathname.
 .It Bq Er EROFS
-The named file resides on a read-only file system.
+The named file would reside on a read-only file system.
 .It Bq Er EEXIST
 The named file exists.
+.It Bq Er EPERM
+The parent directory of the named file has its immutable flag set, see the
+.Xr chflags 2
+manual page for more information.
 .It Bq Er ENOSPC
 The directory in which the entry for the new fifo is being placed
 cannot be extended because there is no space left on the file
@@ -107,10 +134,37 @@ An
 .Tn I/O
 error occurred while reading from or writing to the file system.
 .It Bq Er EFAULT
-.Fa Path
+The
+.Fa path
+argument
 points outside the process's allocated address space.
 .El
+.Pp
+In addition to the errors returned by the
+.Fn mkfifo ,
+the
+.Fn mkfifoat
+may fail if:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Fa path
+argument does not specify an absolute path and the
+.Fa fd
+argument is neither
+.Dv AT_FDCWD
+nor a valid file descriptor open for searching.
+.It Bq Er ENOTDIR
+The
+.Fa path
+argument is not an absolute path and
+.Fa fd
+is neither
+.Dv AT_FDCWD
+nor a file descriptor associated with a directory.
+.El
 .Sh SEE ALSO
+.Xr chflags 2 ,
 .Xr chmod 2 ,
 .Xr mknod 2 ,
 .Xr stat 2 ,
@@ -118,5 +172,13 @@ points outside the process's allocated address space.
 .Sh STANDARDS
 The
 .Fn mkfifo
-function call is expected to conform to
+system call is expected to conform to
 .St -p1003.1-90 .
+The
+.Fn mkfifoat
+system call follows The Open Group Extended API Set 2 specification.
+.Sh HISTORY
+The
+.Fn mkfifoat
+system call appeared in
+.Dx 2.7 .
index fd0b241..b7eff3d 100644 (file)
@@ -9,10 +9,6 @@
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)mknod.2    8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/sys/mknod.2,v 1.9.2.3 2001/12/14 18:34:01 ru Exp $
-.\" $DragonFly: src/lib/libc/sys/mknod.2,v 1.2 2003/06/17 04:26:47 dillon Exp $
+.\" $FreeBSD: src/lib/libc/sys/mknod.2,v 1.18 2008/04/16 13:03:12 kib Exp $
 .\"
-.Dd August 9, 2009
+.Dd August 6, 2010
 .Dt MKNOD 2
 .Os
 .Sh NAME
-.Nm mknod
+.Nm mknod ,
+.Nm mknodat
 .Nd make a special file node
 .Sh LIBRARY
 .Lb libc
 .In sys/stat.h
 .Ft int
 .Fn mknod "const char *path" "mode_t mode" "dev_t dev"
+.Ft int
+.Fn mknodat "int fd" "const char *path" "mode_t mode" "dev_t dev"
 .Sh DESCRIPTION
-The filesystem node
+The file system node
 .Fa path
 is created with the file type and access permissions specified in
 .Fa mode .
@@ -62,12 +60,37 @@ Otherwise,
 .Fa dev
 is ignored.
 .Pp
-.Fn Mknod
+The
+.Fn mknod
+system call
 requires super-user privileges.
+.Pp
+The
+.Fn mknodat
+system call is equivalent to
+.Fn mknod
+except in the case where
+.Fa path
+specifies a relative path.
+In this case the newly created device node is created relative to the
+directory associated with the file descriptor
+.Fa fd
+instead of the current working directory.
+If
+.Fn mknodat
+is passed the special value
+.Dv AT_FDCWD
+in the
+.Fa fd
+parameter, the current working directory is used and the behavior is
+identical to a call to
+.Fn mknod .
 .Sh RETURN VALUES
 .Rv -std mknod
 .Sh ERRORS
-.Fn Mknod
+The
+.Fn mknod
+system call
 will fail and the file will be not created if:
 .Bl -tag -width Er
 .It Bq Er ENOTDIR
@@ -105,7 +128,9 @@ The named file resides on a read-only file system.
 .It Bq Er EEXIST
 The named file exists.
 .It Bq Er EFAULT
-.Fa Path
+The
+.Fa path
+argument
 points outside the process's allocated address space.
 .It Bq Er EINVAL
 Creating anything else than a block or character special
@@ -113,13 +138,45 @@ file (or a
 .Em whiteout )
 is not supported.
 .El
+.Pp
+In addition to the errors returned by the
+.Fn mknod ,
+the
+.Fn mknodat
+may fail if:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Fa path
+argument does not specify an absolute path and the
+.Fa fd
+argument is neither
+.Dv AT_FDCWD
+nor a valid file descriptor open for searching.
+.It Bq Er ENOTDIR
+The
+.Fa path
+argument is not an absolute path and
+.Fa fd
+is neither
+.Dv AT_FDCWD
+nor a file descriptor associated with a directory.
+.El
 .Sh SEE ALSO
 .Xr chmod 2 ,
 .Xr mkfifo 2 ,
 .Xr stat 2 ,
 .Xr umask 2
+.Sh STANDARDS
+The
+.Fn mknodat
+system call follows The Open Group Extended API Set 2 specification.
 .Sh HISTORY
-A
+The
 .Fn mknod
-function call appeared in
+function appeared in
 .At v6 .
+The
+.Fn mknodat
+system call appeared in
+.Dx 2.7 .
index 5bb151c..05df815 100644 (file)
@@ -9,10 +9,6 @@
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)readlink.2 8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/sys/readlink.2,v 1.7.2.4 2001/12/14 18:34:01 ru Exp $
-.\" $DragonFly: src/lib/libc/sys/readlink.2,v 1.2 2003/06/17 04:26:47 dillon Exp $
+.\" $FreeBSD: src/lib/libc/sys/readlink.2,v 1.17 2008/04/16 13:03:12 kib Exp $
 .\"
-.Dd June 4, 1993
+.Dd August 6, 2010
 .Dt READLINK 2
 .Os
 .Sh NAME
-.Nm readlink
+.Nm readlink ,
+.Nm readlinkat
 .Nd read value of a symbolic link
 .Sh LIBRARY
 .Lb libc
 .In unistd.h
 .Ft int
 .Fn readlink "const char *path" "char *buf" "int bufsiz"
+.Ft ssize_t
+.Fn readlinkat "int fd" "const char *restrict path" "char *restrict buf" "size_t bufsize"
 .Sh DESCRIPTION
-.Fn Readlink
+The
+.Fn readlink
+system call
 places the contents of the symbolic link
 .Fa path
 in the buffer
@@ -55,17 +55,40 @@ which has size
 .Fa bufsiz .
 The
 .Fn readlink
-function does not append a
+system call does not append a
 .Dv NUL
 character to
 .Fa buf .
+.Pp
+The
+.Fn readlinkat
+system call is equivalent to
+.Fn readlink
+except in the case where
+.Fa path
+specifies a relative path.
+In this case the symbolic link whose content is read relative to the
+directory associated with the file descriptor
+.Fa fd
+instead of the current working directory.
+If
+.Fn readlinkat
+is passed the special value
+.Dv AT_FDCWD
+in the
+.Fa fd
+parameter, the current working directory is used and the behavior is
+identical to a call to
+.Fn readlink .
 .Sh RETURN VALUES
-The call returns the count of characters placed in the buffer
-if it succeeds, or a -1 if an error occurs, placing the error
+The calls return the count of characters placed in the buffer
+if it succeeds, or a \-1 if an error occurs, placing the error
 code in the global variable
 .Va errno .
 .Sh ERRORS
-.Fn Readlink
+The
+.Fn readlink
+system call
 will fail if:
 .Bl -tag -width Er
 .It Bq Er ENOTDIR
@@ -84,16 +107,50 @@ The named file is not a symbolic link.
 .It Bq Er EIO
 An I/O error occurred while reading from the file system.
 .It Bq Er EFAULT
-.Fa Buf
+The
+.Fa buf
+argument
 extends outside the process's allocated address space.
 .El
+.Pp
+In addition to the errors returned by the
+.Fn readlink ,
+the
+.Fn readlinkat
+may fail if:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Fa path
+argument does not specify an absolute path and the
+.Fa fd
+argument is neither
+.Dv AT_FDCWD
+nor a valid file descriptor open for searching.
+.It Bq Er ENOTDIR
+The
+.Fa path
+argument is not an absolute path and
+.Fa fd
+is neither
+.Dv AT_FDCWD
+nor a file descriptor associated with a directory.
+.El
 .Sh SEE ALSO
 .Xr lstat 2 ,
 .Xr stat 2 ,
 .Xr symlink 2 ,
 .Xr symlink 7
+.Sh STANDARDS
+The
+.Fn readlinkat
+system call follows The Open Group Extended API Set 2 specification.
 .Sh HISTORY
 The
 .Fn readlink
-function call appeared in
+system call appeared in
 .Bx 4.2 .
+The
+.Fn readlinkat
+system call appeared in
+.Dx 2.7 .
index 7e779aa..9326d9e 100644 (file)
@@ -9,10 +9,6 @@
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)symlink.2  8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/sys/symlink.2,v 1.8.2.4 2001/12/14 18:34:01 ru Exp $
-.\" $DragonFly: src/lib/libc/sys/symlink.2,v 1.2 2003/06/17 04:26:47 dillon Exp $
+.\" $FreeBSD: src/lib/libc/sys/symlink.2,v 1.23 2008/04/16 13:03:12 kib Exp $
 .\"
-.Dd June 4, 1993
+.Dd August 6, 2010
 .Dt SYMLINK 2
 .Os
 .Sh NAME
-.Nm symlink
+.Nm symlink ,
+.Nm symlinkat
 .Nd make symbolic link to a file
 .Sh LIBRARY
 .Lb libc
 .In unistd.h
 .Ft int
 .Fn symlink "const char *name1" "const char *name2"
+.Ft int
+.Fn symlinkat "const char *name1" "int fd" "const char *name2"
 .Sh DESCRIPTION
 A symbolic link
 .Fa name2
 is created to
 .Fa name1
-.Pf ( Fa name2
+.Fa ( name2
 is the name of the
 file created,
 .Fa name1
@@ -58,6 +56,27 @@ is the string
 used in creating the symbolic link).
 Either name may be an arbitrary path name; the files need not
 be on the same file system.
+.Pp
+The
+.Fn symlinkat
+system call is equivalent to
+.Fn symlink
+except in the case where
+.Fa name2
+specifies a relative path.
+In this case the symbolic link is created relative to the directory
+associated with the file descriptor
+.Fa fd
+instead of the current working directory.
+If
+.Fn symlinkat
+is passed the special value
+.Dv AT_FDCWD
+in the
+.Fa fd
+parameter, the current working directory is used and the behavior is
+identical to a call to
+.Fn symlink .
 .Sh RETURN VALUES
 .Rv -std symlink
 .Sh ERRORS
@@ -66,21 +85,36 @@ The symbolic link succeeds unless:
 .It Bq Er ENOTDIR
 A component of the
 .Fa name2
-prefix is not a directory.
+path prefix is not a directory.
 .It Bq Er ENAMETOOLONG
-A component of either pathname exceeded 255 characters,
+A component of the
+.Fa name2
+pathname exceeded 255 characters,
 or the entire length of either path name exceeded 1023 characters.
 .It Bq Er ENOENT
-The named file does not exist.
+A component of the
+.Fa name2
+path prefix does not exist.
 .It Bq Er EACCES
 A component of the
 .Fa name2
-path prefix denies search permission.
+path prefix denies search permission, or write permission is denied on the
+parent directory of the file to be created.
 .It Bq Er ELOOP
-Too many symbolic links were encountered in translating the pathname.
+Too many symbolic links were encountered in translating the
+.Fa name2
+path name.
 .It Bq Er EEXIST
-.Fa Name2
+The path name pointed at by the
+.Fa name2
+argument
 already exists.
+.It Bq Er EPERM
+The parent directory of the file named by
+.Fa name2
+has its immutable flag set, see the
+.Xr chflags 2
+manual page for more information.
 .It Bq Er EIO
 An I/O error occurred while making the directory entry for
 .Fa name2 ,
@@ -118,20 +152,55 @@ which the symbolic link is being created has been exhausted.
 .It Bq Er EIO
 An I/O error occurred while making the directory entry or allocating the inode.
 .It Bq Er EFAULT
-.Fa Name1
+The
+.Fa name1
 or
 .Fa name2
+argument
 points outside the process's allocated address space.
 .El
+.Pp
+In addition to the errors returned by the
+.Fn symlink ,
+the
+.Fn symlinkat
+may fail if:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Fa name2
+argument does not specify an absolute path and the
+.Fa fd
+argument is neither
+.Dv AT_FDCWD
+nor a valid file descriptor open for searching.
+.It Bq Er ENOTDIR
+The
+.Fa name2
+argument is not an absolute path and
+.Fa fd
+is neither
+.Dv AT_FDCWD
+nor a file descriptor associated with a directory.
+.El
 .Sh SEE ALSO
 .Xr ln 1 ,
+.Xr chflags 2 ,
 .Xr link 2 ,
 .Xr lstat 2 ,
 .Xr readlink 2 ,
 .Xr unlink 2 ,
 .Xr symlink 7
+.Sh STANDARDS
+The
+.Fn symlinkat
+system call follows The Open Group Extended API Set 2 specification.
 .Sh HISTORY
 The
 .Fn symlink
-function call appeared in
+system call appeared in
 .Bx 4.2 .
+The
+.Fn symlinkat
+system call appeared in
+.Dx 2.7 .
index 71b3d7b..5d31291 100644 (file)
@@ -557,4 +557,9 @@ struct sysent sysent[] = {
        { AS(ioprio_get_args), (sy_call_t *)sys_ioprio_get },   /* 521 = ioprio_get */
        { AS(chroot_kernel_args), (sy_call_t *)sys_chroot_kernel },     /* 522 = chroot_kernel */
        { AS(renameat_args), (sy_call_t *)sys_renameat },       /* 523 = renameat */
+       { AS(mkdirat_args), (sy_call_t *)sys_mkdirat }, /* 524 = mkdirat */
+       { AS(mkfifoat_args), (sy_call_t *)sys_mkfifoat },       /* 525 = mkfifoat */
+       { AS(mknodat_args), (sy_call_t *)sys_mknodat }, /* 526 = mknodat */
+       { AS(readlinkat_args), (sy_call_t *)sys_readlinkat },   /* 527 = readlinkat */
+       { AS(symlinkat_args), (sy_call_t *)sys_symlinkat },     /* 528 = symlinkat */
 };
index 22eddad..600ce1d 100644 (file)
@@ -531,4 +531,9 @@ const char *syscallnames[] = {
        "ioprio_get",                   /* 521 = ioprio_get */
        "chroot_kernel",                        /* 522 = chroot_kernel */
        "renameat",                     /* 523 = renameat */
+       "mkdirat",                      /* 524 = mkdirat */
+       "mkfifoat",                     /* 525 = mkfifoat */
+       "mknodat",                      /* 526 = mknodat */
+       "readlinkat",                   /* 527 = readlinkat */
+       "symlinkat",                    /* 528 = symlinkat */
 };
index 1c2fca5..0bcc1f3 100644 (file)
 522    STD     BSD     { int chroot_kernel(char *path); }
 523    STD     POSIX   { int renameat(int oldfd, char *old, int newfd, \
                                  char *new); }
+524    STD     POSIX   { int mkdirat(int fd, char *path, mode_t mode); }
+525    STD     POSIX   { int mkfifoat(int fd, char *path, mode_t mode); }
+526    STD     POSIX   { int mknodat(int fd, char *path, mode_t mode, \
+                                 dev_t dev); }
+527    STD     POSIX   { int readlinkat(int fd, char *path, char *buf, \
+                                 size_t bufsize); }
+528    STD     POSIX   { int symlinkat(char *path1, int fd, char *path2); }
index b7c0fd5..47dfb5d 100644 (file)
@@ -2108,6 +2108,32 @@ sys_mknod(struct mknod_args *uap)
        return (error);
 }
 
+/*
+ * mknodat_args(int fd, char *path, mode_t mode, dev_t dev)
+ *
+ * Create a special file.  The path is relative to the directory associated
+ * with fd.
+ *
+ * MPALMOSTSAFE
+ */
+int
+sys_mknodat(struct mknodat_args *uap)
+{
+       struct nlookupdata nd;
+       struct file *fp;
+       int error;
+
+       get_mplock();
+       error = nlookup_init_at(&nd, &fp, uap->fd, uap->path, UIO_USERSPACE, 0);
+       if (error == 0) {
+               error = kern_mknod(&nd, uap->mode,
+                                  umajor(uap->dev), uminor(uap->dev));
+       }
+       nlookup_done_at(&nd, fp);
+       rel_mplock();
+       return (error);
+}
+
 int
 kern_mkfifo(struct nlookupdata *nd, int mode)
 {
@@ -2159,6 +2185,30 @@ sys_mkfifo(struct mkfifo_args *uap)
        return (error);
 }
 
+/*
+ * mkfifoat_args(int fd, char *path, mode_t mode)
+ *
+ * Create a named pipe.  The path is relative to the directory associated
+ * with fd.
+ *
+ * MPALMOSTSAFE
+ */
+int
+sys_mkfifoat(struct mkfifoat_args *uap)
+{
+       struct nlookupdata nd;
+       struct file *fp;
+       int error;
+
+       get_mplock();
+       error = nlookup_init_at(&nd, &fp, uap->fd, uap->path, UIO_USERSPACE, 0);
+       if (error == 0)
+               error = kern_mkfifo(&nd, uap->mode);
+       nlookup_done_at(&nd, fp);
+       rel_mplock();
+       return (error);
+}
+
 static int hardlink_check_uid = 0;
 SYSCTL_INT(_security, OID_AUTO, hardlink_check_uid, CTLFLAG_RW,
     &hardlink_check_uid, 0, 
@@ -2358,6 +2408,41 @@ sys_symlink(struct symlink_args *uap)
 }
 
 /*
+ * symlinkat_args(char *path1, int fd, char *path2)
+ *
+ * Make a symbolic link.  The path2 argument is relative to the directory
+ * associated with fd.
+ *
+ * MPALMOSTSAFE
+ */
+int
+sys_symlinkat(struct symlinkat_args *uap)
+{
+       struct thread *td = curthread;
+       struct nlookupdata nd;
+       struct file *fp;
+       char *path1;
+       int error;
+       int mode;
+
+       path1 = objcache_get(namei_oc, M_WAITOK);
+       error = copyinstr(uap->path1, path1, MAXPATHLEN, NULL);
+       if (error == 0) {
+               get_mplock();
+               error = nlookup_init_at(&nd, &fp, uap->fd, uap->path2,
+                   UIO_USERSPACE, 0);
+               if (error == 0) {
+                       mode = ACCESSPERMS & ~td->td_proc->p_fd->fd_cmask;
+                       error = kern_symlink(&nd, path1, mode);
+               }
+               nlookup_done_at(&nd, fp);
+               rel_mplock();
+       }
+       objcache_put(namei_oc, path1);
+       return (error);
+}
+
+/*
  * undelete_args(char *path)
  *
  * Delete a whiteout from the filesystem.
@@ -2862,6 +2947,32 @@ sys_readlink(struct readlink_args *uap)
        return (error);
 }
 
+/*
+ * readlinkat_args(int fd, char *path, char *buf, size_t bufsize)
+ *
+ * Return target name of a symbolic link.  The path is relative to the
+ * directory associated with fd.
+ *
+ * MPALMOSTSAFE
+ */
+int
+sys_readlinkat(struct readlinkat_args *uap)
+{
+       struct nlookupdata nd;
+       struct file *fp;
+       int error;
+
+       get_mplock();
+       error = nlookup_init_at(&nd, &fp, uap->fd, uap->path, UIO_USERSPACE, 0);
+       if (error == 0) {
+               error = kern_readlink(&nd, uap->buf, uap->bufsize,
+                                       &uap->sysmsg_result);
+       }
+       nlookup_done_at(&nd, fp);
+       rel_mplock();
+       return (error);
+}
+
 static int
 setfflags(struct vnode *vp, int flags)
 {
@@ -3881,6 +3992,30 @@ sys_mkdir(struct mkdir_args *uap)
        return (error);
 }
 
+/*
+ * mkdirat_args(int fd, char *path, mode_t mode)
+ *
+ * Make a directory file.  The path is relative to the directory associated
+ * with fd.
+ *
+ * MPALMOSTSAFE
+ */
+int
+sys_mkdirat(struct mkdirat_args *uap)
+{
+       struct nlookupdata nd;
+       struct file *fp;
+       int error;
+
+       get_mplock();
+       error = nlookup_init_at(&nd, &fp, uap->fd, uap->path, UIO_USERSPACE, 0);
+       if (error == 0)
+               error = kern_mkdir(&nd, uap->mode);
+       nlookup_done_at(&nd, fp);
+       rel_mplock();
+       return (error);
+}
+
 int
 kern_rmdir(struct nlookupdata *nd)
 {
index 6c07fc8..306f55e 100644 (file)
@@ -217,9 +217,6 @@ int chmod (const char *, mode_t);
 int    fchmodat (int, const char *, mode_t, int);
 #endif
 int    fstat (int, struct stat *);
-#if __BSD_VISIBLE || __POSIX_VISIBLE >= 200809
-int    fstatat (int, const char *, struct stat *, int);
-#endif
 int    mkdir (const char *, mode_t);
 int    mkfifo (const char *, mode_t);
 #if !defined(_MKNOD_DECLARED) && __XSI_VISIBLE
@@ -228,6 +225,14 @@ int        mknod(const char *, mode_t, dev_t);
 #endif
 int    stat (const char *, struct stat *);
 mode_t umask (mode_t);
+#if __BSD_VISIBLE || __POSIX_VISIBLE >= 200809
+int    fstatat(int, const char *, struct stat *, int);
+int    mkdirat(int, const char *, mode_t);
+int    mkfifoat(int, const char *, mode_t);
+#endif
+#if __BSD_VISIBLE || __XSI_VISIBLE >= 700
+int    mknodat(int, const char *, mode_t, dev_t);
+#endif
 
 #ifndef _POSIX_SOURCE
 int    chflags (const char *, u_long);
index 0d7d32d..ecc96ab 100644 (file)
@@ -354,3 +354,8 @@ HIDE_BSD(ioprio_set)
 HIDE_BSD(ioprio_get)
 HIDE_BSD(chroot_kernel)
 HIDE_POSIX(renameat)
+HIDE_POSIX(mkdirat)
+HIDE_POSIX(mkfifoat)
+HIDE_POSIX(mknodat)
+HIDE_POSIX(readlinkat)
+HIDE_POSIX(symlinkat)
index 3553127..8c83521 100644 (file)
 #define        SYS_ioprio_get  521
 #define        SYS_chroot_kernel       522
 #define        SYS_renameat    523
-#define        SYS_MAXSYSCALL  524
+#define        SYS_mkdirat     524
+#define        SYS_mkfifoat    525
+#define        SYS_mknodat     526
+#define        SYS_readlinkat  527
+#define        SYS_symlinkat   528
+#define        SYS_MAXSYSCALL  529
index 892e5e8..ee18287 100644 (file)
@@ -302,4 +302,9 @@ MIASM =  \
        ioprio_set.o \
        ioprio_get.o \
        chroot_kernel.o \
-       renameat.o
+       renameat.o \
+       mkdirat.o \
+       mkfifoat.o \
+       mknodat.o \
+       readlinkat.o \
+       symlinkat.o
index de8594e..cf95822 100644 (file)
@@ -2310,6 +2310,48 @@ struct   renameat_args {
        int     newfd;  char newfd_[PAD_(int)];
        char *  new;    char new_[PAD_(char *)];
 };
+struct mkdirat_args {
+#ifdef _KERNEL
+       struct sysmsg sysmsg;
+#endif
+       int     fd;     char fd_[PAD_(int)];
+       char *  path;   char path_[PAD_(char *)];
+       mode_t  mode;   char mode_[PAD_(mode_t)];
+};
+struct mkfifoat_args {
+#ifdef _KERNEL
+       struct sysmsg sysmsg;
+#endif
+       int     fd;     char fd_[PAD_(int)];
+       char *  path;   char path_[PAD_(char *)];
+       mode_t  mode;   char mode_[PAD_(mode_t)];
+};
+struct mknodat_args {
+#ifdef _KERNEL
+       struct sysmsg sysmsg;
+#endif
+       int     fd;     char fd_[PAD_(int)];
+       char *  path;   char path_[PAD_(char *)];
+       mode_t  mode;   char mode_[PAD_(mode_t)];
+       dev_t   dev;    char dev_[PAD_(dev_t)];
+};
+struct readlinkat_args {
+#ifdef _KERNEL
+       struct sysmsg sysmsg;
+#endif
+       int     fd;     char fd_[PAD_(int)];
+       char *  path;   char path_[PAD_(char *)];
+       char *  buf;    char buf_[PAD_(char *)];
+       size_t  bufsize;        char bufsize_[PAD_(size_t)];
+};
+struct symlinkat_args {
+#ifdef _KERNEL
+       struct sysmsg sysmsg;
+#endif
+       char *  path1;  char path1_[PAD_(char *)];
+       int     fd;     char fd_[PAD_(int)];
+       char *  path2;  char path2_[PAD_(char *)];
+};
 
 #ifdef COMPAT_43
 
@@ -2920,6 +2962,11 @@ int      sys_ioprio_set (struct ioprio_set_args *);
 int    sys_ioprio_get (struct ioprio_get_args *);
 int    sys_chroot_kernel (struct chroot_kernel_args *);
 int    sys_renameat (struct renameat_args *);
+int    sys_mkdirat (struct mkdirat_args *);
+int    sys_mkfifoat (struct mkfifoat_args *);
+int    sys_mknodat (struct mknodat_args *);
+int    sys_readlinkat (struct readlinkat_args *);
+int    sys_symlinkat (struct symlinkat_args *);
 
 #endif /* !_SYS_SYSPROTO_H_ */
 #undef PAD_
index 62aef5d..39fc544 100644 (file)
@@ -410,4 +410,9 @@ union sysunion {
        struct  ioprio_get_args ioprio_get;
        struct  chroot_kernel_args chroot_kernel;
        struct  renameat_args renameat;
+       struct  mkdirat_args mkdirat;
+       struct  mkfifoat_args mkfifoat;
+       struct  mknodat_args mknodat;
+       struct  readlinkat_args readlinkat;
+       struct  symlinkat_args symlinkat;
 };