Date: Mon, 9 Mar 2015 16:19:45 +0000 (UTC) From: Dmitry Chagin <dchagin@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r279817 - user/dchagin/lemul/sys/fs/fdescfs Message-ID: <201503091619.t29GJj4J096775@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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); +}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201503091619.t29GJj4J096775>