- 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
This commit is contained in:
Alexander Leidinger 2006-09-23 19:06:54 +00:00
parent 0d7c37283e
commit d4b7423fa1
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=162585
2 changed files with 30 additions and 3 deletions

View file

@ -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

View file

@ -611,6 +611,8 @@ linux_bind(struct thread *td, struct linux_bind_args *args)
error = kern_bind(td, linux_args.s, sa);
free(sa, M_SONAME);
if (error == EADDRNOTAVAIL && linux_args.namelen != sizeof(struct sockaddr_in))
return (EINVAL);
return (error);
}
@ -719,8 +721,11 @@ linux_accept(struct thread *td, struct linux_accept_args *args)
bsd_args.anamelen = PTRIN(linux_args.namelen);/* XXX */
error = accept(td, &bsd_args);
bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.name);
if (error)
if (error) {
if (error == EFAULT && linux_args.namelen != sizeof(struct sockaddr_in))
return (EINVAL);
return (error);
}
if (linux_args.addr) {
error = linux_sa_put(PTRIN(linux_args.addr));
if (error) {
@ -1135,7 +1140,7 @@ linux_setsockopt(struct thread *td, struct linux_setsockopt_args *args)
break;
}
if (name == -1)
return (EINVAL);
return (ENOPROTOOPT);
bsd_args.name = name;
bsd_args.val = PTRIN(linux_args.optval);