patch-1.3.71 linux/arch/sparc/kernel/sys_sunos.c
Next file: linux/arch/sparc/kernel/systbls.S
Previous file: linux/arch/sparc/kernel/sys_sparc.c
Back to the patch index
Back to the overall index
- Lines: 411
- Date:
Mon Mar 4 08:49:56 1996
- Orig file:
v1.3.70/linux/arch/sparc/kernel/sys_sunos.c
- Orig date:
Sat Nov 25 19:04:37 1995
diff -u --recursive --new-file v1.3.70/linux/arch/sparc/kernel/sys_sunos.c linux/arch/sparc/kernel/sys_sunos.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sunos.c,v 1.20 1995/11/25 00:58:37 davem Exp $
+/* $Id: sys_sunos.c,v 1.33 1996/03/01 07:16:00 davem Exp $
* sys_sunos.c: SunOS specific syscall compatability support.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -15,6 +15,7 @@
#include <linux/mman.h>
#include <linux/errno.h>
#include <linux/mm.h>
+#include <linux/swap.h>
#include <linux/fs.h>
#include <linux/resource.h>
#include <linux/signal.h>
@@ -26,6 +27,8 @@
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/pconf.h>
+#include <asm/idprom.h> /* for gethostid() */
+#include <asm/unistd.h>
/* For the nfs mount emulation */
#include <linux/socket.h>
@@ -39,24 +42,18 @@
static unsigned long get_sparc_unmapped_area(unsigned long len)
{
- unsigned long addr;
+ unsigned long addr = 0xE8000000UL;
struct vm_area_struct * vmm;
if (len > TASK_SIZE)
return 0;
- addr = 0xE8000000UL; /* To make it work on a sun4c. */
- for (vmm = current->mm->mmap; ; vmm = vmm->vm_next) {
+ for (vmm = find_vma(current, addr); ; vmm = vmm->vm_next) {
+ /* At this point: (!vmm || addr < vmm->vm_end). */
if (TASK_SIZE - len < addr)
return 0;
- if (!vmm)
+ if (!vmm || addr + len <= vmm->vm_start)
return addr;
- if (addr > vmm->vm_end)
- continue;
- if (addr + len > vmm->vm_start) {
- addr = vmm->vm_end;
- continue;
- }
- return addr;
+ addr = vmm->vm_end;
}
}
@@ -99,22 +96,10 @@
return ((retval < KERNBASE) ? 0 : retval);
}
-/* Weird SunOS mm control function.. */
+/* lmbench calls this, just say "yeah, ok" */
asmlinkage int sunos_mctl(unsigned long addr, unsigned long len, int function, char *arg)
{
- printk("%s: Call to sunos_mctl(addr<%08lx>, len<%08lx>, function<%d>, arg<%p>) "
- "is unsupported\n", current->comm, addr, len, function, arg);
- return -EAGAIN;
-}
-
-/* XXX This won't be necessary when I sync up to never kernel in 1.3.x series
- * XXX which has the sys_msync() system call implemented properly.
- */
-asmlinkage int sunos_msync(unsigned long addr, unsigned long len, unsigned long flags)
-{
- printk("%s: Call to sunos_msync(addr<%08lx>, len<%08lx>, flags<%08lx>) "
- "is unsupported\n", current->comm, addr, len, flags);
- return -EINVAL;
+ return 0;
}
/* SunOS is completely broken... it returns 0 on success, otherwise
@@ -188,10 +173,10 @@
/* This should do it hopefully... */
error = sunos_brk(((int) current->mm->brk) + increment);
- if(error == 0)
- return current->mm->brk;
- else
+ if(error)
return error;
+ else
+ return current->mm->brk;
}
/* XXX Completely undocumented, and completely magic...
@@ -316,12 +301,28 @@
asmlinkage unsigned long sunos_sigblock(unsigned long blk_mask)
{
- unsigned long old = current->blocked;
+ unsigned long flags;
+ unsigned long old;
+ save_flags(flags); cli();
+ old = current->blocked;
current->blocked |= (blk_mask & _BLOCKABLE);
+ restore_flags(flags);
return old;
}
+asmlinkage unsigned long sunos_sigsetmask(unsigned long newmask)
+{
+ unsigned long flags;
+ unsigned long retval;
+
+ save_flags(flags); cli();
+ retval = current->blocked;
+ current->blocked = newmask & _BLOCKABLE;
+ restore_flags(flags);
+ return retval;
+}
+
/* SunOS getdents is very similar to the newer Linux (iBCS2 compliant) */
/* getdents system call, the format of the structure just has a different */
/* layout (d_off+d_ino instead of d_ino+d_off) */
@@ -359,7 +360,7 @@
dirent = buf->curr;
buf->previous = dirent;
put_user(ino, &dirent->d_ino);
- put_user((strlen(name)), &dirent->d_namlen);
+ put_user(namlen, &dirent->d_namlen);
put_user(reclen, &dirent->d_reclen);
memcpy_tofs(dirent->d_name, name, namlen);
put_user(0, dirent->d_name + namlen);
@@ -399,6 +400,76 @@
return cnt - buf.count;
}
+/* Old sunos getdirentries, severely broken compatability stuff here. */
+struct sunos_direntry {
+ unsigned long d_ino;
+ unsigned short d_reclen;
+ unsigned short d_namlen;
+ char d_name[1];
+};
+
+struct sunos_direntry_callback {
+ struct sunos_direntry *curr;
+ struct sunos_direntry *previous;
+ int count;
+ int error;
+};
+
+static int sunos_filldirentry(void * __buf, const char * name, int namlen,
+ off_t offset, ino_t ino)
+{
+ struct sunos_direntry * dirent;
+ struct sunos_direntry_callback * buf = (struct sunos_direntry_callback *) __buf;
+ int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
+
+ buf->error = -EINVAL; /* only used if we fail.. */
+ if (reclen > buf->count)
+ return -EINVAL;
+ dirent = buf->previous;
+ dirent = buf->curr;
+ buf->previous = dirent;
+ put_user(ino, &dirent->d_ino);
+ put_user(namlen, &dirent->d_namlen);
+ put_user(reclen, &dirent->d_reclen);
+ memcpy_tofs(dirent->d_name, name, namlen);
+ put_user(0, dirent->d_name + namlen);
+ ((char *) dirent) += reclen;
+ buf->curr = dirent;
+ buf->count -= reclen;
+ return 0;
+}
+
+asmlinkage int sunos_getdirentries(unsigned int fd, void * dirent, int cnt, unsigned int *basep)
+{
+ struct file * file;
+ struct sunos_direntry * lastdirent;
+ struct sunos_direntry_callback buf;
+ int error;
+
+ if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
+ return -EBADF;
+ if (!file->f_op || !file->f_op->readdir)
+ return -ENOTDIR;
+ if(verify_area(VERIFY_WRITE, dirent, cnt) ||
+ verify_area(VERIFY_WRITE, basep, sizeof(unsigned int)))
+ return -EFAULT;
+ if(cnt < (sizeof(struct sunos_direntry) + 255))
+ return -EINVAL;
+
+ buf.curr = (struct sunos_direntry *) dirent;
+ buf.previous = NULL;
+ buf.count = cnt;
+ buf.error = 0;
+ error = file->f_op->readdir(file->f_inode, file, &buf, sunos_filldirentry);
+ if (error < 0)
+ return error;
+ lastdirent = buf.previous;
+ if (!lastdirent)
+ return buf.error;
+ put_user(file->f_pos, basep);
+ return cnt - buf.count;
+}
+
asmlinkage int sunos_getdomainname(char *name, int len)
{
int error;
@@ -430,18 +501,16 @@
if(error)
return error;
memcpy_tofs(&name->sname[0], &system_utsname.sysname[0],
- sizeof(name->sname));
+ sizeof(name->sname) - 1);
memcpy_tofs(&name->nname[0], &system_utsname.nodename[0],
- sizeof(name->nname));
+ sizeof(name->nname) - 1);
name->nname[8] = '\0';
- memcpy_tofs(&name->nnext[0], &system_utsname.nodename[9],
- sizeof(name->nnext));
memcpy_tofs(&name->rel[0], &system_utsname.release[0],
- sizeof(name->rel));
+ sizeof(name->rel) - 1);
memcpy_tofs(&name->ver[0], &system_utsname.version[0],
- sizeof(name->ver));
+ sizeof(name->ver) - 1);
memcpy_tofs(&name->mach[0], &system_utsname.machine[0],
- sizeof(name->mach));
+ sizeof(name->mach) - 1);
return 0;
}
@@ -449,8 +518,8 @@
{
struct pt_regs *regs;
- regs = (struct pt_regs *) (((current->tss.ksp) & PAGE_MASK) +
- (PAGE_SIZE - TRACEREG_SZ));
+ regs = (struct pt_regs *) (current->saved_kernel_stack +
+ sizeof(struct reg_window));
current->tss.sig_address = regs->pc;
current->tss.sig_desc = regs->u_regs[UREG_G1];
send_sig(SIGSYS, current, 1);
@@ -500,9 +569,9 @@
asmlinkage int sunos_select(int width, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval *tvp)
{
- /* SunOS binaries expect that select won't change the tvp contents */
- current->personality |= STICKY_TIMEOUTS;
- return sys_select (width, inp, outp, exp, tvp);
+ /* SunOS binaries expect that select won't change the tvp contents */
+ current->personality |= STICKY_TIMEOUTS;
+ return sys_select (width, inp, outp, exp, tvp);
}
asmlinkage void sunos_nop(void)
@@ -520,38 +589,6 @@
#define SMNT_MULTI 64
#define SMNT_SYS5 128
-struct ufs_mntargs {
- char *dev_name;
-};
-
-struct lo_mntargs {
- char *dev_name;
-};
-
-struct ext2_mntargs {
- char *dev_name;
-};
-
-struct iso9660_mntargs {
- char *dev_name;
-};
-
-struct minix_mntargs {
- char *dev_name;
-};
-
-struct ext_mntargs {
- char *dev_name;
-};
-
-struct msdos_mntargs {
- char *dev_name;
-};
-
-struct xiafs_mntargs {
- char *dev_name;
-};
-
struct sunos_fh_t {
char fh_data [NFS_FHSIZE];
};
@@ -572,23 +609,14 @@
char *netname; /* server's netname */
};
-extern asmlinkage int sys_mount(char *, char *, char *, unsigned long, void *);
-extern int do_mount(dev_t, const char *, char *, int, void *);
+extern int do_mount(kdev_t, const char *, const char *, char *, int, void *);
extern dev_t get_unnamed_dev(void);
extern void put_unnamed_dev(dev_t);
-
-extern sys_mount (char * dev_name, char * dir_name, char * type,
- unsigned long new_flags, void * data);
-
-extern asmlinkage int
-sys_connect(int fd, struct sockaddr *uservaddr, int addrlen);
-
-extern asmlinkage int
-sys_socket(int family, int type, int protocol);
-
-asmlinkage int
-sys_bind(int fd, struct sockaddr *umyaddr, int addrlen);
+extern asmlinkage int sys_mount(char *, char *, char *, unsigned long, void *);
+extern asmlinkage int sys_connect(int fd, struct sockaddr *uservaddr, int addrlen);
+extern asmlinkage int sys_socket(int family, int type, int protocol);
+extern asmlinkage int sys_bind(int fd, struct sockaddr *umyaddr, int addrlen);
/* Bind the socket on a local reserved port and connect it to the
@@ -654,7 +682,6 @@
struct nfs_mount_data linux_nfs_mount;
struct sunos_nfs_mount_args *sunos_mount = data;
dev_t dev;
- struct pt_regs *regs;
error = verify_area(VERIFY_READ, data, sizeof (struct sunos_nfs_mount_args));
if (error)
@@ -700,18 +727,10 @@
dev = get_unnamed_dev ();
- ret = do_mount (dev, dir_name, "nfs", linux_flags, &linux_nfs_mount);
+ ret = do_mount (dev, "", dir_name, "nfs", linux_flags, &linux_nfs_mount);
if (ret)
put_unnamed_dev(dev);
-#if 0
- /* Kill the process: the nfs directory is already mounted */
- regs = (struct pt_regs *) (((current->tss.ksp) & PAGE_MASK) +
- (PAGE_SIZE - TRACEREG_SZ));
- current->tss.sig_address = regs->pc;
- current->tss.sig_desc = regs->u_regs[UREG_G1];
- send_sig(SIGSYS, current, 1);
-#endif
return ret;
}
@@ -740,7 +759,7 @@
if(error)
return error;
if(strcmp(type, "ext2") == 0) {
- dev_fname = (char *) data;;
+ dev_fname = (char *) data;
} else if(strcmp(type, "iso9660") == 0) {
dev_fname = (char *) data;
} else if(strcmp(type, "minix") == 0) {
@@ -761,8 +780,6 @@
if(error)
return error;
error = sys_mount(dev_fname, dir, type, linux_flags, NULL);
- printk("sys_mount(type<%s>, device<%s>) returns %d\n",
- type, dev_fname, error);
return error;
}
@@ -794,8 +811,39 @@
return kill_pg(pgrp, sig, 0);
}
-extern asmlinkage sunos_audit ()
+asmlinkage int sunos_audit(void)
{
printk ("sys_audit\n");
+ return -1;
+}
+
+extern asmlinkage unsigned long sunos_gethostid(void)
+{
+ return (unsigned long) idprom->id_sernum;
+}
+
+extern asmlinkage long sunos_sysconf (int name)
+{
+ switch (name){
+ case _SC_ARG_MAX:
+ return ARG_MAX;
+ case _SC_CHILD_MAX:
+ return CHILD_MAX;
+ case _SC_CLK_TCK:
+ return HZ;
+ case _SC_NGROUPS_MAX:
+ return NGROUPS_MAX;
+ case _SC_OPEN_MAX:
+ return OPEN_MAX;
+ case _SC_JOB_CONTROL:
+ return 1; /* yes, we do support job control */
+ case _SC_SAVED_IDS:
+ return 1; /* yes, we do support saved uids */
+ case _SC_VERSION:
+ /* mhm, POSIX_VERSION is in /usr/include/unistd.h
+ * should it go on /usr/include/linux?
+ */
+ return 199009L;
+ }
return -1;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this