summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/compat/ultrix/files.ultrix4
-rw-r--r--sys/compat/ultrix/syscalls.master18
-rw-r--r--sys/compat/ultrix/ultrix_fs.c436
-rw-r--r--sys/compat/ultrix/ultrix_ioctl.c696
-rw-r--r--sys/compat/ultrix/ultrix_misc.c39
-rw-r--r--sys/compat/ultrix/ultrix_syscall.h4
-rw-r--r--sys/compat/ultrix/ultrix_syscallargs.h37
-rw-r--r--sys/compat/ultrix/ultrix_syscalls.c8
-rw-r--r--sys/compat/ultrix/ultrix_sysent.c20
9 files changed, 1236 insertions, 26 deletions
diff --git a/sys/compat/ultrix/files.ultrix b/sys/compat/ultrix/files.ultrix
index d54c76ef9e3..1e2fc3d780f 100644
--- a/sys/compat/ultrix/files.ultrix
+++ b/sys/compat/ultrix/files.ultrix
@@ -1,4 +1,4 @@
-# $NetBSD: files.ultrix,v 1.1 1995/09/20 00:15:19 thorpej Exp $
+# $NetBSD: files.ultrix,v 1.2 1995/12/26 04:22:30 jonathan Exp $
#
# Config file description for machine-independent Ultrix compat code.
# Included by ports that need it.
@@ -6,6 +6,8 @@
# ports should define any machine-specific files they need in their
# own file lists.
+file compat/ultrix/ultrix_ioctl.c compat_ultrix
file compat/ultrix/ultrix_misc.c compat_ultrix
file compat/ultrix/ultrix_syscalls.c compat_ultrix
file compat/ultrix/ultrix_sysent.c compat_ultrix
+file compat/ultrix/ultrix_fs.c compat_ultrix
diff --git a/sys/compat/ultrix/syscalls.master b/sys/compat/ultrix/syscalls.master
index 6b203215e58..7fb63c6c1c0 100644
--- a/sys/compat/ultrix/syscalls.master
+++ b/sys/compat/ultrix/syscalls.master
@@ -1,4 +1,4 @@
- $NetBSD: syscalls.master,v 1.11 1995/10/07 06:28:00 mycroft Exp $
+ $NetBSD: syscalls.master,v 1.14 1995/12/26 10:06:15 jonathan Exp $
; @(#)syscalls.master 8.1 (Berkeley) 7/19/93
@@ -46,7 +46,7 @@
5 STD { int ultrix_sys_open(char *path, int flags, \
int mode); }
6 NOARGS { int sys_close(int fd); }
-7 UNIMPL old_wait
+7 NOARGS { int compat_43_sys_wait(void); } owait
8 NOARGS { int compat_43_sys_creat(char *path, int mode); }
9 NOARGS { int sys_link(char *path, char *link); }
10 NOARGS { int sys_unlink(char *path); }
@@ -61,7 +61,8 @@
19 NOARGS { long compat_43_sys_lseek(int fd, long offset, \
int whence); }
20 NOARGS { pid_t sys_getpid(void); }
-21 OBSOL mount
+21 STD { int ultrix_sys_mount(char *special, char *dir, \
+ int rdonly, int type, caddr_t data); }
22 OBSOL sysV_unmount
23 NOARGS { int sys_setuid(uid_t uid); }
24 NOARGS { uid_t sys_getuid(void); }
@@ -97,7 +98,7 @@
51 NOARGS { int sys_acct(char *path); }
52 UNIMPL
53 UNIMPL syslock
-54 NOARGS { int sys_ioctl(int fd, u_long com, caddr_t data); }
+54 STD { int ultrix_sys_ioctl(int fd, u_long com, caddr_t data); }
55 NOARGS { int sys_reboot(int opt); }
56 UNIMPL v7 mpxchan
57 NOARGS { int sys_symlink(char *path, char *link); }
@@ -145,7 +146,7 @@
90 NOARGS { int sys_dup2(u_int from, u_int to); }
91 UNIMPL getdopt
92 NOARGS { int sys_fcntl(int fd, int cmd, void *arg); }
-93 NOARGS { int sys_select(u_int nd, fd_set *in, fd_set *ou, \
+93 STD { int ultrix_sys_select(u_int nd, fd_set *in, fd_set *ou, \
fd_set *ex, struct timeval *tv); }
94 UNIMPL setdopt
95 NOARGS { int sys_fsync(int fd); }
@@ -260,7 +261,8 @@
168 STD { int ultrix_sys_quotactl(int cmd, char *special, \
int uid, caddr_t addr); }
169 STD { int ultrix_sys_exportfs(char *path, char *ex); }
-170 UNIMPL mount
+170 UNIMPL { int ultrix_sys_mount(char *special, char *dir, \
+ int rdonly, int type, caddr_t data); }
171 UNIMPL 4 hdwconf
172 UNIMPL msgctl
173 UNIMPL msgget
@@ -275,7 +277,9 @@
182 UNIMPL 0 lockf
183 STD { int ultrix_sys_ustat(int dev, \
struct ultrix_ustat *buf); }
-184 UNIMPL getmnt
+184 STD { int ultrix_sys_getmnt(int *start, \
+ struct ultrix_fs_data *buf, \
+ int bufsize, int mode, char *path); }
185 UNIMPL notdef
186 UNIMPL notdef
187 STD { int ultrix_sys_sigpending(int *mask); }
diff --git a/sys/compat/ultrix/ultrix_fs.c b/sys/compat/ultrix/ultrix_fs.c
new file mode 100644
index 00000000000..9829c895d32
--- /dev/null
+++ b/sys/compat/ultrix/ultrix_fs.c
@@ -0,0 +1,436 @@
+/* $NetBSD: ultrix_fs.c,v 1.2 1995/12/26 10:06:14 jonathan Exp $ */
+
+/*
+ * Copyright (c) 1995
+ * Jonathan Stone (hereinafter referred to as the author)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/exec.h>
+#include <sys/namei.h>
+#include <sys/mount.h>
+#include <net/if.h>
+#include <netinet/in.h>
+
+
+#include <sys/syscallargs.h>
+#include <compat/ultrix/ultrix_syscallargs.h>
+
+#include <vm/vm.h>
+
+#define ULTRIX_MAXPATHLEN 1024
+
+/**
+ ** Ultrix filesystem operations: mount(), getmnt().
+ ** These are included purely so one can place an (ECOFF or ELF)
+ ** NetBSD/pmax kernel in an Ultrix root filesystem, boot it,
+ ** and over-write the Ultrix root parition with NetBSD binaries.
+ **/
+
+/*
+ * Ultrix file system data structure, as modified by
+ * Ultrix getmntent(). This structure is padded to 2560 bytes, for
+ * compatiblity with the size the Ultrix kernel and user apps expect.
+ */
+struct ultrix_fs_data {
+ u_int32_t ufsd_flags; /* how mounted */
+ u_int32_t ufsd_mtsize; /* max transfer size in bytes */
+ u_int32_t ufsd_otsize; /* optimal transfer size in bytes */
+ u_int32_t ufsd_bsize; /* fs block size (bytes) for vm code */
+ u_int32_t ufsd_fstype; /* see ../h/fs_types.h */
+ u_int32_t ufsd_gtot; /* total number of gnodes */
+ u_int32_t ufsd_gfree; /* # of free gnodes */
+ u_int32_t ufsd_btot; /* total number of 1K blocks */
+ u_int32_t ufsd_bfree; /* # of free 1K blocks */
+ u_int32_t ufsd_bfreen; /* user consumable 1K blocks */
+ u_int32_t ufsd_pgthresh; /* min size in bytes before paging*/
+ int32_t ufsd_uid; /* uid that mounted me */
+ int16_t ufsd_dev; /* major/minor of fs */
+ int16_t ufsd_exroot; /* root mapping from exports */
+ char ufsd_devname[ULTRIX_MAXPATHLEN + 4]; /* name of dev */
+ char ufsd_path[ULTRIX_MAXPATHLEN + 4]; /* name of mnt point */
+ u_int32_t ufsd_nupdate; /* number of writes */
+ u_int32_t ufsd_pad[112]; /* pad to 2560 bytes. */
+};
+
+/*
+ * Get statistics on mounted filesystems.
+ */
+#if 0
+struct ultrix_getmnt_args {
+ int32_t *start;
+ struct ultrix_fs_data *buf;
+ int32_t bufsize;
+ int32_t mode;
+ char *path;
+};
+
+#endif
+/*
+ * Ultrix getmnt() flags.
+ * The operation getmnt() should perform is incoded in the flag
+ * argument. There are two independent attributes.
+ *
+ * ULTRIX_NOSTAT_xxx will never hang, but it may not return
+ * up-to-date statistics. (For NFS clients, it returns whatever is
+ * in the cache.) ULTRIX_STAT_xxx returns up-to-date info but may
+ * hang (e.g., on dead NFS servers).
+ *
+ * ULTRIX_xxSTAT_ONE returns statistics on just one filesystem, determined
+ * by the parth argument. ULTRIX_xxSTAT_MANY ignores the path argument and
+ * returns info on as many filesystems fit in the structure.
+ * the start argument, which should be zero on the first call,
+ * can be used to iterate over all filesystems.
+ *
+ */
+#define ULTRIX_NOSTAT_MANY 1
+#define ULTRIX_STAT_MANY 2
+#define ULTRIX_STAT_ONE 3
+#define ULTRIX_NOSTAT_ONE 4
+
+/*
+ * Ultrix gnode-layer filesystem codes.
+ */
+#define ULTRIX_FSTYPE_UNKNOWN 0x0
+#define ULTRIX_FSTYPE_ULTRIX 0x1 /* Ultrix UFS: basically 4.2bsd FFS */
+#define ULTRIX_FSTYPE_NFS 0x5 /* NFS v2 */
+
+/*
+ * Ultrix mount(2) options
+ */
+#define ULTRIX_NM_RONLY 0x0001 /* mount read-only */
+#define ULTRIX_NM_SOFT 0x0002 /* soft mount (hard is default) */
+#define ULTRIX_NM_WSIZE 0x0004 /* set write size */
+#define ULTRIX_NM_RSIZE 0x0008 /* set read size */
+#define ULTRIX_NM_TIMEO 0x0010 /* set initial timeout */
+#define ULTRIX_NM_RETRANS 0x0020 /* set number of request retrys */
+#define ULTRIX_NM_HOSTNAME 0x0040 /* set hostname for error printf */
+#define ULTRIX_NM_PGTHRESH 0x0080 /* set page threshold for exec */
+#define ULTRIX_NM_INT 0x0100 /* allow hard mount keyboard interrupts */
+#define ULTRIX_NM_NOAC 0x0200 /* don't cache attributes */
+
+
+/*
+ * Construct an Ultrix getmnt() ultrix_fs_data from the native NetBSD
+ * struct statfs.
+ */
+static void
+make_ultrix_mntent(sp, tem)
+ register struct statfs *sp;
+ register struct ultrix_fs_data *tem;
+{
+
+ bzero(tem, sizeof (*tem));
+
+ tem->ufsd_flags = sp->f_flags; /* XXX translate */
+ tem->ufsd_mtsize = sp->f_bsize; /* XXX max transfer size */
+ tem->ufsd_otsize = sp->f_iosize;
+ tem->ufsd_bsize = sp->f_bsize;
+ /*
+ * Translate file system type. NetBSD/1.1 has f_type zero,
+ * and uses an fstype string instead.
+ * For now, map types not in Ultrix (kernfs, null, procfs...)
+ * to UFS, since Ultrix mout will try and call mount_unknown
+ * for ULTRIX_FSTYPE_UNKNOWN, but lacks a mount_unknown binary.
+ */
+ tem->ufsd_fstype = ULTRIX_FSTYPE_NFS;
+ if (strcmp(sp->f_fstypename, "ffs") == 0)
+ tem->ufsd_fstype = ULTRIX_FSTYPE_ULTRIX;
+
+ tem->ufsd_gtot = sp->f_files; /* total "gnodes" */
+ tem->ufsd_gfree = sp->f_ffree; /* free "gnodes"/
+ tem->ufsd_btot = sp->f_blocks; /* total 1k blocks */
+ /*tem->ufsd_bfree = sp->f_bfree; /* free 1k blocks */
+ /*tem->ufsd_bfree = sp->f_bavail; /* free 1k blocks */
+ tem->ufsd_bfreen = sp->f_bavail; /* blocks available to users */
+ tem->ufsd_pgthresh = 0; /* not relevant */
+ tem->ufsd_uid = 0; /* XXX kept where ?*/
+ tem->ufsd_dev = 0; /* ?? */
+ tem->ufsd_exroot = 0; /* ?? */
+ strncpy(tem->ufsd_path, sp->f_mntonname, ULTRIX_MAXPATHLEN);
+ strncpy(tem->ufsd_devname, sp->f_mntfromname, ULTRIX_MAXPATHLEN);
+#if 0
+ /* In NetBSD-1.1, filesystem type is unused and always 0 */
+ printf("mntent: %s type %d\n", tem->ufsd_devname, tem->ufsd_fstype);
+ printf("mntent: %s tot %d free %d user%d\n",
+ tem->ufsd_devname, sp->f_blocks, sp->f_bfree, sp->f_bavail);
+#endif
+}
+
+int
+ultrix_sys_getmnt(p, v, retval)
+ struct proc *p;
+ void *v;
+ int *retval;
+{
+ struct ultrix_sys_getmnt_args *uap = v;
+ struct mount *mp, *nmp;
+ struct statfs *sp;
+ struct ultrix_fs_data *sfsp;
+ char *path;
+ int mntflags;
+ int skip;
+ int start;
+ long count, maxcount;
+ int error = 0;
+
+ path = NULL;
+ error = 0;
+ maxcount = SCARG(uap, bufsize) / sizeof(struct ultrix_fs_data);
+ sfsp = SCARG(uap, buf);
+
+ if (SCARG(uap, mode) == ULTRIX_STAT_ONE ||
+ SCARG(uap, mode) == ULTRIX_STAT_MANY)
+ mntflags = MNT_WAIT;
+ else
+ mntflags = MNT_NOWAIT;
+
+ if (SCARG(uap, mode) == ULTRIX_STAT_ONE || SCARG(uap, mode) == ULTRIX_NOSTAT_ONE) {
+ /*
+ * Only get info on mountpoints that matches the path
+ * provided.
+ */
+ MALLOC(path, char *, MAXPATHLEN, M_TEMP, M_WAITOK);
+ if (error = copyinstr(SCARG(uap, path), path, MAXPATHLEN, NULL))
+ goto bad;
+ maxcount = 1;
+ } else {
+ /*
+ * Get info on any mountpoints, somewhat like readdir().
+ * Find out how many mount list entries to skip, and skip
+ * them.
+ */
+ if (error =
+ copyin((caddr_t)SCARG(uap, start), &start,
+ sizeof(*SCARG(uap, start))))
+ goto bad;
+ for (skip = start, mp = mountlist.cqh_first;
+ mp != (void*)&mountlist && skip-- > 0; mp = nmp)
+ nmp = mp->mnt_list.cqe_next;
+ }
+
+ for (count = 0, mp = mountlist.cqh_first;
+ mp != (void*)&mountlist && count < maxcount; mp = nmp) {
+ nmp = mp->mnt_list.cqe_next;
+ if (sfsp != NULL && (mp->mnt_flag & MNT_MLOCK) == 0) {
+ struct ultrix_fs_data tem;
+ sp = &mp->mnt_stat;
+
+ /*
+ * If requested, refresh the fsstat cache.
+ */
+ if ((mntflags & MNT_WAIT) != 0 &&
+ (error = VFS_STATFS(mp, sp, p)) != 0)
+ continue;
+
+ /*
+ * XXX what does this do? -- cgd
+ */
+ sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
+ if (path == NULL ||
+ strcmp(path, sp->f_mntonname) == 0) {
+ make_ultrix_mntent(sp, &tem);
+ if (error =
+ copyout((caddr_t)&tem, sfsp, sizeof(tem)))
+ goto bad;
+ sfsp++;
+ count++;
+ }
+ }
+ }
+
+ if (sfsp != NULL && count > maxcount)
+ *retval = maxcount;
+ else
+ *retval = count;
+
+bad:
+ if (path)
+ FREE(path, M_TEMP);
+ return (error);
+}
+
+
+
+/* Old-style inet sockaddr (no len field) as passed to Ultrix mount(2) */
+struct osockaddr_in {
+ short sin_family;
+ u_short sin_port;
+ struct in_addr sin_addr;
+ char sin_zero[8];
+};
+
+
+/*
+ * fstype-dependent structure passed to Ultrix mount(2) when
+ * mounting NFS filesystems
+ */
+struct ultrix_nfs_args {
+ struct osockaddr_in *addr; /* file server address */
+ nfsv2fh_t *fh; /* file handle to be mounted */
+ int flags; /* flags */
+ int wsize; /* write size in bytes */
+ int rsize; /* read size in bytes */
+ int timeo; /* initial timeout in .1 secs */
+ int retrans; /* times to retry send */
+ char *hostname; /* server's hostname */
+ char *optstr; /* string of nfs mount options*/
+ int gfs_flags; /* gnode flags (ugh) */
+ int pg_thresh; /* paging threshold ? */
+};
+
+
+/*
+ * fstype-dependent structure passed to Ultrix mount(2) when
+ * mounting local (4.2bsd FFS) filesystems
+ */
+struct ultrix_ufs_args {
+ u_long ufs_flags; /* mount flags?*/
+ u_long ufs_pgthresh; /* minimum file size to page */
+};
+
+int
+ultrix_sys_mount(p, v, retval)
+ struct proc *p;
+ void *v;
+ int *retval;
+{
+ struct ultrix_sys_mount_args *uap = v;
+
+ int error;
+ int otype = SCARG(uap, type);
+ extern char sigcode[], esigcode[];
+ char fsname[MFSNAMELEN];
+ char * fstype;
+ struct sys_mount_args nuap;
+
+#define szsigcode (esigcode - sigcode)
+ caddr_t usp = (caddr_t)ALIGN(PS_STRINGS - szsigcode - STACKGAPLEN);
+
+ bzero(&nuap, sizeof(nuap));
+ SCARG(&nuap, flags) = 0;
+
+ /*
+ * Translate Ultrix integer mount codes for UFS and NFS to
+ * NetBSD fstype strings. Other Ultrix filesystem types
+ * (msdos, DEC ods-2) are not supported.
+ */
+ if (otype == ULTRIX_FSTYPE_ULTRIX)
+ fstype = "ufs";
+ else if (otype == ULTRIX_FSTYPE_NFS)
+ fstype = "nfs";
+ else
+ return (EINVAL);
+
+ /* Translate the Ultrix mount-readonly option parameter */
+ if (SCARG(uap, rdonly))
+ SCARG(&nuap, flags) |= MNT_RDONLY;
+
+ /* Copy string-ified version of mount type back out to user space */
+ SCARG(&nuap, type) = (char *)usp;
+ if (error = copyout(fstype, SCARG(&nuap, type), strlen(fstype)+1)) {
+ return (error);
+ }
+ usp += strlen(fstype)+1;
+
+#ifdef later
+ parse ultrix mount option string and set NetBSD flags
+#endif
+ SCARG(&nuap, path) = SCARG(uap, dir);
+
+ if (otype == ULTRIX_FSTYPE_ULTRIX) {
+ /* attempt to mount a native, rather than 4.2bsd, ffs */
+ struct ufs_args ua;
+ struct nameidata nd;
+
+ ua.fspec = SCARG(uap, special);
+ bzero(&ua.export, sizeof(ua.export));
+ SCARG(&nuap, data) = usp;
+
+ if (error = copyout(&ua, SCARG(&nuap, data), sizeof ua)) {
+ return(error);
+ }
+ /*
+ * Ultrix mount has no MNT_UPDATE flag.
+ * Attempt to see if this is the root we're mounting,
+ * and if so, set MNT_UPDATE so we can mount / read-write.
+ */
+ fsname[0] = 0;
+ if (error = copyinstr((caddr_t)SCARG(&nuap, path), fsname,
+ sizeof fsname, (u_int*)0))
+ return(error);
+ if (strcmp(fsname, "/") == 0) {
+ SCARG(&nuap, flags) |= MNT_UPDATE;
+ printf("COMPAT_ULTRIX: mount with MNT_UPDATE on %s\n",
+ fsname);
+ }
+ } else if (otype == ULTRIX_FSTYPE_NFS) {
+ struct ultrix_nfs_args una;
+ struct nfs_args na;
+ struct osockaddr_in osa;
+ struct sockaddr_in *sap = (struct sockaddr_in *)& osa;
+
+ bzero(&osa, sizeof(osa));
+ bzero(&una, sizeof(una));
+ if (error = copyin(SCARG(uap, data), &una, sizeof una)) {
+ return (error);
+ }
+ /*
+ * This is the only syscall boundary the
+ * address of the server passes, so do backwards
+ * compatibility on 4.3style sockaddrs here.
+ */
+ if (error = copyin(una.addr, &osa, sizeof osa)) {
+ printf("ultrix_mount: nfs copyin osa\n");
+ return (error);
+ }
+ sap->sin_family = (u_char)osa.sin_family;
+ sap->sin_len = sizeof(*sap);
+ /* allocate space above caller's stack for nfs_args */
+ SCARG(&nuap, data) = usp;
+ usp += sizeof (na);
+ /* allocate space above caller's stack for server sockaddr */
+ na.addr = (struct sockaddr *)usp;
+ usp += sizeof(*sap);
+ na.addrlen = sap->sin_len;
+ na.sotype = SOCK_DGRAM;
+ na.proto = IPPROTO_UDP;
+ na.fh = una.fh;
+ na.flags = /*una.flags;*/ NFSMNT_NOCONN | NFSMNT_RESVPORT;
+ na.wsize = una.wsize;
+ na.rsize = una.rsize;
+ na.timeo = una.timeo;
+ na.retrans = una.retrans;
+ na.hostname = una.hostname;
+ if (error = copyout(sap, na.addr, sizeof (*sap) ))
+ return (error);
+ if (error = copyout(&na, SCARG(&nuap, data), sizeof na))
+ return (error);
+ }
+ return (sys_mount(p, &nuap, retval));
+}
diff --git a/sys/compat/ultrix/ultrix_ioctl.c b/sys/compat/ultrix/ultrix_ioctl.c
new file mode 100644
index 00000000000..bdf6c514868
--- /dev/null
+++ b/sys/compat/ultrix/ultrix_ioctl.c
@@ -0,0 +1,696 @@
+/* $NetBSD: ultrix_ioctl.c,v 1.1 1995/12/26 04:44:39 jonathan Exp $ */
+/* from : NetBSD: sunos_ioctl.c,v 1.21 1995/10/07 06:27:31 mycroft Exp */
+
+/*
+ * Copyright (c) 1993 Markus Wild.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * loosely from: Header: sunos_ioctl.c,v 1.7 93/05/28 04:40:43 torek Exp
+ */
+
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/systm.h>
+#include <sys/file.h>
+#include <sys/filedesc.h>
+#include <sys/ioctl.h>
+#include <sys/termios.h>
+#include <sys/tty.h>
+#include <sys/socket.h>
+#include <sys/audioio.h>
+#include <net/if.h>
+
+#include <sys/mount.h>
+
+#include <compat/ultrix/ultrix_syscallargs.h>
+#include <sys/syscallargs.h>
+
+#include <compat/sunos/sunos.h>
+
+#include "ultrix_tty.h"
+
+
+/*
+ * SunOS ioctl calls.
+ * This file is something of a hodge-podge.
+ * Support gets added as things turn up....
+ */
+
+static struct speedtab sptab[] = {
+ { 0, 0 },
+ { 50, 1 },
+ { 75, 2 },
+ { 110, 3 },
+ { 134, 4 },
+ { 135, 4 },
+ { 150, 5 },
+ { 200, 6 },
+ { 300, 7 },
+ { 600, 8 },
+ { 1200, 9 },
+ { 1800, 10 },
+ { 2400, 11 },
+ { 4800, 12 },
+ { 9600, 13 },
+ { 19200, 14 },
+ { 38400, 15 },
+ { -1, -1 }
+};
+
+static u_long s2btab[] = {
+ 0,
+ 50,
+ 75,
+ 110,
+ 134,
+ 150,
+ 200,
+ 300,
+ 600,
+ 1200,
+ 1800,
+ 2400,
+ 4800,
+ 9600,
+ 19200,
+ 38400,
+};
+
+/*
+ * these two conversion functions have mostly been done
+ * with some perl cut&paste, then handedited to comment
+ * out what doesn't exist under NetBSD.
+ * A note from Markus's code:
+ * (l & BITMASK1) / BITMASK1 * BITMASK2 is translated
+ * optimally by gcc m68k, much better than any ?: stuff.
+ * Code may vary with different architectures of course.
+ *
+ * I don't know what optimizer you used, but seeing divu's and
+ * bfextu's in the m68k assembly output did not encourage me...
+ * as well, gcc on the sparc definately generates much better
+ * code with ?:.
+ */
+
+static void
+stios2btios(st, bt)
+ struct sunos_termios *st;
+ struct termios *bt;
+{
+ register u_long l, r;
+
+ l = st->c_iflag;
+ r = ((l & 0x00000001) ? IGNBRK : 0);
+ r |= ((l & 0x00000002) ? BRKINT : 0);
+ r |= ((l & 0x00000004) ? IGNPAR : 0);
+ r |= ((l & 0x00000008) ? PARMRK : 0);
+ r |= ((l & 0x00000010) ? INPCK : 0);
+ r |= ((l & 0x00000020) ? ISTRIP : 0);
+ r |= ((l & 0x00000040) ? INLCR : 0);
+ r |= ((l & 0x00000080) ? IGNCR : 0);
+ r |= ((l & 0x00000100) ? ICRNL : 0);
+ /* ((l & 0x00000200) ? IUCLC : 0) */
+ r |= ((l & 0x00000400) ? IXON : 0);
+ r |= ((l & 0x00000800) ? IXANY : 0);
+ r |= ((l & 0x00001000) ? IXOFF : 0);
+ r |= ((l & 0x00002000) ? IMAXBEL : 0);
+ bt->c_iflag = r;
+
+ l = st->c_oflag;
+ r = ((l & 0x00000001) ? OPOST : 0);
+ /* ((l & 0x00000002) ? OLCUC : 0) */
+ r |= ((l & 0x00000004) ? ONLCR : 0);
+ /* ((l & 0x00000008) ? OCRNL : 0) */
+ /* ((l & 0x00000010) ? ONOCR : 0) */
+ /* ((l & 0x00000020) ? ONLRET : 0) */
+ /* ((l & 0x00000040) ? OFILL : 0) */
+ /* ((l & 0x00000080) ? OFDEL : 0) */
+ /* ((l & 0x00000100) ? NLDLY : 0) */
+ /* ((l & 0x00000100) ? NL1 : 0) */
+ /* ((l & 0x00000600) ? CRDLY : 0) */
+ /* ((l & 0x00000200) ? CR1 : 0) */
+ /* ((l & 0x00000400) ? CR2 : 0) */
+ /* ((l & 0x00000600) ? CR3 : 0) */
+ /* ((l & 0x00001800) ? TABDLY : 0) */
+ /* ((l & 0x00000800) ? TAB1 : 0) */
+ /* ((l & 0x00001000) ? TAB2 : 0) */
+ r |= ((l & 0x00001800) ? OXTABS : 0);
+ /* ((l & 0x00002000) ? BSDLY : 0) */
+ /* ((l & 0x00002000) ? BS1 : 0) */
+ /* ((l & 0x00004000) ? VTDLY : 0) */
+ /* ((l & 0x00004000) ? VT1 : 0) */
+ /* ((l & 0x00008000) ? FFDLY : 0) */
+ /* ((l & 0x00008000) ? FF1 : 0) */
+ /* ((l & 0x00010000) ? PAGEOUT : 0) */
+ /* ((l & 0x00020000) ? WRAP : 0) */
+ bt->c_oflag = r;
+
+ l = st->c_cflag;
+ switch (l & 0x00000030) {
+ case 0:
+ r = CS5;
+ break;
+ case 0x00000010:
+ r = CS6;
+ break;
+ case 0x00000020:
+ r = CS7;
+ break;
+ case 0x00000030:
+ r = CS8;
+ break;
+ }
+ r |= ((l & 0x00000040) ? CSTOPB : 0);
+ r |= ((l & 0x00000080) ? CREAD : 0);
+ r |= ((l & 0x00000100) ? PARENB : 0);
+ r |= ((l & 0x00000200) ? PARODD : 0);
+ r |= ((l & 0x00000400) ? HUPCL : 0);
+ r |= ((l & 0x00000800) ? CLOCAL : 0);
+ /* ((l & 0x00001000) ? LOBLK : 0) */
+ r |= ((l & 0x80000000) ? (CRTS_IFLOW|CCTS_OFLOW) : 0);
+ bt->c_cflag = r;
+
+ bt->c_ispeed = bt->c_ospeed = s2btab[l & 0x0000000f];
+
+ l = st->c_lflag;
+ r = ((l & 0x00000001) ? ISIG : 0);
+ r |= ((l & 0x00000002) ? ICANON : 0);
+ /* ((l & 0x00000004) ? XCASE : 0) */
+ r |= ((l & 0x00000008) ? ECHO : 0);
+ r |= ((l & 0x00000010) ? ECHOE : 0);
+ r |= ((l & 0x00000020) ? ECHOK : 0);
+ r |= ((l & 0x00000040) ? ECHONL : 0);
+ r |= ((l & 0x00000080) ? NOFLSH : 0);
+ r |= ((l & 0x00000100) ? TOSTOP : 0);
+ r |= ((l & 0x00000200) ? ECHOCTL : 0);
+ r |= ((l & 0x00000400) ? ECHOPRT : 0);
+ r |= ((l & 0x00000800) ? ECHOKE : 0);
+ /* ((l & 0x00001000) ? DEFECHO : 0) */
+ r |= ((l & 0x00002000) ? FLUSHO : 0);
+ r |= ((l & 0x00004000) ? PENDIN : 0);
+ bt->c_lflag = r;
+
+ bt->c_cc[VINTR] = st->c_cc[0] ? st->c_cc[0] : _POSIX_VDISABLE;
+ bt->c_cc[VQUIT] = st->c_cc[1] ? st->c_cc[1] : _POSIX_VDISABLE;
+ bt->c_cc[VERASE] = st->c_cc[2] ? st->c_cc[2] : _POSIX_VDISABLE;
+ bt->c_cc[VKILL] = st->c_cc[3] ? st->c_cc[3] : _POSIX_VDISABLE;
+ bt->c_cc[VEOF] = st->c_cc[4] ? st->c_cc[4] : _POSIX_VDISABLE;
+ bt->c_cc[VEOL] = st->c_cc[5] ? st->c_cc[5] : _POSIX_VDISABLE;
+ bt->c_cc[VEOL2] = st->c_cc[6] ? st->c_cc[6] : _POSIX_VDISABLE;
+ /* bt->c_cc[VSWTCH] = st->c_cc[7] ? st->c_cc[7] : _POSIX_VDISABLE; */
+ bt->c_cc[VSTART] = st->c_cc[8] ? st->c_cc[8] : _POSIX_VDISABLE;
+ bt->c_cc[VSTOP] = st->c_cc[9] ? st->c_cc[9] : _POSIX_VDISABLE;
+ bt->c_cc[VSUSP] = st->c_cc[10] ? st->c_cc[10] : _POSIX_VDISABLE;
+ bt->c_cc[VDSUSP] = st->c_cc[11] ? st->c_cc[11] : _POSIX_VDISABLE;
+ bt->c_cc[VREPRINT] = st->c_cc[12] ? st->c_cc[12] : _POSIX_VDISABLE;
+ bt->c_cc[VDISCARD] = st->c_cc[13] ? st->c_cc[13] : _POSIX_VDISABLE;
+ bt->c_cc[VWERASE] = st->c_cc[14] ? st->c_cc[14] : _POSIX_VDISABLE;
+ bt->c_cc[VLNEXT] = st->c_cc[15] ? st->c_cc[15] : _POSIX_VDISABLE;
+ bt->c_cc[VSTATUS] = st->c_cc[16] ? st->c_cc[16] : _POSIX_VDISABLE;
+
+ /* if `raw mode', create native VMIN/VTIME from SunOS VEOF/VEOL */
+ bt->c_cc[VMIN] = (bt->c_lflag & ICANON) ? 1 : bt->c_cc[VEOF];
+ bt->c_cc[VTIME] = (bt->c_lflag & ICANON) ? 1 : bt->c_cc[VEOL];
+}
+
+
+static void
+btios2stios(bt, st)
+ struct termios *bt;
+ struct sunos_termios *st;
+{
+ register u_long l, r;
+
+ l = bt->c_iflag;
+ r = ((l & IGNBRK) ? 0x00000001 : 0);
+ r |= ((l & BRKINT) ? 0x00000002 : 0);
+ r |= ((l & IGNPAR) ? 0x00000004 : 0);
+ r |= ((l & PARMRK) ? 0x00000008 : 0);
+ r |= ((l & INPCK) ? 0x00000010 : 0);
+ r |= ((l & ISTRIP) ? 0x00000020 : 0);
+ r |= ((l & INLCR) ? 0x00000040 : 0);
+ r |= ((l & IGNCR) ? 0x00000080 : 0);
+ r |= ((l & ICRNL) ? 0x00000100 : 0);
+ /* ((l & IUCLC) ? 0x00000200 : 0) */
+ r |= ((l & IXON) ? 0x00000400 : 0);
+ r |= ((l & IXANY) ? 0x00000800 : 0);
+ r |= ((l & IXOFF) ? 0x00001000 : 0);
+ r |= ((l & IMAXBEL) ? 0x00002000 : 0);
+ st->c_iflag = r;
+
+ l = bt->c_oflag;
+ r = ((l & OPOST) ? 0x00000001 : 0);
+ /* ((l & OLCUC) ? 0x00000002 : 0) */
+ r |= ((l & ONLCR) ? 0x00000004 : 0);
+ /* ((l & OCRNL) ? 0x00000008 : 0) */
+ /* ((l & ONOCR) ? 0x00000010 : 0) */
+ /* ((l & ONLRET) ? 0x00000020 : 0) */
+ /* ((l & OFILL) ? 0x00000040 : 0) */
+ /* ((l & OFDEL) ? 0x00000080 : 0) */
+ /* ((l & NLDLY) ? 0x00000100 : 0) */
+ /* ((l & NL1) ? 0x00000100 : 0) */
+ /* ((l & CRDLY) ? 0x00000600 : 0) */
+ /* ((l & CR1) ? 0x00000200 : 0) */
+ /* ((l & CR2) ? 0x00000400 : 0) */
+ /* ((l & CR3) ? 0x00000600 : 0) */
+ /* ((l & TABDLY) ? 0x00001800 : 0) */
+ /* ((l & TAB1) ? 0x00000800 : 0) */
+ /* ((l & TAB2) ? 0x00001000 : 0) */
+ r |= ((l & OXTABS) ? 0x00001800 : 0);
+ /* ((l & BSDLY) ? 0x00002000 : 0) */
+ /* ((l & BS1) ? 0x00002000 : 0) */
+ /* ((l & VTDLY) ? 0x00004000 : 0) */
+ /* ((l & VT1) ? 0x00004000 : 0) */
+ /* ((l & FFDLY) ? 0x00008000 : 0) */
+ /* ((l & FF1) ? 0x00008000 : 0) */
+ /* ((l & PAGEOUT) ? 0x00010000 : 0) */
+ /* ((l & WRAP) ? 0x00020000 : 0) */
+ st->c_oflag = r;
+
+ l = bt->c_cflag;
+ switch (l & CSIZE) {
+ case CS5:
+ r = 0;
+ break;
+ case CS6:
+ r = 0x00000010;
+ break;
+ case CS7:
+ r = 0x00000020;
+ break;
+ case CS8:
+ r = 0x00000030;
+ break;
+ }
+ r |= ((l & CSTOPB) ? 0x00000040 : 0);
+ r |= ((l & CREAD) ? 0x00000080 : 0);
+ r |= ((l & PARENB) ? 0x00000100 : 0);
+ r |= ((l & PARODD) ? 0x00000200 : 0);
+ r |= ((l & HUPCL) ? 0x00000400 : 0);
+ r |= ((l & CLOCAL) ? 0x00000800 : 0);
+ /* ((l & LOBLK) ? 0x00001000 : 0) */
+ r |= ((l & (CRTS_IFLOW|CCTS_OFLOW)) ? 0x80000000 : 0);
+ st->c_cflag = r;
+
+ l = bt->c_lflag;
+ r = ((l & ISIG) ? 0x00000001 : 0);
+ r |= ((l & ICANON) ? 0x00000002 : 0);
+ /* ((l & XCASE) ? 0x00000004 : 0) */
+ r |= ((l & ECHO) ? 0x00000008 : 0);
+ r |= ((l & ECHOE) ? 0x00000010 : 0);
+ r |= ((l & ECHOK) ? 0x00000020 : 0);
+ r |= ((l & ECHONL) ? 0x00000040 : 0);
+ r |= ((l & NOFLSH) ? 0x00000080 : 0);
+ r |= ((l & TOSTOP) ? 0x00000100 : 0);
+ r |= ((l & ECHOCTL) ? 0x00000200 : 0);
+ r |= ((l & ECHOPRT) ? 0x00000400 : 0);
+ r |= ((l & ECHOKE) ? 0x00000800 : 0);
+ /* ((l & DEFECHO) ? 0x00001000 : 0) */
+ r |= ((l & FLUSHO) ? 0x00002000 : 0);
+ r |= ((l & PENDIN) ? 0x00004000 : 0);
+ st->c_lflag = r;
+
+ l = ttspeedtab(bt->c_ospeed, sptab);
+ if (l >= 0)
+ st->c_cflag |= l;
+
+ st->c_cc[0] = bt->c_cc[VINTR] != _POSIX_VDISABLE? bt->c_cc[VINTR]:0;
+ st->c_cc[1] = bt->c_cc[VQUIT] != _POSIX_VDISABLE? bt->c_cc[VQUIT]:0;
+ st->c_cc[2] = bt->c_cc[VERASE] != _POSIX_VDISABLE? bt->c_cc[VERASE]:0;
+ st->c_cc[3] = bt->c_cc[VKILL] != _POSIX_VDISABLE? bt->c_cc[VKILL]:0;
+ st->c_cc[4] = bt->c_cc[VEOF] != _POSIX_VDISABLE? bt->c_cc[VEOF]:0;
+ st->c_cc[5] = bt->c_cc[VEOL] != _POSIX_VDISABLE? bt->c_cc[VEOL]:0;
+ st->c_cc[6] = bt->c_cc[VEOL2] != _POSIX_VDISABLE? bt->c_cc[VEOL2]:0;
+ st->c_cc[7] = 0;
+ /* bt->c_cc[VSWTCH] != _POSIX_VDISABLE? bt->c_cc[VSWTCH]: */
+ st->c_cc[8] = bt->c_cc[VSTART] != _POSIX_VDISABLE? bt->c_cc[VSTART]:0;
+ st->c_cc[9] = bt->c_cc[VSTOP] != _POSIX_VDISABLE? bt->c_cc[VSTOP]:0;
+ st->c_cc[10]= bt->c_cc[VSUSP] != _POSIX_VDISABLE? bt->c_cc[VSUSP]:0;
+ st->c_cc[11]= bt->c_cc[VDSUSP] != _POSIX_VDISABLE? bt->c_cc[VDSUSP]:0;
+ st->c_cc[12]= bt->c_cc[VREPRINT]!= _POSIX_VDISABLE? bt->c_cc[VREPRINT]:0;
+ st->c_cc[13]= bt->c_cc[VDISCARD]!= _POSIX_VDISABLE? bt->c_cc[VDISCARD]:0;
+ st->c_cc[14]= bt->c_cc[VWERASE] != _POSIX_VDISABLE? bt->c_cc[VWERASE]:0;
+ st->c_cc[15]= bt->c_cc[VLNEXT] != _POSIX_VDISABLE? bt->c_cc[VLNEXT]:0;
+ st->c_cc[16]= bt->c_cc[VSTATUS] != _POSIX_VDISABLE? bt->c_cc[VSTATUS]:0;
+
+ if (!(bt->c_lflag & ICANON)) {
+ /* SunOS stores VMIN/VTIME in VEOF/VEOL (if ICANON is off) */
+ st->c_cc[4] = bt->c_cc[VMIN];
+ st->c_cc[5] = bt->c_cc[VTIME];
+ }
+
+ st->c_line = 0;
+}
+
+static void
+stios2stio(ts, t)
+ struct sunos_termios *ts;
+ struct sunos_termio *t;
+{
+ t->c_iflag = ts->c_iflag;
+ t->c_oflag = ts->c_oflag;
+ t->c_cflag = ts->c_cflag;
+ t->c_lflag = ts->c_lflag;
+ t->c_line = ts->c_line;
+ bcopy(ts->c_cc, t->c_cc, 8);
+}
+
+static void
+stio2stios(t, ts)
+ struct sunos_termio *t;
+ struct sunos_termios *ts;
+{
+ ts->c_iflag = t->c_iflag;
+ ts->c_oflag = t->c_oflag;
+ ts->c_cflag = t->c_cflag;
+ ts->c_lflag = t->c_lflag;
+ ts->c_line = t->c_line;
+ bcopy(t->c_cc, ts->c_cc, 8); /* don't touch the upper fields! */
+}
+
+int
+ultrix_sys_ioctl(p, v, retval)
+ register struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct ultrix_sys_ioctl_args *uap = v;
+ register struct filedesc *fdp = p->p_fd;
+ register struct file *fp;
+ register int (*ctl)();
+ int error;
+
+ if ( (unsigned)SCARG(uap, fd) >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL)
+ return EBADF;
+
+ if ((fp->f_flag & (FREAD|FWRITE)) == 0)
+ return EBADF;
+
+ ctl = fp->f_ops->fo_ioctl;
+
+ switch (SCARG(uap, com)) {
+ case _IOR('t', 0, int):
+ SCARG(uap, com) = TIOCGETD;
+ break;
+ case _IOW('t', 1, int):
+ {
+ int disc;
+
+ if ((error = copyin(SCARG(uap, data), (caddr_t)&disc,
+ sizeof disc)) != 0)
+ return error;
+
+ /* map SunOS NTTYDISC into our termios discipline */
+ if (disc == 2)
+ disc = 0;
+ /* all other disciplines are not supported by NetBSD */
+ if (disc)
+ return ENXIO;
+
+ return (*ctl)(fp, TIOCSETD, (caddr_t)&disc, p);
+ }
+ case _IOW('t', 101, int): /* sun SUNOS_TIOCSSOFTCAR */
+ {
+ int x; /* unused */
+
+ return copyin((caddr_t)&x, SCARG(uap, data), sizeof x);
+ }
+ case _IOR('t', 100, int): /* sun SUNOS_TIOCSSOFTCAR */
+ {
+ int x = 0;
+
+ return copyout((caddr_t)&x, SCARG(uap, data), sizeof x);
+ }
+ case _IO('t', 36): /* sun TIOCCONS, no parameters */
+ {
+ int on = 1;
+ return (*ctl)(fp, TIOCCONS, (caddr_t)&on, p);
+ }
+ case _IOW('t', 37, struct sunos_ttysize):
+ {
+ struct winsize ws;
+ struct sunos_ttysize ss;
+
+ if ((error = (*ctl)(fp, TIOCGWINSZ, (caddr_t)&ws, p)) != 0)
+ return (error);
+
+ if ((error = copyin (SCARG(uap, data), &ss, sizeof (ss))) != 0)
+ return error;
+
+ ws.ws_row = ss.ts_row;
+ ws.ws_col = ss.ts_col;
+
+ return ((*ctl)(fp, TIOCSWINSZ, (caddr_t)&ws, p));
+ }
+ case _IOW('t', 38, struct sunos_ttysize):
+ {
+ struct winsize ws;
+ struct sunos_ttysize ss;
+
+ if ((error = (*ctl)(fp, TIOCGWINSZ, (caddr_t)&ws, p)) != 0)
+ return (error);
+
+ ss.ts_row = ws.ws_row;
+ ss.ts_col = ws.ws_col;
+
+ return copyout ((caddr_t)&ss, SCARG(uap, data), sizeof (ss));
+ }
+ case _IOW('t', 130, int):
+ SCARG(uap, com) = TIOCSPGRP;
+ break;
+ case _IOR('t', 131, int):
+ SCARG(uap, com) = TIOCGPGRP;
+ break;
+ case _IO('t', 132):
+ SCARG(uap, com) = TIOCSCTTY;
+ break;
+ case ULTRIX_TCGETA:
+ case ULTRIX_TCGETS:
+ {
+ struct termios bts;
+ struct ultrix_termios sts;
+ struct ultrix_termio st;
+
+ if ((error = (*ctl)(fp, TIOCGETA, (caddr_t)&bts, p)) != 0)
+ return error;
+
+ btios2stios (&bts, &sts);
+ if (SCARG(uap, com) == ULTRIX_TCGETA) {
+ stios2stio (&sts, &st);
+ return copyout((caddr_t)&st, SCARG(uap, data),
+ sizeof (st));
+ } else
+ return copyout((caddr_t)&sts, SCARG(uap, data),
+ sizeof (sts));
+ /*NOTREACHED*/
+ }
+ case ULTRIX_TCSETA:
+ case ULTRIX_TCSETAW:
+ case ULTRIX_TCSETAF:
+ {
+ struct termios bts;
+ struct ultrix_termios sts;
+ struct ultrix_termio st;
+ int result;
+
+ if ((error = copyin(SCARG(uap, data), (caddr_t)&st,
+ sizeof (st))) != 0)
+ return error;
+
+ /* get full BSD termios so we don't lose information */
+ if ((error = (*ctl)(fp, TIOCGETA, (caddr_t)&bts, p)) != 0)
+ return error;
+
+ /*
+ * convert to sun termios, copy in information from
+ * termio, and convert back, then set new values.
+ */
+ btios2stios(&bts, &sts);
+ stio2stios(&st, &sts);
+ stios2btios(&sts, &bts);
+
+ /*
+ * map ioctl code: ultrix tcsets are numbered in reverse order
+ */
+#ifdef notyet
+ return (*ctl)(fp, ULTRIX_TCSETA - SCARG(uap, com) + TIOCSETA,
+ (caddr_t)&bts, p);
+#else
+ result= (*ctl)(fp, ULTRIX_TCSETA - SCARG(uap, com) + TIOCSETA,
+ (caddr_t)&bts, p);
+ printf("ultrix TCSETA %x returns %d\n",
+ ULTRIX_TCSETA - SCARG(uap, com), result);
+ return result;
+#endif
+
+ }
+ case ULTRIX_TCSETS:
+ case ULTRIX_TCSETSW:
+ case ULTRIX_TCSETSF:
+ {
+ struct termios bts;
+ struct ultrix_termios sts;
+ int result;
+
+ if ((error = copyin (SCARG(uap, data), (caddr_t)&sts,
+ sizeof (sts))) != 0)
+ return error;
+ stios2btios (&sts, &bts);
+#ifndef DEBUG
+ return (*ctl)(fp, ULTRIX_TCSETS - SCARG(uap, com) + TIOCSETA,
+ (caddr_t)&bts, p);
+#else
+ result = (*ctl)(fp, ULTRIX_TCSETS - SCARG(uap, com) + TIOCSETA,
+ (caddr_t)&bts, p);
+ printf("ultrix TCSETS %x returns %d\n",
+ ULTRIX_TCSETS - SCARG(uap, com), result);
+ return result;
+#endif
+ }
+/*
+ * Pseudo-tty ioctl translations.
+ */
+ case _IOW('t', 32, int): { /* TIOCTCNTL */
+ int error, on;
+
+ if (error = copyin (SCARG(uap, data), (caddr_t)&on, sizeof (on)))
+ return error;
+ return (*ctl)(fp, TIOCUCNTL, (caddr_t)&on, p);
+ }
+ case _IOW('t', 33, int): { /* TIOCSIGNAL */
+ int error, sig;
+
+ if (error = copyin (SCARG(uap, data), (caddr_t)&sig, sizeof (sig)))
+ return error;
+ return (*ctl)(fp, TIOCSIG, (caddr_t)&sig, p);
+ }
+
+/*
+ * Socket ioctl translations.
+ */
+#define IFREQ_IN(a) { \
+ struct ifreq ifreq; \
+ if (error = copyin (SCARG(uap, data), (caddr_t)&ifreq, sizeof (ifreq))) \
+ return error; \
+ return (*ctl)(fp, a, (caddr_t)&ifreq, p); \
+}
+#define IFREQ_INOUT(a) { \
+ struct ifreq ifreq; \
+ if (error = copyin (SCARG(uap, data), (caddr_t)&ifreq, sizeof (ifreq))) \
+ return error; \
+ if (error = (*ctl)(fp, a, (caddr_t)&ifreq, p)) \
+ return error; \
+ return copyout ((caddr_t)&ifreq, SCARG(uap, data), sizeof (ifreq)); \
+}
+
+ case _IOW('i', 12, struct ifreq):
+ /* SIOCSIFADDR */
+ break;
+
+ case _IOWR('i', 13, struct ifreq):
+ IFREQ_INOUT(OSIOCGIFADDR);
+
+ case _IOW('i', 14, struct ifreq):
+ /* SIOCSIFDSTADDR */
+ break;
+
+ case _IOWR('i', 15, struct ifreq):
+ IFREQ_INOUT(OSIOCGIFDSTADDR);
+
+ case _IOW('i', 16, struct ifreq):
+ /* SIOCSIFFLAGS */
+ break;
+
+ case _IOWR('i', 17, struct ifreq):
+ /* SIOCGIFFLAGS */
+ break;
+
+ case _IOW('i', 21, struct ifreq):
+ IFREQ_IN(SIOCSIFMTU);
+
+ case _IOWR('i', 22, struct ifreq):
+ IFREQ_INOUT(SIOCGIFMTU);
+
+ case _IOWR('i', 23, struct ifreq):
+ IFREQ_INOUT(SIOCGIFBRDADDR);
+
+ case _IOW('i', 24, struct ifreq):
+ IFREQ_IN(SIOCSIFBRDADDR);
+
+ case _IOWR('i', 25, struct ifreq):
+ IFREQ_INOUT(OSIOCGIFNETMASK);
+
+ case _IOW('i', 26, struct ifreq):
+ IFREQ_IN(SIOCSIFNETMASK);
+
+ case _IOWR('i', 27, struct ifreq):
+ IFREQ_INOUT(SIOCGIFMETRIC);
+
+ case _IOWR('i', 28, struct ifreq):
+ IFREQ_IN(SIOCSIFMETRIC);
+
+ case _IOW('i', 30, struct arpreq):
+ /* SIOCSARP */
+ break;
+
+ case _IOWR('i', 31, struct arpreq):
+ /* SIOCGARP */
+ break;
+
+ case _IOW('i', 32, struct arpreq):
+ /* SIOCDARP */
+ break;
+
+ case _IOW('i', 18, struct ifreq): /* SIOCSIFMEM */
+ case _IOWR('i', 19, struct ifreq): /* SIOCGIFMEM */
+ case _IOW('i', 40, struct ifreq): /* SIOCUPPER */
+ case _IOW('i', 41, struct ifreq): /* SIOCLOWER */
+ case _IOW('i', 44, struct ifreq): /* SIOCSETSYNC */
+ case _IOWR('i', 45, struct ifreq): /* SIOCGETSYNC */
+ case _IOWR('i', 46, struct ifreq): /* SIOCSDSTATS */
+ case _IOWR('i', 47, struct ifreq): /* SIOCSESTATS */
+ case _IOW('i', 48, int): /* SIOCSPROMISC */
+ case _IOW('i', 49, struct ifreq): /* SIOCADDMULTI */
+ case _IOW('i', 50, struct ifreq): /* SIOCDELMULTI */
+ return EOPNOTSUPP;
+
+ case _IOWR('i', 20, struct ifconf): /* SIOCGIFCONF */
+ {
+ struct ifconf ifconf;
+
+ /*
+ * XXX: two more problems
+ * 1. our sockaddr's are variable length, not always sizeof(sockaddr)
+ * 2. this returns a name per protocol, ie. it returns two "lo0"'s
+ */
+ if (error = copyin (SCARG(uap, data), (caddr_t)&ifconf,
+ sizeof (ifconf)))
+ return error;
+ if (error = (*ctl)(fp, OSIOCGIFCONF, (caddr_t)&ifconf, p))
+ return error;
+ return copyout ((caddr_t)&ifconf, SCARG(uap, data),
+ sizeof (ifconf));
+ }
+
+ }
+ return (sys_ioctl(p, uap, retval));
+}
diff --git a/sys/compat/ultrix/ultrix_misc.c b/sys/compat/ultrix/ultrix_misc.c
index 9a42e7bbaab..80512eac5e3 100644
--- a/sys/compat/ultrix/ultrix_misc.c
+++ b/sys/compat/ultrix/ultrix_misc.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ultrix_misc.c,v 1.16.2.1 1995/10/18 06:46:14 jonathan Exp $ */
+/* $NetBSD: ultrix_misc.c,v 1.18 1995/12/26 04:23:14 jonathan Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -193,6 +193,43 @@ ultrix_sys_execv(p, v, retval)
return (sys_execve(p, &ouap, retval));
}
+ultrix_sys_select(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct sys_select_args *uap = v;
+ struct timeval atv, *tvp;
+ int error;
+
+ /* Limit number of FDs selected on to the native maximum */
+
+ if (SCARG(uap, nd) > FD_SETSIZE)
+ SCARG(uap, nd) = FD_SETSIZE;
+
+ /* Check for negative timeval */
+ if (SCARG(uap, tv)) {
+ error = copyin((caddr_t)SCARG(uap, tv), (caddr_t)&atv,
+ sizeof(atv));
+ if (error)
+ goto done;
+#ifdef DEBUG
+ /* Ultrix clients sometimes give negative timeouts? */
+ if (atv.tv_sec < 0 || atv.tv_usec < 0)
+ printf("ultrix select( %d, %d)\n",
+ atv.tv_sec, atv.tv_usec);
+ /*tvp = (timeval *)STACKGAPBASE;*/
+#endif
+
+ }
+ error = sys_select(p, (void*) uap, retval);
+ if (error == EINVAL)
+ printf("ultrix select: bad args?\n");
+
+done:
+ return error;
+}
+
#if defined(NFSCLIENT)
async_daemon(p, v, retval)
struct proc *p;
diff --git a/sys/compat/ultrix/ultrix_syscall.h b/sys/compat/ultrix/ultrix_syscall.h
index 3ac40c25b31..ecf9d58658a 100644
--- a/sys/compat/ultrix/ultrix_syscall.h
+++ b/sys/compat/ultrix/ultrix_syscall.h
@@ -12,6 +12,7 @@
#define ULTRIX_SYS_write 4
#define ULTRIX_SYS_open 5
#define ULTRIX_SYS_close 6
+#define ULTRIX_SYS_owait 7
#define ULTRIX_SYS_creat 8
#define ULTRIX_SYS_link 9
#define ULTRIX_SYS_unlink 10
@@ -25,7 +26,7 @@
/* 18 is obsolete stat */
#define ULTRIX_SYS_lseek 19
#define ULTRIX_SYS_getpid 20
- /* 21 is obsolete mount */
+#define ULTRIX_SYS_mount 21
/* 22 is obsolete sysV_unmount */
#define ULTRIX_SYS_setuid 23
#define ULTRIX_SYS_getuid 24
@@ -148,6 +149,7 @@
#define ULTRIX_SYS_exportfs 169
#define ULTRIX_SYS_uname 179
#define ULTRIX_SYS_ustat 183
+#define ULTRIX_SYS_getmnt 184
#define ULTRIX_SYS_sigpending 187
#define ULTRIX_SYS_setsid 188
#define ULTRIX_SYS_waitpid 189
diff --git a/sys/compat/ultrix/ultrix_syscallargs.h b/sys/compat/ultrix/ultrix_syscallargs.h
index ac03a0be564..0b30b52388b 100644
--- a/sys/compat/ultrix/ultrix_syscallargs.h
+++ b/sys/compat/ultrix/ultrix_syscallargs.h
@@ -24,6 +24,20 @@ struct ultrix_sys_mknod_args {
syscallarg(int) dev;
};
+struct ultrix_sys_mount_args {
+ syscallarg(char *) special;
+ syscallarg(char *) dir;
+ syscallarg(int) rdonly;
+ syscallarg(int) type;
+ syscallarg(caddr_t) data;
+};
+
+struct ultrix_sys_ioctl_args {
+ syscallarg(int) fd;
+ syscallarg(u_long) com;
+ syscallarg(caddr_t) data;
+};
+
struct ultrix_sys_mmap_args {
syscallarg(caddr_t) addr;
syscallarg(size_t) len;
@@ -44,6 +58,14 @@ struct ultrix_sys_wait3_args {
syscallarg(struct rusage *) rusage;
};
+struct ultrix_sys_select_args {
+ syscallarg(u_int) nd;
+ syscallarg(fd_set *) in;
+ syscallarg(fd_set *) ou;
+ syscallarg(fd_set *) ex;
+ syscallarg(struct timeval *) tv;
+};
+
struct ultrix_sys_setsockopt_args {
syscallarg(int) s;
syscallarg(int) level;
@@ -91,6 +113,14 @@ struct ultrix_sys_ustat_args {
syscallarg(struct ultrix_ustat *) buf;
};
+struct ultrix_sys_getmnt_args {
+ syscallarg(int *) start;
+ syscallarg(struct ultrix_fs_data *) buf;
+ syscallarg(int) bufsize;
+ syscallarg(int) mode;
+ syscallarg(char *) path;
+};
+
struct ultrix_sys_sigpending_args {
syscallarg(int *) mask;
};
@@ -128,6 +158,7 @@ int sys_read __P((struct proc *, void *, register_t *));
int sys_write __P((struct proc *, void *, register_t *));
int ultrix_sys_open __P((struct proc *, void *, register_t *));
int sys_close __P((struct proc *, void *, register_t *));
+int compat_43_sys_wait __P((struct proc *, void *, register_t *));
int compat_43_sys_creat __P((struct proc *, void *, register_t *));
int sys_link __P((struct proc *, void *, register_t *));
int sys_unlink __P((struct proc *, void *, register_t *));
@@ -139,6 +170,7 @@ int sys_chown __P((struct proc *, void *, register_t *));
int sys_obreak __P((struct proc *, void *, register_t *));
int compat_43_sys_lseek __P((struct proc *, void *, register_t *));
int sys_getpid __P((struct proc *, void *, register_t *));
+int ultrix_sys_mount __P((struct proc *, void *, register_t *));
int sys_setuid __P((struct proc *, void *, register_t *));
int sys_getuid __P((struct proc *, void *, register_t *));
int sys_access __P((struct proc *, void *, register_t *));
@@ -151,7 +183,7 @@ int sys_pipe __P((struct proc *, void *, register_t *));
int sys_profil __P((struct proc *, void *, register_t *));
int sys_getgid __P((struct proc *, void *, register_t *));
int sys_acct __P((struct proc *, void *, register_t *));
-int sys_ioctl __P((struct proc *, void *, register_t *));
+int ultrix_sys_ioctl __P((struct proc *, void *, register_t *));
int sys_reboot __P((struct proc *, void *, register_t *));
int sys_symlink __P((struct proc *, void *, register_t *));
int sys_readlink __P((struct proc *, void *, register_t *));
@@ -183,7 +215,7 @@ int compat_43_sys_sethostname __P((struct proc *, void *, register_t *));
int compat_43_sys_getdtablesize __P((struct proc *, void *, register_t *));
int sys_dup2 __P((struct proc *, void *, register_t *));
int sys_fcntl __P((struct proc *, void *, register_t *));
-int sys_select __P((struct proc *, void *, register_t *));
+int ultrix_sys_select __P((struct proc *, void *, register_t *));
int sys_fsync __P((struct proc *, void *, register_t *));
int sys_setpriority __P((struct proc *, void *, register_t *));
int sys_socket __P((struct proc *, void *, register_t *));
@@ -250,6 +282,7 @@ int ultrix_sys_quotactl __P((struct proc *, void *, register_t *));
int ultrix_sys_exportfs __P((struct proc *, void *, register_t *));
int ultrix_sys_uname __P((struct proc *, void *, register_t *));
int ultrix_sys_ustat __P((struct proc *, void *, register_t *));
+int ultrix_sys_getmnt __P((struct proc *, void *, register_t *));
int ultrix_sys_sigpending __P((struct proc *, void *, register_t *));
int sys_setsid __P((struct proc *, void *, register_t *));
int ultrix_sys_waitpid __P((struct proc *, void *, register_t *));
diff --git a/sys/compat/ultrix/ultrix_syscalls.c b/sys/compat/ultrix/ultrix_syscalls.c
index f0695ed78f2..cd6cfe6b455 100644
--- a/sys/compat/ultrix/ultrix_syscalls.c
+++ b/sys/compat/ultrix/ultrix_syscalls.c
@@ -13,7 +13,7 @@ char *ultrix_syscallnames[] = {
"write", /* 4 = write */
"open", /* 5 = open */
"close", /* 6 = close */
- "#7 (unimplemented old_wait)", /* 7 = unimplemented old_wait */
+ "owait", /* 7 = owait */
"creat", /* 8 = creat */
"link", /* 9 = link */
"unlink", /* 10 = unlink */
@@ -27,7 +27,7 @@ char *ultrix_syscallnames[] = {
"#18 (obsolete stat)", /* 18 = obsolete stat */
"lseek", /* 19 = lseek */
"getpid", /* 20 = getpid */
- "#21 (obsolete mount)", /* 21 = obsolete mount */
+ "mount", /* 21 = mount */
"#22 (obsolete sysV_unmount)", /* 22 = obsolete sysV_unmount */
"setuid", /* 23 = setuid */
"getuid", /* 24 = getuid */
@@ -185,7 +185,7 @@ char *ultrix_syscallnames[] = {
"#167 (unimplemented)", /* 167 = unimplemented */
"quotactl", /* 168 = quotactl */
"exportfs", /* 169 = exportfs */
- "#170 (unimplemented mount)", /* 170 = unimplemented mount */
+ "#170 (unimplemented { int ultrix_sys_mount ( char * special , char * dir , int rdonly , int type , caddr_t data ) ; })", /* 170 = unimplemented { int ultrix_sys_mount ( char * special , char * dir , int rdonly , int type , caddr_t data ) ; } */
"#171 (unimplemented 4 hdwconf)", /* 171 = unimplemented 4 hdwconf */
"#172 (unimplemented msgctl)", /* 172 = unimplemented msgctl */
"#173 (unimplemented msgget)", /* 173 = unimplemented msgget */
@@ -199,7 +199,7 @@ char *ultrix_syscallnames[] = {
"#181 (unimplemented 0 plock)", /* 181 = unimplemented 0 plock */
"#182 (unimplemented 0 lockf)", /* 182 = unimplemented 0 lockf */
"ustat", /* 183 = ustat */
- "#184 (unimplemented getmnt)", /* 184 = unimplemented getmnt */
+ "getmnt", /* 184 = getmnt */
"#185 (unimplemented notdef)", /* 185 = unimplemented notdef */
"#186 (unimplemented notdef)", /* 186 = unimplemented notdef */
"sigpending", /* 187 = sigpending */
diff --git a/sys/compat/ultrix/ultrix_sysent.c b/sys/compat/ultrix/ultrix_sysent.c
index fdf44822eb1..13a53958973 100644
--- a/sys/compat/ultrix/ultrix_sysent.c
+++ b/sys/compat/ultrix/ultrix_sysent.c
@@ -48,7 +48,7 @@ struct sysent ultrix_sysent[] = {
{ 1, s(struct sys_close_args),
sys_close }, /* 6 = close */
{ 0, 0,
- sys_nosys }, /* 7 = unimplemented old_wait */
+ compat_43_sys_wait }, /* 7 = owait */
{ 2, s(struct compat_43_sys_creat_args),
compat_43_sys_creat }, /* 8 = creat */
{ 2, s(struct sys_link_args),
@@ -75,8 +75,8 @@ struct sysent ultrix_sysent[] = {
compat_43_sys_lseek }, /* 19 = lseek */
{ 0, 0,
sys_getpid }, /* 20 = getpid */
- { 0, 0,
- sys_nosys }, /* 21 = obsolete mount */
+ { 5, s(struct ultrix_sys_mount_args),
+ ultrix_sys_mount }, /* 21 = mount */
{ 0, 0,
sys_nosys }, /* 22 = obsolete sysV_unmount */
{ 1, s(struct sys_setuid_args),
@@ -141,8 +141,8 @@ struct sysent ultrix_sysent[] = {
sys_nosys }, /* 52 = unimplemented */
{ 0, 0,
sys_nosys }, /* 53 = unimplemented syslock */
- { 3, s(struct sys_ioctl_args),
- sys_ioctl }, /* 54 = ioctl */
+ { 3, s(struct ultrix_sys_ioctl_args),
+ ultrix_sys_ioctl }, /* 54 = ioctl */
{ 1, s(struct sys_reboot_args),
sys_reboot }, /* 55 = reboot */
{ 0, 0,
@@ -219,8 +219,8 @@ struct sysent ultrix_sysent[] = {
sys_nosys }, /* 91 = unimplemented getdopt */
{ 3, s(struct sys_fcntl_args),
sys_fcntl }, /* 92 = fcntl */
- { 5, s(struct sys_select_args),
- sys_select }, /* 93 = select */
+ { 5, s(struct ultrix_sys_select_args),
+ ultrix_sys_select }, /* 93 = select */
{ 0, 0,
sys_nosys }, /* 94 = unimplemented setdopt */
{ 1, s(struct sys_fsync_args),
@@ -386,7 +386,7 @@ struct sysent ultrix_sysent[] = {
{ 2, s(struct ultrix_sys_exportfs_args),
ultrix_sys_exportfs }, /* 169 = exportfs */
{ 0, 0,
- sys_nosys }, /* 170 = unimplemented mount */
+ sys_nosys }, /* 170 = unimplemented { int ultrix_sys_mount ( char * special , char * dir , int rdonly , int type , caddr_t data ) ; } */
{ 0, 0,
sys_nosys }, /* 171 = unimplemented 4 hdwconf */
{ 0, 0,
@@ -413,8 +413,8 @@ struct sysent ultrix_sysent[] = {
sys_nosys }, /* 182 = unimplemented 0 lockf */
{ 2, s(struct ultrix_sys_ustat_args),
ultrix_sys_ustat }, /* 183 = ustat */
- { 0, 0,
- sys_nosys }, /* 184 = unimplemented getmnt */
+ { 5, s(struct ultrix_sys_getmnt_args),
+ ultrix_sys_getmnt }, /* 184 = getmnt */
{ 0, 0,
sys_nosys }, /* 185 = unimplemented notdef */
{ 0, 0,