tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[PATCH] llink(2) (was: Re: Adding linux_link(2) system call, second round)
On Sun, Jul 31, 2011 at 06:36:53PM +0000, Christos Zoulas wrote:
> I don't have an issue with it as long as:
> - fsck does not get confused
> - filesystems don't need to be modified to support it
> - there is consensus that this is not harmful
> - I am also ambivalent about exposing this in the native abi
> because it will only cause confusion.
Attached is the patch that adds llink(2) and its documentation. The test I
ran are below (the llink program just calls llink(2)).
fsck has no probmem with it, ffs was not modified. For it
being harmful, I cannot immagine what could be done with it, but
we could restrict it to root just in case.
On confusion, well, I think the llink name speaks by itself.
# ls -li
total 1
3648 drwxr-xr-x 2 root wheel 512 Aug 1 11:31 dir
3 -rw-r--r-- 2 root wheel 0 Aug 1 11:30 file
3 -rw-r--r-- 2 root wheel 0 Aug 1 11:30 hfile
5 lrwxr-xr-x 1 root wheel 3 Aug 1 11:31 sdir -> dir
4 lrwxr-xr-x 1 root wheel 4 Aug 1 11:31 sfile -> file
6 lrwxr-xr-x 1 root wheel 11 Aug 1 11:32 void -> nonexistent
# /home2/manu/llink sfile hsfile
# /home2/manu/llink sdir hsdir
# /home2/manu/llink void hvoid
# ls -li
total 1
3648 drwxr-xr-x 2 root wheel 512 Aug 1 11:31 dir
3 -rw-r--r-- 2 root wheel 0 Aug 1 11:30 file
3 -rw-r--r-- 2 root wheel 0 Aug 1 11:30 hfile
5 lrwxr-xr-x 2 root wheel 3 Aug 1 11:31 hsdir -> dir
4 lrwxr-xr-x 2 root wheel 4 Aug 1 11:31 hsfile -> file
6 lrwxr-xr-x 2 root wheel 11 Aug 1 11:32 hvoid -> nonexistent
5 lrwxr-xr-x 2 root wheel 3 Aug 1 11:31 sdir -> dir
4 lrwxr-xr-x 2 root wheel 4 Aug 1 11:31 sfile -> file
6 lrwxr-xr-x 2 root wheel 11 Aug 1 11:32 void -> nonexistent
--
Emmanuel Dreyfus
manu%netbsd.org@localhost
Index: include/unistd.h
===================================================================
RCS file: /cvsroot/src/include/unistd.h,v
retrieving revision 1.126
diff -U4 -r1.126 unistd.h
--- include/unistd.h 26 Jun 2011 16:42:40 -0000 1.126
+++ include/unistd.h 1 Aug 2011 09:34:20 -0000
@@ -124,8 +124,9 @@
pid_t getppid(void);
uid_t getuid(void);
int isatty(int);
int link(const char *, const char *);
+int llink(const char *, const char *);
long pathconf(const char *, int);
int pause(void);
int pipe(int *);
#if __SSP_FORTIFY_LEVEL == 0
Index: sys/kern/vfs_syscalls.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.430
diff -U4 -r1.430 vfs_syscalls.c
--- sys/kern/vfs_syscalls.c 17 Jun 2011 14:23:51 -0000 1.430
+++ sys/kern/vfs_syscalls.c 1 Aug 2011 09:34:20 -0000
@@ -1769,27 +1769,32 @@
}
/*
* Make a hard file link.
+ * The flag argument can be
+ * - FOLLOW for sys_link, to link to symlink target
+ * - NOFOLLOW for sys_llink, to link to symlink itself
*/
/* ARGSUSED */
-int
-sys_link(struct lwp *l, const struct sys_link_args *uap, register_t *retval)
+static int
+do_sys_link(struct lwp *l, const char *path, const char *link,
+ int flags, register_t *retval)
{
- /* {
- syscallarg(const char *) path;
- syscallarg(const char *) link;
- } */
struct vnode *vp;
struct pathbuf *linkpb;
struct nameidata nd;
+ namei_simple_flags_t namei_simple_flags;
int error;
- error = namei_simple_user(SCARG(uap, path),
- NSM_FOLLOW_TRYEMULROOT, &vp);
+ if (flags & FOLLOW)
+ namei_simple_flags = NSM_FOLLOW_TRYEMULROOT;
+ else
+ namei_simple_flags = NSM_NOFOLLOW_TRYEMULROOT;
+
+ error = namei_simple_user(path, namei_simple_flags, &vp);
if (error != 0)
return (error);
- error = pathbuf_copyin(SCARG(uap, link), &linkpb);
+ error = pathbuf_copyin(link, &linkpb);
if (error) {
goto out1;
}
NDINIT(&nd, CREATE, LOCKPARENT | TRYEMULROOT, linkpb);
@@ -1826,8 +1831,35 @@
goto out2;
}
int
+sys_link(struct lwp *l, const struct sys_link_args *uap, register_t *retval)
+{
+ /* {
+ syscallarg(const char *) path;
+ syscallarg(const char *) link;
+ } */
+ const char *path = SCARG(uap, path);
+ const char *link = SCARG(uap, link);
+
+ return do_sys_link(l, path, link, FOLLOW, retval);
+}
+
+int
+sys_llink(struct lwp *l, const struct sys_llink_args *uap, register_t *retval)
+{
+ /* {
+ syscallarg(const char *) path;
+ syscallarg(const char *) link;
+ } */
+ const char *path = SCARG(uap, path);
+ const char *link = SCARG(uap, link);
+
+ return do_sys_link(l, path, link, NOFOLLOW, retval);
+}
+
+
+int
do_sys_symlink(const char *patharg, const char *link, enum uio_seg seg)
{
struct proc *p = curproc;
struct vattr vattr;
@@ -1850,8 +1882,10 @@
error = ENOMEM;
goto out1;
}
}
+ ktrkuser("symlink-target", path, strlen(path));
+
NDINIT(&nd, CREATE, LOCKPARENT | TRYEMULROOT, linkpb);
if ((error = namei(&nd)) != 0)
goto out2;
if (nd.ni_vp) {
Index: sys/kern/syscalls.master
===================================================================
RCS file: /cvsroot/src/sys/kern/syscalls.master,v
retrieving revision 1.249
diff -U4 -r1.249 syscalls.master
--- sys/kern/syscalls.master 26 Jun 2011 17:05:24 -0000 1.249
+++ sys/kern/syscalls.master 1 Aug 2011 09:34:20 -0000
@@ -892,4 +892,5 @@
455 STD RUMP { int|sys||kqueue1(int flags); }
456 STD RUMP { int|sys||paccept(int s, struct sockaddr *name, \
socklen_t *anamelen, const sigset_t *mask, \
int flags); }
+457 STD RUMP { int|sys||llink(const char *path, const char *link); }
Index: distrib/sets/lists/comp/mi
===================================================================
RCS file: /cvsroot/src/distrib/sets/lists/comp/mi,v
retrieving revision 1.1635
diff -U4 -r1.1635 mi
--- distrib/sets/lists/comp/mi 28 Jun 2011 04:53:51 -0000 1.1635
+++ distrib/sets/lists/comp/mi 1 Aug 2011 09:34:20 -0000
@@ -4400,8 +4400,9 @@
./usr/share/man/cat2/lfs_segclean.0 comp-c-catman .cat
./usr/share/man/cat2/lfs_segwait.0 comp-c-catman .cat
./usr/share/man/cat2/link.0 comp-c-catman .cat
./usr/share/man/cat2/listen.0 comp-c-catman .cat
+./usr/share/man/cat2/llink.0 comp-c-catman .cat
./usr/share/man/cat2/lseek.0 comp-c-catman .cat
./usr/share/man/cat2/lstat.0 comp-c-catman .cat
./usr/share/man/cat2/lutimes.0 comp-c-catman .cat
./usr/share/man/cat2/m68k_sync_icache.0 comp-c-catman
.cat
@@ -10563,8 +10565,9 @@
./usr/share/man/html2/lfs_segclean.html comp-c-htmlman
html
./usr/share/man/html2/lfs_segwait.html comp-c-htmlman html
./usr/share/man/html2/link.html comp-c-htmlman
html
./usr/share/man/html2/listen.html comp-c-htmlman html
+./usr/share/man/html2/llink.html comp-c-htmlman html
./usr/share/man/html2/lseek.html comp-c-htmlman html
./usr/share/man/html2/lstat.html comp-c-htmlman html
./usr/share/man/html2/lutimes.html comp-c-htmlman html
./usr/share/man/html2/m68k_sync_icache.html comp-c-htmlman html
@@ -16506,8 +16510,9 @@
./usr/share/man/man2/lfs_segclean.2 comp-c-man .man
./usr/share/man/man2/lfs_segwait.2 comp-c-man .man
./usr/share/man/man2/link.2 comp-c-man .man
./usr/share/man/man2/listen.2 comp-c-man .man
+./usr/share/man/man2/llink.2 comp-c-man .man
./usr/share/man/man2/lseek.2 comp-c-man .man
./usr/share/man/man2/lstat.2 comp-c-man .man
./usr/share/man/man2/lutimes.2 comp-c-man .man
./usr/share/man/man2/m68k_sync_icache.2 comp-c-man
.man
Index: lib/libc/sys/link.2
===================================================================
RCS file: /cvsroot/src/lib/libc/sys/link.2,v
retrieving revision 1.24
diff -U4 -r1.24 link.2
--- lib/libc/sys/link.2 31 May 2010 12:16:20 -0000 1.24
+++ lib/libc/sys/link.2 1 Aug 2011 09:34:20 -0000
@@ -1,7 +1,7 @@
.\" $NetBSD: link.2,v 1.24 2010/05/31 12:16:20 njoly Exp $
.\"
-.\" Copyright (c) 1980, 1991, 1993
+.\" Copyright (c) 1980, 1991, 1993, 2011
.\" The Regents of the University of California. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
@@ -40,8 +40,10 @@
.Sh SYNOPSIS
.In unistd.h
.Ft int
.Fn link "const char *name1" "const char *name2"
+.Ft int
+.Fn llink "const char *name1" "const char *name2"
.Sh DESCRIPTION
The
.Fn link
function call
@@ -76,8 +78,17 @@
must be in the same file system.
.Fa name1
may not be a directory unless the caller is the super-user
and the file system containing it supports linking to directories.
+.Pp
+.Fn llink
+is like
+.Fn link
+except in the case where the named file is a symbolic link, in which case
+.Fn llink
+links on the symbolic link itself, while
+.Fn link
+links on the symbolic link target.
.Sh RETURN VALUES
Upon successful completion, a value of 0 is returned.
Otherwise, a value of \-1 is returned and
.Va errno
Index: lib/libc/sys/Makefile.inc
===================================================================
RCS file: /cvsroot/src/lib/libc/sys/Makefile.inc,v
retrieving revision 1.207
diff -U4 -r1.207 Makefile.inc
--- lib/libc/sys/Makefile.inc 27 Jun 2011 16:39:44 -0000 1.207
+++ lib/libc/sys/Makefile.inc 1 Aug 2011 09:34:20 -0000
@@ -99,13 +99,13 @@
_ksem_close.S _ksem_destroy.S _ksem_getvalue.S _ksem_init.S \
_ksem_post.S _ksem_trywait.S _ksem_unlink.S _ksem_wait.S \
_ksem_open.S \
lchflags.S lchmod.S lchown.S lfs_bmapv.S lfs_markv.S lfs_segclean.S \
- __lfs_segwait50.S link.S listen.S __lstat50.S __lutimes50.S \
- _lwp_create.S _lwp_exit.S _lwp_kill.S ___lwp_park50.S \
- _lwp_self.S _lwp_wait.S _lwp_unpark.S _lwp_unpark_all.S \
- _lwp_suspend.S _lwp_continue.S _lwp_wakeup.S _lwp_detach.S \
- _lwp_setprivate.S \
+ __lfs_segwait50.S link.S listen.S llink.S __lstat50.S \
+ __lutimes50.S _lwp_create.S _lwp_exit.S _lwp_kill.S \
+ ___lwp_park50.S _lwp_self.S _lwp_wait.S _lwp_unpark.S \
+ _lwp_unpark_all.S _lwp_suspend.S _lwp_continue.S \
+ _lwp_wakeup.S _lwp_detach.S _lwp_setprivate.S \
_lwp_setname.S _lwp_getname.S _lwp_ctl.S \
madvise.S mincore.S minherit.S mkdir.S mkfifo.S __mknod50.S \
mlock.S mlockall.S modctl.S __mount50.S mprotect.S \
__msgctl50.S msgget.S munlock.S munlockall.S munmap.S \
@@ -282,8 +282,9 @@
MLINKS+=intro.2 errno.2
MLINKS+=kqueue.2 kevent.2
MLINKS+=ktrace.2 fktrace.2
MLINKS+=lseek.2 seek.2
+MLINKS+=link.2 llink.2
MLINKS+=_lwp_suspend.2 _lwp_continue.2
MLINKS+=_lwp_getprivate.2 _lwp_setprivate.2
MLINKS+=madvise.2 posix_madvise.2
MLINKS+=mlock.2 munlock.2
Home |
Main Index |
Thread Index |
Old Index