+int
+fgetattrlist(proc_t p, struct fgetattrlist_args *uap, __unused int32_t *retval)
+{
+ struct vfs_context *ctx;
+ vnode_t vp = NULL;
+ int error;
+ struct getattrlist_args ap;
+
+ ctx = vfs_context_current();
+ error = 0;
+
+ if ((error = file_vnode(uap->fd, &vp)) != 0)
+ return (error);
+
+ if ((error = vnode_getwithref(vp)) != 0) {
+ file_drop(uap->fd);
+ return(error);
+ }
+
+ ap.path = 0;
+ ap.alist = uap->alist;
+ ap.attributeBuffer = uap->attributeBuffer;
+ ap.bufferSize = uap->bufferSize;
+ ap.options = uap->options;
+
+ error = getattrlist_internal(vp, &ap, p, ctx);
+
+ file_drop(uap->fd);
+ if (vp)
+ vnode_put(vp);
+
+ return error;
+}
+
+int
+getattrlist(proc_t p, struct getattrlist_args *uap, __unused int32_t *retval)
+{
+ struct vfs_context *ctx;
+ struct nameidata nd;
+ vnode_t vp = NULL;
+ u_long nameiflags;
+ int error;
+
+ ctx = vfs_context_current();
+ error = 0;
+
+ /*
+ * Look up the file.
+ */
+ nameiflags = NOTRIGGER | AUDITVNPATH1;
+ if (!(uap->options & FSOPT_NOFOLLOW))
+ nameiflags |= FOLLOW;
+ NDINIT(&nd, LOOKUP, nameiflags, UIO_USERSPACE, uap->path, ctx);
+
+ if ((error = namei(&nd)) != 0)
+ goto out;
+ vp = nd.ni_vp;
+ nameidone(&nd);
+
+ error = getattrlist_internal(vp, uap, p, ctx);
+out:
+ if (vp)
+ vnode_put(vp);
+ return error;
+}
+