mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-30 22:43:12 +03:00
* sysdeps/unix/sysv/linux/renameat.c: Move errno setting code in
separate function __atfct_seterrno_2. * include/fcntl.h: Declare __atfct_seterrno_2. * posix/unistd.h: Declare linkat, symlinkat, readlinkat. * io/Makefile (routines): Add linkat, symlinkat, readlinkat. * io/Versions [GLIBC_2.4]: Export linkat, symlinkat, readlinkat. * io/linkat.c: New file. * io/readlinkat.c: New file. * io/symlinkat.c: New file. * sysdeps/unix/sysv/linux/linkat.c: New file. * sysdeps/unix/sysv/linux/readlinkat.c: New file. * sysdeps/unix/sysv/linux/symlinkat.c: New file.
This commit is contained in:
15
ChangeLog
15
ChangeLog
@ -1,3 +1,18 @@
|
|||||||
|
2005-12-15 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
* sysdeps/unix/sysv/linux/renameat.c: Move errno setting code in
|
||||||
|
separate function __atfct_seterrno_2.
|
||||||
|
* include/fcntl.h: Declare __atfct_seterrno_2.
|
||||||
|
* posix/unistd.h: Declare linkat, symlinkat, readlinkat.
|
||||||
|
* io/Makefile (routines): Add linkat, symlinkat, readlinkat.
|
||||||
|
* io/Versions [GLIBC_2.4]: Export linkat, symlinkat, readlinkat.
|
||||||
|
* io/linkat.c: New file.
|
||||||
|
* io/readlinkat.c: New file.
|
||||||
|
* io/symlinkat.c: New file.
|
||||||
|
* sysdeps/unix/sysv/linux/linkat.c: New file.
|
||||||
|
* sysdeps/unix/sysv/linux/readlinkat.c: New file.
|
||||||
|
* sysdeps/unix/sysv/linux/symlinkat.c: New file.
|
||||||
|
|
||||||
2005-12-15 Roland McGrath <roland@redhat.com>
|
2005-12-15 Roland McGrath <roland@redhat.com>
|
||||||
|
|
||||||
[BZ #1997]
|
[BZ #1997]
|
||||||
|
4
NEWS
4
NEWS
@ -1,4 +1,4 @@
|
|||||||
GNU C Library NEWS -- history of user-visible changes. 2005-12-02
|
GNU C Library NEWS -- history of user-visible changes. 2005-12-15
|
||||||
Copyright (C) 1992-2002,2003,2004,2005 Free Software Foundation, Inc.
|
Copyright (C) 1992-2002,2003,2004,2005 Free Software Foundation, Inc.
|
||||||
See the end for copying conditions.
|
See the end for copying conditions.
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ Version 2.4
|
|||||||
recommend using the stable 2.3 branch.
|
recommend using the stable 2.3 branch.
|
||||||
|
|
||||||
* New interfaces: fdopendir, openat, fstatat, fchownat, futimesat, renameat,
|
* New interfaces: fdopendir, openat, fstatat, fchownat, futimesat, renameat,
|
||||||
unlinkat, mkdirat, mkfifoat, mknodat.
|
unlinkat, mkdirat, mkfifoat, mknodat, linkat, symlinkat, readlinkat.
|
||||||
|
|
||||||
Version 2.3.6
|
Version 2.3.6
|
||||||
|
|
||||||
|
@ -21,5 +21,8 @@ libc_hidden_proto (__fcntl)
|
|||||||
/* Helper functions for the various *at functions. For Linux. */
|
/* Helper functions for the various *at functions. For Linux. */
|
||||||
extern void __atfct_seterrno (int errval, int fd, const char *buf)
|
extern void __atfct_seterrno (int errval, int fd, const char *buf)
|
||||||
attribute_hidden;
|
attribute_hidden;
|
||||||
|
extern void __atfct_seterrno_2 (int errval, int fd1, const char *buf1,
|
||||||
|
int fd2, const char *buf2)
|
||||||
|
attribute_hidden;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -45,7 +45,7 @@ routines := \
|
|||||||
getcwd getwd getdirname \
|
getcwd getwd getdirname \
|
||||||
chown fchown lchown fchownat \
|
chown fchown lchown fchownat \
|
||||||
ttyname ttyname_r isatty \
|
ttyname ttyname_r isatty \
|
||||||
link symlink readlink \
|
link linkat symlink symlinkat readlink readlinkat \
|
||||||
unlink unlinkat rmdir \
|
unlink unlinkat rmdir \
|
||||||
ftw ftw64 fts poll \
|
ftw ftw64 fts poll \
|
||||||
posix_fadvise posix_fadvise64 \
|
posix_fadvise posix_fadvise64 \
|
||||||
|
@ -100,8 +100,11 @@ libc {
|
|||||||
GLIBC_2.4 {
|
GLIBC_2.4 {
|
||||||
fchownat;
|
fchownat;
|
||||||
__fxstatat; __fxstatat64;
|
__fxstatat; __fxstatat64;
|
||||||
|
linkat;
|
||||||
mkdirat; mkfifoat; __xmknodat;
|
mkdirat; mkfifoat; __xmknodat;
|
||||||
openat; openat64;
|
openat; openat64;
|
||||||
|
readlinkat;
|
||||||
|
symlinkat;
|
||||||
unlinkat;
|
unlinkat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
51
io/linkat.c
Normal file
51
io/linkat.c
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/* 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 <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* Make a link to FROM relative to FROMFD called TO relative to TOFD. */
|
||||||
|
int
|
||||||
|
linkat (fromfd, from, tofd, to)
|
||||||
|
int fromfd;
|
||||||
|
const char *from;
|
||||||
|
int tofd;
|
||||||
|
const char *to;
|
||||||
|
{
|
||||||
|
if (from == NULL || to == NULL)
|
||||||
|
{
|
||||||
|
__set_errno (EINVAL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((tofd != AT_FDCWD && tofd < 0 && *to != '/')
|
||||||
|
|| (fromfd != AT_FDCWD && fromfd < 0 && *from != '/'))
|
||||||
|
{
|
||||||
|
__set_errno (EBADF);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
__set_errno (ENOSYS);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
stub_warning (linkat)
|
||||||
|
|
||||||
|
#include <stub-tag.h>
|
50
io/readlinkat.c
Normal file
50
io/readlinkat.c
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/* 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 <unistd.h>
|
||||||
|
|
||||||
|
/* Read the contents of the symbolic link PATH relative to FD into no
|
||||||
|
more than LEN bytes of BUF. The contents are not null-terminated.
|
||||||
|
Returns the number of characters read, or -1 for errors. */
|
||||||
|
int
|
||||||
|
readlinkat (fd, path, buf, len)
|
||||||
|
int fd;
|
||||||
|
const char *path;
|
||||||
|
char *buf;
|
||||||
|
size_t len;
|
||||||
|
{
|
||||||
|
if (path == NULL)
|
||||||
|
{
|
||||||
|
__set_errno (EINVAL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd != AT_FDCWD && fd < 0 && *path != '/')
|
||||||
|
{
|
||||||
|
__set_errno (EBADF);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
__set_errno (ENOSYS);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
stub_warning (readlinkat)
|
||||||
|
|
||||||
|
#include <stub-tag.h>
|
49
io/symlinkat.c
Normal file
49
io/symlinkat.c
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/* 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 <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* Make a link to FROM called TO relative to FD. */
|
||||||
|
int
|
||||||
|
symlinkat (from, fd, to)
|
||||||
|
const char *from;
|
||||||
|
int fd;
|
||||||
|
const char *to;
|
||||||
|
{
|
||||||
|
if (from == NULL || to == NULL)
|
||||||
|
{
|
||||||
|
__set_errno (EINVAL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd != AT_FDCWD && fd < 0 && *to != '/')
|
||||||
|
{
|
||||||
|
__set_errno (EBADF);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
__set_errno (ENOSYS);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
stub_warning (symlinkat)
|
||||||
|
|
||||||
|
#include <stub-tag.h>
|
@ -742,6 +742,13 @@ extern int ttyslot (void) __THROW;
|
|||||||
extern int link (__const char *__from, __const char *__to)
|
extern int link (__const char *__from, __const char *__to)
|
||||||
__THROW __nonnull ((1, 2)) __wur;
|
__THROW __nonnull ((1, 2)) __wur;
|
||||||
|
|
||||||
|
#ifdef __USE_GNU
|
||||||
|
/* Like link but relative paths in TO and FROM are interpreted relative
|
||||||
|
to FROMFD and TOFD respectively. */
|
||||||
|
extern int linkat (int __fromfd, __const char *__from, int __tofd,
|
||||||
|
__const char *__to) __THROW __nonnull ((2, 4)) __wur;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K
|
#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K
|
||||||
/* Make a symbolic link to FROM named TO. */
|
/* Make a symbolic link to FROM named TO. */
|
||||||
extern int symlink (__const char *__from, __const char *__to)
|
extern int symlink (__const char *__from, __const char *__to)
|
||||||
@ -754,6 +761,17 @@ extern int readlink (__const char *__restrict __path, char *__restrict __buf,
|
|||||||
size_t __len) __THROW __nonnull ((1, 2)) __wur;
|
size_t __len) __THROW __nonnull ((1, 2)) __wur;
|
||||||
#endif /* Use BSD. */
|
#endif /* Use BSD. */
|
||||||
|
|
||||||
|
#ifdef __USE_GNU
|
||||||
|
/* Like symlink but a relative path in TO is interpreted relative to TOFD. */
|
||||||
|
extern int symlinkat (__const char *__from, int __tofd,
|
||||||
|
__const char *__to) __THROW __nonnull ((1, 3)) __wur;
|
||||||
|
|
||||||
|
/* Like readlink but a relative PATH is interpreted relative to FD. */
|
||||||
|
extern int readlinkat (int __fd, __const char *__restrict __path,
|
||||||
|
char *__restrict __buf, size_t __len)
|
||||||
|
__THROW __nonnull ((2, 3)) __wur;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Remove the link NAME. */
|
/* Remove the link NAME. */
|
||||||
extern int unlink (__const char *__name) __THROW __nonnull ((1));
|
extern int unlink (__const char *__name) __THROW __nonnull ((1));
|
||||||
|
|
||||||
|
87
sysdeps/unix/sysv/linux/linkat.c
Normal file
87
sysdeps/unix/sysv/linux/linkat.c
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/* 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 <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sysdep.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* Make a link to FROM named TO but relative paths in TO and FROM are
|
||||||
|
interpreted relative to FROMFD and TOFD respectively. */
|
||||||
|
int
|
||||||
|
linkat (fromfd, from, tofd, to)
|
||||||
|
int fromfd;
|
||||||
|
const char *from;
|
||||||
|
int tofd;
|
||||||
|
const char *to;
|
||||||
|
{
|
||||||
|
static const char procfd[] = "/proc/self/fd/%d/%s";
|
||||||
|
char *buffrom = NULL;
|
||||||
|
|
||||||
|
if (fromfd != AT_FDCWD && from[0] != '/')
|
||||||
|
{
|
||||||
|
size_t filelen = strlen (from);
|
||||||
|
/* 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;
|
||||||
|
buffrom = alloca (buflen);
|
||||||
|
|
||||||
|
__snprintf (buffrom, buflen, procfd, fromfd, from);
|
||||||
|
from = buffrom;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *bufto = NULL;
|
||||||
|
|
||||||
|
if (tofd != AT_FDCWD && to[0] != '/')
|
||||||
|
{
|
||||||
|
size_t filelen = strlen (to);
|
||||||
|
/* 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;
|
||||||
|
bufto = alloca (buflen);
|
||||||
|
|
||||||
|
__snprintf (bufto, buflen, procfd, tofd, to);
|
||||||
|
to = bufto;
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERNAL_SYSCALL_DECL (err);
|
||||||
|
|
||||||
|
int result = INTERNAL_SYSCALL (link, err, 2, from, to);
|
||||||
|
|
||||||
|
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
|
||||||
|
{
|
||||||
|
__atfct_seterrno_2 (INTERNAL_SYSCALL_ERRNO (result, err), tofd, bufto,
|
||||||
|
fromfd, buffrom);
|
||||||
|
result = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
69
sysdeps/unix/sysv/linux/readlinkat.c
Normal file
69
sysdeps/unix/sysv/linux/readlinkat.c
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/* 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 <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sysdep.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* Read the contents of the symbolic link PATH relative to FD into no
|
||||||
|
more than LEN bytes of BUF. */
|
||||||
|
int
|
||||||
|
readlinkat (fd, path, buf, len)
|
||||||
|
int fd;
|
||||||
|
const char *path;
|
||||||
|
char *buf;
|
||||||
|
size_t len;
|
||||||
|
{
|
||||||
|
char *pathbuf = NULL;
|
||||||
|
|
||||||
|
if (fd != AT_FDCWD && path[0] != '/')
|
||||||
|
{
|
||||||
|
size_t pathlen = strlen (path);
|
||||||
|
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 + pathlen;
|
||||||
|
pathbuf = __alloca (buflen);
|
||||||
|
|
||||||
|
__snprintf (pathbuf, buflen, procfd, fd, path);
|
||||||
|
path = pathbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERNAL_SYSCALL_DECL (err);
|
||||||
|
|
||||||
|
int result = INTERNAL_SYSCALL (readlink, err, 3, path, buf, len);
|
||||||
|
|
||||||
|
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
|
||||||
|
{
|
||||||
|
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, pathbuf);
|
||||||
|
result = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
67
sysdeps/unix/sysv/linux/symlinkat.c
Normal file
67
sysdeps/unix/sysv/linux/symlinkat.c
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/* 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 <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sysdep.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* Make a symbolic link to FROM named TO relative to TOFD. */
|
||||||
|
int
|
||||||
|
symlinkat (from, tofd, to)
|
||||||
|
const char *from;
|
||||||
|
int tofd;
|
||||||
|
const char *to;
|
||||||
|
{
|
||||||
|
char *buf = NULL;
|
||||||
|
|
||||||
|
if (tofd != AT_FDCWD && to[0] != '/')
|
||||||
|
{
|
||||||
|
size_t tolen = strlen (to);
|
||||||
|
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 + tolen;
|
||||||
|
buf = __alloca (buflen);
|
||||||
|
|
||||||
|
__snprintf (buf, buflen, procfd, tofd, to);
|
||||||
|
to = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERNAL_SYSCALL_DECL (err);
|
||||||
|
|
||||||
|
int result = INTERNAL_SYSCALL (symlink, err, 2, from, to);
|
||||||
|
|
||||||
|
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
|
||||||
|
{
|
||||||
|
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), tofd, buf);
|
||||||
|
result = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
Reference in New Issue
Block a user