summaryrefslogtreecommitdiffstats
path: root/sys/compat
diff options
context:
space:
mode:
authornetchild <netchild@FreeBSD.org>2006-03-18 18:20:17 +0000
committernetchild <netchild@FreeBSD.org>2006-03-18 18:20:17 +0000
commitc1829f604cdf8a3f393bfa6cb85fe9a6d4908919 (patch)
tree0bfbd4f21076e4935e7376b8d0502c8d258d4cfa /sys/compat
parentd4f801f4ab01a2c0d88e59ddabc9757533800554 (diff)
downloadFreeBSD-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.c17
-rw-r--r--sys/compat/linux/linux_getcwd.c2
-rw-r--r--sys/compat/linux/linux_ioctl.c35
-rw-r--r--sys/compat/linux/linux_misc.c19
-rw-r--r--sys/compat/linux/linux_socket.c99
-rw-r--r--sys/compat/linux/linux_stats.c62
-rw-r--r--sys/compat/linux/linux_sysctl.c4
-rw-r--r--sys/compat/linux/linux_uid16.c4
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>
OpenPOWER on IntegriCloud