patch-2.4.0-test2 linux/arch/ia64/ia32/sys_ia32.c
Next file: linux/arch/ia64/kernel/Makefile
Previous file: linux/arch/ia64/ia32/ia32_traps.c
Back to the patch index
Back to the overall index
- Lines: 1369
- Date:
Thu Jun 22 07:09:44 2000
- Orig file:
v2.4.0-test1/linux/arch/ia64/ia32/sys_ia32.c
- Orig date:
Tue May 23 15:31:33 2000
diff -u --recursive --new-file v2.4.0-test1/linux/arch/ia64/ia32/sys_ia32.c linux/arch/ia64/ia32/sys_ia32.c
@@ -7,6 +7,8 @@
* Copyright (C) 1999 Arun Sharma <arun.sharma@intel.com>
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 2000 Hewlett-Packard Co.
+ * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com>
*
* These routines maintain argument size conversion between 32bit and 64bit
* environment.
@@ -55,24 +57,29 @@
#include <net/sock.h>
#include <asm/ia32.h>
-#define A(__x) ((unsigned long)(__x))
-#define AA(__x) ((unsigned long)(__x))
+#define A(__x) ((unsigned long)(__x))
+#define AA(__x) ((unsigned long)(__x))
+#define ROUND_UP(x,a) ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1)))
+#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
+
+extern asmlinkage long sys_execve (char *, char **, char **, struct pt_regs *);
+extern asmlinkage long sys_munmap (unsigned long, size_t len);
+extern asmlinkage long sys_mprotect (unsigned long, size_t, unsigned long);
static int
nargs(unsigned int arg, char **ap)
{
- char *ptr;
- int n, err;
+ int n, err, addr;
n = 0;
do {
- if (err = get_user(ptr, (int *)arg))
+ if ((err = get_user(addr, (int *)A(arg))) != 0)
return(err);
if (ap)
- *ap++ = ptr;
+ *ap++ = (char *)A(addr);
arg += sizeof(unsigned int);
n++;
- } while (ptr);
+ } while (addr);
return(n - 1);
}
@@ -106,14 +113,14 @@
down(¤t->mm->mmap_sem);
lock_kernel();
- av = do_mmap_pgoff(0, NULL, len,
- PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0);
+ av = (char **) do_mmap_pgoff(0, 0UL, len, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, 0);
unlock_kernel();
up(¤t->mm->mmap_sem);
if (IS_ERR(av))
- return(av);
+ return (long)av;
ae = av + na + 1;
av[na] = (char *)0;
ae[ne] = (char *)0;
@@ -121,7 +128,7 @@
(void)nargs(envp, ae);
r = sys_execve(filename, av, ae, regs);
if (IS_ERR(r))
- sys_munmap(av, len);
+ sys_munmap((unsigned long) av, len);
return(r);
}
@@ -146,9 +153,9 @@
return err;
}
-extern asmlinkage int sys_newstat(char * filename, struct stat * statbuf);
+extern asmlinkage long sys_newstat(char * filename, struct stat * statbuf);
-asmlinkage int
+asmlinkage long
sys32_newstat(char * filename, struct stat32 *statbuf)
{
int ret;
@@ -163,9 +170,9 @@
return ret;
}
-extern asmlinkage int sys_newlstat(char * filename, struct stat * statbuf);
+extern asmlinkage long sys_newlstat(char * filename, struct stat * statbuf);
-asmlinkage int
+asmlinkage long
sys32_newlstat(char * filename, struct stat32 *statbuf)
{
int ret;
@@ -180,9 +187,9 @@
return ret;
}
-extern asmlinkage int sys_newfstat(unsigned int fd, struct stat * statbuf);
+extern asmlinkage long sys_newfstat(unsigned int fd, struct stat * statbuf);
-asmlinkage int
+asmlinkage long
sys32_newfstat(unsigned int fd, struct stat32 *statbuf)
{
int ret;
@@ -214,31 +221,26 @@
return -EINVAL;
if (prot & PROT_WRITE)
prot |= PROT_EXEC;
-#ifdef DDD
-#else // DDD
prot |= PROT_WRITE;
-#endif // DDD
front = NULL;
back = NULL;
if ((baddr = (addr & PAGE_MASK)) != addr && get_user(c, (char *)baddr) == 0) {
front = kmalloc(addr - baddr, GFP_KERNEL);
memcpy(front, (void *)baddr, addr - baddr);
}
-#ifndef DDD
- if (addr)
-#endif
- if (((addr + len) & ~PAGE_MASK) && get_user(c, (char *)(addr + len)) == 0) {
+ if (addr && ((addr + len) & ~PAGE_MASK) && get_user(c, (char *)(addr + len)) == 0) {
back = kmalloc(PAGE_SIZE - ((addr + len) & ~PAGE_MASK), GFP_KERNEL);
- memcpy(back, addr + len, PAGE_SIZE - ((addr + len) & ~PAGE_MASK));
+ memcpy(back, (char *)addr + len, PAGE_SIZE - ((addr + len) & ~PAGE_MASK));
}
- if ((r = do_mmap(0, baddr, len + (addr - baddr), prot, flags | MAP_ANONYMOUS, 0)) < 0)
+ down(¤t->mm->mmap_sem);
+ r = do_mmap(0, baddr, len + (addr - baddr), prot, flags | MAP_ANONYMOUS, 0);
+ up(¤t->mm->mmap_sem);
+ if (r < 0)
return(r);
-#ifndef DDD
if (addr == 0)
addr = r;
-#endif // DDD
if (back) {
- memcpy(addr + len, back, PAGE_SIZE - ((addr + len) & ~PAGE_MASK));
+ memcpy((char *)addr + len, back, PAGE_SIZE - ((addr + len) & ~PAGE_MASK));
kfree(back);
}
if (front) {
@@ -246,7 +248,7 @@
kfree(front);
}
if (flags & MAP_ANONYMOUS) {
- memset(addr, 0, len);
+ memset((char *)addr, 0, len);
return(addr);
}
if (!file)
@@ -280,7 +282,7 @@
unsigned int offset;
};
-asmlinkage int
+asmlinkage long
sys32_mmap(struct mmap_arg_struct *arg)
{
int error = -EFAULT;
@@ -290,7 +292,6 @@
if (copy_from_user(&a, arg, sizeof(a)))
return -EFAULT;
- down(¤t->mm->mmap_sem);
lock_kernel();
if (!(a.flags & MAP_ANONYMOUS)) {
error = -EBADF;
@@ -300,23 +301,19 @@
}
a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-#ifdef DDD
if ((a.flags & MAP_FIXED) && ((a.addr & ~PAGE_MASK) || (a.offset & ~PAGE_MASK))) {
-#else // DDD
- if (1) {
-#endif // DDD
unlock_kernel();
- up(¤t->mm->mmap_sem);
error = do_mmap_fake(file, a.addr, a.len, a.prot, a.flags, a.offset);
- down(¤t->mm->mmap_sem);
lock_kernel();
- } else
+ } else {
+ down(¤t->mm->mmap_sem);
error = do_mmap(file, a.addr, a.len, a.prot, a.flags, a.offset);
+ up(¤t->mm->mmap_sem);
+ }
if (file)
fput(file);
out:
unlock_kernel();
- up(¤t->mm->mmap_sem);
return error;
}
@@ -349,7 +346,7 @@
return(sys_mprotect(start & PAGE_MASK, len & PAGE_MASK, prot));
}
-asmlinkage int
+asmlinkage long
sys32_rt_sigaction(int sig, struct sigaction32 *act,
struct sigaction32 *oact, unsigned int sigsetsize)
{
@@ -408,10 +405,10 @@
}
-extern asmlinkage int sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset,
- size_t sigsetsize);
+extern asmlinkage long sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset,
+ size_t sigsetsize);
-asmlinkage int
+asmlinkage long
sys32_rt_sigprocmask(int how, sigset32_t *set, sigset32_t *oset,
unsigned int sigsetsize)
{
@@ -466,9 +463,9 @@
return err;
}
-extern asmlinkage int sys_statfs(const char * path, struct statfs * buf);
+extern asmlinkage long sys_statfs(const char * path, struct statfs * buf);
-asmlinkage int
+asmlinkage long
sys32_statfs(const char * path, struct statfs32 *buf)
{
int ret;
@@ -483,9 +480,9 @@
return ret;
}
-extern asmlinkage int sys_fstatfs(unsigned int fd, struct statfs * buf);
+extern asmlinkage long sys_fstatfs(unsigned int fd, struct statfs * buf);
-asmlinkage int
+asmlinkage long
sys32_fstatfs(unsigned int fd, struct statfs32 *buf)
{
int ret;
@@ -552,7 +549,7 @@
extern int do_getitimer(int which, struct itimerval *value);
-asmlinkage int
+asmlinkage long
sys32_getitimer(int which, struct itimerval32 *it)
{
struct itimerval kit;
@@ -567,7 +564,7 @@
extern int do_setitimer(int which, struct itimerval *, struct itimerval *);
-asmlinkage int
+asmlinkage long
sys32_setitimer(int which, struct itimerval32 *in, struct itimerval32 *out)
{
struct itimerval kin, kout;
@@ -612,7 +609,7 @@
extern struct timezone sys_tz;
extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
-asmlinkage int
+asmlinkage long
sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz)
{
if (tv) {
@@ -628,7 +625,7 @@
return 0;
}
-asmlinkage int
+asmlinkage long
sys32_settimeofday(struct timeval32 *tv, struct timezone *tz)
{
struct timeval ktv;
@@ -646,56 +643,135 @@
return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
}
-struct dirent32 {
- unsigned int d_ino;
- unsigned int d_off;
- unsigned short d_reclen;
- char d_name[NAME_MAX + 1];
+struct linux32_dirent {
+ u32 d_ino;
+ u32 d_off;
+ u16 d_reclen;
+ char d_name[1];
};
-static void
-xlate_dirent(void *dirent64, void *dirent32, long n)
+struct old_linux32_dirent {
+ u32 d_ino;
+ u32 d_offset;
+ u16 d_namlen;
+ char d_name[1];
+};
+
+struct getdents32_callback {
+ struct linux32_dirent * current_dir;
+ struct linux32_dirent * previous;
+ int count;
+ int error;
+};
+
+struct readdir32_callback {
+ struct old_linux32_dirent * dirent;
+ int count;
+};
+
+static int
+filldir32 (void *__buf, const char *name, int namlen, off_t offset, ino_t ino)
{
- long off;
- struct dirent *dirp;
- struct dirent32 *dirp32;
-
- off = 0;
- while (off < n) {
- dirp = (struct dirent *)(dirent64 + off);
- dirp32 = (struct dirent32 *)(dirent32 + off);
- off += dirp->d_reclen;
- dirp32->d_ino = dirp->d_ino;
- dirp32->d_off = (unsigned int)dirp->d_off;
- dirp32->d_reclen = dirp->d_reclen;
- strncpy(dirp32->d_name, dirp->d_name, dirp->d_reclen - ((3 * 4) + 2));
- }
- return;
+ struct linux32_dirent * dirent;
+ struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
+ int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4);
+
+ buf->error = -EINVAL; /* only used if we fail.. */
+ if (reclen > buf->count)
+ return -EINVAL;
+ dirent = buf->previous;
+ if (dirent)
+ put_user(offset, &dirent->d_off);
+ dirent = buf->current_dir;
+ buf->previous = dirent;
+ put_user(ino, &dirent->d_ino);
+ put_user(reclen, &dirent->d_reclen);
+ copy_to_user(dirent->d_name, name, namlen);
+ put_user(0, dirent->d_name + namlen);
+ ((char *) dirent) += reclen;
+ buf->current_dir = dirent;
+ buf->count -= reclen;
+ return 0;
}
asmlinkage long
-sys32_getdents(unsigned int fd, void * dirent32, unsigned int count)
+sys32_getdents (unsigned int fd, void * dirent, unsigned int count)
+{
+ struct file * file;
+ struct linux32_dirent * lastdirent;
+ struct getdents32_callback buf;
+ int error;
+
+ error = -EBADF;
+ file = fget(fd);
+ if (!file)
+ goto out;
+
+ buf.current_dir = (struct linux32_dirent *) dirent;
+ buf.previous = NULL;
+ buf.count = count;
+ buf.error = 0;
+
+ lock_kernel();
+ error = vfs_readdir(file, filldir32, &buf);
+ if (error < 0)
+ goto out_putf;
+ error = buf.error;
+ lastdirent = buf.previous;
+ if (lastdirent) {
+ put_user(file->f_pos, &lastdirent->d_off);
+ error = count - buf.count;
+ }
+
+out_putf:
+ unlock_kernel();
+ fput(file);
+out:
+ return error;
+}
+
+static int
+fillonedir32 (void * __buf, const char * name, int namlen, off_t offset, ino_t ino)
{
- long n;
- void *dirent64;
+ struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
+ struct old_linux32_dirent * dirent;
- dirent64 = (unsigned long)(dirent32 + (sizeof(long) - 1)) & ~(sizeof(long) - 1);
- if ((n = sys_getdents(fd, dirent64, count - (dirent64 - dirent32))) < 0)
- return(n);
- xlate_dirent(dirent64, dirent32, n);
- return(n);
+ if (buf->count)
+ return -EINVAL;
+ buf->count++;
+ dirent = buf->dirent;
+ put_user(ino, &dirent->d_ino);
+ put_user(offset, &dirent->d_offset);
+ put_user(namlen, &dirent->d_namlen);
+ copy_to_user(dirent->d_name, name, namlen);
+ put_user(0, dirent->d_name + namlen);
+ return 0;
}
-asmlinkage int
-sys32_readdir(unsigned int fd, void * dirent32, unsigned int count)
+asmlinkage long
+sys32_readdir (unsigned int fd, void * dirent, unsigned int count)
{
- int n;
- struct dirent dirent64;
+ int error;
+ struct file * file;
+ struct readdir32_callback buf;
- if ((n = old_readdir(fd, &dirent64, count)) < 0)
- return(n);
- xlate_dirent(&dirent64, dirent32, dirent64.d_reclen);
- return(n);
+ error = -EBADF;
+ file = fget(fd);
+ if (!file)
+ goto out;
+
+ buf.count = 0;
+ buf.dirent = dirent;
+
+ lock_kernel();
+ error = vfs_readdir(file, fillonedir32, &buf);
+ if (error >= 0)
+ error = buf.count;
+ unlock_kernel();
+
+ fput(file);
+out:
+ return error;
}
/*
@@ -708,9 +784,9 @@
*/
#define MAX_SELECT_SECONDS \
((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
-#define ROUND_UP(x,y) (((x)+(y)-1)/(y))
+#define ROUND_UP_TIME(x,y) (((x)+(y)-1)/(y))
-asmlinkage int
+asmlinkage long
sys32_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval32 *tvp32)
{
fd_set_bits fds;
@@ -730,7 +806,7 @@
goto out_nofds;
if ((unsigned long) sec < MAX_SELECT_SECONDS) {
- timeout = ROUND_UP(usec, 1000000/HZ);
+ timeout = ROUND_UP_TIME(usec, 1000000/HZ);
timeout += sec * (unsigned long) HZ;
}
}
@@ -807,13 +883,15 @@
unsigned int tvp;
};
-asmlinkage int old_select(struct sel_arg_struct *arg)
+asmlinkage long
+old_select(struct sel_arg_struct *arg)
{
struct sel_arg_struct a;
if (copy_from_user(&a, arg, sizeof(a)))
return -EFAULT;
- return sys32_select(a.n, a.inp, a.outp, a.exp, a.tvp);
+ return sys32_select(a.n, (fd_set *)A(a.inp), (fd_set *)A(a.outp), (fd_set *)A(a.exp),
+ (struct timeval32 *)A(a.tvp));
}
struct timespec32 {
@@ -821,10 +899,9 @@
int tv_nsec;
};
-extern asmlinkage int sys_nanosleep(struct timespec *rqtp,
- struct timespec *rmtp);
+extern asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
-asmlinkage int
+asmlinkage long
sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
{
struct timespec t;
@@ -1005,9 +1082,9 @@
int rlim_max;
};
-extern asmlinkage int sys_getrlimit(unsigned int resource, struct rlimit *rlim);
+extern asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit *rlim);
-asmlinkage int
+asmlinkage long
sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim)
{
struct rlimit r;
@@ -1024,9 +1101,9 @@
return ret;
}
-extern asmlinkage int sys_setrlimit(unsigned int resource, struct rlimit *rlim);
+extern asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit *rlim);
-asmlinkage int
+asmlinkage long
sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim)
{
struct rlimit r;
@@ -1047,118 +1124,6 @@
return ret;
}
-/* Argument list sizes for sys_socketcall */
-#define AL(x) ((x) * sizeof(u32))
-static unsigned char nas[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
- AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
- AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};
-#undef AL
-
-extern asmlinkage int sys_bind(int fd, struct sockaddr *umyaddr, int addrlen);
-extern asmlinkage int sys_connect(int fd, struct sockaddr *uservaddr,
- int addrlen);
-extern asmlinkage int sys_accept(int fd, struct sockaddr *upeer_sockaddr,
- int *upeer_addrlen);
-extern asmlinkage int sys_getsockname(int fd, struct sockaddr *usockaddr,
- int *usockaddr_len);
-extern asmlinkage int sys_getpeername(int fd, struct sockaddr *usockaddr,
- int *usockaddr_len);
-extern asmlinkage int sys_send(int fd, void *buff, size_t len, unsigned flags);
-extern asmlinkage int sys_sendto(int fd, u32 buff, __kernel_size_t32 len,
- unsigned flags, u32 addr, int addr_len);
-extern asmlinkage int sys_recv(int fd, void *ubuf, size_t size, unsigned flags);
-extern asmlinkage int sys_recvfrom(int fd, u32 ubuf, __kernel_size_t32 size,
- unsigned flags, u32 addr, u32 addr_len);
-extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
- char *optval, int optlen);
-extern asmlinkage int sys_getsockopt(int fd, int level, int optname,
- u32 optval, u32 optlen);
-
-extern asmlinkage int sys_socket(int family, int type, int protocol);
-extern asmlinkage int sys_socketpair(int family, int type, int protocol,
- int usockvec[2]);
-extern asmlinkage int sys_shutdown(int fd, int how);
-extern asmlinkage int sys_listen(int fd, int backlog);
-
-asmlinkage int sys32_socketcall(int call, u32 *args)
-{
- int i, ret;
- u32 a[6];
- u32 a0,a1;
-
- if (call<SYS_SOCKET||call>SYS_RECVMSG)
- return -EINVAL;
- if (copy_from_user(a, args, nas[call]))
- return -EFAULT;
- a0=a[0];
- a1=a[1];
-
- switch(call)
- {
- case SYS_SOCKET:
- ret = sys_socket(a0, a1, a[2]);
- break;
- case SYS_BIND:
- ret = sys_bind(a0, (struct sockaddr *)A(a1), a[2]);
- break;
- case SYS_CONNECT:
- ret = sys_connect(a0, (struct sockaddr *)A(a1), a[2]);
- break;
- case SYS_LISTEN:
- ret = sys_listen(a0, a1);
- break;
- case SYS_ACCEPT:
- ret = sys_accept(a0, (struct sockaddr *)A(a1),
- (int *)A(a[2]));
- break;
- case SYS_GETSOCKNAME:
- ret = sys_getsockname(a0, (struct sockaddr *)A(a1),
- (int *)A(a[2]));
- break;
- case SYS_GETPEERNAME:
- ret = sys_getpeername(a0, (struct sockaddr *)A(a1),
- (int *)A(a[2]));
- break;
- case SYS_SOCKETPAIR:
- ret = sys_socketpair(a0, a1, a[2], (int *)A(a[3]));
- break;
- case SYS_SEND:
- ret = sys_send(a0, (void *)A(a1), a[2], a[3]);
- break;
- case SYS_SENDTO:
- ret = sys_sendto(a0, a1, a[2], a[3], a[4], a[5]);
- break;
- case SYS_RECV:
- ret = sys_recv(a0, (void *)A(a1), a[2], a[3]);
- break;
- case SYS_RECVFROM:
- ret = sys_recvfrom(a0, a1, a[2], a[3], a[4], a[5]);
- break;
- case SYS_SHUTDOWN:
- ret = sys_shutdown(a0,a1);
- break;
- case SYS_SETSOCKOPT:
- ret = sys_setsockopt(a0, a1, a[2], (char *)A(a[3]),
- a[4]);
- break;
- case SYS_GETSOCKOPT:
- ret = sys_getsockopt(a0, a1, a[2], a[3], a[4]);
- break;
- case SYS_SENDMSG:
- ret = sys32_sendmsg(a0, (struct msghdr32 *)A(a1),
- a[2]);
- break;
- case SYS_RECVMSG:
- ret = sys32_recvmsg(a0, (struct msghdr32 *)A(a1),
- a[2]);
- break;
- default:
- ret = EINVAL;
- break;
- }
- return ret;
-}
-
/*
* Declare the IA32 version of the msghdr
*/
@@ -1181,13 +1146,13 @@
if (!access_ok(VERIFY_READ, mp32, sizeof(*mp32)))
return(-EFAULT);
__get_user(i, &mp32->msg_name);
- mp->msg_name = (void *)i;
+ mp->msg_name = (void *)A(i);
__get_user(mp->msg_namelen, &mp32->msg_namelen);
__get_user(i, &mp32->msg_iov);
- mp->msg_iov = (struct iov *)i;
+ mp->msg_iov = (struct iovec *)A(i);
__get_user(mp->msg_iovlen, &mp32->msg_iovlen);
__get_user(i, &mp32->msg_control);
- mp->msg_control = (void *)i;
+ mp->msg_control = (void *)A(i);
__get_user(mp->msg_controllen, &mp32->msg_controllen);
__get_user(mp->msg_flags, &mp32->msg_flags);
return(0);
@@ -1233,7 +1198,7 @@
iov32 = (struct iovec32 *)iov;
for (ct = m->msg_iovlen; ct-- > 0; ) {
iov[ct].iov_len = (__kernel_size_t)iov32[ct].iov_len;
- iov[ct].iov_base = (void *)iov32[ct].iov_base;
+ iov[ct].iov_base = (void *) A(iov32[ct].iov_base);
err += iov[ct].iov_len;
}
out:
@@ -1258,7 +1223,7 @@
* BSD sendmsg interface
*/
-asmlinkage int sys32_sendmsg(int fd, struct msghdr32 *msg, unsigned flags)
+int sys32_sendmsg(int fd, struct msghdr32 *msg, unsigned flags)
{
struct socket *sock;
char address[MAX_SOCK_ADDR];
@@ -1337,7 +1302,8 @@
* BSD recvmsg interface
*/
-asmlinkage int sys32_recvmsg(int fd, struct msghdr32 *msg, unsigned int flags)
+int
+sys32_recvmsg (int fd, struct msghdr32 *msg, unsigned int flags)
{
struct socket *sock;
struct iovec iovstack[UIO_FASTIOV];
@@ -1419,6 +1385,118 @@
return err;
}
+/* Argument list sizes for sys_socketcall */
+#define AL(x) ((x) * sizeof(u32))
+static unsigned char nas[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
+ AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
+ AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};
+#undef AL
+
+extern asmlinkage long sys_bind(int fd, struct sockaddr *umyaddr, int addrlen);
+extern asmlinkage long sys_connect(int fd, struct sockaddr *uservaddr,
+ int addrlen);
+extern asmlinkage long sys_accept(int fd, struct sockaddr *upeer_sockaddr,
+ int *upeer_addrlen);
+extern asmlinkage long sys_getsockname(int fd, struct sockaddr *usockaddr,
+ int *usockaddr_len);
+extern asmlinkage long sys_getpeername(int fd, struct sockaddr *usockaddr,
+ int *usockaddr_len);
+extern asmlinkage long sys_send(int fd, void *buff, size_t len, unsigned flags);
+extern asmlinkage long sys_sendto(int fd, u32 buff, __kernel_size_t32 len,
+ unsigned flags, u32 addr, int addr_len);
+extern asmlinkage long sys_recv(int fd, void *ubuf, size_t size, unsigned flags);
+extern asmlinkage long sys_recvfrom(int fd, u32 ubuf, __kernel_size_t32 size,
+ unsigned flags, u32 addr, u32 addr_len);
+extern asmlinkage long sys_setsockopt(int fd, int level, int optname,
+ char *optval, int optlen);
+extern asmlinkage long sys_getsockopt(int fd, int level, int optname,
+ u32 optval, u32 optlen);
+
+extern asmlinkage long sys_socket(int family, int type, int protocol);
+extern asmlinkage long sys_socketpair(int family, int type, int protocol,
+ int usockvec[2]);
+extern asmlinkage long sys_shutdown(int fd, int how);
+extern asmlinkage long sys_listen(int fd, int backlog);
+
+asmlinkage long sys32_socketcall(int call, u32 *args)
+{
+ int ret;
+ u32 a[6];
+ u32 a0,a1;
+
+ if (call<SYS_SOCKET||call>SYS_RECVMSG)
+ return -EINVAL;
+ if (copy_from_user(a, args, nas[call]))
+ return -EFAULT;
+ a0=a[0];
+ a1=a[1];
+
+ switch(call)
+ {
+ case SYS_SOCKET:
+ ret = sys_socket(a0, a1, a[2]);
+ break;
+ case SYS_BIND:
+ ret = sys_bind(a0, (struct sockaddr *)A(a1), a[2]);
+ break;
+ case SYS_CONNECT:
+ ret = sys_connect(a0, (struct sockaddr *)A(a1), a[2]);
+ break;
+ case SYS_LISTEN:
+ ret = sys_listen(a0, a1);
+ break;
+ case SYS_ACCEPT:
+ ret = sys_accept(a0, (struct sockaddr *)A(a1),
+ (int *)A(a[2]));
+ break;
+ case SYS_GETSOCKNAME:
+ ret = sys_getsockname(a0, (struct sockaddr *)A(a1),
+ (int *)A(a[2]));
+ break;
+ case SYS_GETPEERNAME:
+ ret = sys_getpeername(a0, (struct sockaddr *)A(a1),
+ (int *)A(a[2]));
+ break;
+ case SYS_SOCKETPAIR:
+ ret = sys_socketpair(a0, a1, a[2], (int *)A(a[3]));
+ break;
+ case SYS_SEND:
+ ret = sys_send(a0, (void *)A(a1), a[2], a[3]);
+ break;
+ case SYS_SENDTO:
+ ret = sys_sendto(a0, a1, a[2], a[3], a[4], a[5]);
+ break;
+ case SYS_RECV:
+ ret = sys_recv(a0, (void *)A(a1), a[2], a[3]);
+ break;
+ case SYS_RECVFROM:
+ ret = sys_recvfrom(a0, a1, a[2], a[3], a[4], a[5]);
+ break;
+ case SYS_SHUTDOWN:
+ ret = sys_shutdown(a0,a1);
+ break;
+ case SYS_SETSOCKOPT:
+ ret = sys_setsockopt(a0, a1, a[2], (char *)A(a[3]),
+ a[4]);
+ break;
+ case SYS_GETSOCKOPT:
+ ret = sys_getsockopt(a0, a1, a[2], a[3], a[4]);
+ break;
+ case SYS_SENDMSG:
+ ret = sys32_sendmsg(a0, (struct msghdr32 *)A(a1),
+ a[2]);
+ break;
+ case SYS_RECVMSG:
+ ret = sys32_recvmsg(a0, (struct msghdr32 *)A(a1),
+ a[2]);
+ break;
+ default:
+ ret = EINVAL;
+ break;
+ }
+ return ret;
+}
+
/*
* sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
*
@@ -1613,7 +1691,7 @@
static int
do_sys32_msgctl (int first, int second, void *uptr)
{
- int err, err2;
+ int err = -EINVAL, err2;
struct msqid_ds m;
struct msqid64_ds m64;
struct msqid_ds32 *up = (struct msqid_ds32 *)uptr;
@@ -1644,7 +1722,7 @@
case MSG_STAT:
old_fs = get_fs ();
set_fs (KERNEL_DS);
- err = sys_msgctl (first, second, &m64);
+ err = sys_msgctl (first, second, (void *) &m64);
set_fs (old_fs);
err2 = put_user (m64.msg_perm.key, &up->msg_perm.key);
err2 |= __put_user(m64.msg_perm.uid, &up->msg_perm.uid);
@@ -1725,7 +1803,7 @@
case SHM_STAT:
old_fs = get_fs ();
set_fs (KERNEL_DS);
- err = sys_shmctl (first, second, &s64);
+ err = sys_shmctl (first, second, (void *) &s64);
set_fs (old_fs);
if (err < 0)
break;
@@ -1753,7 +1831,7 @@
case SHM_INFO:
old_fs = get_fs ();
set_fs (KERNEL_DS);
- err = sys_shmctl (first, second, &si);
+ err = sys_shmctl (first, second, (void *)&si);
set_fs (old_fs);
if (err < 0)
break;
@@ -1773,7 +1851,7 @@
return err;
}
-asmlinkage int
+asmlinkage long
sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
{
int version, err;
@@ -1898,10 +1976,10 @@
return err;
}
-extern asmlinkage int sys_wait4(pid_t pid,unsigned int * stat_addr,
+extern asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr,
int options, struct rusage * ru);
-asmlinkage int
+asmlinkage long
sys32_wait4(__kernel_pid_t32 pid, unsigned int *stat_addr, int options,
struct rusage32 *ru)
{
@@ -1923,17 +2001,17 @@
}
}
-asmlinkage int
+asmlinkage long
sys32_waitpid(__kernel_pid_t32 pid, unsigned int *stat_addr, int options)
{
return sys32_wait4(pid, stat_addr, options, NULL);
}
-extern asmlinkage int
+extern asmlinkage long
sys_getrusage(int who, struct rusage *ru);
-asmlinkage int
+asmlinkage long
sys32_getrusage(int who, struct rusage32 *ru)
{
struct rusage r;
@@ -2429,9 +2507,9 @@
/* 32-bit timeval and related flotsam. */
-extern asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on);
+extern asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int on);
-asmlinkage int
+asmlinkage long
sys32_ioperm(u32 from, u32 num, int on)
{
return sys_ioperm((unsigned long)from, (unsigned long)num, on);
@@ -2503,10 +2581,10 @@
__kernel_time_t32 dqb_itime;
};
-extern asmlinkage int sys_quotactl(int cmd, const char *special, int id,
+extern asmlinkage long sys_quotactl(int cmd, const char *special, int id,
caddr_t addr);
-asmlinkage int
+asmlinkage long
sys32_quotactl(int cmd, const char *special, int id, unsigned long addr)
{
int cmds = cmd >> SUBCMDSHIFT;
@@ -2550,13 +2628,13 @@
return err;
}
-extern asmlinkage int sys_utime(char * filename, struct utimbuf * times);
+extern asmlinkage long sys_utime(char * filename, struct utimbuf * times);
struct utimbuf32 {
__kernel_time_t32 actime, modtime;
};
-asmlinkage int
+asmlinkage long
sys32_utime(char * filename, struct utimbuf32 *times)
{
struct utimbuf t;
@@ -2640,10 +2718,10 @@
__put_user(*fdset, ufdset);
}
-extern asmlinkage int sys_sysfs(int option, unsigned long arg1,
+extern asmlinkage long sys_sysfs(int option, unsigned long arg1,
unsigned long arg2);
-asmlinkage int
+asmlinkage long
sys32_sysfs(int option, u32 arg1, u32 arg2)
{
return sys_sysfs(option, arg1, arg2);
@@ -2739,7 +2817,7 @@
#define SMBFS_NAME "smbfs"
#define NCPFS_NAME "ncpfs"
-asmlinkage int
+asmlinkage long
sys32_mount(char *dev_name, char *dir_name, char *type,
unsigned long new_flags, u32 data)
{
@@ -2813,9 +2891,9 @@
char _f[22];
};
-extern asmlinkage int sys_sysinfo(struct sysinfo *info);
+extern asmlinkage long sys_sysinfo(struct sysinfo *info);
-asmlinkage int
+asmlinkage long
sys32_sysinfo(struct sysinfo32 *info)
{
struct sysinfo s;
@@ -2841,10 +2919,10 @@
return ret;
}
-extern asmlinkage int sys_sched_rr_get_interval(pid_t pid,
+extern asmlinkage long sys_sched_rr_get_interval(pid_t pid,
struct timespec *interval);
-asmlinkage int
+asmlinkage long
sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval)
{
struct timespec t;
@@ -2860,10 +2938,10 @@
return ret;
}
-extern asmlinkage int sys_sigprocmask(int how, old_sigset_t *set,
+extern asmlinkage long sys_sigprocmask(int how, old_sigset_t *set,
old_sigset_t *oset);
-asmlinkage int
+asmlinkage long
sys32_sigprocmask(int how, old_sigset_t32 *set, old_sigset_t32 *oset)
{
old_sigset_t s;
@@ -2879,9 +2957,9 @@
return 0;
}
-extern asmlinkage int sys_sigpending(old_sigset_t *set);
+extern asmlinkage long sys_sigpending(old_sigset_t *set);
-asmlinkage int
+asmlinkage long
sys32_sigpending(old_sigset_t32 *set)
{
old_sigset_t s;
@@ -2895,9 +2973,9 @@
return ret;
}
-extern asmlinkage int sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
+extern asmlinkage long sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
-asmlinkage int
+asmlinkage long
sys32_rt_sigpending(sigset_t32 *set, __kernel_size_t32 sigsetsize)
{
sigset_t s;
@@ -3000,11 +3078,11 @@
return d;
}
-extern asmlinkage int
+extern asmlinkage long
sys_rt_sigtimedwait(const sigset_t *uthese, siginfo_t *uinfo,
const struct timespec *uts, size_t sigsetsize);
-asmlinkage int
+asmlinkage long
sys32_rt_sigtimedwait(sigset_t32 *uthese, siginfo_t32 *uinfo,
struct timespec32 *uts, __kernel_size_t32 sigsetsize)
{
@@ -3041,10 +3119,10 @@
return ret;
}
-extern asmlinkage int
+extern asmlinkage long
sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo);
-asmlinkage int
+asmlinkage long
sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo)
{
siginfo_t info;
@@ -3062,9 +3140,9 @@
return ret;
}
-extern asmlinkage int sys_setreuid(uid_t ruid, uid_t euid);
+extern asmlinkage long sys_setreuid(uid_t ruid, uid_t euid);
-asmlinkage int sys32_setreuid(__kernel_uid_t32 ruid, __kernel_uid_t32 euid)
+asmlinkage long sys32_setreuid(__kernel_uid_t32 ruid, __kernel_uid_t32 euid)
{
uid_t sruid, seuid;
@@ -3073,9 +3151,9 @@
return sys_setreuid(sruid, seuid);
}
-extern asmlinkage int sys_setresuid(uid_t ruid, uid_t euid, uid_t suid);
+extern asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid);
-asmlinkage int
+asmlinkage long
sys32_setresuid(__kernel_uid_t32 ruid, __kernel_uid_t32 euid,
__kernel_uid_t32 suid)
{
@@ -3087,9 +3165,9 @@
return sys_setresuid(sruid, seuid, ssuid);
}
-extern asmlinkage int sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
+extern asmlinkage long sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
-asmlinkage int
+asmlinkage long
sys32_getresuid(__kernel_uid_t32 *ruid, __kernel_uid_t32 *euid,
__kernel_uid_t32 *suid)
{
@@ -3105,9 +3183,9 @@
return ret;
}
-extern asmlinkage int sys_setregid(gid_t rgid, gid_t egid);
+extern asmlinkage long sys_setregid(gid_t rgid, gid_t egid);
-asmlinkage int
+asmlinkage long
sys32_setregid(__kernel_gid_t32 rgid, __kernel_gid_t32 egid)
{
gid_t srgid, segid;
@@ -3117,9 +3195,9 @@
return sys_setregid(srgid, segid);
}
-extern asmlinkage int sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid);
+extern asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid);
-asmlinkage int
+asmlinkage long
sys32_setresgid(__kernel_gid_t32 rgid, __kernel_gid_t32 egid,
__kernel_gid_t32 sgid)
{
@@ -3131,9 +3209,9 @@
return sys_setresgid(srgid, segid, ssgid);
}
-extern asmlinkage int sys_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid);
+extern asmlinkage long sys_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid);
-asmlinkage int
+asmlinkage long
sys32_getresgid(__kernel_gid_t32 *rgid, __kernel_gid_t32 *egid,
__kernel_gid_t32 *sgid)
{
@@ -3152,9 +3230,9 @@
return ret;
}
-extern asmlinkage int sys_getgroups(int gidsetsize, gid_t *grouplist);
+extern asmlinkage long sys_getgroups(int gidsetsize, gid_t *grouplist);
-asmlinkage int
+asmlinkage long
sys32_getgroups(int gidsetsize, __kernel_gid_t32 *grouplist)
{
gid_t gl[NGROUPS];
@@ -3171,9 +3249,9 @@
return ret;
}
-extern asmlinkage int sys_setgroups(int gidsetsize, gid_t *grouplist);
+extern asmlinkage long sys_setgroups(int gidsetsize, gid_t *grouplist);
-asmlinkage int
+asmlinkage long
sys32_setgroups(int gidsetsize, __kernel_gid_t32 *grouplist)
{
gid_t gl[NGROUPS];
@@ -3617,7 +3695,7 @@
kmsg->msg_control = (void *) orig_cmsg_uptr;
}
-asmlinkage int
+asmlinkage long
sys32_sendmsg(int fd, struct msghdr32 *user_msg, unsigned user_flags)
{
struct socket *sock;
@@ -3665,7 +3743,7 @@
return err;
}
-asmlinkage int
+asmlinkage long
sys32_recvmsg(int fd, struct msghdr32 *user_msg, unsigned int user_flags)
{
struct iovec iovstack[UIO_FASTIOV];
@@ -3756,7 +3834,7 @@
extern void check_pending(int signum);
-asmlinkage int
+asmlinkage long
sys32_sigaction (int sig, struct old_sigaction32 *act,
struct old_sigaction32 *oact)
{
@@ -3801,21 +3879,21 @@
return sys_create_module(name_user, (size_t)size);
}
-extern asmlinkage int sys_init_module(const char *name_user,
+extern asmlinkage long sys_init_module(const char *name_user,
struct module *mod_user);
/* Hey, when you're trying to init module, take time and prepare us a nice 64bit
* module structure, even if from 32bit modutils... Why to pollute kernel... :))
*/
-asmlinkage int
+asmlinkage long
sys32_init_module(const char *name_user, struct module *mod_user)
{
return sys_init_module(name_user, mod_user);
}
-extern asmlinkage int sys_delete_module(const char *name_user);
+extern asmlinkage long sys_delete_module(const char *name_user);
-asmlinkage int
+asmlinkage long
sys32_delete_module(const char *name_user)
{
return sys_delete_module(name_user);
@@ -4090,7 +4168,7 @@
return error;
}
-asmlinkage int
+asmlinkage long
sys32_query_module(char *name_user, int which, char *buf,
__kernel_size_t32 bufsize, u32 ret)
{
@@ -4158,9 +4236,9 @@
char name[60];
};
-extern asmlinkage int sys_get_kernel_syms(struct kernel_sym *table);
+extern asmlinkage long sys_get_kernel_syms(struct kernel_sym *table);
-asmlinkage int
+asmlinkage long
sys32_get_kernel_syms(struct kernel_sym32 *table)
{
int len, i;
@@ -4192,19 +4270,19 @@
return -ENOSYS;
}
-asmlinkage int
+asmlinkage long
sys32_init_module(const char *name_user, struct module *mod_user)
{
return -ENOSYS;
}
-asmlinkage int
+asmlinkage long
sys32_delete_module(const char *name_user)
{
return -ENOSYS;
}
-asmlinkage int
+asmlinkage long
sys32_query_module(const char *name_user, int which, char *buf, size_t bufsize,
size_t *ret)
{
@@ -4216,7 +4294,7 @@
return -ENOSYS;
}
-asmlinkage int
+asmlinkage long
sys32_get_kernel_syms(struct kernel_sym *table)
{
return -ENOSYS;
@@ -4432,7 +4510,7 @@
return err;
}
-extern asmlinkage int sys_nfsservctl(int cmd, void *arg, void *resp);
+extern asmlinkage long sys_nfsservctl(int cmd, void *arg, void *resp);
int asmlinkage
sys32_nfsservctl(int cmd, struct nfsctl_arg32 *arg32, union nfsctl_res32 *res32)
@@ -4503,9 +4581,9 @@
return err;
}
-asmlinkage int sys_utimes(char *, struct timeval *);
+asmlinkage long sys_utimes(char *, struct timeval *);
-asmlinkage int
+asmlinkage long
sys32_utimes(char *filename, struct timeval32 *tvs)
{
char *kfilename;
@@ -4533,7 +4611,7 @@
}
/* These are here just in case some old ia32 binary calls it. */
-asmlinkage int
+asmlinkage long
sys32_pause(void)
{
current->state = TASK_INTERRUPTIBLE;
@@ -4542,19 +4620,19 @@
}
/* PCI config space poking. */
-extern asmlinkage int sys_pciconfig_read(unsigned long bus,
+extern asmlinkage long sys_pciconfig_read(unsigned long bus,
unsigned long dfn,
unsigned long off,
unsigned long len,
unsigned char *buf);
-extern asmlinkage int sys_pciconfig_write(unsigned long bus,
+extern asmlinkage long sys_pciconfig_write(unsigned long bus,
unsigned long dfn,
unsigned long off,
unsigned long len,
unsigned char *buf);
-asmlinkage int
+asmlinkage long
sys32_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
{
return sys_pciconfig_read((unsigned long) bus,
@@ -4564,7 +4642,7 @@
(unsigned char *)AA(ubuf));
}
-asmlinkage int
+asmlinkage long
sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
{
return sys_pciconfig_write((unsigned long) bus,
@@ -4574,11 +4652,11 @@
(unsigned char *)AA(ubuf));
}
-extern asmlinkage int sys_prctl(int option, unsigned long arg2,
+extern asmlinkage long sys_prctl(int option, unsigned long arg2,
unsigned long arg3, unsigned long arg4,
unsigned long arg5);
-asmlinkage int
+asmlinkage long
sys32_prctl(int option, u32 arg2, u32 arg3, u32 arg4, u32 arg5)
{
return sys_prctl(option,
@@ -4589,9 +4667,9 @@
}
-extern asmlinkage int sys_newuname(struct new_utsname * name);
+extern asmlinkage long sys_newuname(struct new_utsname * name);
-asmlinkage int
+asmlinkage long
sys32_newuname(struct new_utsname * name)
{
int ret = sys_newuname(name);
@@ -4627,9 +4705,9 @@
}
-extern asmlinkage int sys_personality(unsigned long);
+extern asmlinkage long sys_personality(unsigned long);
-asmlinkage int
+asmlinkage long
sys32_personality(unsigned long personality)
{
int ret;
@@ -4646,7 +4724,7 @@
extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset,
size_t count);
-asmlinkage int
+asmlinkage long
sys32_sendfile(int out_fd, int in_fd, __kernel_off_t32 *offset, s32 count)
{
mm_segment_t old_fs = get_fs();
@@ -4683,7 +4761,7 @@
extern int do_adjtimex(struct timex *);
-asmlinkage int
+asmlinkage long
sys32_adjtimex(struct timex32 *utp)
{
struct timex txc;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)