diff options
author | netchild <netchild@FreeBSD.org> | 2006-03-18 18:20:17 +0000 |
---|---|---|
committer | netchild <netchild@FreeBSD.org> | 2006-03-18 18:20:17 +0000 |
commit | c1829f604cdf8a3f393bfa6cb85fe9a6d4908919 (patch) | |
tree | 0bfbd4f21076e4935e7376b8d0502c8d258d4cfa /sys/compat | |
parent | d4f801f4ab01a2c0d88e59ddabc9757533800554 (diff) | |
download | FreeBSD-src-c1829f604cdf8a3f393bfa6cb85fe9a6d4908919.zip FreeBSD-src-c1829f604cdf8a3f393bfa6cb85fe9a6d4908919.tar.gz |
Get rid of the need of COMPAT_43 in the linuxolator.
Submitted by: Divacky Roman <xdivac02@stud.fit.vutbr.cz>
Obtained from: DragonFly (some parts)
Diffstat (limited to 'sys/compat')
-rw-r--r-- | sys/compat/linux/linux_file.c | 17 | ||||
-rw-r--r-- | sys/compat/linux/linux_getcwd.c | 2 | ||||
-rw-r--r-- | sys/compat/linux/linux_ioctl.c | 35 | ||||
-rw-r--r-- | sys/compat/linux/linux_misc.c | 19 | ||||
-rw-r--r-- | sys/compat/linux/linux_socket.c | 99 | ||||
-rw-r--r-- | sys/compat/linux/linux_stats.c | 62 | ||||
-rw-r--r-- | sys/compat/linux/linux_sysctl.c | 4 | ||||
-rw-r--r-- | sys/compat/linux/linux_uid16.c | 4 |
8 files changed, 211 insertions, 31 deletions
diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c index 79a8ba9..b0d054d 100644 --- a/sys/compat/linux/linux_file.c +++ b/sys/compat/linux/linux_file.c @@ -54,8 +54,6 @@ __FBSDID("$FreeBSD$"); #include <ufs/ufs/quota.h> #include <ufs/ufs/ufsmount.h> -#include "opt_compat.h" - #ifdef COMPAT_LINUX32 #include <machine/../linux32/linux.h> #include <machine/../linux32/linux32_proto.h> @@ -669,6 +667,21 @@ linux_truncate(struct thread *td, struct linux_truncate_args *args) } int +linux_ftruncate(struct thread *td, struct linux_ftruncate_args *args) +{ + struct ftruncate_args /* { + int fd; + int pad; + off_t length; + } */ nuap; + + nuap.fd = args->fd; + nuap.pad = 0; + nuap.length = args->length; + return (ftruncate(td, &nuap)); +} + +int linux_link(struct thread *td, struct linux_link_args *args) { char *path, *to; diff --git a/sys/compat/linux/linux_getcwd.c b/sys/compat/linux/linux_getcwd.c index 2835d5c..90f40cf 100644 --- a/sys/compat/linux/linux_getcwd.c +++ b/sys/compat/linux/linux_getcwd.c @@ -59,8 +59,6 @@ __FBSDID("$FreeBSD$"); #include <sys/dirent.h> #include <ufs/ufs/dir.h> /* XXX only for DIRBLKSIZ */ -#include "opt_compat.h" - #ifdef COMPAT_LINUX32 #include <machine/../linux32/linux.h> #include <machine/../linux32/linux32_proto.h> diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c index 14568e2..a8e494d 100644 --- a/sys/compat/linux/linux_ioctl.c +++ b/sys/compat/linux/linux_ioctl.c @@ -2280,6 +2280,29 @@ linux_gifhwaddr(struct ifnet *ifp, struct l_ifreq *ifr) return (ENOENT); } + + /* +* If we fault in bsd_to_linux_ifreq() then we will fault when we call +* the native ioctl(). Thus, we don't really need to check the return +* value of this function. +*/ +static int +bsd_to_linux_ifreq(struct ifreq *arg) +{ + struct ifreq ifr; + size_t ifr_len = sizeof(struct ifreq); + int error; + + if ((error = copyin(arg, &ifr, ifr_len))) + return (error); + + *(u_short *)&ifr.ifr_addr = ifr.ifr_addr.sa_family; + + error = copyout(&ifr, arg, ifr_len); + + return (error); +} + /* * Socket related ioctls */ @@ -2411,8 +2434,9 @@ linux_ioctl_socket(struct thread *td, struct linux_ioctl_args *args) break; case LINUX_SIOCGIFADDR: - args->cmd = OSIOCGIFADDR; + args->cmd = SIOCGIFADDR; error = ioctl(td, (struct ioctl_args *)args); + bsd_to_linux_ifreq((struct ifreq *)args->arg); break; case LINUX_SIOCSIFADDR: @@ -2422,18 +2446,21 @@ linux_ioctl_socket(struct thread *td, struct linux_ioctl_args *args) break; case LINUX_SIOCGIFDSTADDR: - args->cmd = OSIOCGIFDSTADDR; + args->cmd = SIOCGIFDSTADDR; error = ioctl(td, (struct ioctl_args *)args); + bsd_to_linux_ifreq((struct ifreq *)args->arg); break; case LINUX_SIOCGIFBRDADDR: - args->cmd = OSIOCGIFBRDADDR; + args->cmd = SIOCGIFBRDADDR; error = ioctl(td, (struct ioctl_args *)args); + bsd_to_linux_ifreq((struct ifreq *)args->arg); break; case LINUX_SIOCGIFNETMASK: - args->cmd = OSIOCGIFNETMASK; + args->cmd = SIOCGIFNETMASK; error = ioctl(td, (struct ioctl_args *)args); + bsd_to_linux_ifreq((struct ifreq *)args->arg); break; case LINUX_SIOCSIFNETMASK: diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index 758d756..a63c2a3 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -30,6 +30,7 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include "opt_compat.h" #include "opt_mac.h" #include <sys/param.h> @@ -72,8 +73,6 @@ __FBSDID("$FreeBSD$"); #include <posix4/sched.h> -#include "opt_compat.h" - #include <compat/linux/linux_sysproto.h> #ifdef COMPAT_LINUX32 @@ -1402,3 +1401,19 @@ linux_getpriority(struct thread *td, struct linux_getpriority_args *args) td->td_retval[0] = 20 - td->td_retval[0]; return error; } + +int +linux_sethostname(struct thread *td, struct linux_sethostname_args *args) +{ + struct proc *p = td->td_proc; + int name[2]; + int error; + + name[0] = CTL_KERN; + name[1] = KERN_HOSTNAME; + if ((error = suser_cred(p->p_ucred, SUSER_ALLOWJAIL))) + return (error); + return (userland_sysctl(td, name, 2, 0, 0, 0, args->hostname, + args->len, 0, 0)); +} + diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index ce1135c..e7e98f8 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -33,10 +33,6 @@ __FBSDID("$FreeBSD$"); #include "opt_compat.h" #include "opt_inet6.h" -#ifndef COMPAT_43 -#error "Unable to compile Linux-emulator due to missing COMPAT_43 option!" -#endif - #include <sys/param.h> #include <sys/proc.h> #include <sys/systm.h> @@ -62,8 +58,6 @@ __FBSDID("$FreeBSD$"); #include <netinet6/ip6_var.h> #endif -#include "opt_compat.h" - #ifdef COMPAT_LINUX32 #include <machine/../linux32/linux.h> #include <machine/../linux32/linux32_proto.h> @@ -343,6 +337,48 @@ linux_to_bsd_msg_flags(int flags) return ret_flags; } +/* +* If bsd_to_linux_sockaddr() or linux_to_bsd_sockaddr() faults, then the +* native syscall will fault. Thus, we don't really need to check the +* return values for these functions. +*/ + +static int +bsd_to_linux_sockaddr(struct sockaddr *arg) +{ + struct sockaddr sa; + size_t sa_len = sizeof(struct sockaddr); + int error; + + if ((error = copyin(arg, &sa, sa_len))) + return (error); + + *(u_short *)&sa = sa.sa_family; + + error = copyout(&sa, arg, sa_len); + + return (error); +} + +static int +linux_to_bsd_sockaddr(struct sockaddr *arg, int len) +{ + struct sockaddr sa; + size_t sa_len = sizeof(struct sockaddr); + int error; + + if ((error = copyin(arg, &sa, sa_len))) + return (error); + + sa.sa_family = *(sa_family_t *)&sa; + sa.sa_len = len; + + error = copyout(&sa, arg, sa_len); + + return (error); +} + + static int linux_sa_put(struct osockaddr *osa) { @@ -685,7 +721,8 @@ linux_accept(struct thread *td, struct linux_accept_args *args) /* XXX: */ bsd_args.name = (struct sockaddr * __restrict)PTRIN(linux_args.addr); bsd_args.anamelen = PTRIN(linux_args.namelen);/* XXX */ - error = oaccept(td, &bsd_args); + error = accept(td, &bsd_args); + bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.name); if (error) return (error); if (linux_args.addr) { @@ -732,7 +769,8 @@ linux_getsockname(struct thread *td, struct linux_getsockname_args *args) /* XXX: */ bsd_args.asa = (struct sockaddr * __restrict)PTRIN(linux_args.addr); bsd_args.alen = PTRIN(linux_args.namelen); /* XXX */ - error = ogetsockname(td, &bsd_args); + error = getsockname(td, &bsd_args); + bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.asa); if (error) return (error); error = linux_sa_put(PTRIN(linux_args.addr)); @@ -751,7 +789,7 @@ static int linux_getpeername(struct thread *td, struct linux_getpeername_args *args) { struct linux_getpeername_args linux_args; - struct ogetpeername_args /* { + struct getpeername_args /* { int fdes; caddr_t asa; int *alen; @@ -762,9 +800,10 @@ linux_getpeername(struct thread *td, struct linux_getpeername_args *args) return (error); bsd_args.fdes = linux_args.s; - bsd_args.asa = (caddr_t)PTRIN(linux_args.addr); + bsd_args.asa = (struct sockaddr *)PTRIN(linux_args.addr); bsd_args.alen = (int *)PTRIN(linux_args.namelen); - error = ogetpeername(td, &bsd_args); + error = getpeername(td, &bsd_args); + bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.asa); if (error) return (error); error = linux_sa_put(PTRIN(linux_args.addr)); @@ -920,11 +959,15 @@ linux_recvfrom(struct thread *td, struct linux_recvfrom_args *args) struct sockaddr * __restrict from; socklen_t * __restrict fromlenaddr; } */ bsd_args; + size_t len; int error; if ((error = copyin(args, &linux_args, sizeof(linux_args)))) return (error); + if ((error = copyin(PTRIN(linux_args.fromlen), &len, sizeof(size_t)))) + return (error); + bsd_args.s = linux_args.s; bsd_args.buf = PTRIN(linux_args.buf); bsd_args.len = linux_args.len; @@ -932,7 +975,11 @@ linux_recvfrom(struct thread *td, struct linux_recvfrom_args *args) /* XXX: */ bsd_args.from = (struct sockaddr * __restrict)PTRIN(linux_args.from); bsd_args.fromlenaddr = PTRIN(linux_args.fromlen);/* XXX */ - error = orecvfrom(td, &bsd_args); + + linux_to_bsd_sockaddr((struct sockaddr *)bsd_args.from, len); + error = recvfrom(td, &bsd_args); + bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.from); + if (error) return (error); if (linux_args.from) { @@ -1004,7 +1051,13 @@ linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args) bsd_args.s = linux_args.s; bsd_args.msg = PTRIN(linux_args.msg); bsd_args.flags = linux_to_bsd_msg_flags(linux_args.flags); - error = recvmsg(td, &bsd_args); + if (msg.msg_name) { + linux_to_bsd_sockaddr((struct sockaddr *)msg.msg_name, + msg.msg_namelen); + error = recvmsg(td, &bsd_args); + bsd_to_linux_sockaddr((struct sockaddr *)msg.msg_name); + } else + error = recvmsg(td, &bsd_args); if (error) return (error); @@ -1092,7 +1145,16 @@ linux_setsockopt(struct thread *td, struct linux_setsockopt_args *args) bsd_args.name = name; bsd_args.val = PTRIN(linux_args.optval); bsd_args.valsize = linux_args.optlen; - return (setsockopt(td, &bsd_args)); + + if (name == IPV6_NEXTHOP) { + linux_to_bsd_sockaddr((struct sockaddr *)bsd_args.val, + bsd_args.valsize); + error = setsockopt(td, &bsd_args); + bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.val); + } else + error = setsockopt(td, &bsd_args); + + return (error); } struct linux_getsockopt_args { @@ -1142,7 +1204,14 @@ linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args) bsd_args.name = name; bsd_args.val = PTRIN(linux_args.optval); bsd_args.avalsize = PTRIN(linux_args.optlen); - return (getsockopt(td, &bsd_args)); + + if (name == IPV6_NEXTHOP) { + error = getsockopt(td, &bsd_args); + bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.val); + } else + error = getsockopt(td, &bsd_args); + + return (error); } int diff --git a/sys/compat/linux/linux_stats.c b/sys/compat/linux/linux_stats.c index b5be68a..f4f1bbd 100644 --- a/sys/compat/linux/linux_stats.c +++ b/sys/compat/linux/linux_stats.c @@ -29,6 +29,7 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include "opt_compat.h" #include "opt_mac.h" #include <sys/param.h> @@ -46,8 +47,6 @@ __FBSDID("$FreeBSD$"); #include <sys/systm.h> #include <sys/vnode.h> -#include "opt_compat.h" - #ifdef COMPAT_LINUX32 #include <machine/../linux32/linux.h> #include <machine/../linux32/linux32_proto.h> @@ -187,6 +186,65 @@ linux_newfstat(struct thread *td, struct linux_newfstat_args *args) return (error); } +static int +stat_copyout(struct stat *buf, void *ubuf) +{ + struct l_stat lbuf; + + bzero(&lbuf, sizeof(lbuf)); + lbuf.st_dev = buf->st_dev; + lbuf.st_ino = buf->st_ino; + lbuf.st_mode = buf->st_mode; + lbuf.st_nlink = buf->st_nlink; + lbuf.st_uid = buf->st_uid; + lbuf.st_gid = buf->st_gid; + lbuf.st_rdev = buf->st_rdev; + if (buf->st_size < (quad_t)1 << 32) + lbuf.st_size = buf->st_size; + else + lbuf.st_size = -2; + lbuf.st_atime = buf->st_atime; + lbuf.st_mtime = buf->st_mtime; + lbuf.st_ctime = buf->st_ctime; + lbuf.st_blksize = buf->st_blksize; + lbuf.st_blocks = buf->st_blocks; + lbuf.st_flags = buf->st_flags; + lbuf.st_gen = buf->st_gen; + + return (copyout(&lbuf, ubuf, sizeof(lbuf))); +} + +int +linux_stat(struct thread *td, struct linux_stat_args *args) +{ + struct stat buf; + int error; +#ifdef DEBUG + if (ldebug(stat)) + printf(ARGS(stat, "%s, *"), args->path); +#endif + error = kern_stat(td, args->path, UIO_SYSSPACE, &buf); + if (error) + return (error); + return(stat_copyout(&buf, args->up)); +} + +int +linux_lstat(struct thread *td, struct linux_lstat_args *args) +{ + struct stat buf; + int error; + +#ifdef DEBUG + if (ldebug(lstat)) + printf(ARGS(lstat, "%s, *"), args->path); +#endif + error = kern_lstat(td, args->path, UIO_SYSSPACE, &buf); + if (error) + return (error); + return(stat_copyout(&buf, args->up)); +} + /* XXX - All fields of type l_int are defined as l_long on i386 */ struct l_statfs { l_int f_type; diff --git a/sys/compat/linux/linux_sysctl.c b/sys/compat/linux/linux_sysctl.c index f20a1de..9111dbe 100644 --- a/sys/compat/linux/linux_sysctl.c +++ b/sys/compat/linux/linux_sysctl.c @@ -29,6 +29,8 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include "opt_compat.h" + #include <sys/param.h> #include <sys/lock.h> #include <sys/malloc.h> @@ -38,8 +40,6 @@ __FBSDID("$FreeBSD$"); #include <sys/systm.h> #include <sys/sbuf.h> -#include "opt_compat.h" - #ifdef COMPAT_LINUX32 #include <machine/../linux32/linux.h> #include <machine/../linux32/linux32_proto.h> diff --git a/sys/compat/linux/linux_uid16.c b/sys/compat/linux/linux_uid16.c index 52a6df2..ba01aef 100644 --- a/sys/compat/linux/linux_uid16.c +++ b/sys/compat/linux/linux_uid16.c @@ -27,6 +27,8 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include "opt_compat.h" + #include <sys/param.h> #include <sys/lock.h> #include <sys/malloc.h> @@ -36,8 +38,6 @@ __FBSDID("$FreeBSD$"); #include <sys/sysproto.h> #include <sys/systm.h> -#include "opt_compat.h" - #ifdef COMPAT_LINUX32 #include <machine/../linux32/linux.h> #include <machine/../linux32/linux32_proto.h> |