summaryrefslogtreecommitdiffstats
path: root/sys/compat/linux/linux_file.c
diff options
context:
space:
mode:
authornetchild <netchild@FreeBSD.org>2006-09-23 19:06:54 +0000
committernetchild <netchild@FreeBSD.org>2006-09-23 19:06:54 +0000
commit6ecb474f4fee36803a21cadcee5dc0f6b0e6b4d2 (patch)
tree7a35442ca35fbab402321b222ccf332ac2aa2150 /sys/compat/linux/linux_file.c
parent39ac06be39bc2d3437458d0d947516526772cffb (diff)
downloadFreeBSD-src-6ecb474f4fee36803a21cadcee5dc0f6b0e6b4d2.zip
FreeBSD-src-6ecb474f4fee36803a21cadcee5dc0f6b0e6b4d2.tar.gz
MFp4:
- Linux returns ENOPROTOOPT in a case of not supported opt to setsockopt. - Return EISDIR in pread() when arg is a directory. - Return EINVAL instead of EFAULT when namelen is not correct in accept(). - Return EINVAL instead of EACCESS if invalid access mode is entered in access(). - Return EINVAL instead of EADDRNOTAVAIL in a case of bad salen param to bind(). Submitted by: rdivacky Tested with: LTP (vfork01 fails now, but it seems to be a race and not caused by those changes) MFC after: 1 week
Diffstat (limited to 'sys/compat/linux/linux_file.c')
-rw-r--r--sys/compat/linux/linux_file.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c
index 327f604..185ca5c 100644
--- a/sys/compat/linux/linux_file.c
+++ b/sys/compat/linux/linux_file.c
@@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
#include <sys/syscallsubr.h>
#include <sys/sysproto.h>
#include <sys/tty.h>
+#include <sys/unistd.h>
#include <sys/vnode.h>
#include <ufs/ufs/extattr.h>
@@ -480,6 +481,10 @@ linux_access(struct thread *td, struct linux_access_args *args)
char *path;
int error;
+ /* linux convention */
+ if (args->flags & ~(F_OK | X_OK | W_OK | R_OK))
+ return (EINVAL);
+
LCONVPATHEXIST(td, args->path, &path);
#ifdef DEBUG
@@ -488,6 +493,7 @@ linux_access(struct thread *td, struct linux_access_args *args)
#endif
error = kern_access(td, path, UIO_SYSSPACE, args->flags);
LFREEPATH(path);
+
return (error);
}
@@ -724,12 +730,28 @@ linux_pread(td, uap)
struct linux_pread_args *uap;
{
struct pread_args bsd;
+ struct vnode *vp;
+ int error;
bsd.fd = uap->fd;
bsd.buf = uap->buf;
bsd.nbyte = uap->nbyte;
bsd.offset = uap->offset;
- return pread(td, &bsd);
+
+ error = pread(td, &bsd);
+
+ if (error == 0) {
+ /* This seems to violate POSIX but linux does it */
+ if ((error = fgetvp(td, uap->fd, &vp)) != 0)
+ return (error);
+ if (vp->v_type == VDIR) {
+ vrele(vp);
+ return (EISDIR);
+ }
+ vrele(vp);
+ }
+
+ return (error);
}
int
OpenPOWER on IntegriCloud