svn commit: r279817 - user/dchagin/lemul/sys/fs/fdescfs
Dmitry Chagin
dchagin at FreeBSD.org
Mon Mar 9 16:19:45 UTC 2015
Author: dchagin
Date: Mon Mar 9 16:19:44 2015
New Revision: 279817
URL: https://svnweb.freebsd.org/changeset/base/279817
Log:
Most Linux distros symbolically link /dev/fd to /proc/self/fd for
compatibility with other unix-like systems. On Linux this is a subdirectory
containing one entry for each file which the reading the directory process
has open, named by its file descriptor, and which is a symbolic link to the
actual file.
On FreeBSD we have a bit similar interface - fdescfs(5). Unlike Linux opening
our /dev/fd/X (as the most unix-like systems) gives a duplicate of the file
descriptor while on Linux gives a new file. Also fdescfs(5) does not provide
readlink method.
At least newest bash and rm depends on /dev/fd, so add readlink method to
the fdescfs(5).
Modified:
user/dchagin/lemul/sys/fs/fdescfs/fdesc_vnops.c
Modified: user/dchagin/lemul/sys/fs/fdescfs/fdesc_vnops.c
==============================================================================
--- user/dchagin/lemul/sys/fs/fdescfs/fdesc_vnops.c Mon Mar 9 15:54:14 2015 (r279816)
+++ user/dchagin/lemul/sys/fs/fdescfs/fdesc_vnops.c Mon Mar 9 16:19:44 2015 (r279817)
@@ -53,6 +53,7 @@
#include <sys/namei.h>
#include <sys/proc.h>
#include <sys/stat.h>
+#include <sys/sysent.h>
#include <sys/vnode.h>
#include <fs/fdescfs/fdesc.h>
@@ -69,6 +70,7 @@ static vop_getattr_t fdesc_getattr;
static vop_lookup_t fdesc_lookup;
static vop_open_t fdesc_open;
static vop_readdir_t fdesc_readdir;
+static vop_readlink_t fdesc_readlink;
static vop_reclaim_t fdesc_reclaim;
static vop_setattr_t fdesc_setattr;
@@ -81,6 +83,7 @@ static struct vop_vector fdesc_vnodeops
.vop_open = fdesc_open,
.vop_pathconf = vop_stdpathconf,
.vop_readdir = fdesc_readdir,
+ .vop_readlink = fdesc_readlink,
.vop_reclaim = fdesc_reclaim,
.vop_setattr = fdesc_setattr,
};
@@ -368,7 +371,7 @@ fdesc_lookup(ap)
error = vn_vget_ino_gen(dvp, fdesc_get_ino_alloc, &arg,
LK_EXCLUSIVE, &fvp);
}
-
+
if (error)
goto bad;
*vpp = fvp;
@@ -562,7 +565,10 @@ fdesc_readdir(ap)
break;
dp->d_namlen = sprintf(dp->d_name, "%d", fcnt);
dp->d_reclen = UIO_MX;
- dp->d_type = DT_CHR;
+ if (SV_CURPROC_ABI() == SV_ABI_LINUX)
+ dp->d_type = DT_LNK;
+ else
+ dp->d_type = DT_CHR;
dp->d_fileno = i + FD_DESC;
break;
}
@@ -602,3 +608,73 @@ fdesc_reclaim(ap)
vp->v_data = NULL;
return (0);
}
+
+static int
+fdesc_readlink(struct vop_readlink_args *va)
+{
+ struct vnode *vp, *vn = va->a_vp;
+ struct fdescnode *fd = vn->v_data;
+ struct thread *td = curthread;
+ struct uio *uio = va->a_uio;
+ struct filedesc *fdp;
+ struct file *fp;
+ char *freepath, *fullpath;
+ size_t pathlen;
+ int error, locked;
+
+ if (VTOFDESC(vn)->fd_type != Fdesc)
+ panic("fdesc_readlink: not fdescfs link");
+
+ if (vn->v_type != VLNK)
+ return (EINVAL);
+
+ vhold(vn);
+ locked = VOP_ISLOCKED(vn);
+ VOP_UNLOCK(vn, 0);
+
+ fdp = td->td_proc->p_fd;
+ error = fget_unlocked(fdp, fd->fd_fd, NULL, &fp, NULL);
+ if (error != 0)
+ goto out;
+
+ freepath = NULL;
+ switch (fp->f_type) {
+ case DTYPE_VNODE:
+ vp = fp->f_vnode;
+ vref(vp);
+ error = vn_fullpath(td, vp, &fullpath, &freepath);
+ vrele(vp);
+ break;
+
+ case DTYPE_SOCKET:
+ fullpath = "socket:[0]";
+ break;
+
+ case DTYPE_PIPE:
+ fullpath = "pipe:[0]";
+ break;
+
+ case DTYPE_LINUXEFD:
+ fullpath = "anon_inode:[eventpoll]";
+ break;
+
+ default:
+ fullpath = "anon_inode:[unknown]";
+ break;
+ }
+
+ if (error == 0) {
+ pathlen = strnlen(fullpath, MAXPATHLEN);
+ error = uiomove(fullpath, pathlen, uio);
+ }
+ if (freepath != NULL)
+ free(freepath, M_TEMP);
+
+ fdrop(fp, td);
+
+ out:
+
+ vn_lock(vn, locked | LK_RETRY);
+ vdrop(vn);
+ return (error);
+}
More information about the svn-src-user
mailing list