ibcs2_xenix.c revision 115684
1/*- 2 * Copyright (c) 1994 Sean Eric Fagan 3 * Copyright (c) 1994 S�ren Schmidt 4 * Copyright (c) 1995 Steven Wallace 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer 12 * in this position and unchanged. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include <sys/cdefs.h> 32__FBSDID("$FreeBSD: head/sys/i386/ibcs2/ibcs2_xenix.c 115684 2003-06-02 06:48:51Z obrien $"); 33 34#include <sys/param.h> 35#include <sys/systm.h> 36#include <sys/namei.h> 37#include <sys/sysproto.h> 38#include <sys/jail.h> 39#include <sys/kernel.h> 40#include <sys/filio.h> 41#include <sys/vnode.h> 42#include <sys/sysctl.h> 43 44#include <machine/cpu.h> 45 46#include <i386/ibcs2/ibcs2_types.h> 47#include <i386/ibcs2/ibcs2_unistd.h> 48#include <i386/ibcs2/ibcs2_signal.h> 49#include <i386/ibcs2/ibcs2_util.h> 50#include <i386/ibcs2/ibcs2_proto.h> 51#include <i386/ibcs2/ibcs2_xenix.h> 52#include <i386/ibcs2/ibcs2_xenix_syscall.h> 53 54 55extern struct sysent xenix_sysent[]; 56 57int 58ibcs2_xenix(struct thread *td, struct ibcs2_xenix_args *uap) 59{ 60 struct trapframe *tf = td->td_frame; 61 struct sysent *callp; 62 u_int code; 63 64 code = (tf->tf_eax & 0xff00) >> 8; 65 callp = &xenix_sysent[code]; 66 67 if(code < IBCS2_XENIX_MAXSYSCALL) 68 return((*callp->sy_call)(td, (void *)uap)); 69 else 70 return ENOSYS; 71} 72 73int 74xenix_rdchk(td, uap) 75 struct thread *td; 76 struct xenix_rdchk_args *uap; 77{ 78 int error; 79 struct ioctl_args sa; 80 caddr_t sg = stackgap_init(); 81 82 DPRINTF(("IBCS2: 'xenix rdchk'\n")); 83 sa.fd = uap->fd; 84 sa.com = FIONREAD; 85 sa.data = stackgap_alloc(&sg, sizeof(int)); 86 if ((error = ioctl(td, &sa)) != 0) 87 return error; 88 td->td_retval[0] = (*((int*)sa.data)) ? 1 : 0; 89 return 0; 90} 91 92int 93xenix_chsize(td, uap) 94 struct thread *td; 95 struct xenix_chsize_args *uap; 96{ 97 struct ftruncate_args sa; 98 99 DPRINTF(("IBCS2: 'xenix chsize'\n")); 100 sa.fd = uap->fd; 101 sa.pad = 0; 102 sa.length = uap->size; 103 return ftruncate(td, &sa); 104} 105 106 107int 108xenix_ftime(td, uap) 109 struct thread *td; 110 struct xenix_ftime_args *uap; 111{ 112 struct timeval tv; 113 struct ibcs2_timeb { 114 unsigned long time __packed; 115 unsigned short millitm; 116 short timezone; 117 short dstflag; 118 } itb; 119 120 DPRINTF(("IBCS2: 'xenix ftime'\n")); 121 microtime(&tv); 122 itb.time = tv.tv_sec; 123 itb.millitm = (tv.tv_usec / 1000); 124 itb.timezone = tz_minuteswest; 125 itb.dstflag = tz_dsttime != DST_NONE; 126 127 return copyout((caddr_t)&itb, (caddr_t)uap->tp, 128 sizeof(struct ibcs2_timeb)); 129} 130 131int 132xenix_nap(struct thread *td, struct xenix_nap_args *uap) 133{ 134 long period; 135 136 DPRINTF(("IBCS2: 'xenix nap %d ms'\n", uap->millisec)); 137 period = (long)uap->millisec / (1000/hz); 138 if (period) 139 while (tsleep(&period, PPAUSE, "nap", period) 140 != EWOULDBLOCK) ; 141 return 0; 142} 143 144int 145xenix_utsname(struct thread *td, struct xenix_utsname_args *uap) 146{ 147 struct ibcs2_sco_utsname { 148 char sysname[9]; 149 char nodename[9]; 150 char release[16]; 151 char kernelid[20]; 152 char machine[9]; 153 char bustype[9]; 154 char sysserial[10]; 155 unsigned short sysorigin; 156 unsigned short sysoem; 157 char numusers[9]; 158 unsigned short numcpu; 159 } ibcs2_sco_uname; 160 161 DPRINTF(("IBCS2: 'xenix sco_utsname'\n")); 162 bzero(&ibcs2_sco_uname, sizeof(struct ibcs2_sco_utsname)); 163 strncpy(ibcs2_sco_uname.sysname, ostype, 164 sizeof(ibcs2_sco_uname.sysname) - 1); 165 getcredhostname(td->td_ucred, ibcs2_sco_uname.nodename, 166 sizeof(ibcs2_sco_uname.nodename) - 1); 167 strncpy(ibcs2_sco_uname.release, osrelease, 168 sizeof(ibcs2_sco_uname.release) - 1); 169 strncpy(ibcs2_sco_uname.kernelid, version, 170 sizeof(ibcs2_sco_uname.kernelid) - 1); 171 strncpy(ibcs2_sco_uname.machine, machine, 172 sizeof(ibcs2_sco_uname.machine) - 1); 173 strncpy(ibcs2_sco_uname.bustype, "ISA/EISA", 174 sizeof(ibcs2_sco_uname.bustype) - 1); 175 strncpy(ibcs2_sco_uname.sysserial, "no charge", 176 sizeof(ibcs2_sco_uname.sysserial) - 1); 177 strncpy(ibcs2_sco_uname.numusers, "unlim", 178 sizeof(ibcs2_sco_uname.numusers) - 1); 179 ibcs2_sco_uname.sysorigin = 0xFFFF; 180 ibcs2_sco_uname.sysoem = 0xFFFF; 181 ibcs2_sco_uname.numcpu = 1; 182 return copyout((caddr_t)&ibcs2_sco_uname, 183 (caddr_t)(void *)(intptr_t)uap->addr, 184 sizeof(struct ibcs2_sco_utsname)); 185} 186 187int 188xenix_scoinfo(struct thread *td, struct xenix_scoinfo_args *uap) 189{ 190 /* scoinfo (not documented) */ 191 td->td_retval[0] = 0; 192 return 0; 193} 194 195int 196xenix_eaccess(struct thread *td, struct xenix_eaccess_args *uap) 197{ 198 struct ucred *cred = td->td_ucred; 199 struct vnode *vp; 200 struct nameidata nd; 201 int error, flags; 202 caddr_t sg = stackgap_init(); 203 204 CHECKALTEXIST(td, &sg, uap->path); 205 206 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, 207 uap->path, td); 208 if ((error = namei(&nd)) != 0) 209 return error; 210 vp = nd.ni_vp; 211 212 /* Flags == 0 means only check for existence. */ 213 if (uap->flags) { 214 flags = 0; 215 if (uap->flags & IBCS2_R_OK) 216 flags |= VREAD; 217 if (uap->flags & IBCS2_W_OK) 218 flags |= VWRITE; 219 if (uap->flags & IBCS2_X_OK) 220 flags |= VEXEC; 221 if ((flags & VWRITE) == 0 || (error = vn_writechk(vp)) == 0) 222 error = VOP_ACCESS(vp, flags, cred, td); 223 } 224 NDFREE(&nd, NDF_ONLY_PNBUF); 225 vput(vp); 226 return error; 227} 228