1999-04-27 21:56:52 +04:00
|
|
|
/* $NetBSD: osf1_misc.c,v 1.27 1999/04/27 17:56:52 cgd Exp $ */
|
1999-04-24 11:23:54 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (c) 1999 Christopher G. Demetriou. 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. 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. All advertising materials mentioning features or use of this software
|
|
|
|
* must display the following acknowledgement:
|
|
|
|
* This product includes software developed by Christopher G. Demetriou
|
|
|
|
* for the NetBSD Project.
|
|
|
|
* 4. 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.
|
|
|
|
*/
|
1995-02-14 00:39:00 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Author: Chris G. Demetriou
|
|
|
|
*
|
|
|
|
* Permission to use, copy, modify and distribute this software and
|
|
|
|
* its documentation is hereby granted, provided that both the copyright
|
|
|
|
* notice and this permission notice appear in all copies of the
|
|
|
|
* software, derivative works or modified versions, and any portions
|
|
|
|
* thereof, and that both notices appear in supporting documentation.
|
|
|
|
*
|
|
|
|
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
|
|
|
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
|
|
|
|
* FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
|
|
|
*
|
|
|
|
* Carnegie Mellon requests users of this software to return to
|
|
|
|
*
|
|
|
|
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
|
|
|
* School of Computer Science
|
|
|
|
* Carnegie Mellon University
|
|
|
|
* Pittsburgh PA 15213-3890
|
|
|
|
*
|
|
|
|
* any improvements or extensions that they make and grant Carnegie the
|
|
|
|
* rights to redistribute these changes.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/systm.h>
|
1995-10-07 09:25:19 +03:00
|
|
|
#include <sys/namei.h>
|
|
|
|
#include <sys/proc.h>
|
1995-02-14 00:39:00 +03:00
|
|
|
#include <sys/file.h>
|
1995-10-07 09:25:19 +03:00
|
|
|
#include <sys/stat.h>
|
1995-02-14 00:39:00 +03:00
|
|
|
#include <sys/filedesc.h>
|
1995-10-07 09:25:19 +03:00
|
|
|
#include <sys/kernel.h>
|
1995-02-14 00:39:00 +03:00
|
|
|
#include <sys/malloc.h>
|
|
|
|
#include <sys/mman.h>
|
1995-10-07 09:25:19 +03:00
|
|
|
#include <sys/mount.h>
|
1995-02-14 00:39:00 +03:00
|
|
|
#include <sys/signal.h>
|
1995-06-28 08:41:30 +04:00
|
|
|
#include <sys/signalvar.h>
|
1995-10-07 09:25:19 +03:00
|
|
|
#include <sys/reboot.h>
|
1995-02-14 00:39:00 +03:00
|
|
|
#include <sys/syscallargs.h>
|
1998-05-20 20:34:29 +04:00
|
|
|
#include <sys/exec.h>
|
|
|
|
#include <sys/vnode.h>
|
|
|
|
#include <sys/socketvar.h>
|
1999-04-27 10:37:12 +04:00
|
|
|
#include <vm/vm.h> /* XXX UVM headers are Cool */
|
|
|
|
#include <uvm/uvm.h> /* XXX see mmap emulation */
|
1995-10-07 09:25:19 +03:00
|
|
|
|
1999-04-24 11:23:54 +04:00
|
|
|
#include <compat/osf1/osf1.h>
|
1995-06-28 08:41:30 +04:00
|
|
|
#include <compat/osf1/osf1_syscall.h>
|
1995-02-14 00:39:00 +03:00
|
|
|
#include <compat/osf1/osf1_syscallargs.h>
|
1995-10-07 09:25:19 +03:00
|
|
|
#include <compat/osf1/osf1_util.h>
|
|
|
|
|
|
|
|
#include <vm/vm.h>
|
1995-02-14 00:39:00 +03:00
|
|
|
|
1998-05-20 20:34:29 +04:00
|
|
|
void cvtstat2osf1 __P((struct stat *, struct osf1_stat *));
|
1999-04-27 21:50:59 +04:00
|
|
|
void cvtrusage2osf1 __P((struct rusage *, struct osf1_rusage *));
|
1998-05-20 20:34:29 +04:00
|
|
|
|
1995-02-14 00:39:00 +03:00
|
|
|
#ifdef SYSCALL_DEBUG
|
|
|
|
extern int scdebug;
|
|
|
|
#endif
|
|
|
|
|
1999-04-24 11:23:54 +04:00
|
|
|
const char osf1_emul_path[] = "/emul/osf1";
|
|
|
|
|
1999-04-26 05:23:01 +04:00
|
|
|
const struct emul_flags_xtab osf1_open_flags_xtab[] = {
|
1999-04-24 11:23:54 +04:00
|
|
|
{ OSF1_O_ACCMODE, OSF1_O_RDONLY, O_RDONLY },
|
|
|
|
{ OSF1_O_ACCMODE, OSF1_O_WRONLY, O_WRONLY },
|
|
|
|
{ OSF1_O_ACCMODE, OSF1_O_RDWR, O_RDWR },
|
|
|
|
{ OSF1_O_NONBLOCK, OSF1_O_NONBLOCK, O_NONBLOCK },
|
|
|
|
{ OSF1_O_APPEND, OSF1_O_APPEND, O_APPEND },
|
|
|
|
#if 0 /* no equivalent +++ */
|
|
|
|
{ OSF1_O_DEFER, OSF1_O_DEFER, ??? },
|
|
|
|
#endif
|
|
|
|
{ OSF1_O_CREAT, OSF1_O_CREAT, O_CREAT },
|
|
|
|
{ OSF1_O_TRUNC, OSF1_O_TRUNC, O_TRUNC },
|
|
|
|
{ OSF1_O_EXCL, OSF1_O_EXCL, O_EXCL },
|
|
|
|
{ OSF1_O_NOCTTY, OSF1_O_NOCTTY, O_NOCTTY },
|
|
|
|
{ OSF1_O_SYNC, OSF1_O_SYNC, O_SYNC },
|
|
|
|
{ OSF1_O_NDELAY, OSF1_O_NDELAY, O_NDELAY },
|
|
|
|
#if 0 /* no equivalent, also same value as O_NDELAY! */
|
|
|
|
{ OSF1_O_DRD, OSF1_O_DRD, ??? },
|
|
|
|
#endif
|
|
|
|
{ OSF1_O_DSYNC, OSF1_O_DSYNC, O_DSYNC },
|
|
|
|
{ OSF1_O_RSYNC, OSF1_O_RSYNC, O_RSYNC },
|
|
|
|
{ 0 }
|
|
|
|
};
|
1995-04-22 23:48:19 +04:00
|
|
|
|
1995-02-14 00:39:00 +03:00
|
|
|
int
|
1995-10-07 09:25:19 +03:00
|
|
|
osf1_sys_open(p, v, retval)
|
1995-02-14 00:39:00 +03:00
|
|
|
struct proc *p;
|
1995-09-20 02:44:25 +04:00
|
|
|
void *v;
|
|
|
|
register_t *retval;
|
|
|
|
{
|
1999-04-24 11:06:35 +04:00
|
|
|
struct osf1_sys_open_args *uap = v;
|
|
|
|
struct sys_open_args a;
|
1999-04-24 11:23:54 +04:00
|
|
|
const char *path;
|
|
|
|
caddr_t sg;
|
|
|
|
unsigned long leftovers;
|
1995-02-14 00:39:00 +03:00
|
|
|
#ifdef SYSCALL_DEBUG
|
|
|
|
char pnbuf[1024];
|
|
|
|
|
|
|
|
if (scdebug &&
|
|
|
|
copyinstr(SCARG(uap, path), pnbuf, sizeof pnbuf, NULL) == 0)
|
1996-10-13 04:46:49 +04:00
|
|
|
printf("osf1_open: open: %s\n", pnbuf);
|
1995-02-14 00:39:00 +03:00
|
|
|
#endif
|
|
|
|
|
1999-04-24 11:23:54 +04:00
|
|
|
sg = stackgap_init(p->p_emul);
|
|
|
|
|
|
|
|
/* translate flags */
|
|
|
|
SCARG(&a, flags) = emul_flags_translate(osf1_open_flags_xtab,
|
|
|
|
SCARG(uap, flags), &leftovers);
|
|
|
|
if (leftovers != 0)
|
|
|
|
return (EINVAL);
|
|
|
|
|
|
|
|
/* copy mode, no translation necessary */
|
1995-02-14 00:39:00 +03:00
|
|
|
SCARG(&a, mode) = SCARG(uap, mode);
|
|
|
|
|
1999-04-24 11:23:54 +04:00
|
|
|
/* pick appropriate path */
|
|
|
|
path = SCARG(uap, path);
|
|
|
|
if (SCARG(&a, flags) & O_CREAT)
|
|
|
|
OSF1_CHECK_ALT_CREAT(p, &sg, path);
|
|
|
|
else
|
|
|
|
OSF1_CHECK_ALT_EXIST(p, &sg, path);
|
|
|
|
SCARG(&a, path) = path;
|
|
|
|
|
1995-10-07 09:25:19 +03:00
|
|
|
return sys_open(p, &a, retval);
|
1995-02-14 00:39:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
1995-10-07 09:25:19 +03:00
|
|
|
osf1_sys_setsysinfo(p, v, retval)
|
1995-02-14 00:39:00 +03:00
|
|
|
struct proc *p;
|
1995-09-20 02:44:25 +04:00
|
|
|
void *v;
|
|
|
|
register_t *retval;
|
|
|
|
{
|
1995-02-14 00:39:00 +03:00
|
|
|
|
1999-04-24 11:23:54 +04:00
|
|
|
/* XXX */
|
1995-02-14 00:39:00 +03:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
1998-05-20 20:34:29 +04:00
|
|
|
int
|
1995-10-07 09:25:19 +03:00
|
|
|
osf1_sys_getrlimit(p, v, retval)
|
1995-02-14 00:39:00 +03:00
|
|
|
struct proc *p;
|
1995-09-20 02:44:25 +04:00
|
|
|
void *v;
|
1995-02-14 00:39:00 +03:00
|
|
|
register_t *retval;
|
|
|
|
{
|
1999-04-24 11:06:35 +04:00
|
|
|
struct osf1_sys_getrlimit_args *uap = v;
|
|
|
|
struct sys_getrlimit_args a;
|
1995-02-14 00:39:00 +03:00
|
|
|
|
1999-04-26 07:30:48 +04:00
|
|
|
switch (SCARG(uap, which)) {
|
|
|
|
case OSF1_RLIMIT_CPU:
|
|
|
|
SCARG(&a, which) = RLIMIT_CPU;
|
|
|
|
break;
|
|
|
|
case OSF1_RLIMIT_FSIZE:
|
|
|
|
SCARG(&a, which) = RLIMIT_FSIZE;
|
|
|
|
break;
|
|
|
|
case OSF1_RLIMIT_DATA:
|
|
|
|
SCARG(&a, which) = RLIMIT_DATA;
|
|
|
|
break;
|
|
|
|
case OSF1_RLIMIT_STACK:
|
|
|
|
SCARG(&a, which) = RLIMIT_STACK;
|
|
|
|
break;
|
|
|
|
case OSF1_RLIMIT_CORE:
|
|
|
|
SCARG(&a, which) = RLIMIT_CORE;
|
|
|
|
break;
|
|
|
|
case OSF1_RLIMIT_RSS:
|
|
|
|
SCARG(&a, which) = RLIMIT_RSS;
|
|
|
|
break;
|
|
|
|
case OSF1_RLIMIT_NOFILE:
|
|
|
|
SCARG(&a, which) = RLIMIT_NOFILE;
|
|
|
|
break;
|
|
|
|
case OSF1_RLIMIT_AS: /* unhandled */
|
|
|
|
default:
|
1995-02-14 00:39:00 +03:00
|
|
|
return (EINVAL);
|
1999-04-26 07:30:48 +04:00
|
|
|
}
|
1995-02-14 00:39:00 +03:00
|
|
|
|
1999-04-26 07:30:48 +04:00
|
|
|
/* XXX should translate */
|
1995-02-14 00:39:00 +03:00
|
|
|
SCARG(&a, rlp) = SCARG(uap, rlp);
|
|
|
|
|
1995-10-07 09:25:19 +03:00
|
|
|
return sys_getrlimit(p, &a, retval);
|
1995-02-14 00:39:00 +03:00
|
|
|
}
|
|
|
|
|
1998-05-20 20:34:29 +04:00
|
|
|
int
|
1995-10-07 09:25:19 +03:00
|
|
|
osf1_sys_setrlimit(p, v, retval)
|
1995-02-14 00:39:00 +03:00
|
|
|
struct proc *p;
|
1995-09-20 02:44:25 +04:00
|
|
|
void *v;
|
|
|
|
register_t *retval;
|
|
|
|
{
|
1999-04-24 11:06:35 +04:00
|
|
|
struct osf1_sys_setrlimit_args *uap = v;
|
|
|
|
struct sys_setrlimit_args a;
|
1995-02-14 00:39:00 +03:00
|
|
|
|
1999-04-26 07:30:48 +04:00
|
|
|
switch (SCARG(uap, which)) {
|
|
|
|
case OSF1_RLIMIT_CPU:
|
|
|
|
SCARG(&a, which) = RLIMIT_CPU;
|
|
|
|
break;
|
|
|
|
case OSF1_RLIMIT_FSIZE:
|
|
|
|
SCARG(&a, which) = RLIMIT_FSIZE;
|
|
|
|
break;
|
|
|
|
case OSF1_RLIMIT_DATA:
|
|
|
|
SCARG(&a, which) = RLIMIT_DATA;
|
|
|
|
break;
|
|
|
|
case OSF1_RLIMIT_STACK:
|
|
|
|
SCARG(&a, which) = RLIMIT_STACK;
|
|
|
|
break;
|
|
|
|
case OSF1_RLIMIT_CORE:
|
|
|
|
SCARG(&a, which) = RLIMIT_CORE;
|
|
|
|
break;
|
|
|
|
case OSF1_RLIMIT_RSS:
|
|
|
|
SCARG(&a, which) = RLIMIT_RSS;
|
|
|
|
break;
|
|
|
|
case OSF1_RLIMIT_NOFILE:
|
|
|
|
SCARG(&a, which) = RLIMIT_NOFILE;
|
|
|
|
break;
|
|
|
|
case OSF1_RLIMIT_AS: /* unhandled */
|
|
|
|
default:
|
1995-02-14 00:39:00 +03:00
|
|
|
return (EINVAL);
|
1999-04-26 07:30:48 +04:00
|
|
|
}
|
1995-02-14 00:39:00 +03:00
|
|
|
|
1999-04-26 07:30:48 +04:00
|
|
|
/* XXX should translate */
|
1995-02-14 00:39:00 +03:00
|
|
|
SCARG(&a, rlp) = SCARG(uap, rlp);
|
|
|
|
|
1995-10-07 09:25:19 +03:00
|
|
|
return sys_setrlimit(p, &a, retval);
|
1995-02-14 00:39:00 +03:00
|
|
|
}
|
|
|
|
|
1999-04-26 05:23:01 +04:00
|
|
|
const struct emul_flags_xtab osf1_mmap_prot_xtab[] = {
|
1999-04-24 11:23:54 +04:00
|
|
|
#if 0 /* pseudo-flag */
|
|
|
|
{ OSF1_PROT_NONE, OSF1_PROT_NONE, PROT_NONE },
|
|
|
|
#endif
|
|
|
|
{ OSF1_PROT_READ, OSF1_PROT_READ, PROT_READ },
|
|
|
|
{ OSF1_PROT_WRITE, OSF1_PROT_WRITE, PROT_WRITE },
|
|
|
|
{ OSF1_PROT_EXEC, OSF1_PROT_EXEC, PROT_EXEC },
|
|
|
|
{ 0 }
|
|
|
|
};
|
|
|
|
|
1999-04-26 05:23:01 +04:00
|
|
|
const struct emul_flags_xtab osf1_mmap_flags_xtab[] = {
|
1999-04-24 11:23:54 +04:00
|
|
|
{ OSF1_MAP_SHARED, OSF1_MAP_SHARED, MAP_SHARED },
|
|
|
|
{ OSF1_MAP_PRIVATE, OSF1_MAP_PRIVATE, MAP_PRIVATE },
|
|
|
|
{ OSF1_MAP_TYPE, OSF1_MAP_FILE, MAP_FILE },
|
|
|
|
{ OSF1_MAP_TYPE, OSF1_MAP_ANON, MAP_ANON },
|
|
|
|
{ OSF1_MAP_FIXED, OSF1_MAP_FIXED, MAP_FIXED },
|
|
|
|
#if 0 /* pseudo-flag, and the default */
|
|
|
|
{ OSF1_MAP_VARIABLE, OSF1_MAP_VARIABLE, 0 },
|
|
|
|
#endif
|
|
|
|
{ OSF1_MAP_HASSEMAPHORE, OSF1_MAP_HASSEMAPHORE, MAP_HASSEMAPHORE },
|
|
|
|
{ OSF1_MAP_INHERIT, OSF1_MAP_INHERIT, MAP_INHERIT },
|
|
|
|
#if 0 /* no equivalent +++ */
|
|
|
|
{ OSF1_MAP_UNALIGNED, OSF1_MAP_UNALIGNED, ??? },
|
|
|
|
#endif
|
|
|
|
{ 0 }
|
|
|
|
};
|
1995-02-14 00:39:00 +03:00
|
|
|
|
|
|
|
int
|
1995-10-07 09:25:19 +03:00
|
|
|
osf1_sys_mmap(p, v, retval)
|
1995-02-14 00:39:00 +03:00
|
|
|
struct proc *p;
|
1995-09-20 02:44:25 +04:00
|
|
|
void *v;
|
|
|
|
register_t *retval;
|
|
|
|
{
|
1999-04-24 11:06:35 +04:00
|
|
|
struct osf1_sys_mmap_args *uap = v;
|
|
|
|
struct sys_mmap_args a;
|
1999-04-24 11:23:54 +04:00
|
|
|
unsigned long leftovers;
|
1995-02-14 00:39:00 +03:00
|
|
|
|
|
|
|
SCARG(&a, addr) = SCARG(uap, addr);
|
|
|
|
SCARG(&a, len) = SCARG(uap, len);
|
|
|
|
SCARG(&a, fd) = SCARG(uap, fd);
|
|
|
|
SCARG(&a, pad) = 0;
|
|
|
|
SCARG(&a, pos) = SCARG(uap, pos);
|
|
|
|
|
1999-04-24 11:23:54 +04:00
|
|
|
/* translate prot */
|
|
|
|
SCARG(&a, prot) = emul_flags_translate(osf1_mmap_prot_xtab,
|
|
|
|
SCARG(uap, prot), &leftovers);
|
|
|
|
if (leftovers != 0)
|
1995-02-14 00:39:00 +03:00
|
|
|
return (EINVAL);
|
1999-04-24 11:23:54 +04:00
|
|
|
|
|
|
|
/* translate flags */
|
|
|
|
SCARG(&a, flags) = emul_flags_translate(osf1_mmap_flags_xtab,
|
|
|
|
SCARG(uap, flags), &leftovers);
|
|
|
|
if (leftovers != 0)
|
1995-02-14 00:39:00 +03:00
|
|
|
return (EINVAL);
|
|
|
|
|
1999-04-27 10:37:12 +04:00
|
|
|
/*
|
|
|
|
* XXX The following code is evil.
|
|
|
|
*
|
|
|
|
* The OSF/1 mmap() function attempts to map non-fixed entries
|
|
|
|
* near the address that the user specified. Therefore, for
|
|
|
|
* non-fixed entires we try to find space in the address space
|
|
|
|
* starting at that address. If the user specified zero, we
|
|
|
|
* start looking at at least NBPG, so that programs can't
|
|
|
|
* accidentally live through deferencing NULL.
|
|
|
|
*
|
|
|
|
* The need for this kludgery is increased by the fact that
|
|
|
|
* the loader data segment is mapped at
|
|
|
|
* (end of user address space) - 1G, MAXDSIZ is 1G, and
|
|
|
|
* the VM system tries allocate non-fixed mappings _AFTER_
|
|
|
|
* (start of data) + MAXDSIZ. With the loader, of course,
|
|
|
|
* that means that it'll start trying at
|
|
|
|
* (end of user address space), and will never succeed!
|
|
|
|
*
|
|
|
|
* Notes:
|
|
|
|
*
|
|
|
|
* * Though we find space here, if something else (e.g. a second
|
|
|
|
* thread) were mucking with the address space the mapping
|
|
|
|
* we found might be used by another mmap(), and this call
|
|
|
|
* would clobber that region.
|
|
|
|
*
|
|
|
|
* * In general, tricks like this only work for MAP_ANON mappings,
|
|
|
|
* because of sharing/cache issues. That's not a problem on
|
|
|
|
* the Alpha, and though it's not good style to abuse that fact,
|
|
|
|
* there's little choice.
|
|
|
|
*
|
|
|
|
* * In order for this to be done right, the VM system should
|
|
|
|
* really try to use the requested 'addr' passed in to mmap()
|
|
|
|
* as a hint, even if non-fixed. If it's passed as zero,
|
|
|
|
* _maybe_ then try (start of data) + MAXDSIZ, or maybe
|
|
|
|
* provide a better way to avoid the data region altogether.
|
|
|
|
*/
|
|
|
|
if ((SCARG(&a, flags) & MAP_FIXED) == 0) {
|
|
|
|
vaddr_t addr = round_page(SCARG(&a, addr));
|
|
|
|
vsize_t size = round_page(SCARG(&a, len));
|
|
|
|
int fixed = 0;
|
|
|
|
|
|
|
|
vm_map_lock(&p->p_vmspace->vm_map);
|
|
|
|
|
|
|
|
/* if non-NULL address given, start looking there */
|
|
|
|
if (addr != 0 && uvm_map_findspace(&p->p_vmspace->vm_map,
|
|
|
|
addr, size, &addr, NULL, 0, 0) != NULL) {
|
|
|
|
fixed = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* didn't find anything. take it again from the top. */
|
|
|
|
if (uvm_map_findspace(&p->p_vmspace->vm_map, NBPG, size, &addr,
|
|
|
|
NULL, 0, 0) != NULL) {
|
|
|
|
fixed = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
|
|
|
vm_map_unlock(&p->p_vmspace->vm_map);
|
|
|
|
if (fixed) {
|
|
|
|
SCARG(&a, flags) |= MAP_FIXED;
|
|
|
|
SCARG(&a, addr) = (void *)addr;
|
|
|
|
}
|
|
|
|
}
|
1999-04-26 05:23:01 +04:00
|
|
|
|
1995-10-07 09:25:19 +03:00
|
|
|
return sys_mmap(p, &a, retval);
|
1995-02-14 00:39:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
1995-10-07 09:25:19 +03:00
|
|
|
osf1_sys_usleep_thread(p, v, retval)
|
1995-02-14 00:39:00 +03:00
|
|
|
struct proc *p;
|
1995-09-20 02:44:25 +04:00
|
|
|
void *v;
|
|
|
|
register_t *retval;
|
|
|
|
{
|
1999-04-24 11:06:35 +04:00
|
|
|
struct osf1_sys_usleep_thread_args *uap = v;
|
1995-02-14 00:39:00 +03:00
|
|
|
struct timeval tv, endtv;
|
|
|
|
u_long ticks;
|
|
|
|
int error, s;
|
|
|
|
|
1998-05-20 20:34:29 +04:00
|
|
|
if ((error = copyin(SCARG(uap, sleep), &tv, sizeof tv)))
|
1995-02-14 00:39:00 +03:00
|
|
|
return (error);
|
|
|
|
|
|
|
|
ticks = ((u_long)tv.tv_sec * 1000000 + tv.tv_usec) / tick;
|
|
|
|
s = splclock();
|
|
|
|
tv = time;
|
|
|
|
splx(s);
|
|
|
|
|
|
|
|
tsleep(p, PUSER|PCATCH, "OSF/1", ticks); /* XXX */
|
|
|
|
|
|
|
|
if (SCARG(uap, slept) != NULL) {
|
|
|
|
s = splclock();
|
1995-03-21 16:33:34 +03:00
|
|
|
timersub(&time, &tv, &endtv);
|
1995-02-14 00:39:00 +03:00
|
|
|
splx(s);
|
|
|
|
if (tv.tv_sec < 0 || tv.tv_usec < 0)
|
|
|
|
tv.tv_sec = tv.tv_usec = 0;
|
|
|
|
|
|
|
|
error = copyout(&endtv, SCARG(uap, slept), sizeof endtv);
|
|
|
|
}
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get file status; this version follows links.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1998-05-20 20:34:29 +04:00
|
|
|
int
|
1995-10-07 09:25:19 +03:00
|
|
|
osf1_sys_stat(p, v, retval)
|
1995-02-14 00:39:00 +03:00
|
|
|
struct proc *p;
|
1995-09-20 02:44:25 +04:00
|
|
|
void *v;
|
|
|
|
register_t *retval;
|
|
|
|
{
|
1999-04-24 11:09:49 +04:00
|
|
|
struct osf1_sys_stat_args *uap = v;
|
1995-02-14 00:39:00 +03:00
|
|
|
struct stat sb;
|
|
|
|
struct osf1_stat osb;
|
|
|
|
int error;
|
|
|
|
struct nameidata nd;
|
1999-04-24 11:23:54 +04:00
|
|
|
caddr_t sg;
|
|
|
|
|
|
|
|
sg = stackgap_init(p->p_emul);
|
|
|
|
OSF1_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
|
1995-02-14 00:39:00 +03:00
|
|
|
|
|
|
|
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
|
|
|
|
SCARG(uap, path), p);
|
1998-05-20 20:34:29 +04:00
|
|
|
if ((error = namei(&nd)))
|
1995-02-14 00:39:00 +03:00
|
|
|
return (error);
|
|
|
|
error = vn_stat(nd.ni_vp, &sb, p);
|
|
|
|
vput(nd.ni_vp);
|
|
|
|
if (error)
|
|
|
|
return (error);
|
|
|
|
cvtstat2osf1(&sb, &osb);
|
|
|
|
error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb));
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get file status; this version does not follow links.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1998-05-20 20:34:29 +04:00
|
|
|
int
|
1995-10-07 09:25:19 +03:00
|
|
|
osf1_sys_lstat(p, v, retval)
|
1995-02-14 00:39:00 +03:00
|
|
|
struct proc *p;
|
1995-09-20 02:44:25 +04:00
|
|
|
void *v;
|
|
|
|
register_t *retval;
|
|
|
|
{
|
1999-04-24 11:09:49 +04:00
|
|
|
struct osf1_sys_lstat_args *uap = v;
|
1995-02-14 00:39:00 +03:00
|
|
|
struct stat sb;
|
|
|
|
struct osf1_stat osb;
|
|
|
|
int error;
|
|
|
|
struct nameidata nd;
|
1999-04-24 11:23:54 +04:00
|
|
|
caddr_t sg;
|
|
|
|
|
|
|
|
sg = stackgap_init(p->p_emul);
|
|
|
|
OSF1_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
|
1995-02-14 00:39:00 +03:00
|
|
|
|
|
|
|
NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE,
|
|
|
|
SCARG(uap, path), p);
|
1998-05-20 20:34:29 +04:00
|
|
|
if ((error = namei(&nd)))
|
1995-02-14 00:39:00 +03:00
|
|
|
return (error);
|
|
|
|
error = vn_stat(nd.ni_vp, &sb, p);
|
|
|
|
vput(nd.ni_vp);
|
|
|
|
if (error)
|
|
|
|
return (error);
|
|
|
|
cvtstat2osf1(&sb, &osb);
|
|
|
|
error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb));
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Return status information about a file descriptor.
|
|
|
|
*/
|
1998-05-20 20:34:29 +04:00
|
|
|
int
|
1995-10-07 09:25:19 +03:00
|
|
|
osf1_sys_fstat(p, v, retval)
|
1995-02-14 00:39:00 +03:00
|
|
|
struct proc *p;
|
1995-09-20 02:44:25 +04:00
|
|
|
void *v;
|
|
|
|
register_t *retval;
|
|
|
|
{
|
1999-04-24 11:09:49 +04:00
|
|
|
struct osf1_sys_fstat_args *uap = v;
|
|
|
|
struct filedesc *fdp = p->p_fd;
|
|
|
|
struct file *fp;
|
1995-02-14 00:39:00 +03:00
|
|
|
struct stat ub;
|
|
|
|
struct osf1_stat oub;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
if ((unsigned)SCARG(uap, fd) >= fdp->fd_nfiles ||
|
|
|
|
(fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL)
|
|
|
|
return (EBADF);
|
|
|
|
switch (fp->f_type) {
|
|
|
|
|
|
|
|
case DTYPE_VNODE:
|
|
|
|
error = vn_stat((struct vnode *)fp->f_data, &ub, p);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DTYPE_SOCKET:
|
|
|
|
error = soo_stat((struct socket *)fp->f_data, &ub);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
panic("ofstat");
|
|
|
|
/*NOTREACHED*/
|
|
|
|
}
|
|
|
|
cvtstat2osf1(&ub, &oub);
|
|
|
|
if (error == 0)
|
|
|
|
error = copyout((caddr_t)&oub, (caddr_t)SCARG(uap, sb),
|
|
|
|
sizeof (oub));
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
1999-04-26 10:10:36 +04:00
|
|
|
#define bsd2osf_dev(dev) osf1_makedev(major(dev), minor(dev))
|
|
|
|
#define osf2bsd_dev(dev) makedev(osf1_major(dev), osf1_minor(dev))
|
1995-02-14 00:39:00 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Convert from a stat structure to an osf1 stat structure.
|
|
|
|
*/
|
1998-05-20 20:34:29 +04:00
|
|
|
void
|
1995-02-14 00:39:00 +03:00
|
|
|
cvtstat2osf1(st, ost)
|
|
|
|
struct stat *st;
|
|
|
|
struct osf1_stat *ost;
|
|
|
|
{
|
|
|
|
|
|
|
|
ost->st_dev = bsd2osf_dev(st->st_dev);
|
|
|
|
ost->st_ino = st->st_ino;
|
|
|
|
ost->st_mode = st->st_mode;
|
|
|
|
ost->st_nlink = st->st_nlink;
|
|
|
|
ost->st_uid = st->st_uid == -2 ? (u_int16_t) -2 : st->st_uid;
|
|
|
|
ost->st_gid = st->st_gid == -2 ? (u_int16_t) -2 : st->st_gid;
|
|
|
|
ost->st_rdev = bsd2osf_dev(st->st_rdev);
|
|
|
|
ost->st_size = st->st_size;
|
|
|
|
ost->st_atime_sec = st->st_atime;
|
|
|
|
ost->st_spare1 = 0;
|
|
|
|
ost->st_mtime_sec = st->st_mtime;
|
|
|
|
ost->st_spare2 = 0;
|
|
|
|
ost->st_ctime_sec = st->st_ctime;
|
|
|
|
ost->st_spare3 = 0;
|
|
|
|
ost->st_blksize = st->st_blksize;
|
|
|
|
ost->st_blocks = st->st_blocks;
|
|
|
|
ost->st_flags = st->st_flags;
|
|
|
|
ost->st_gen = st->st_gen;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
1995-10-07 09:25:19 +03:00
|
|
|
osf1_sys_mknod(p, v, retval)
|
1995-02-14 00:39:00 +03:00
|
|
|
struct proc *p;
|
1995-09-20 02:44:25 +04:00
|
|
|
void *v;
|
|
|
|
register_t *retval;
|
|
|
|
{
|
1999-04-24 11:06:35 +04:00
|
|
|
struct osf1_sys_mknod_args *uap = v;
|
1995-10-07 09:25:19 +03:00
|
|
|
struct sys_mknod_args a;
|
1999-04-24 11:23:54 +04:00
|
|
|
caddr_t sg;
|
|
|
|
|
|
|
|
sg = stackgap_init(p->p_emul);
|
|
|
|
OSF1_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
|
1995-02-14 00:39:00 +03:00
|
|
|
|
|
|
|
SCARG(&a, path) = SCARG(uap, path);
|
|
|
|
SCARG(&a, mode) = SCARG(uap, mode);
|
|
|
|
SCARG(&a, dev) = osf2bsd_dev(SCARG(uap, dev));
|
|
|
|
|
1995-10-07 09:25:19 +03:00
|
|
|
return sys_mknod(p, &a, retval);
|
1995-02-14 00:39:00 +03:00
|
|
|
}
|
|
|
|
|
1999-04-26 05:23:01 +04:00
|
|
|
const struct emul_flags_xtab osf1_fcntl_getsetfd_flags_xtab[] = {
|
|
|
|
{ OSF1_FD_CLOEXEC, OSF1_FD_CLOEXEC, FD_CLOEXEC },
|
|
|
|
{ 0 }
|
|
|
|
};
|
|
|
|
|
|
|
|
const struct emul_flags_xtab osf1_fcntl_getsetfd_flags_rxtab[] = {
|
|
|
|
{ FD_CLOEXEC, FD_CLOEXEC, OSF1_FD_CLOEXEC },
|
|
|
|
{ 0 }
|
|
|
|
};
|
|
|
|
|
|
|
|
const struct emul_flags_xtab osf1_fcntl_getsetfl_flags_xtab[] = {
|
|
|
|
{ OSF1_FNONBLOCK, OSF1_FNONBLOCK, FNONBLOCK },
|
1999-04-26 09:57:53 +04:00
|
|
|
{ OSF1_FAPPEND, OSF1_FAPPEND, FAPPEND },
|
1999-04-26 05:23:01 +04:00
|
|
|
{ OSF1_FASYNC, OSF1_FASYNC, FASYNC },
|
|
|
|
{ OSF1_FSYNC, OSF1_FSYNC, FFSYNC },
|
1999-04-26 09:57:53 +04:00
|
|
|
{ OSF1_FNDELAY, OSF1_FNDELAY, FNDELAY },
|
|
|
|
{ OSF1_FDSYNC, OSF1_FDSYNC, FDSYNC },
|
|
|
|
{ OSF1_FRSYNC, OSF1_FRSYNC, FRSYNC },
|
1999-04-26 05:23:01 +04:00
|
|
|
{ 0 }
|
|
|
|
};
|
|
|
|
|
|
|
|
const struct emul_flags_xtab osf1_fcntl_getsetfl_flags_rxtab[] = {
|
|
|
|
{ FNONBLOCK, FNONBLOCK, OSF1_FNONBLOCK },
|
1999-04-26 09:57:53 +04:00
|
|
|
{ FAPPEND, FAPPEND, OSF1_FAPPEND },
|
1999-04-26 05:23:01 +04:00
|
|
|
{ FASYNC, FASYNC, OSF1_FASYNC },
|
|
|
|
{ FFSYNC, FFSYNC, OSF1_FSYNC },
|
1999-04-26 09:57:53 +04:00
|
|
|
{ FNDELAY, FNDELAY, OSF1_FNDELAY },
|
|
|
|
{ FDSYNC, FDSYNC, OSF1_FDSYNC },
|
|
|
|
{ FRSYNC, FRSYNC, OSF1_FRSYNC },
|
1999-04-26 05:23:01 +04:00
|
|
|
{ 0 }
|
|
|
|
};
|
|
|
|
|
1995-02-14 00:39:00 +03:00
|
|
|
int
|
1995-10-07 09:25:19 +03:00
|
|
|
osf1_sys_fcntl(p, v, retval)
|
1995-02-14 00:39:00 +03:00
|
|
|
struct proc *p;
|
1995-09-20 02:44:25 +04:00
|
|
|
void *v;
|
|
|
|
register_t *retval;
|
|
|
|
{
|
1999-04-24 11:06:35 +04:00
|
|
|
struct osf1_sys_fcntl_args *uap = v;
|
1995-10-07 09:25:19 +03:00
|
|
|
struct sys_fcntl_args a;
|
1999-04-26 05:23:01 +04:00
|
|
|
unsigned long leftovers;
|
1995-02-14 00:39:00 +03:00
|
|
|
int error;
|
|
|
|
|
|
|
|
SCARG(&a, fd) = SCARG(uap, fd);
|
|
|
|
|
1999-04-26 05:23:01 +04:00
|
|
|
leftovers = 0;
|
1995-02-14 00:39:00 +03:00
|
|
|
switch (SCARG(uap, cmd)) {
|
|
|
|
case OSF1_F_DUPFD:
|
|
|
|
SCARG(&a, cmd) = F_DUPFD;
|
|
|
|
SCARG(&a, arg) = SCARG(uap, arg);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OSF1_F_GETFD:
|
|
|
|
SCARG(&a, cmd) = F_GETFD;
|
1999-04-26 05:23:01 +04:00
|
|
|
SCARG(&a, arg) = 0; /* ignored */
|
1995-02-14 00:39:00 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
case OSF1_F_SETFD:
|
|
|
|
SCARG(&a, cmd) = F_SETFD;
|
1999-04-26 05:23:01 +04:00
|
|
|
SCARG(&a, arg) = (void *)emul_flags_translate(
|
|
|
|
osf1_fcntl_getsetfd_flags_xtab,
|
|
|
|
(unsigned long)SCARG(uap, arg), &leftovers);
|
1995-02-14 00:39:00 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
case OSF1_F_GETFL:
|
|
|
|
SCARG(&a, cmd) = F_GETFL;
|
1999-04-26 05:23:01 +04:00
|
|
|
SCARG(&a, arg) = 0; /* ignored */
|
1995-02-14 00:39:00 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
case OSF1_F_SETFL:
|
|
|
|
SCARG(&a, cmd) = F_SETFL;
|
1999-04-26 05:23:01 +04:00
|
|
|
SCARG(&a, arg) = (void *)emul_flags_translate(
|
|
|
|
osf1_fcntl_getsetfl_flags_xtab,
|
|
|
|
(unsigned long)SCARG(uap, arg), &leftovers);
|
1995-02-14 00:39:00 +03:00
|
|
|
break;
|
|
|
|
|
1999-04-27 21:50:59 +04:00
|
|
|
case OSF1_F_GETOWN: /* XXX not yet supported */
|
|
|
|
case OSF1_F_SETOWN: /* XXX not yet supported */
|
|
|
|
case OSF1_F_GETLK: /* XXX not yet supported */
|
|
|
|
case OSF1_F_SETLK: /* XXX not yet supported */
|
|
|
|
case OSF1_F_SETLKW: /* XXX not yet supported */
|
1999-04-26 05:23:01 +04:00
|
|
|
/* XXX translate. */
|
|
|
|
return (EINVAL);
|
|
|
|
|
1999-04-27 21:50:59 +04:00
|
|
|
case OSF1_F_RGETLK: /* [lock mgr op] XXX not supported */
|
|
|
|
case OSF1_F_RSETLK: /* [lock mgr op] XXX not supported */
|
|
|
|
case OSF1_F_CNVT: /* [lock mgr op] XXX not supported */
|
|
|
|
case OSF1_F_RSETLKW: /* [lock mgr op] XXX not supported */
|
|
|
|
case OSF1_F_PURGEFS: /* [lock mgr op] XXX not supported */
|
|
|
|
case OSF1_F_PURGENFS: /* [DECsafe op] XXX not supported */
|
1999-04-26 05:23:01 +04:00
|
|
|
default:
|
|
|
|
/* XXX syslog? */
|
1995-02-14 00:39:00 +03:00
|
|
|
return (EINVAL);
|
|
|
|
}
|
1999-04-26 05:23:01 +04:00
|
|
|
if (leftovers != 0)
|
|
|
|
return (EINVAL);
|
1995-02-14 00:39:00 +03:00
|
|
|
|
1995-10-07 09:25:19 +03:00
|
|
|
error = sys_fcntl(p, &a, retval);
|
1995-02-14 00:39:00 +03:00
|
|
|
|
|
|
|
if (error)
|
|
|
|
return error;
|
|
|
|
|
|
|
|
switch (SCARG(uap, cmd)) {
|
1999-04-26 05:23:01 +04:00
|
|
|
case OSF1_F_GETFD:
|
|
|
|
retval[0] = emul_flags_translate(
|
|
|
|
osf1_fcntl_getsetfd_flags_rxtab, retval[0], NULL);
|
|
|
|
break;
|
|
|
|
|
1995-02-14 00:39:00 +03:00
|
|
|
case OSF1_F_GETFL:
|
1999-04-26 05:23:01 +04:00
|
|
|
retval[0] = emul_flags_translate(
|
|
|
|
osf1_fcntl_getsetfl_flags_rxtab, retval[0], NULL);
|
1995-02-14 00:39:00 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
1995-10-07 09:25:19 +03:00
|
|
|
osf1_sys_socket(p, v, retval)
|
1995-02-14 00:39:00 +03:00
|
|
|
struct proc *p;
|
1995-09-20 02:44:25 +04:00
|
|
|
void *v;
|
|
|
|
register_t *retval;
|
|
|
|
{
|
1999-04-24 11:09:49 +04:00
|
|
|
struct osf1_sys_socket_args *uap = v;
|
1995-10-07 09:25:19 +03:00
|
|
|
struct sys_socket_args a;
|
1995-02-14 00:39:00 +03:00
|
|
|
|
1999-04-26 05:23:01 +04:00
|
|
|
/* XXX TRANSLATE */
|
|
|
|
|
1995-02-14 00:39:00 +03:00
|
|
|
if (SCARG(uap, type) > AF_LINK)
|
|
|
|
return (EINVAL); /* XXX After AF_LINK, divergence. */
|
|
|
|
|
|
|
|
SCARG(&a, domain) = SCARG(uap, domain);
|
|
|
|
SCARG(&a, type) = SCARG(uap, type);
|
|
|
|
SCARG(&a, protocol) = SCARG(uap, protocol);
|
|
|
|
|
1995-10-07 09:25:19 +03:00
|
|
|
return sys_socket(p, &a, retval);
|
1995-02-14 00:39:00 +03:00
|
|
|
}
|
|
|
|
|
1999-04-26 05:23:01 +04:00
|
|
|
const struct emul_flags_xtab osf1_sendrecv_msg_flags_xtab[] = {
|
|
|
|
{ OSF1_MSG_OOB, OSF1_MSG_OOB, MSG_OOB },
|
|
|
|
{ OSF1_MSG_PEEK, OSF1_MSG_PEEK, MSG_PEEK },
|
|
|
|
{ OSF1_MSG_DONTROUTE, OSF1_MSG_DONTROUTE, MSG_DONTROUTE },
|
|
|
|
{ OSF1_MSG_EOR, OSF1_MSG_EOR, MSG_EOR },
|
|
|
|
{ OSF1_MSG_TRUNC, OSF1_MSG_TRUNC, MSG_TRUNC },
|
|
|
|
{ OSF1_MSG_CTRUNC, OSF1_MSG_CTRUNC, MSG_CTRUNC },
|
|
|
|
{ OSF1_MSG_WAITALL, OSF1_MSG_WAITALL, MSG_WAITALL },
|
|
|
|
{ 0 }
|
|
|
|
};
|
|
|
|
|
1995-02-14 00:39:00 +03:00
|
|
|
int
|
1995-10-07 09:25:19 +03:00
|
|
|
osf1_sys_sendto(p, v, retval)
|
1995-02-14 00:39:00 +03:00
|
|
|
struct proc *p;
|
1995-09-20 02:44:25 +04:00
|
|
|
void *v;
|
|
|
|
register_t *retval;
|
|
|
|
{
|
1999-04-24 11:09:49 +04:00
|
|
|
struct osf1_sys_sendto_args *uap = v;
|
1995-10-07 09:25:19 +03:00
|
|
|
struct sys_sendto_args a;
|
1999-04-26 05:23:01 +04:00
|
|
|
unsigned long leftovers;
|
1995-02-14 00:39:00 +03:00
|
|
|
|
|
|
|
SCARG(&a, s) = SCARG(uap, s);
|
|
|
|
SCARG(&a, buf) = SCARG(uap, buf);
|
|
|
|
SCARG(&a, len) = SCARG(uap, len);
|
|
|
|
SCARG(&a, to) = SCARG(uap, to);
|
|
|
|
SCARG(&a, tolen) = SCARG(uap, tolen);
|
|
|
|
|
1999-04-26 05:23:01 +04:00
|
|
|
/* translate flags */
|
|
|
|
SCARG(&a, flags) = emul_flags_translate(osf1_sendrecv_msg_flags_xtab,
|
|
|
|
SCARG(uap, flags), &leftovers);
|
|
|
|
if (leftovers != 0)
|
|
|
|
return (EINVAL);
|
|
|
|
|
1995-10-07 09:25:19 +03:00
|
|
|
return sys_sendto(p, &a, retval);
|
1995-02-14 00:39:00 +03:00
|
|
|
}
|
|
|
|
|
1999-04-26 05:23:01 +04:00
|
|
|
const struct emul_flags_xtab osf1_reboot_opt_xtab[] = {
|
1999-04-24 11:23:54 +04:00
|
|
|
#if 0 /* pseudo-flag */
|
|
|
|
{ OSF1_RB_AUTOBOOT, OSF1_RB_AUTOBOOT, RB_AUTOBOOT },
|
|
|
|
#endif
|
|
|
|
{ OSF1_RB_ASKNAME, OSF1_RB_ASKNAME, RB_ASKNAME },
|
|
|
|
{ OSF1_RB_SINGLE, OSF1_RB_SINGLE, RB_SINGLE },
|
|
|
|
{ OSF1_RB_NOSYNC, OSF1_RB_NOSYNC, RB_NOSYNC },
|
|
|
|
#if 0 /* same value as O_NDELAY, only used at boot time? */
|
|
|
|
{ OSF1_RB_KDB, OSF1_RB_KDB, RB_KDB },
|
|
|
|
#endif
|
|
|
|
{ OSF1_RB_HALT, OSF1_RB_HALT, RB_HALT },
|
|
|
|
{ OSF1_RB_INITNAME, OSF1_RB_INITNAME, RB_INITNAME },
|
|
|
|
{ OSF1_RB_DFLTROOT, OSF1_RB_DFLTROOT, RB_DFLTROOT },
|
|
|
|
#if 0 /* no equivalents +++ */
|
|
|
|
{ OSF1_RB_ALTBOOT, OSF1_RB_ALTBOOT, ??? },
|
|
|
|
{ OSF1_RB_UNIPROC, OSF1_RB_UNIPROC, ??? },
|
|
|
|
{ OSF1_RB_PARAM, OSF1_RB_PARAM, ??? },
|
|
|
|
#endif
|
|
|
|
{ OSF1_RB_DUMP, OSF1_RB_DUMP, RB_DUMP },
|
|
|
|
{ 0 }
|
|
|
|
};
|
1995-02-14 00:39:00 +03:00
|
|
|
|
|
|
|
int
|
1995-10-07 09:25:19 +03:00
|
|
|
osf1_sys_reboot(p, v, retval)
|
1995-02-14 00:39:00 +03:00
|
|
|
struct proc *p;
|
1995-09-20 02:44:25 +04:00
|
|
|
void *v;
|
1995-02-14 00:39:00 +03:00
|
|
|
register_t *retval;
|
|
|
|
{
|
1999-04-24 11:06:35 +04:00
|
|
|
struct osf1_sys_reboot_args *uap = v;
|
1995-10-07 09:25:19 +03:00
|
|
|
struct sys_reboot_args a;
|
1999-04-24 11:23:54 +04:00
|
|
|
unsigned long leftovers;
|
1995-02-14 00:39:00 +03:00
|
|
|
|
1999-04-24 11:23:54 +04:00
|
|
|
/* translate opt */
|
|
|
|
SCARG(&a, opt) = emul_flags_translate(osf1_reboot_opt_xtab,
|
|
|
|
SCARG(uap, opt), &leftovers);
|
|
|
|
if (leftovers != 0)
|
1995-02-14 00:39:00 +03:00
|
|
|
return (EINVAL);
|
|
|
|
|
1996-08-09 14:30:23 +04:00
|
|
|
SCARG(&a, bootstr) = NULL;
|
1995-02-14 00:39:00 +03:00
|
|
|
|
1995-10-07 09:25:19 +03:00
|
|
|
return sys_reboot(p, &a, retval);
|
1995-02-14 00:39:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
1995-10-07 09:25:19 +03:00
|
|
|
osf1_sys_lseek(p, v, retval)
|
1995-02-14 00:39:00 +03:00
|
|
|
struct proc *p;
|
1995-09-20 02:44:25 +04:00
|
|
|
void *v;
|
1995-02-14 00:39:00 +03:00
|
|
|
register_t *retval;
|
|
|
|
{
|
1999-04-24 11:06:35 +04:00
|
|
|
struct osf1_sys_lseek_args *uap = v;
|
1995-10-07 09:25:19 +03:00
|
|
|
struct sys_lseek_args a;
|
1995-02-14 00:39:00 +03:00
|
|
|
|
|
|
|
SCARG(&a, fd) = SCARG(uap, fd);
|
|
|
|
SCARG(&a, pad) = 0;
|
|
|
|
SCARG(&a, offset) = SCARG(uap, offset);
|
|
|
|
SCARG(&a, whence) = SCARG(uap, whence);
|
|
|
|
|
1995-10-07 09:25:19 +03:00
|
|
|
return sys_lseek(p, &a, retval);
|
1995-02-14 00:39:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* OSF/1 defines _POSIX_SAVED_IDS, which means that our normal
|
|
|
|
* setuid() won't work.
|
|
|
|
*
|
|
|
|
* Instead, by P1003.1b-1993, setuid() is supposed to work like:
|
|
|
|
* If the process has appropriate [super-user] priviledges, the
|
|
|
|
* setuid() function sets the real user ID, effective user
|
|
|
|
* ID, and the saved set-user-ID to uid.
|
|
|
|
* If the process does not have appropriate priviledges, but uid
|
|
|
|
* is equal to the real user ID or the saved set-user-ID, the
|
|
|
|
* setuid() function sets the effective user ID to uid; the
|
|
|
|
* real user ID and saved set-user-ID remain unchanged by
|
|
|
|
* this function call.
|
|
|
|
*/
|
|
|
|
int
|
1995-10-07 09:25:19 +03:00
|
|
|
osf1_sys_setuid(p, v, retval)
|
1995-02-14 00:39:00 +03:00
|
|
|
struct proc *p;
|
1995-09-20 02:44:25 +04:00
|
|
|
void *v;
|
1995-02-14 00:39:00 +03:00
|
|
|
register_t *retval;
|
|
|
|
{
|
1999-04-24 11:06:35 +04:00
|
|
|
struct osf1_sys_setuid_args *uap = v;
|
1999-04-24 11:09:49 +04:00
|
|
|
struct pcred *pc = p->p_cred;
|
1995-02-14 00:39:00 +03:00
|
|
|
uid_t uid = SCARG(uap, uid);
|
|
|
|
int error;
|
|
|
|
|
|
|
|
if ((error = suser(pc->pc_ucred, &p->p_acflag)) != 0 &&
|
|
|
|
uid != pc->p_ruid && uid != pc->p_svuid)
|
|
|
|
return (error);
|
|
|
|
|
|
|
|
pc->pc_ucred = crcopy(pc->pc_ucred);
|
|
|
|
pc->pc_ucred->cr_uid = uid;
|
|
|
|
if (error == 0) {
|
|
|
|
(void)chgproccnt(pc->p_ruid, -1);
|
|
|
|
(void)chgproccnt(uid, 1);
|
|
|
|
pc->p_ruid = uid;
|
|
|
|
pc->p_svuid = uid;
|
|
|
|
}
|
|
|
|
p->p_flag |= P_SUGID;
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* OSF/1 defines _POSIX_SAVED_IDS, which means that our normal
|
|
|
|
* setgid() won't work.
|
|
|
|
*
|
|
|
|
* If you change "uid" to "gid" in the discussion, above, about
|
|
|
|
* setuid(), you'll get a correct description of setgid().
|
|
|
|
*/
|
|
|
|
int
|
1995-10-07 09:25:19 +03:00
|
|
|
osf1_sys_setgid(p, v, retval)
|
1995-02-14 00:39:00 +03:00
|
|
|
struct proc *p;
|
1995-09-20 02:44:25 +04:00
|
|
|
void *v;
|
1995-02-14 00:39:00 +03:00
|
|
|
register_t *retval;
|
|
|
|
{
|
1999-04-24 11:06:35 +04:00
|
|
|
struct osf1_sys_setgid_args *uap = v;
|
1999-04-24 11:09:49 +04:00
|
|
|
struct pcred *pc = p->p_cred;
|
1995-02-14 00:39:00 +03:00
|
|
|
gid_t gid = SCARG(uap, gid);
|
|
|
|
int error;
|
|
|
|
|
|
|
|
if ((error = suser(pc->pc_ucred, &p->p_acflag)) != 0 &&
|
|
|
|
gid != pc->p_rgid && gid != pc->p_svgid)
|
|
|
|
return (error);
|
|
|
|
|
|
|
|
pc->pc_ucred = crcopy(pc->pc_ucred);
|
|
|
|
pc->pc_ucred->cr_gid = gid;
|
|
|
|
if (error == 0) {
|
|
|
|
pc->p_rgid = gid;
|
|
|
|
pc->p_svgid = gid;
|
|
|
|
}
|
|
|
|
p->p_flag |= P_SUGID;
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The structures end up being the same... but we can't be sure that
|
|
|
|
* the other word of our iov_len is zero!
|
|
|
|
*/
|
|
|
|
int
|
1995-10-07 09:25:19 +03:00
|
|
|
osf1_sys_readv(p, v, retval)
|
1995-02-14 00:39:00 +03:00
|
|
|
struct proc *p;
|
1995-09-20 02:44:25 +04:00
|
|
|
void *v;
|
|
|
|
register_t *retval;
|
|
|
|
{
|
1999-04-24 11:06:35 +04:00
|
|
|
struct osf1_sys_readv_args *uap = v;
|
|
|
|
struct sys_readv_args a;
|
1995-02-14 00:39:00 +03:00
|
|
|
struct osf1_iovec *oio;
|
|
|
|
struct iovec *nio;
|
1998-05-20 20:34:29 +04:00
|
|
|
caddr_t sg = stackgap_init(p->p_emul);
|
|
|
|
int error, osize, nsize, i;
|
1995-02-14 00:39:00 +03:00
|
|
|
|
|
|
|
if (SCARG(uap, iovcnt) > (STACKGAPLEN / sizeof (struct iovec)))
|
|
|
|
return (EINVAL);
|
|
|
|
|
1998-05-20 20:34:29 +04:00
|
|
|
osize = SCARG(uap, iovcnt) * sizeof (struct osf1_iovec);
|
|
|
|
nsize = SCARG(uap, iovcnt) * sizeof (struct iovec);
|
|
|
|
|
|
|
|
oio = malloc(osize, M_TEMP, M_WAITOK);
|
|
|
|
nio = malloc(nsize, M_TEMP, M_WAITOK);
|
1995-02-14 00:39:00 +03:00
|
|
|
|
|
|
|
error = 0;
|
1998-05-20 20:34:29 +04:00
|
|
|
if ((error = copyin(SCARG(uap, iovp), oio, osize)))
|
1995-02-14 00:39:00 +03:00
|
|
|
goto punt;
|
|
|
|
for (i = 0; i < SCARG(uap, iovcnt); i++) {
|
|
|
|
nio[i].iov_base = oio[i].iov_base;
|
|
|
|
nio[i].iov_len = oio[i].iov_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
SCARG(&a, fd) = SCARG(uap, fd);
|
1998-05-20 20:34:29 +04:00
|
|
|
SCARG(&a, iovp) = stackgap_alloc(&sg, nsize);
|
1995-02-14 00:39:00 +03:00
|
|
|
SCARG(&a, iovcnt) = SCARG(uap, iovcnt);
|
|
|
|
|
1998-05-20 20:34:29 +04:00
|
|
|
if ((error = copyout(nio, (caddr_t)SCARG(&a, iovp), nsize)))
|
1995-10-07 09:25:19 +03:00
|
|
|
goto punt;
|
|
|
|
error = sys_readv(p, &a, retval);
|
1995-02-14 00:39:00 +03:00
|
|
|
|
|
|
|
punt:
|
|
|
|
free(oio, M_TEMP);
|
|
|
|
free(nio, M_TEMP);
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
1995-10-07 09:25:19 +03:00
|
|
|
osf1_sys_writev(p, v, retval)
|
1995-02-14 00:39:00 +03:00
|
|
|
struct proc *p;
|
1995-09-20 02:44:25 +04:00
|
|
|
void *v;
|
|
|
|
register_t *retval;
|
|
|
|
{
|
1999-04-24 11:06:35 +04:00
|
|
|
struct osf1_sys_writev_args *uap = v;
|
|
|
|
struct sys_writev_args a;
|
1995-02-14 00:39:00 +03:00
|
|
|
struct osf1_iovec *oio;
|
|
|
|
struct iovec *nio;
|
1998-05-20 20:34:29 +04:00
|
|
|
caddr_t sg = stackgap_init(p->p_emul);
|
|
|
|
int error, osize, nsize, i;
|
1995-02-14 00:39:00 +03:00
|
|
|
|
|
|
|
if (SCARG(uap, iovcnt) > (STACKGAPLEN / sizeof (struct iovec)))
|
|
|
|
return (EINVAL);
|
|
|
|
|
1998-05-20 20:34:29 +04:00
|
|
|
osize = SCARG(uap, iovcnt) * sizeof (struct osf1_iovec);
|
|
|
|
nsize = SCARG(uap, iovcnt) * sizeof (struct iovec);
|
|
|
|
|
|
|
|
oio = malloc(osize, M_TEMP, M_WAITOK);
|
|
|
|
nio = malloc(nsize, M_TEMP, M_WAITOK);
|
1995-02-14 00:39:00 +03:00
|
|
|
|
|
|
|
error = 0;
|
1998-05-20 20:34:29 +04:00
|
|
|
if ((error = copyin(SCARG(uap, iovp), oio, osize)))
|
1995-02-14 00:39:00 +03:00
|
|
|
goto punt;
|
|
|
|
for (i = 0; i < SCARG(uap, iovcnt); i++) {
|
|
|
|
nio[i].iov_base = oio[i].iov_base;
|
|
|
|
nio[i].iov_len = oio[i].iov_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
SCARG(&a, fd) = SCARG(uap, fd);
|
1998-05-20 20:34:29 +04:00
|
|
|
SCARG(&a, iovp) = stackgap_alloc(&sg, nsize);
|
1995-02-14 00:39:00 +03:00
|
|
|
SCARG(&a, iovcnt) = SCARG(uap, iovcnt);
|
|
|
|
|
1998-05-20 20:34:29 +04:00
|
|
|
if ((error = copyout(nio, (caddr_t)SCARG(&a, iovp), nsize)))
|
1995-10-07 09:25:19 +03:00
|
|
|
goto punt;
|
|
|
|
error = sys_writev(p, &a, retval);
|
1995-02-14 00:39:00 +03:00
|
|
|
|
|
|
|
punt:
|
|
|
|
free(oio, M_TEMP);
|
|
|
|
free(nio, M_TEMP);
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* More of the stupid off_t padding! */
|
|
|
|
int
|
1995-10-07 09:25:19 +03:00
|
|
|
osf1_sys_truncate(p, v, retval)
|
1995-02-14 00:39:00 +03:00
|
|
|
struct proc *p;
|
1995-09-20 02:44:25 +04:00
|
|
|
void *v;
|
1995-10-07 09:25:19 +03:00
|
|
|
register_t *retval;
|
1995-09-20 02:44:25 +04:00
|
|
|
{
|
1999-04-24 11:06:35 +04:00
|
|
|
struct osf1_sys_truncate_args *uap = v;
|
1995-10-07 09:25:19 +03:00
|
|
|
struct sys_truncate_args a;
|
1999-04-24 11:23:54 +04:00
|
|
|
caddr_t sg;
|
|
|
|
|
|
|
|
sg = stackgap_init(p->p_emul);
|
|
|
|
OSF1_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
|
1995-02-14 00:39:00 +03:00
|
|
|
|
|
|
|
SCARG(&a, path) = SCARG(uap, path);
|
|
|
|
SCARG(&a, pad) = 0;
|
|
|
|
SCARG(&a, length) = SCARG(uap, length);
|
|
|
|
|
1995-10-07 09:25:19 +03:00
|
|
|
return sys_truncate(p, &a, retval);
|
1995-02-14 00:39:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
1995-10-07 09:25:19 +03:00
|
|
|
osf1_sys_ftruncate(p, v, retval)
|
1995-02-14 00:39:00 +03:00
|
|
|
struct proc *p;
|
1995-09-20 02:44:25 +04:00
|
|
|
void *v;
|
1995-10-07 09:25:19 +03:00
|
|
|
register_t *retval;
|
1995-09-20 02:44:25 +04:00
|
|
|
{
|
1999-04-24 11:06:35 +04:00
|
|
|
struct osf1_sys_ftruncate_args *uap = v;
|
1995-10-07 09:25:19 +03:00
|
|
|
struct sys_ftruncate_args a;
|
1995-02-14 00:39:00 +03:00
|
|
|
|
|
|
|
SCARG(&a, fd) = SCARG(uap, fd);
|
|
|
|
SCARG(&a, pad) = 0;
|
|
|
|
SCARG(&a, length) = SCARG(uap, length);
|
|
|
|
|
1995-10-07 09:25:19 +03:00
|
|
|
return sys_ftruncate(p, &a, retval);
|
1995-02-14 00:39:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
1995-10-07 09:53:04 +03:00
|
|
|
osf1_sys_getrusage(p, v, retval)
|
1995-02-14 00:39:00 +03:00
|
|
|
struct proc *p;
|
1995-10-07 09:25:19 +03:00
|
|
|
void *v;
|
1995-02-14 00:39:00 +03:00
|
|
|
register_t *retval;
|
|
|
|
{
|
1999-04-27 21:50:59 +04:00
|
|
|
struct osf1_sys_getrusage_args *uap = v;
|
|
|
|
struct sys_getrusage_args a;
|
|
|
|
struct osf1_rusage osf1_rusage;
|
|
|
|
struct rusage netbsd_rusage;
|
|
|
|
caddr_t sg;
|
|
|
|
int error;
|
1995-02-14 00:39:00 +03:00
|
|
|
|
1999-04-27 21:50:59 +04:00
|
|
|
switch (SCARG(uap, who)) {
|
|
|
|
case OSF1_RUSAGE_SELF:
|
|
|
|
SCARG(&a, who) = RUSAGE_SELF;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OSF1_RUSAGE_CHILDREN:
|
|
|
|
SCARG(&a, who) = RUSAGE_CHILDREN;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OSF1_RUSAGE_THREAD: /* XXX not supported */
|
|
|
|
default:
|
|
|
|
return (EINVAL);
|
|
|
|
}
|
|
|
|
|
|
|
|
sg = stackgap_init(p->p_emul);
|
|
|
|
SCARG(&a, rusage) = stackgap_alloc(&sg, sizeof netbsd_rusage);
|
|
|
|
|
|
|
|
error = sys_getrusage(p, &a, retval);
|
|
|
|
if (error == 0)
|
|
|
|
error = copyin((caddr_t)SCARG(&a, rusage),
|
|
|
|
(caddr_t)&netbsd_rusage, sizeof netbsd_rusage);
|
|
|
|
if (error == 0) {
|
|
|
|
cvtrusage2osf1(&netbsd_rusage, &osf1_rusage);
|
|
|
|
error = copyout((caddr_t)&osf1_rusage,
|
|
|
|
(caddr_t)SCARG(uap, rusage), sizeof osf1_rusage);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Convert from as rusage structure to an osf1 rusage structure.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
cvtrusage2osf1(ru, oru)
|
|
|
|
struct rusage *ru;
|
|
|
|
struct osf1_rusage *oru;
|
|
|
|
{
|
|
|
|
oru->ru_utime.tv_sec = ru->ru_utime.tv_sec;
|
|
|
|
oru->ru_utime.tv_usec = ru->ru_utime.tv_usec;
|
|
|
|
|
|
|
|
oru->ru_stime.tv_sec = ru->ru_stime.tv_sec;
|
|
|
|
oru->ru_stime.tv_usec = ru->ru_stime.tv_usec;
|
|
|
|
|
|
|
|
oru->ru_maxrss = ru->ru_maxrss;
|
|
|
|
oru->ru_ixrss = ru->ru_ixrss;
|
|
|
|
oru->ru_idrss = ru->ru_idrss;
|
|
|
|
oru->ru_isrss = ru->ru_isrss;
|
|
|
|
oru->ru_minflt = ru->ru_minflt;
|
|
|
|
oru->ru_majflt = ru->ru_majflt;
|
|
|
|
oru->ru_nswap = ru->ru_nswap;
|
|
|
|
oru->ru_inblock = ru->ru_inblock;
|
|
|
|
oru->ru_oublock = ru->ru_oublock;
|
|
|
|
oru->ru_msgsnd = ru->ru_msgsnd;
|
|
|
|
oru->ru_msgrcv = ru->ru_msgrcv;
|
|
|
|
oru->ru_nsignals = ru->ru_nsignals;
|
|
|
|
oru->ru_nvcsw = ru->ru_nvcsw;
|
|
|
|
oru->ru_nivcsw = ru->ru_nivcsw;
|
1995-02-14 00:39:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
1995-10-07 09:53:04 +03:00
|
|
|
osf1_sys_madvise(p, v, retval)
|
1995-02-14 00:39:00 +03:00
|
|
|
struct proc *p;
|
1995-10-07 09:25:19 +03:00
|
|
|
void *v;
|
1995-02-14 00:39:00 +03:00
|
|
|
register_t *retval;
|
|
|
|
{
|
|
|
|
|
1995-10-07 09:53:04 +03:00
|
|
|
/* XXX */
|
1995-02-14 00:39:00 +03:00
|
|
|
return EINVAL;
|
|
|
|
}
|
1996-09-03 07:12:17 +04:00
|
|
|
|
|
|
|
int
|
|
|
|
osf1_sys_execve(p, v, retval)
|
|
|
|
struct proc *p;
|
|
|
|
void *v;
|
|
|
|
register_t *retval;
|
|
|
|
{
|
1999-04-24 11:06:35 +04:00
|
|
|
struct osf1_sys_execve_args *uap = v;
|
1996-09-03 07:12:17 +04:00
|
|
|
struct sys_execve_args ap;
|
|
|
|
caddr_t sg;
|
|
|
|
|
|
|
|
sg = stackgap_init(p->p_emul);
|
|
|
|
OSF1_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
|
|
|
|
|
|
|
|
SCARG(&ap, path) = SCARG(uap, path);
|
|
|
|
SCARG(&ap, argp) = SCARG(uap, argp);
|
|
|
|
SCARG(&ap, envp) = SCARG(uap, envp);
|
|
|
|
|
|
|
|
return sys_execve(p, &ap, retval);
|
|
|
|
}
|