When sproc is used to create a share group with shared memory, there is a

private area called PRDA that remains unshared. We implement this by using
different vmspace for each share group member, and keeping the memory
appings in sync on each mmap/munmap/mprotect/break...

We use irix_saddr_sync_vmcmd and irix_saddr_sync_syscall to apply a
vmcmd or a syscall to all share group member, this makes the job a bit
easier.

Also implements {get|set}rlimit{64}.
This commit is contained in:
manu 2002-06-12 20:33:20 +00:00
parent bd46e08c93
commit 022bd85d32
13 changed files with 536 additions and 140 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: files.irix,v 1.23 2002/05/26 21:37:12 manu Exp $
# $NetBSD: files.irix,v 1.24 2002/06/12 20:33:20 manu Exp $
#
file arch/mips/mips/irix_syscall.c compat_irix
@ -14,6 +14,7 @@ file compat/irix/irix_mman.c compat_irix
file compat/irix/irix_misc.c compat_irix
file compat/irix/irix_mount.c compat_irix
file compat/irix/irix_prctl.c compat_irix
file compat/irix/irix_resource.c compat_irix
file compat/irix/irix_signal.c compat_irix
file compat/irix/irix_stat.c compat_irix
file compat/irix/irix_swap.c compat_irix
@ -27,17 +28,17 @@ file compat/irix/irix_usema.c compat_irix
file arch/mips/mips/svr4_machdep.c compat_irix
file compat/svr4/svr4_fcntl.c compat_irix
file compat/svr4/svr4_filio.c compat_irix
file compat/svr4/svr4_ioctl.c compat_irix
file compat/svr4/svr4_ipc.c compat_irix
file compat/svr4/svr4_misc.c compat_irix
file compat/svr4/svr4_stat.c compat_irix
file compat/svr4/svr4_net.c compat_irix
file compat/svr4/svr4_signal.c compat_irix
file compat/svr4/svr4_signo.c compat_irix
file compat/svr4/svr4_ipc.c compat_irix
file compat/svr4/svr4_ioctl.c compat_irix
file compat/svr4/svr4_stream.c compat_irix
file compat/svr4/svr4_socket.c compat_irix
file compat/svr4/svr4_sockio.c compat_irix
file compat/svr4/svr4_stat.c compat_irix
file compat/svr4/svr4_stream.c compat_irix
file compat/svr4/svr4_termios.c compat_irix
file compat/svr4/svr4_ttold.c compat_irix
file compat/svr4/svr4_filio.c compat_irix
file compat/svr4/svr4_sockio.c compat_irix
file compat/svr4/svr4_net.c compat_irix

View File

@ -1,4 +1,4 @@
/* $NetBSD: irix_exec.c,v 1.17 2002/06/05 17:27:11 manu Exp $ */
/* $NetBSD: irix_exec.c,v 1.18 2002/06/12 20:33:20 manu Exp $ */
/*-
* Copyright (c) 2001-2002 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: irix_exec.c,v 1.17 2002/06/05 17:27:11 manu Exp $");
__KERNEL_RCSID(0, "$NetBSD: irix_exec.c,v 1.18 2002/06/12 20:33:20 manu Exp $");
#ifndef ELFSIZE
#define ELFSIZE 32 /* XXX should die */
@ -59,6 +59,7 @@ __KERNEL_RCSID(0, "$NetBSD: irix_exec.c,v 1.17 2002/06/05 17:27:11 manu Exp $");
#include <compat/irix/irix_syscall.h>
#include <compat/irix/irix_types.h>
#include <compat/irix/irix_exec.h>
#include <compat/irix/irix_prctl.h>
#include <compat/irix/irix_signal.h>
#include <compat/irix/irix_errno.h>
@ -267,26 +268,14 @@ irix_e_proc_exec(p, epp)
struct exec_package *epp;
{
int error;
struct exec_vmcmd evc;
irix_e_proc_init(p, p->p_vmspace);
/*
* On IRIX, usinit(3) expects the kernel to prepare one page of
* memory mapped at address 0x200000. It is used for shared
* semaphores and locks.
*/
bzero(&evc, sizeof(evc));
evc.ev_addr = IRIX_SH_ARENA_ADDR;
evc.ev_len = IRIX_SH_ARENA_SZ;
evc.ev_prot = UVM_PROT_RW;
evc.ev_proc = *vmcmd_map_zero;
error = (*evc.ev_proc)(p, &evc);
/* Initialize the process private area (PRDA) */
error = irix_prda_init(p);
#ifdef DEBUG_IRIX
printf("irix_e_proc_init(): uvm_map() returned %d\n", error);
if (error != 0)
printf("irix_e_proc_init(): IRIX_SHARED_ARENA map failed ");
printf("irix_e_proc_init(): PRDA map failed ");
#endif
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: irix_exec.h,v 1.10 2002/06/05 17:27:11 manu Exp $ */
/* $NetBSD: irix_exec.h,v 1.11 2002/06/12 20:33:20 manu Exp $ */
/*-
* Copyright (c) 2001-2002 The NetBSD Foundation, Inc.
@ -49,18 +49,16 @@
#include <compat/svr4/svr4_types.h>
#include <compat/svr4/svr4_signal.h>
/* Address and size of shared arena used by usinit(3) on IRIX */
#define IRIX_SH_ARENA_ADDR 0x200000
#define IRIX_SH_ARENA_SZ PAGE_SIZE
/* IRIX specific per-process data */
/* IRIX specific per-process data, zero'ed on allocation */
struct irix_emuldata {
#define ied_startcopy ied_sigtramp
void *ied_sigtramp[SVR4_NSIG]; /* Address of signal trampoline */
#define ied_endcopy ied_pptr
struct proc *ied_pptr; /* parent process or NULL, for SIGHUP on exit */
int ied_procblk_count; /* semaphore for blockproc */
struct proc *ied_sharedparent; /* parent of the shared group */
struct proc *ied_shareparent; /* parent of the share group */
int ied_shareaddr; /* VM space is shared with parent */
/* Only the share group parent keeps track of this: */
};
/* e_flags used by IRIX for ABI selection */

View File

@ -1,4 +1,4 @@
/* $NetBSD: irix_mman.c,v 1.1 2002/04/22 05:58:46 manu Exp $ */
/* $NetBSD: irix_mman.c,v 1.2 2002/06/12 20:33:20 manu Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -37,12 +37,15 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: irix_mman.c,v 1.1 2002/04/22 05:58:46 manu Exp $");
__KERNEL_RCSID(0, "$NetBSD: irix_mman.c,v 1.2 2002/06/12 20:33:20 manu Exp $");
#include "opt_sysv.h"
#include <sys/types.h>
#include <sys/param.h>
#include <sys/signal.h>
#include <sys/proc.h>
#include <sys/exec.h>
#include <sys/filedesc.h>
#include <sys/file.h>
#include <sys/vnode.h>
@ -51,13 +54,21 @@ __KERNEL_RCSID(0, "$NetBSD: irix_mman.c,v 1.1 2002/04/22 05:58:46 manu Exp $");
#include <sys/systm.h>
#include <sys/syscallargs.h>
#include <compat/svr4/svr4_types.h>
#include <compat/svr4/svr4_lwp.h>
#include <compat/svr4/svr4_ucontext.h>
#include <compat/svr4/svr4_signal.h>
#include <compat/svr4/svr4_syscallargs.h>
#include <compat/irix/irix_types.h>
#include <compat/irix/irix_signal.h>
#include <compat/irix/irix_mman.h>
#include <compat/irix/irix_prctl.h>
#include <compat/irix/irix_exec.h>
#include <compat/irix/irix_syscallargs.h>
int irix_mmap __P((struct proc *, void *, size_t, int ,
int, int, off_t, register_t *));
static int irix_mmap __P((struct proc *, void *, size_t, int ,
int, int, off_t, register_t *));
int
irix_sys_mmap(p, v, retval)
@ -99,7 +110,7 @@ irix_sys_mmap64(p, v, retval)
SCARG(uap, pos), retval);
}
int
static int
irix_mmap(p, addr, len, prot, flags, fd, pos, retval)
struct proc *p;
void *addr;
@ -112,8 +123,8 @@ irix_mmap(p, addr, len, prot, flags, fd, pos, retval)
{
struct sys_mmap_args cup;
int bsd_flags = 0;
int error = 0;
bsd_flags = 0;
if (flags & IRIX_MAP_SHARED)
bsd_flags |= MAP_SHARED;
if (flags & IRIX_MAP_PRIVATE)
@ -157,7 +168,6 @@ irix_mmap(p, addr, len, prot, flags, fd, pos, retval)
struct file *fp;
struct vnode *vp;
struct vattr vattr;
int error = 0;
/* getvnode does FILE_USE */
if ((error = getvnode(p->p_fd, fd, &fp)) != 0)
@ -207,5 +217,76 @@ out:
SCARG(&cup, fd) = fd;
SCARG(&cup, pos) = pos;
return sys_mmap(p, &cup, retval);
if ((u_long)addr >= (u_long)IRIX_PRDA &&
(u_long)addr + len < (u_long)IRIX_PRDA + sizeof(struct irix_prda))
printf("Warning: shared mmap() on process private arena\n");
/* Eventually do it for a whole share group */
return irix_sync_saddr_syscall(p, &cup, retval, (void *)sys_mmap);
};
int
irix_sys_munmap(p, v, retval)
struct proc *p;
void *v;
register_t *retval;
{
struct irix_sys_munmap_args /* {
syscallarg(void *) addr;
syscallarg(int) len;
} */ *uap = v;
void *addr = SCARG(uap, addr);
int len = SCARG(uap, len);
if ((u_long)addr >= (u_long)IRIX_PRDA &&
(u_long)addr + len < (u_long)IRIX_PRDA + sizeof(struct irix_prda))
printf("Warning: shared munmap() on process private arena\n");
/* Eventually do it for a whole share group */
return irix_sync_saddr_syscall(p, v, retval, (void *)sys_munmap);
}
int
irix_sys_break(p, v, retval)
struct proc *p;
void *v;
register_t *retval;
{
/* Eventually do it for a whole share group */
return irix_sync_saddr_syscall(p, v, retval, (void *)svr4_sys_break);
}
#ifdef SYSVSHM
int
irix_sys_shmsys(p, v, retval)
struct proc *p;
void *v;
register_t *retval;
{
/* Eventually do it for a whole share group */
return irix_sync_saddr_syscall(p, v, retval, (void *)svr4_sys_shmsys);
}
#endif
int
irix_sys_mprotect(p, v, retval)
struct proc *p;
void *v;
register_t *retval;
{
struct irix_sys_mprotect_args /* {
syscallarg(void *) addr;
syscallarg(int) len;
syscallarg(int) prot;
} */ *uap = v;
void *addr = SCARG(uap, addr);
int len = SCARG(uap, len);
if ((u_long)addr >= (u_long)IRIX_PRDA &&
(u_long)addr + len < (u_long)IRIX_PRDA + sizeof(struct irix_prda))
printf("Warning: shared mprotect() on process private arena\n");
/* Eventually do it for a whole share group */
return irix_sync_saddr_syscall(p, v, retval, (void *)sys_mprotect);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: irix_prctl.c,v 1.12 2002/06/05 17:27:11 manu Exp $ */
/* $NetBSD: irix_prctl.c,v 1.13 2002/06/12 20:33:20 manu Exp $ */
/*-
* Copyright (c) 2001-2002 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: irix_prctl.c,v 1.12 2002/06/05 17:27:11 manu Exp $");
__KERNEL_RCSID(0, "$NetBSD: irix_prctl.c,v 1.13 2002/06/12 20:33:20 manu Exp $");
#include <sys/errno.h>
#include <sys/types.h>
@ -52,6 +52,7 @@ __KERNEL_RCSID(0, "$NetBSD: irix_prctl.c,v 1.12 2002/06/05 17:27:11 manu Exp $")
#include <sys/resourcevar.h>
#include <uvm/uvm_extern.h>
#include <uvm/uvm_map.h>
#include <machine/regnum.h>
#include <machine/vmparam.h>
@ -68,7 +69,7 @@ struct irix_sproc_child_args {
struct proc **isc_proc;
void *isc_entry;
void *isc_arg;
void *isc_aux;
size_t isc_len;
int isc_inh;
struct proc *isc_parent;
};
@ -96,6 +97,7 @@ irix_sys_prctl(p, v, retval)
case IRIX_PR_GETSHMASK: { /* Get shared resources */
struct proc *p2;
int shmask = 0;
struct irix_emuldata *ied;
p2 = pfind((pid_t)SCARG(uap, arg1));
@ -107,31 +109,32 @@ irix_sys_prctl(p, v, retval)
if (p2 == NULL)
return EINVAL;
if (p->p_vmspace == p2->p_vmspace)
ied = (struct irix_emuldata *)p->p_emuldata;
if (ied->ied_shareaddr)
shmask |= IRIX_PR_SADDR;
if (p->p_fd == p2->p_fd)
shmask |= IRIX_PR_SFDS;
if (p->p_cwdi == p2->p_cwdi);
shmask |= IRIX_PR_SDIR;
shmask |= (IRIX_PR_SDIR|IRIX_PR_SUMASK);
*retval = (register_t)shmask;
return 0;
break;
}
case IRIX_PR_LASTSHEXIT: /* "Last sproc exit" */
/* We do nothing */
case IRIX_PR_LASTSHEXIT: /* "Last sproc exit" */
/* We no nothing */
break;
case IRIX_PR_GETNSHARE: { /* Number of sproc share group memb.*/
struct irix_emuldata *ied;
struct proc *pp;
struct proc *sharedparent;
struct proc *shareparent;
int count;
ied = (struct irix_emuldata *)p->p_emuldata;
sharedparent = ied->ied_sharedparent;
if (sharedparent == NULL) {
shareparent = ied->ied_shareparent;
if (shareparent == NULL) {
*retval = 0;
return 0;
}
@ -139,8 +142,8 @@ irix_sys_prctl(p, v, retval)
count = 0;
LIST_FOREACH(pp, &allproc, p_list) {
if (irix_check_exec(pp)) {
ied = (struct irix_emuldata *)p->p_emuldata;
if (ied->ied_sharedparent == sharedparent)
ied = (struct irix_emuldata *)pp->p_emuldata;
if (ied->ied_shareparent == shareparent)
count++;
}
}
@ -248,9 +251,9 @@ irix_sys_sproc(p, v, retval)
syscallarg(unsigned) inh;
syscallarg(void *) arg;
} */ *uap = v;
return irix_sproc(SCARG(uap, entry), SCARG(uap, inh), SCARG(uap, arg),
NULL, 0, 0, p, retval);
NULL, p->p_rlimit[RLIMIT_STACK].rlim_cur, 0, p, retval);
}
@ -267,18 +270,21 @@ irix_sproc(entry, inh, arg, sp, len, pid, p, retval)
{
int bsd_flags = 0;
struct exec_vmcmd vmc;
struct frame *tf = (struct frame *)p->p_md.md_regs;
int error;
struct proc *p2;
struct proc *pp;
struct irix_sproc_child_args isc;
struct irix_emuldata *ied;
struct irix_emuldata *iedp;
segsz_t stacksize;
#ifdef DEBUG_IRIX
printf("irix_sproc(): entry = %p, inh = %x, arg = %p, sp = 0x%08lx, len = 0x%08lx, pid = %d\n", entry, inh, arg, (u_long)sp, (u_long)len, pid);
#endif
if (inh & IRIX_PR_SADDR)
bsd_flags |= FORK_SHAREVM;
if (len == 0)
return EINVAL;
if (inh & IRIX_PR_SFDS)
bsd_flags |= FORK_SHAREFILES;
if (inh & (IRIX_PR_SUMASK|IRIX_PR_SDIR)) {
@ -296,15 +302,19 @@ irix_sproc(entry, inh, arg, sp, len, pid, p, retval)
* Setting up child stack
*/
if (inh & IRIX_PR_SADDR) {
if (len == 0)
len = p->p_rlimit[RLIMIT_STACK].rlim_cur;
if (sp == NULL)
sp = (caddr_t)(round_page(tf->f_regs[SP])
- IRIX_SPROC_STACK_OFFSET - len);
while (trunc_page((u_long)sp) >=
(u_long)p->p_vmspace->vm_maxsaddr)
sp -= IRIX_SPROC_STACK_OFFSET;
if (sp == NULL) {
/*
* All share group members have vm_maxsaddr set
* to the bottom of the lowest stack in address space,
* therefore we map the new stack there.
*/
sp = p->p_vmspace->vm_maxsaddr;
/* Compute new stacks's bottom address */
sp = (caddr_t)trunc_page((u_long)sp - len);
}
/* Now map the new stack */
bzero(&vmc, sizeof(vmc));
vmc.ev_addr = trunc_page((u_long)sp);
vmc.ev_len = round_page(len);
@ -315,10 +325,23 @@ irix_sproc(entry, inh, arg, sp, len, pid, p, retval)
printf("irix_sproc(): new stack addr=0x%08lx, len=0x%08lx\n",
(u_long)sp, (u_long)len);
#endif
if ((error = (*vmc.ev_proc)(p, &vmc)) != 0)
/* Eventually do map for a whole share group */
if ((error = irix_sync_saddr_vmcmd(p, &vmc)) != 0)
return error;
p->p_vmspace->vm_maxsaddr = (void *)trunc_page((u_long)sp);
/* Update stack parameters for the share group members */
ied = (struct irix_emuldata *)p->p_emuldata;
stacksize = (p->p_vmspace->vm_minsaddr - sp) / PAGE_SIZE;
LIST_FOREACH(pp, &allproc, p_list) {
if (irix_check_exec(pp) == 0)
continue;
iedp = (struct irix_emuldata *)pp->p_emuldata;
if (iedp->ied_shareparent != ied->ied_shareparent)
continue;
pp->p_vmspace->vm_maxsaddr = (caddr_t)sp;
pp->p_vmspace->vm_ssize = stacksize;
}
}
/*
@ -327,17 +350,18 @@ irix_sproc(entry, inh, arg, sp, len, pid, p, retval)
isc.isc_proc = &p2;
isc.isc_entry = entry;
isc.isc_arg = arg;
isc.isc_len = len;
isc.isc_inh = inh;
isc.isc_parent = p;
if ((error = copyin((void *)(tf->f_regs[SP] + 28),
&isc.isc_aux, sizeof(isc.isc_aux))) != 0)
isc.isc_aux = 0;
/*
* If revelant, initialize as the parent od the shared group
* If revelant, initialize as the parent of the share group
*/
ied = (struct irix_emuldata *)(p->p_emuldata);
if (ied->ied_sharedparent == NULL)
ied->ied_sharedparent = p;
if (ied->ied_shareparent == NULL)
ied->ied_shareparent = p;
if (inh & IRIX_PR_SADDR)
ied->ied_shareaddr = 1;
if ((error = fork1(p, bsd_flags, SIGCHLD, (void *)sp, len,
(void *)irix_sproc_child, (void *)&isc, retval, &p2)) != 0)
@ -361,14 +385,52 @@ irix_sproc_child(isc)
struct irix_sproc_child_args *isc;
{
struct proc *p2 = *isc->isc_proc;
struct frame *tf = (struct frame *)p2->p_md.md_regs;
int inh = isc->isc_inh;
struct proc *parent = isc->isc_parent;
struct frame *tf = (struct frame *)p2->p_md.md_regs;
struct frame *ptf = (struct frame *)parent->p_md.md_regs;
struct pcred *pc;
struct plimit *pl;
struct irix_emuldata *ied;
struct irix_emuldata *parent_ied;
/*
* Handle shared VM space. The process private arena is not shared
*/
if (inh & IRIX_PR_SADDR) {
int error;
vaddr_t dstaddrp;
vaddr_t vm_min;
vsize_t vm_len;
vm_min = vm_map_min(&parent->p_vmspace->vm_map);
vm_len = vm_map_max(&parent->p_vmspace->vm_map) - vm_min;
/* Drop the current VM space */
uvm_unmap(&p2->p_vmspace->vm_map, vm_min, vm_min + vm_len);
/* Clone the mapping from the parent */
error = uvm_map_extract(&parent->p_vmspace->vm_map,
vm_min, vm_len, &p2->p_vmspace->vm_map, &dstaddrp, 0);
if (error != 0) {
printf("sproc: uvm_map_extract failed ");
printf("error = %d, pid = %d\n", error, p2->p_pid);
sigexit(p2, SIGSEGV);
}
/* Unmap the process private arena (shared) */
uvm_unmap(&p2->p_vmspace->vm_map, (vaddr_t)IRIX_PRDA,
(vaddr_t)((u_long)IRIX_PRDA + sizeof(struct irix_prda)));
/* Remap the process private arena (unshared) */
error = irix_prda_init(p2);
if (error != 0) {
printf("sproc: uvm_map arena failed ");
printf("error = %d, pid = %d\n", error, p2->p_pid);
sigexit(p2, SIGSEGV);
}
}
/*
* Handle shared process UID/GID
*/
@ -397,21 +459,30 @@ irix_sproc_child(isc)
* Setup PC to return to the child entry point
*/
tf->f_regs[PC] = (unsigned long)isc->isc_entry;
tf->f_regs[RA] = 0;
/*
* Setup child arguments
* The libc stub will copy S3 to A1 once we return to userland.
*/
tf->f_regs[A0] = (unsigned long)isc->isc_arg;
tf->f_regs[A1] = (unsigned long)isc->isc_aux;
tf->f_regs[S3] = (unsigned long)isc->isc_aux;
tf->f_regs[A1] = 0;
tf->f_regs[A2] = 0;
tf->f_regs[A3] = 0;
if (ptf->f_regs[S3] == (unsigned long)isc->isc_len) {
tf->f_regs[S0] = ptf->f_regs[S0];
tf->f_regs[S1] = ptf->f_regs[S1];
tf->f_regs[S2] = ptf->f_regs[S2];
tf->f_regs[S3] = ptf->f_regs[S3];
}
/*
* Join the shared group
* Join the share group
*/
ied = (struct irix_emuldata *)(p2->p_emuldata);
parent_ied = (struct irix_emuldata *)(parent->p_emuldata);
ied->ied_sharedparent = parent_ied->ied_sharedparent;
ied->ied_shareparent = parent_ied->ied_shareparent;
if (inh & IRIX_PR_SADDR)
ied->ied_shareaddr = 1;
/*
* We do not need isc anymore, we can wakeup our parent
@ -494,9 +565,9 @@ irix_sys_procblk(p, v, retval)
if (irix_check_exec(target) == 0)
continue;
/* Is this process in the target shared group? */
/* Is this process in the target share group? */
pp_ied = (struct irix_emuldata *)pp->p_emuldata;
if (pp_ied->ied_sharedparent != ied->ied_sharedparent)
if (pp_ied->ied_shareparent != ied->ied_shareparent)
continue;
/* Recall procblk for this process */
@ -525,3 +596,146 @@ irix_sys_procblk(p, v, retval)
return 0;
}
int
irix_prda_init(p)
struct proc *p;
{
int error;
struct exec_vmcmd evc;
bzero(&evc, sizeof(evc));
evc.ev_addr = (u_long)IRIX_PRDA;
evc.ev_len = sizeof(struct irix_prda);
evc.ev_prot = UVM_PROT_RW;
evc.ev_proc = *vmcmd_map_zero;
error = (*evc.ev_proc)(p, &evc);
return error;
}
int
irix_sync_saddr_syscall(p, v, retval, syscall)
struct proc *p;
void *v;
register_t *retval;
int (*syscall) __P((struct proc *, void *, register_t *));
{
struct irix_emuldata *ied;
struct irix_emuldata *iedp;
struct proc *pp;
int error;
/*
* First run the system call on the original process
*/
if ((error = (*syscall)(p, v, retval)) != 0)
return error;
/*
* Is memory shared with other members of the share group ?
*/
ied = (struct irix_emuldata *)p->p_emuldata;
if (ied->ied_shareaddr == 0 || ied->ied_shareparent == NULL)
return 0;
/*
* Do the syscall for all ather process in the share group
*/
LIST_FOREACH(pp, &allproc, p_list) {
if (pp != p && irix_check_exec(pp)) {
iedp = (struct irix_emuldata *)pp->p_emuldata;
if (iedp->ied_shareparent == ied->ied_shareparent &&
iedp->ied_shareaddr == 1)
if ((error = (*syscall)(pp, v, retval)) != 0)
break;
}
}
/* Full success */
if (pp == NULL)
return 0;
/*
* In case of failure, destroy the whole share group
*/
LIST_FOREACH(pp, &allproc, p_list) {
if (irix_check_exec(pp)) {
iedp = (struct irix_emuldata *)pp->p_emuldata;
if (iedp->ied_shareparent == ied->ied_shareparent)
sigexit(pp, SIGSEGV);
}
}
#ifdef DEBUG_IRIX
printf("irix_sync_saddr_syscall: killed IRIX share group (pid %d)\n",
p->p_pid);
#endif
return error;
}
int
irix_sync_saddr_vmcmd(p, evc)
struct proc *p;
struct exec_vmcmd *evc;
{
struct irix_emuldata *ied;
struct irix_emuldata *iedp;
struct proc *pp;
int error;
void *addr;
int len;
/*
* First, do the command on the original process
*/
if ((error = (*evc->ev_proc)(p, evc)) != 0)
return error;
/*
* Check that this vmcmd does not operate on the private arena
*/
addr = (void *)evc->ev_addr;
len = evc->ev_len;
if ((u_long)addr >= (u_long)IRIX_PRDA &&
(u_long)addr + len < (u_long)IRIX_PRDA + sizeof(struct irix_prda))
printf("Warning: shared vmcmd on process private arena\n");
/*
* If the process shares memory within a share group, apply
* the vmcmd to all other members of the share group
*/
ied = (struct irix_emuldata *)p->p_emuldata;
if (ied->ied_shareaddr == 0 || ied->ied_shareparent == NULL)
return 0;
LIST_FOREACH(pp, &allproc, p_list) {
if (pp != p && irix_check_exec(pp)) {
iedp = (struct irix_emuldata *)pp->p_emuldata;
if (iedp->ied_shareparent == ied->ied_shareparent &&
iedp->ied_shareaddr == 1)
if ((error = (*evc->ev_proc)(pp, evc)) != 0)
break;
}
}
/* Full success */
if (pp == NULL)
return 0;
/*
* In case of failure, destroy the whole share group
*/
LIST_FOREACH(pp, &allproc, p_list) {
if (irix_check_exec(pp)) {
iedp = (struct irix_emuldata *)pp->p_emuldata;
if (iedp->ied_shareparent == ied->ied_shareparent)
sigexit(pp, SIGSEGV);
}
}
#ifdef DEBUG_IRIX
printf("irix_sync_saddr_vmcmd: killed IRIX share group (pid %d)\n",
p->p_pid);
#endif
return EFAULT;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: irix_prctl.h,v 1.3 2002/06/05 17:27:11 manu Exp $ */
/* $NetBSD: irix_prctl.h,v 1.4 2002/06/12 20:33:20 manu Exp $ */
/*-
* Copyright (c) 2001-2002 The NetBSD Foundation, Inc.
@ -39,6 +39,11 @@
#ifndef _IRIX_PRCTL_H_
#define _IRIX_PRCTL_H_
int irix_prda_init __P((struct proc *));
int irix_sync_saddr_syscall __P((struct proc *, void *, register_t *,
int (*syscall) __P((struct proc *, void *, register_t *))));
int irix_sync_saddr_vmcmd __P((struct proc *, struct exec_vmcmd *));
/* From IRIX's <sys/prctl.h> */
#define IRIX_PR_MAXPROCS 1
@ -75,9 +80,6 @@
#define IRIX_PR_NOLIBC 0x02000000
#define IRIX_PR_EVENT 0x04000000
/* offset between parent and children stack when IRIX_PR_SADDR is used */
#define IRIX_SPROC_STACK_OFFSET 0x04000000
/* blockproc constants */
#define IRIX_PR_MAXBLOCKCNT 10000
#define IRIX_PR_MINBLOCKCNT -10000
@ -91,4 +93,48 @@
#define IRIX_PROCBLK_COUNTALL 5
#define IRIX_PROCBLK_ONLYONE -3
/* From <sys/prctl.h> */
#define IRIX_PRDA ((struct prda *)0x00200000L)
struct irix_prda_sys {
irix_pid_t t_pid;
uint32_t t_hint;
uint32_t t_dlactseq;
uint32_t t_fpflags;
uint32_t t_prid;
uint32_t t_dlendseq;
uint64_t t_unused1[5];
irix_pid_t t_rpid;
int32_t t_resched;
int32_t t_syserror;
int32_t t_nid;
int32_t t_affinity_nid;
uint32_t t_unused2[5];
uint32_t t_cpu;
uint32_t t_flags;
irix_k_sigset_t t_hold;
};
struct irix_prda {
char unused[2048];
union {
char fill[512];
uint32_t rsvd[8];
} sys2_prda;
union {
char fill[512];
} lib2_prda;
union {
char fill[512];
} usr2rda;
union {
struct irix_prda_sys prda_sys;
char fill[128];
} sys_prda;
union {
char fill[256];
} lib_prda;
union {
char fill[128];
} usr_prda;
};
#endif /* _IRIX_IRIX_PRCTL_H_ */

View File

@ -1,10 +1,10 @@
/* $NetBSD: irix_syscall.h,v 1.46 2002/06/05 17:27:11 manu Exp $ */
/* $NetBSD: irix_syscall.h,v 1.47 2002/06/12 20:33:20 manu Exp $ */
/*
* System call numbers.
*
* DO NOT EDIT-- this file is automatically generated.
* created from NetBSD: syscalls.master,v 1.43 2002/05/22 05:14:03 manu Exp
* created from NetBSD: syscalls.master,v 1.44 2002/06/05 17:27:12 manu Exp
*/
/* syscall: "syscall" ret: "int" args: */
@ -154,9 +154,15 @@
/* 72 is obsolete rmount */
/* 73 is obsolete rumount */
/* 74 is obsolete rfstart */
/* 75 is obsolete sigret */
/* 76 is obsolete rdebug */
/* 77 is obsolete rfstop */
/* syscall: "getrlimit64" ret: "int" args: "int" "struct irix_rlimit64 *" */
#define IRIX_SYS_getrlimit64 75
/* syscall: "setrlimit64" ret: "int" args: "int" "const struct irix_rlimit64 *" */
#define IRIX_SYS_setrlimit64 76
/* syscall: "nanosleep" ret: "int" args: "const struct timespec *" "struct timespec *" */
#define IRIX_SYS_nanosleep 77
/* syscall: "lseek64" ret: "irix_off64_t" args: "int" "int" "irix_off64_t" "int" "int" "int" "int" */
#define IRIX_SYS_lseek64 78
@ -322,6 +328,12 @@
/* syscall: "fchdir" ret: "int" args: "int" */
#define IRIX_SYS_fchdir 147
/* syscall: "getrlimit" ret: "int" args: "int" "struct irix_rlimit *" */
#define IRIX_SYS_getrlimit 148
/* syscall: "setrlimit" ret: "int" args: "int" "const struct irix_rlimit *" */
#define IRIX_SYS_setrlimit 149
/* syscall: "fchown" ret: "int" args: "int" "int" "int" */
#define IRIX_SYS_fchown 152

View File

@ -1,10 +1,10 @@
/* $NetBSD: irix_syscallargs.h,v 1.46 2002/06/05 17:27:12 manu Exp $ */
/* $NetBSD: irix_syscallargs.h,v 1.47 2002/06/12 20:33:20 manu Exp $ */
/*
* System call argument lists.
*
* DO NOT EDIT-- this file is automatically generated.
* created from NetBSD: syscalls.master,v 1.43 2002/05/22 05:14:03 manu Exp
* created from NetBSD: syscalls.master,v 1.44 2002/06/05 17:27:12 manu Exp
*/
#ifndef _IRIX_SYS__SYSCALLARGS_H_
@ -33,6 +33,10 @@ struct irix_sys_open_args {
syscallarg(int) mode;
};
struct irix_sys_break_args {
syscallarg(caddr_t) nsize;
};
struct irix_sys_syssgi_args {
syscallarg(int) request;
syscallarg(void *) arg1;
@ -42,6 +46,13 @@ struct irix_sys_syssgi_args {
syscallarg(void *) arg5;
};
struct irix_sys_shmsys_args {
syscallarg(int) what;
syscallarg(int) a2;
syscallarg(int) a3;
syscallarg(int) a4;
};
struct irix_sys_ioctl_args {
syscallarg(int) fd;
syscallarg(u_long) com;
@ -62,6 +73,16 @@ struct irix_sys_fcntl_args {
syscallarg(char *) arg;
};
struct irix_sys_getrlimit64_args {
syscallarg(int) resource;
syscallarg(struct irix_rlimit64 *) rlp;
};
struct irix_sys_setrlimit64_args {
syscallarg(int) resource;
syscallarg(const struct irix_rlimit64 *) rlp;
};
struct irix_sys_lseek64_args {
syscallarg(int) fd;
syscallarg(int) pad1;
@ -122,11 +143,32 @@ struct irix_sys_mmap_args {
syscallarg(irix_off_t) pos;
};
struct irix_sys_munmap_args {
syscallarg(void *) addr;
syscallarg(int) len;
};
struct irix_sys_mprotect_args {
syscallarg(void *) addr;
syscallarg(int) len;
syscallarg(int) prot;
};
struct irix_sys_setpgrp_args {
syscallarg(int) pid;
syscallarg(int) pgid;
};
struct irix_sys_getrlimit_args {
syscallarg(int) resource;
syscallarg(struct irix_rlimit *) rlp;
};
struct irix_sys_setrlimit_args {
syscallarg(int) resource;
syscallarg(const struct irix_rlimit *) rlp;
};
struct irix_sys_systeminfo_args {
syscallarg(int) what;
syscallarg(char *) buf;
@ -253,7 +295,7 @@ int sys_chdir(struct proc *, void *, register_t *);
int svr4_sys_time(struct proc *, void *, register_t *);
int sys_chmod(struct proc *, void *, register_t *);
int sys___posix_chown(struct proc *, void *, register_t *);
int svr4_sys_break(struct proc *, void *, register_t *);
int irix_sys_break(struct proc *, void *, register_t *);
int compat_43_sys_lseek(struct proc *, void *, register_t *);
int sys_getpid(struct proc *, void *, register_t *);
int sys_setuid(struct proc *, void *, register_t *);
@ -278,7 +320,7 @@ int svr4_sys_msgsys(struct proc *, void *, register_t *);
#else
#endif
#ifdef SYSVSHM
int svr4_sys_shmsys(struct proc *, void *, register_t *);
int irix_sys_shmsys(struct proc *, void *, register_t *);
#else
#endif
#ifdef SYSVSEM
@ -293,6 +335,9 @@ int sys_umask(struct proc *, void *, register_t *);
int sys_chroot(struct proc *, void *, register_t *);
int irix_sys_fcntl(struct proc *, void *, register_t *);
int svr4_sys_ulimit(struct proc *, void *, register_t *);
int irix_sys_getrlimit64(struct proc *, void *, register_t *);
int irix_sys_setrlimit64(struct proc *, void *, register_t *);
int sys_nanosleep(struct proc *, void *, register_t *);
int irix_sys_lseek64(struct proc *, void *, register_t *);
int sys_rmdir(struct proc *, void *, register_t *);
int sys_mkdir(struct proc *, void *, register_t *);
@ -341,13 +386,15 @@ int irix_sys_prctl(struct proc *, void *, register_t *);
int irix_sys_procblk(struct proc *, void *, register_t *);
int irix_sys_sprocsp(struct proc *, void *, register_t *);
int irix_sys_mmap(struct proc *, void *, register_t *);
int sys_munmap(struct proc *, void *, register_t *);
int sys_mprotect(struct proc *, void *, register_t *);
int irix_sys_munmap(struct proc *, void *, register_t *);
int irix_sys_mprotect(struct proc *, void *, register_t *);
int sys___msync13(struct proc *, void *, register_t *);
int sys_getpgrp(struct proc *, void *, register_t *);
int irix_sys_setpgrp(struct proc *, void *, register_t *);
int sys_fsync(struct proc *, void *, register_t *);
int sys_fchdir(struct proc *, void *, register_t *);
int irix_sys_getrlimit(struct proc *, void *, register_t *);
int irix_sys_setrlimit(struct proc *, void *, register_t *);
int sys___posix_fchown(struct proc *, void *, register_t *);
int sys_fchmod(struct proc *, void *, register_t *);
int irix_sys_systeminfo(struct proc *, void *, register_t *);

View File

@ -1,14 +1,14 @@
/* $NetBSD: irix_syscalls.c,v 1.46 2002/06/05 17:27:12 manu Exp $ */
/* $NetBSD: irix_syscalls.c,v 1.47 2002/06/12 20:33:20 manu Exp $ */
/*
* System call names.
*
* DO NOT EDIT-- this file is automatically generated.
* created from NetBSD: syscalls.master,v 1.43 2002/05/22 05:14:03 manu Exp
* created from NetBSD: syscalls.master,v 1.44 2002/06/05 17:27:12 manu Exp
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: irix_syscalls.c,v 1.46 2002/06/05 17:27:12 manu Exp $");
__KERNEL_RCSID(0, "$NetBSD: irix_syscalls.c,v 1.47 2002/06/12 20:33:20 manu Exp $");
#if defined(_KERNEL_OPT)
#if defined(_KERNEL_OPT)
@ -122,9 +122,9 @@ const char *const irix_syscallnames[] = {
"#72 (obsolete rmount)", /* 72 = obsolete rmount */
"#73 (obsolete rumount)", /* 73 = obsolete rumount */
"#74 (obsolete rfstart)", /* 74 = obsolete rfstart */
"#75 (obsolete sigret)", /* 75 = obsolete sigret */
"#76 (obsolete rdebug)", /* 76 = obsolete rdebug */
"#77 (obsolete rfstop)", /* 77 = obsolete rfstop */
"getrlimit64", /* 75 = getrlimit64 */
"setrlimit64", /* 76 = setrlimit64 */
"nanosleep", /* 77 = nanosleep */
"lseek64", /* 78 = lseek64 */
"rmdir", /* 79 = rmdir */
"mkdir", /* 80 = mkdir */
@ -195,8 +195,8 @@ const char *const irix_syscallnames[] = {
"#145 (unimplemented vhangup)", /* 145 = unimplemented vhangup */
"fsync", /* 146 = fsync */
"fchdir", /* 147 = fchdir */
"#148 (unimplemented getrlimit)", /* 148 = unimplemented getrlimit */
"#149 (unimplemented setrlimit)", /* 149 = unimplemented setrlimit */
"getrlimit", /* 148 = getrlimit */
"setrlimit", /* 149 = setrlimit */
"#150 (unimplemented cacheflush)", /* 150 = unimplemented cacheflush */
"#151 (unimplemented cachectl)", /* 151 = unimplemented cachectl */
"fchown", /* 152 = fchown */

View File

@ -1,14 +1,14 @@
/* $NetBSD: irix_sysent.c,v 1.46 2002/06/05 17:27:12 manu Exp $ */
/* $NetBSD: irix_sysent.c,v 1.47 2002/06/12 20:33:20 manu Exp $ */
/*
* System call switch table.
*
* DO NOT EDIT-- this file is automatically generated.
* created from NetBSD: syscalls.master,v 1.43 2002/05/22 05:14:03 manu Exp
* created from NetBSD: syscalls.master,v 1.44 2002/06/05 17:27:12 manu Exp
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: irix_sysent.c,v 1.46 2002/06/05 17:27:12 manu Exp $");
__KERNEL_RCSID(0, "$NetBSD: irix_sysent.c,v 1.47 2002/06/12 20:33:20 manu Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ntp.h"
@ -69,8 +69,8 @@ struct sysent irix_sysent[] = {
sys_chmod }, /* 15 = chmod */
{ 3, s(struct sys___posix_chown_args), 0,
sys___posix_chown }, /* 16 = chown */
{ 1, s(struct svr4_sys_break_args), 0,
svr4_sys_break }, /* 17 = break */
{ 1, s(struct irix_sys_break_args), 0,
irix_sys_break }, /* 17 = break */
{ 0, 0, 0,
sys_nosys }, /* 18 = obsolete stat */
{ 3, s(struct compat_43_sys_lseek_args), 0,
@ -145,8 +145,8 @@ struct sysent irix_sysent[] = {
{ 0, 0, 0,
sys_nosys }, /* 51 = unimplemented acct */
#ifdef SYSVSHM
{ 4, s(struct svr4_sys_shmsys_args), 0,
svr4_sys_shmsys }, /* 52 = shmsys */
{ 4, s(struct irix_sys_shmsys_args), 0,
irix_sys_shmsys }, /* 52 = shmsys */
#else
{ 0, 0, 0,
sys_nosys }, /* 52 = unimplemented shmsys */
@ -200,12 +200,12 @@ struct sysent irix_sysent[] = {
sys_nosys }, /* 73 = obsolete rumount */
{ 0, 0, 0,
sys_nosys }, /* 74 = obsolete rfstart */
{ 0, 0, 0,
sys_nosys }, /* 75 = obsolete sigret */
{ 0, 0, 0,
sys_nosys }, /* 76 = obsolete rdebug */
{ 0, 0, 0,
sys_nosys }, /* 77 = obsolete rfstop */
{ 2, s(struct irix_sys_getrlimit64_args), 0,
irix_sys_getrlimit64 }, /* 75 = getrlimit64 */
{ 2, s(struct irix_sys_setrlimit64_args), 0,
irix_sys_setrlimit64 }, /* 76 = setrlimit64 */
{ 2, s(struct sys_nanosleep_args), 0,
sys_nanosleep }, /* 77 = nanosleep */
{ 7, s(struct irix_sys_lseek64_args), 0,
irix_sys_lseek64 }, /* 78 = lseek64 */
{ 1, s(struct sys_rmdir_args), 0,
@ -320,10 +320,10 @@ struct sysent irix_sysent[] = {
sys_nosys }, /* 133 = unimplemented sgigsc */
{ 6, s(struct irix_sys_mmap_args), 0,
irix_sys_mmap }, /* 134 = mmap */
{ 2, s(struct sys_munmap_args), 0,
sys_munmap }, /* 135 = munmap */
{ 3, s(struct sys_mprotect_args), 0,
sys_mprotect }, /* 136 = mprotect */
{ 2, s(struct irix_sys_munmap_args), 0,
irix_sys_munmap }, /* 135 = munmap */
{ 3, s(struct irix_sys_mprotect_args), 0,
irix_sys_mprotect }, /* 136 = mprotect */
{ 3, s(struct sys___msync13_args), 0,
sys___msync13 }, /* 137 = __msync13 */
{ 0, 0, 0,
@ -346,10 +346,10 @@ struct sysent irix_sysent[] = {
sys_fsync }, /* 146 = fsync */
{ 1, s(struct sys_fchdir_args), 0,
sys_fchdir }, /* 147 = fchdir */
{ 0, 0, 0,
sys_nosys }, /* 148 = unimplemented getrlimit */
{ 0, 0, 0,
sys_nosys }, /* 149 = unimplemented setrlimit */
{ 2, s(struct irix_sys_getrlimit_args), 0,
irix_sys_getrlimit }, /* 148 = getrlimit */
{ 2, s(struct irix_sys_setrlimit_args), 0,
irix_sys_setrlimit }, /* 149 = setrlimit */
{ 0, 0, 0,
sys_nosys }, /* 150 = unimplemented cacheflush */
{ 0, 0, 0,

View File

@ -1,4 +1,4 @@
/* $NetBSD: irix_syssgi.c,v 1.27 2002/05/28 21:15:42 manu Exp $ */
/* $NetBSD: irix_syssgi.c,v 1.28 2002/06/12 20:33:20 manu Exp $ */
/*-
* Copyright (c) 2001-2002 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: irix_syssgi.c,v 1.27 2002/05/28 21:15:42 manu Exp $");
__KERNEL_RCSID(0, "$NetBSD: irix_syssgi.c,v 1.28 2002/06/12 20:33:20 manu Exp $");
#include "opt_ddb.h"
@ -73,6 +73,7 @@ __KERNEL_RCSID(0, "$NetBSD: irix_syssgi.c,v 1.27 2002/05/28 21:15:42 manu Exp $"
#include <compat/irix/irix_types.h>
#include <compat/irix/irix_signal.h>
#include <compat/irix/irix_prctl.h>
#include <compat/irix/irix_syscall.h>
#include <compat/irix/irix_syscallargs.h>
#include <compat/irix/irix_syssgi.h>
@ -391,8 +392,8 @@ irix_syssgi_mapelf(fd, ph, count, p, retval)
vcp->ev_addr += base_vcp->ev_addr;
}
error = (*vcp->ev_proc)(p, vcp);
if (error)
/* Eventually do it for a whole share group */
if ((error = irix_sync_saddr_vmcmd(p, vcp)) != 0)
goto bad;
}
pht++;

View File

@ -1,4 +1,4 @@
/* $NetBSD: irix_types.h,v 1.12 2002/03/16 13:29:42 manu Exp $ */
/* $NetBSD: irix_types.h,v 1.13 2002/06/12 20:33:21 manu Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -61,6 +61,7 @@ typedef __int64_t irix_app32_long_long_t;
typedef __uint32_t irix_ino_t;
typedef __int32_t irix_off_t;
typedef __uint32_t irix_app32_ptr_t;
typedef __uint64_t irix_k_sigset_t;
#if 1 /* _MIPS_SZLONG == 32 */
typedef unsigned long irix_mode_t;

View File

@ -1,4 +1,4 @@
$NetBSD: syscalls.master,v 1.44 2002/06/05 17:27:12 manu Exp $
$NetBSD: syscalls.master,v 1.45 2002/06/12 20:33:21 manu Exp $
; @(#)syscalls.master 8.1 (Berkeley) 7/19/93
@ -77,7 +77,7 @@
15 NOARGS { int sys_chmod(char *path, int mode); }
16 NOARGS { int sys___posix_chown(char *path, int uid, \
int gid); } chown
17 NOARGS { int svr4_sys_break(caddr_t nsize); }
17 STD { int irix_sys_break(caddr_t nsize); }
18 OBSOL stat
19 NOARGS { long compat_43_sys_lseek(int fd, long offset, \
int whence); }
@ -121,7 +121,7 @@
50 UNIMPL sysmips
51 UNIMPL acct
#ifdef SYSVSHM
52 NOARGS { int svr4_sys_shmsys(int what, int a2, int a3, \
52 STD { int irix_sys_shmsys(int what, int a2, int a3, \
int a4); }
#else
52 UNIMPL shmsys
@ -157,9 +157,12 @@
72 OBSOL rmount
73 OBSOL rumount
74 OBSOL rfstart
75 OBSOL sigret
76 OBSOL rdebug
77 OBSOL rfstop
75 STD { int irix_sys_getrlimit64(int resource, \
struct irix_rlimit64 *rlp); }
76 STD { int irix_sys_setrlimit64(int resource, \
const struct irix_rlimit64 *rlp); }
77 NOARGS { int sys_nanosleep(const struct timespec *rqtp, \
struct timespec *rmtp); }
78 STD { irix_off64_t irix_sys_lseek64(int fd, int pad1, \
irix_off64_t offset, int whence, \
int pad2, int pad3, int pad4); }
@ -255,8 +258,9 @@
133 UNIMPL sgigsc
134 STD { void *irix_sys_mmap(void *addr, irix_size_t len, \
int prot, int flags, int fd, irix_off_t pos); }
135 NOARGS { int sys_munmap(void *addr, int len); }
136 NOARGS { int sys_mprotect(void *addr, int len, int prot); }
135 STD { int irix_sys_munmap(void *addr, int len); }
136 STD { int irix_sys_mprotect(void *addr, \
int len, int prot); }
137 NOARGS { int sys___msync13(void *addr, \
size_t len, int flags); }
138 UNIMPL madvise
@ -269,8 +273,10 @@
145 UNIMPL vhangup
146 NOARGS { int sys_fsync(int fd); }
147 NOARGS { int sys_fchdir(int fd); }
148 UNIMPL getrlimit
149 UNIMPL setrlimit
148 STD { int irix_sys_getrlimit(int resource, \
struct irix_rlimit *rlp); }
149 STD { int irix_sys_setrlimit(int resource, \
const struct irix_rlimit *rlp); }
150 UNIMPL cacheflush
151 UNIMPL cachectl
152 NOARGS { int sys___posix_fchown(int fd, int uid, int gid); } \