Revision 64 at sourceforge.net
This commit is contained in:
+106
@@ -0,0 +1,106 @@
|
||||
# Generated automatically from Makefile.in by configure.
|
||||
#### Start of system configuration section. ####
|
||||
|
||||
srcdir = .
|
||||
|
||||
ifeq ($(srcdir),.)
|
||||
srcdir = ../../..
|
||||
endif
|
||||
|
||||
VPATH := $(srcdir)
|
||||
|
||||
# Common prefix for machine-independent installed files.
|
||||
prefix = /usr/local
|
||||
|
||||
# Common prefix for machine-dependent installed files.
|
||||
exec_prefix = ${prefix}
|
||||
|
||||
bindir = $(exec_prefix)/bin
|
||||
libdir = $(exec_prefix)/Sys/libs
|
||||
|
||||
INSTALL = /usr/bin/install -c
|
||||
INSTALL_DATA = ${INSTALL} -m 644
|
||||
|
||||
CC = gcc
|
||||
|
||||
CFLAGS = -O2
|
||||
LDFLAGS =
|
||||
|
||||
RANLIB = ranlib
|
||||
AR = ar
|
||||
|
||||
DO_CATENATE = no
|
||||
|
||||
#### End system configuration section ####
|
||||
|
||||
# I *love* GNU make!
|
||||
define catenate
|
||||
/bin/echo -n creating $@...
|
||||
/bin/echo "$(^:%=#include \"%\"\n)" >$@
|
||||
/bin/echo done
|
||||
endef
|
||||
|
||||
ifeq ($(BASE), morphos)
|
||||
FLAVOR_CFLAGS = -mcpu=$(FPU)
|
||||
FIXED_A4= -ffixed-r13
|
||||
else
|
||||
FLAVOR_CFLAGS = -m$(CPU) -m$(FPU)
|
||||
FIXED_A4= -ffixed-a4
|
||||
endif
|
||||
|
||||
INCS = -I$(srcdir) -I$(srcdir)/../library -I$(srcdir)/../include
|
||||
|
||||
ALL_CFLAGS = $(CFLAGS) $(FLAVOR_CFLAGS) $(INCS) $(OTHER_CFLAGS)
|
||||
|
||||
LIB = libstdlib.a
|
||||
|
||||
.c.o:
|
||||
$(CC) $(ALL_CFLAGS) -c $< -o $@
|
||||
|
||||
A4_SRC = bsearch.c heapsort.c qsort.c
|
||||
|
||||
OPTI0 = execve.c
|
||||
|
||||
SRC = $(filter-out $(A4_SRC),$(notdir $(wildcard $(srcdir)/*.c)))
|
||||
|
||||
ifeq ($(DO_CATENATE), yes)
|
||||
|
||||
$(LIB): all.o a4.o
|
||||
rm -f $@
|
||||
$(AR) rv $@ $^
|
||||
$(RANLIB) $@
|
||||
|
||||
all.c: $(SRC)
|
||||
@$(catenate)
|
||||
|
||||
a4.c: $(A4_SRC)
|
||||
@$(catenate)
|
||||
|
||||
a4.o: a4.c
|
||||
$(CC) $(ALL_CFLAGS) $(FIXED_A4) -c $< -o $@
|
||||
|
||||
else
|
||||
|
||||
OBJS= $(SRC:.c=.o)
|
||||
A4_OBJS= $(A4_SRC:.c=.o)
|
||||
|
||||
|
||||
$(LIB): $(OBJS) $(A4_OBJS)
|
||||
rm -f $@
|
||||
$(AR) rv $@ $^
|
||||
$(RANLIB) $@
|
||||
|
||||
$(A4_OBJS): %.o: %.c
|
||||
$(CC) $(ALL_CFLAGS) $(FIXED_A4) -c $< -o $@
|
||||
|
||||
execve.o: execve.c
|
||||
$(CC) $(ALL_CFLAGS) -O1 -c $< -o $@
|
||||
|
||||
endif
|
||||
|
||||
|
||||
clean:
|
||||
rm -rf 680?0 notrap powerpc
|
||||
|
||||
clobber: clean
|
||||
rm -f Makefile
|
||||
@@ -0,0 +1,105 @@
|
||||
#### Start of system configuration section. ####
|
||||
|
||||
srcdir = @srcdir@
|
||||
|
||||
ifeq ($(srcdir),.)
|
||||
srcdir = ../../..
|
||||
endif
|
||||
|
||||
VPATH := $(srcdir)
|
||||
|
||||
# Common prefix for machine-independent installed files.
|
||||
prefix = @prefix@
|
||||
|
||||
# Common prefix for machine-dependent installed files.
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
bindir = $(exec_prefix)/bin
|
||||
libdir = $(exec_prefix)/Sys/libs
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
CC = @CC@
|
||||
|
||||
CFLAGS = @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
RANLIB = @RANLIB@
|
||||
AR = @AR@
|
||||
|
||||
DO_CATENATE = @DO_CATENATE@
|
||||
|
||||
#### End system configuration section ####
|
||||
|
||||
# I *love* GNU make!
|
||||
define catenate
|
||||
/bin/echo -n creating $@...
|
||||
/bin/echo "$(^:%=#include \"%\"\n)" >$@
|
||||
/bin/echo done
|
||||
endef
|
||||
|
||||
ifeq ($(BASE), morphos)
|
||||
FLAVOR_CFLAGS = -mcpu=$(FPU)
|
||||
FIXED_A4= -ffixed-r13
|
||||
else
|
||||
FLAVOR_CFLAGS = -m$(CPU) -m$(FPU)
|
||||
FIXED_A4= -ffixed-a4
|
||||
endif
|
||||
|
||||
INCS = -I$(srcdir) -I$(srcdir)/../library -I$(srcdir)/../include
|
||||
|
||||
ALL_CFLAGS = $(CFLAGS) $(FLAVOR_CFLAGS) $(INCS) $(OTHER_CFLAGS)
|
||||
|
||||
LIB = libstdlib.a
|
||||
|
||||
.c.o:
|
||||
$(CC) $(ALL_CFLAGS) -c $< -o $@
|
||||
|
||||
A4_SRC = bsearch.c heapsort.c qsort.c
|
||||
|
||||
OPTI0 = execve.c
|
||||
|
||||
SRC = $(filter-out $(A4_SRC),$(notdir $(wildcard $(srcdir)/*.c)))
|
||||
|
||||
ifeq ($(DO_CATENATE), yes)
|
||||
|
||||
$(LIB): all.o a4.o
|
||||
rm -f $@
|
||||
$(AR) rv $@ $^
|
||||
$(RANLIB) $@
|
||||
|
||||
all.c: $(SRC)
|
||||
@$(catenate)
|
||||
|
||||
a4.c: $(A4_SRC)
|
||||
@$(catenate)
|
||||
|
||||
a4.o: a4.c
|
||||
$(CC) $(ALL_CFLAGS) $(FIXED_A4) -c $< -o $@
|
||||
|
||||
else
|
||||
|
||||
OBJS= $(SRC:.c=.o)
|
||||
A4_OBJS= $(A4_SRC:.c=.o)
|
||||
|
||||
|
||||
$(LIB): $(OBJS) $(A4_OBJS)
|
||||
rm -f $@
|
||||
$(AR) rv $@ $^
|
||||
$(RANLIB) $@
|
||||
|
||||
$(A4_OBJS): %.o: %.c
|
||||
$(CC) $(ALL_CFLAGS) $(FIXED_A4) -c $< -o $@
|
||||
|
||||
execve.o: execve.c
|
||||
$(CC) $(ALL_CFLAGS) -O1 -c $< -o $@
|
||||
|
||||
endif
|
||||
|
||||
|
||||
clean:
|
||||
rm -rf 680?0 notrap powerpc
|
||||
|
||||
clobber: clean
|
||||
rm -f Makefile
|
||||
@@ -0,0 +1,10 @@
|
||||
#define _KERNEL
|
||||
#include "ixemul.h"
|
||||
|
||||
void abort (void)
|
||||
{
|
||||
syscall (SYS_kill, 0, SIGABRT);
|
||||
/* if this should be caught, do exit directly... */
|
||||
ix_panic ("ABORT! abort is called");
|
||||
exit(20);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* the Systems Programming Group of the University of Utah Computer
|
||||
* Science Department.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that: (1) source distributions retain this entire copyright
|
||||
* notice and comment, and (2) distributions including binaries display
|
||||
* the following acknowledgement: ``This product includes software
|
||||
* developed by the University of California, Berkeley and its contributors''
|
||||
* in the documentation or other materials provided with the distribution
|
||||
* and in all advertising materials mentioning features or use of this
|
||||
* software. Neither the name of the University nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
/* abs - int absolute value */
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
#ifndef mc68000
|
||||
int abs(int j)
|
||||
{ return j>=0?j:-j; }
|
||||
#else
|
||||
ENTRY(abs)
|
||||
asm(" \n\
|
||||
movl sp@(4),d0 \n\
|
||||
jge L1 \n\
|
||||
negl d0 \n\
|
||||
L1: \n\
|
||||
rts \n\
|
||||
");
|
||||
#endif
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Chris Torek.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that: (1) source distributions retain this entire copyright
|
||||
* notice and comment, and (2) distributions including binaries display
|
||||
* the following acknowledgement: ``This product includes software
|
||||
* developed by the University of California, Berkeley and its contributors''
|
||||
* in the documentation or other materials provided with the distribution
|
||||
* and in all advertising materials mentioning features or use of this
|
||||
* software. Neither the name of the University nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)atexit.c 5.1 (Berkeley) 5/15/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#define _KERNEL
|
||||
#include "ixemul.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "atexit.h"
|
||||
|
||||
#define __atexit (u.u_atexit)
|
||||
|
||||
struct atexit *
|
||||
get_atexit_table()
|
||||
{
|
||||
usetup;
|
||||
register struct atexit *p;
|
||||
|
||||
if ((p = __atexit) == 0)
|
||||
{
|
||||
/* don't need a static table anymore, since OpenLibrary() comes
|
||||
* before ix_startup() */
|
||||
__atexit = p = (struct atexit *) syscall (SYS_malloc, sizeof (*p));
|
||||
bzero (p, sizeof (*p));
|
||||
}
|
||||
|
||||
if (p->ind >= ATEXIT_SIZE) {
|
||||
if ((p = (struct atexit *) syscall (SYS_malloc, sizeof(*p))) == NULL)
|
||||
return (NULL);
|
||||
#if 0
|
||||
/* this was in the original source */
|
||||
__atexit->next = p;
|
||||
__atexit = p;
|
||||
#else
|
||||
p->next = __atexit;
|
||||
__atexit = p;
|
||||
p->ind = 0;
|
||||
#endif
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* Register a function to be performed at exit.
|
||||
*/
|
||||
/* For MorphOS, this is the PPC entry point. Assume that it is
|
||||
* called with a pointer to a PPC function.
|
||||
*/
|
||||
int
|
||||
atexit(void (*fn)())
|
||||
{
|
||||
register struct atexit *p = get_atexit_table();
|
||||
if (!p)
|
||||
return (-1);
|
||||
#ifndef NATIVE_MORPHOS
|
||||
p->fns[p->ind] = fn;
|
||||
#else
|
||||
p->fns[p->ind].is_68k = 0;
|
||||
p->fns[p->ind].fn = fn;
|
||||
#endif
|
||||
++p->ind;
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef NATIVE_MORPHOS
|
||||
/* For MorphOS, this is the 68k entry point. Assume that it is
|
||||
* called with a pointer to a 68k function.
|
||||
*/
|
||||
|
||||
int
|
||||
atexit_68k(void)
|
||||
{
|
||||
void (*fn)() = ((void(**)())REG_A7)[1];
|
||||
register struct atexit *p = get_atexit_table();
|
||||
if (!p)
|
||||
return (-1);
|
||||
p->fns[p->ind].is_68k = 1;
|
||||
p->fns[p->ind].fn = fn;
|
||||
++p->ind;
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct EmulLibEntry _gate_atexit = {
|
||||
TRAP_LIB, 0, (void(*)())atexit_68k
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
#ifndef _ATEXIT_H_
|
||||
#define _ATEXIT_H_
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that: (1) source distributions retain this entire copyright
|
||||
* notice and comment, and (2) distributions including binaries display
|
||||
* the following acknowledgement: ``This product includes software
|
||||
* developed by the University of California, Berkeley and its contributors''
|
||||
* in the documentation or other materials provided with the distribution
|
||||
* and in all advertising materials mentioning features or use of this
|
||||
* software. Neither the name of the University nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* @(#)atexit.h 5.1 (Berkeley) 5/15/90
|
||||
*/
|
||||
|
||||
/* must be at least 32 to guarantee ANSI conformance */
|
||||
#define ATEXIT_SIZE 32
|
||||
|
||||
#ifndef NATIVE_MORPHOS
|
||||
|
||||
struct atexit {
|
||||
struct atexit *next; /* next in list */
|
||||
int ind; /* next index in this table */
|
||||
void (*fns[ATEXIT_SIZE])(); /* the table itself */
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
struct atexit_entry {
|
||||
int is_68k;
|
||||
void (*fn)();
|
||||
};
|
||||
|
||||
struct atexit {
|
||||
struct atexit *next; /* next in list */
|
||||
int ind; /* next index in this table */
|
||||
struct atexit_entry fns[ATEXIT_SIZE]; /* the table itself */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
struct atexit *__atexit; /* points to head of LIFO stack */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 1988 The Regents of the University of California.
|
||||
* 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)atof.c 5.3 (Berkeley) 1/8/93";*/
|
||||
static char *rcsid = "$Id: atof.c,v 1.1.1.1 2005/03/15 15:57:07 laire Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#define _KERNEL
|
||||
#include "ixemul.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
double
|
||||
atof(ascii)
|
||||
const char *ascii;
|
||||
{
|
||||
return(strtod(ascii, (char **)NULL));
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 1988 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that: (1) source distributions retain this entire copyright
|
||||
* notice and comment, and (2) distributions including binaries display
|
||||
* the following acknowledgement: ``This product includes software
|
||||
* developed by the University of California, Berkeley and its contributors''
|
||||
* in the documentation or other materials provided with the distribution
|
||||
* and in all advertising materials mentioning features or use of this
|
||||
* software. Neither the name of the University nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)atoi.c 5.6 (Berkeley) 6/1/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#define _KERNEL
|
||||
#include "ixemul.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
|
||||
int
|
||||
atoi(const char *str)
|
||||
{
|
||||
return((int)strtol(str, (char **)NULL, 10));
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 1988 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that: (1) source distributions retain this entire copyright
|
||||
* notice and comment, and (2) distributions including binaries display
|
||||
* the following acknowledgement: ``This product includes software
|
||||
* developed by the University of California, Berkeley and its contributors''
|
||||
* in the documentation or other materials provided with the distribution
|
||||
* and in all advertising materials mentioning features or use of this
|
||||
* software. Neither the name of the University nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)atol.c 5.6 (Berkeley) 6/1/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#define _KERNEL
|
||||
#include "ixemul.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
long
|
||||
atol(const char *str)
|
||||
{
|
||||
return(strtol(str, (char **)NULL, 10));
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright (c) 1990 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that: (1) source distributions retain this entire copyright
|
||||
* notice and comment, and (2) distributions including binaries display
|
||||
* the following acknowledgement: ``This product includes software
|
||||
* developed by the University of California, Berkeley and its contributors''
|
||||
* in the documentation or other materials provided with the distribution
|
||||
* and in all advertising materials mentioning features or use of this
|
||||
* software. Neither the name of the University nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)bsearch.c 5.3 (Berkeley) 5/17/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#define _KERNEL
|
||||
#include "ixemul.h"
|
||||
|
||||
#include <stddef.h> /* size_t */
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef NATIVE_MORPHOS
|
||||
#define bsearch _bsearch
|
||||
#define FLAGPRM ,int is68k
|
||||
|
||||
/* code for:
|
||||
movem.l d0-d1,-(sp)
|
||||
jsr (a0)
|
||||
addq.l #8,sp
|
||||
rts
|
||||
*/
|
||||
static const UWORD compar_gate[] = {
|
||||
0x48E7,0xC000,0x4E90,0x508F,0x4E75
|
||||
};
|
||||
|
||||
static inline int my_compar(const void *p, const void *q, int (*qcmp)(), int is68k) {
|
||||
if (is68k) {
|
||||
REG_D0 = (ULONG)p;
|
||||
REG_D1 = (ULONG)q;
|
||||
REG_A0 = (ULONG)qcmp;
|
||||
//REG_A4 = REG_A4;
|
||||
return MyEmulHandle->EmulCallDirect68k((APTR)compar_gate);
|
||||
} else {
|
||||
return qcmp(p, q);
|
||||
}
|
||||
}
|
||||
#define CMP(x, y) my_compar(x, y, compar, is68k)
|
||||
|
||||
#else
|
||||
#define FLAGPRM
|
||||
#define CMP(x, y) compar(x, y)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Perform a binary search.
|
||||
*
|
||||
* The code below is a bit sneaky. After a comparison fails, we
|
||||
* divide the work in half by moving either left or right. If lim
|
||||
* is odd, moving left simply involves halving lim: e.g., when lim
|
||||
* is 5 we look at item 2, so we change lim to 2 so that we will
|
||||
* look at items 0 & 1. If lim is even, the same applies. If lim
|
||||
* is odd, moving right again involes halving lim, this time moving
|
||||
* the base up one item past p: e.g., when lim is 5 we change base
|
||||
* to item 3 and make lim 2 so that we will look at items 3 and 4.
|
||||
* If lim is even, however, we have to shrink it by one before
|
||||
* halving: e.g., when lim is 4, we still looked at item 2, so we
|
||||
* have to make lim 3, then halve, obtaining 1, so that we will only
|
||||
* look at item 3.
|
||||
*/
|
||||
void *
|
||||
bsearch(const void *key, const void *base0,
|
||||
size_t nmemb, size_t size, int (*compar)() FLAGPRM)
|
||||
{
|
||||
register char *base = (char *)base0;
|
||||
register int lim, cmp;
|
||||
register void *p;
|
||||
|
||||
for (lim = nmemb; lim != 0; lim >>= 1) {
|
||||
p = base + (lim >> 1) * size;
|
||||
cmp = CMP(key, p);
|
||||
if (cmp == 0)
|
||||
return (p);
|
||||
if (cmp > 0) { /* key > p: move right */
|
||||
base = (char *)p + size;
|
||||
lim--;
|
||||
} /* else move left */
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
#ifdef NATIVE_MORPHOS
|
||||
#undef bsearch
|
||||
#undef FLAGPRM
|
||||
#undef CMP
|
||||
|
||||
void *
|
||||
bsearch(const void *key, const void *base0,
|
||||
size_t nmemb, size_t size, int (*compar)())
|
||||
{
|
||||
return _bsearch(key, base0, nmemb, size, compar, 0);
|
||||
}
|
||||
|
||||
void *
|
||||
_trampoline_bsearch(void)
|
||||
{
|
||||
int *p = (int *)REG_A7;
|
||||
const void *key = (void *)p[1];
|
||||
const void *base0 = (const void *)p[2];
|
||||
size_t nmemb = p[3];
|
||||
size_t size = p[4];
|
||||
int (*compar)() = (int(*)())p[5];
|
||||
|
||||
return _bsearch(key, base0, nmemb, size, compar, 1);
|
||||
}
|
||||
|
||||
const struct EmulLibEntry _gate_bsearch = {
|
||||
TRAP_LIB, 0, (void(*)())_trampoline_bsearch
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that: (1) source distributions retain this entire copyright
|
||||
* notice and comment, and (2) distributions including binaries display
|
||||
* the following acknowledgement: ``This product includes software
|
||||
* developed by the University of California, Berkeley and its contributors''
|
||||
* in the documentation or other materials provided with the distribution
|
||||
* and in all advertising materials mentioning features or use of this
|
||||
* software. Neither the name of the University nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)calloc.c 5.5 (Berkeley) 5/17/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#define _KERNEL
|
||||
#include "ixemul.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void *
|
||||
calloc (size_t num, size_t size)
|
||||
{
|
||||
register void *p;
|
||||
|
||||
size *= num;
|
||||
if ((p = (void *) syscall (SYS_malloc, size)))
|
||||
bzero(p, size);
|
||||
return(p);
|
||||
}
|
||||
|
||||
void
|
||||
cfree(void *p)
|
||||
{
|
||||
(void)syscall (SYS_free, p);
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 1990 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Chris Torek.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that: (1) source distributions retain this entire copyright
|
||||
* notice and comment, and (2) distributions including binaries display
|
||||
* the following acknowledgement: ``This product includes software
|
||||
* developed by the University of California, Berkeley and its contributors''
|
||||
* in the documentation or other materials provided with the distribution
|
||||
* and in all advertising materials mentioning features or use of this
|
||||
* software. Neither the name of the University nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)div.c 5.1 (Berkeley) 5/16/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#define _KERNEL
|
||||
#include "ixemul.h"
|
||||
|
||||
#include <stdlib.h> /* div_t */
|
||||
|
||||
/*
|
||||
* I AM NOT SURE THIS IS COMPLETELY PORTABLE
|
||||
* (or that it is even right)
|
||||
*/
|
||||
div_t /* const */
|
||||
div(int num, int denom)
|
||||
{
|
||||
div_t r;
|
||||
|
||||
/* avoid deep thought */
|
||||
if (num > 0 && denom < 0) {
|
||||
num = -num;
|
||||
denom = -denom;
|
||||
}
|
||||
r.quot = num / denom;
|
||||
r.rem = num % denom;
|
||||
if (num < 0 && denom > 0) {
|
||||
/*
|
||||
* Machine division and remainer may work either way. The
|
||||
* ANSI standard says that |r.quot| < |n/d| (where n/d
|
||||
* computed in infinite precision). If the remainder is
|
||||
* positive, we got the `wrong' answer, so fix it.
|
||||
*/
|
||||
if (r.rem > 0) {
|
||||
r.quot++;
|
||||
r.rem -= denom;
|
||||
}
|
||||
}
|
||||
return (r);
|
||||
}
|
||||
+243
@@ -0,0 +1,243 @@
|
||||
/*-
|
||||
* Copyright (c) 1991 The Regents of the University of California.
|
||||
* 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)exec.c 5.9 (Berkeley) 6/17/91";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#define _KERNEL
|
||||
#include "ixemul.h"
|
||||
#include "kprintf.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <paths.h>
|
||||
|
||||
#ifdef __STDC__
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
|
||||
static char **
|
||||
buildargv(ap, arg, envpp)
|
||||
va_list ap;
|
||||
const char *arg;
|
||||
char ***envpp;
|
||||
{
|
||||
register size_t max, off;
|
||||
register char **argv = NULL;
|
||||
|
||||
for (off = max = 0;; ++off) {
|
||||
if (off >= max) {
|
||||
max += 50; /* Starts out at 0. */
|
||||
max *= 2; /* Ramp up fast. */
|
||||
if (!(argv = realloc(argv, max * sizeof(char *))))
|
||||
return(NULL);
|
||||
if (off == 0) {
|
||||
argv[0] = (char *)arg;
|
||||
off = 1;
|
||||
}
|
||||
}
|
||||
if (!(argv[off] = va_arg(ap, char *)))
|
||||
break;
|
||||
}
|
||||
/* Get environment pointer if user supposed to provide one. */
|
||||
if (envpp)
|
||||
*envpp = va_arg(ap, char **);
|
||||
return(argv);
|
||||
}
|
||||
|
||||
int execl(const char *name, const char *arg, ...)
|
||||
{
|
||||
usetup;
|
||||
va_list ap;
|
||||
int sverrno;
|
||||
char **argv;
|
||||
|
||||
va_start(ap, arg);
|
||||
if ((argv = buildargv(ap, arg, (char ***)NULL)))
|
||||
(void)execve(name, argv, *u.u_environ);
|
||||
va_end(ap);
|
||||
sverrno = errno;
|
||||
free(argv);
|
||||
errno = sverrno;
|
||||
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
|
||||
return(-1);
|
||||
}
|
||||
|
||||
int execle(const char *name, const char *arg, ...)
|
||||
{
|
||||
usetup;
|
||||
va_list ap;
|
||||
int sverrno;
|
||||
char **argv, **envp;
|
||||
|
||||
va_start(ap, arg);
|
||||
if ((argv = buildargv(ap, arg, &envp)))
|
||||
(void)execve(name, argv, envp);
|
||||
va_end(ap);
|
||||
sverrno = errno;
|
||||
free(argv);
|
||||
errno = sverrno;
|
||||
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
|
||||
return(-1);
|
||||
}
|
||||
|
||||
int execlp(const char *name, const char *arg, ...)
|
||||
{
|
||||
usetup;
|
||||
va_list ap;
|
||||
int sverrno;
|
||||
char **argv;
|
||||
|
||||
va_start(ap, arg);
|
||||
if ((argv = buildargv(ap, arg, (char ***)NULL)))
|
||||
(void)execvp(name, argv);
|
||||
va_end(ap);
|
||||
sverrno = errno;
|
||||
free(argv);
|
||||
errno = sverrno;
|
||||
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
|
||||
return(-1);
|
||||
}
|
||||
|
||||
int execv(const char *name, char * const *argv)
|
||||
{
|
||||
usetup;
|
||||
|
||||
execve(name, argv, *u.u_environ);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
int execvp(const char *name, char * const *argv)
|
||||
{
|
||||
usetup;
|
||||
register int lp, ln;
|
||||
register char *p;
|
||||
int eacces, etxtbsy;
|
||||
char *bp, *cur, *path, buf[MAXPATHLEN];
|
||||
|
||||
eacces = etxtbsy = 0;
|
||||
/* If it's an absolute or relative path name, it's easy. */
|
||||
if (index(name, '/') || index (name, ':')) {
|
||||
bp = (char *)name;
|
||||
cur = path = NULL;
|
||||
goto retry;
|
||||
}
|
||||
bp = buf;
|
||||
|
||||
/* first try to call execve() without path lookup. execve() walks
|
||||
a (possibly provided) CLI PATH, and also supports resident
|
||||
programs. If this fails, we can still try to find the program
|
||||
along the $PATH */
|
||||
|
||||
execv (name, argv);
|
||||
/* if we get here, the execv() failed. So start magic ;-)) */
|
||||
|
||||
/* only continue if execv didn't find the program. */
|
||||
if (errno != ENOENT)
|
||||
return -1;
|
||||
|
||||
/* Get the path we're searching. */
|
||||
if (!(path = getenv("PATH")))
|
||||
path = _PATH_DEFPATH;
|
||||
cur = path = strdup(path);
|
||||
|
||||
while ((p = strsep(&cur, ",:"))) {
|
||||
/*
|
||||
* It's a SHELL path -- double, leading and trailing colons
|
||||
* mean the current directory.
|
||||
*/
|
||||
if (!*p) {
|
||||
p = ".";
|
||||
lp = 1;
|
||||
} else
|
||||
lp = strlen(p);
|
||||
ln = strlen(name);
|
||||
|
||||
/*
|
||||
* If the path is too long complain. This is a possible
|
||||
* security issue; given a way to make the path too long
|
||||
* the user may execute the wrong program.
|
||||
*/
|
||||
if (lp + ln + 2 > sizeof(buf)) {
|
||||
syscall(SYS_write, STDERR_FILENO, "execvp: ", 8);
|
||||
syscall(SYS_write, STDERR_FILENO, p, lp);
|
||||
syscall(SYS_write, STDERR_FILENO, ": path too long\n", 16);
|
||||
continue;
|
||||
}
|
||||
bcopy(p, buf, lp);
|
||||
buf[lp] = '/';
|
||||
bcopy(name, buf + lp + 1, ln);
|
||||
buf[lp + ln + 1] = '\0';
|
||||
retry: execve(bp, argv, *u.u_environ);
|
||||
switch(errno) {
|
||||
case EACCES:
|
||||
eacces = 1;
|
||||
break;
|
||||
case ENOENT:
|
||||
break;
|
||||
case ENOEXEC: {
|
||||
register size_t cnt;
|
||||
register char **ap;
|
||||
|
||||
for (cnt = 0, ap = (char **)argv; *ap; ++ap, ++cnt);
|
||||
if ((ap = malloc((cnt + 2) * sizeof(char *)))) {
|
||||
bcopy(argv + 1, ap + 2, cnt * sizeof(char *));
|
||||
ap[0] = "sh";
|
||||
ap[1] = bp;
|
||||
execve(_PATH_BSHELL, ap, *u.u_environ);
|
||||
free(ap);
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
case ETXTBSY:
|
||||
if (etxtbsy < 3)
|
||||
sleep(++etxtbsy);
|
||||
goto retry;
|
||||
default:
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (eacces)
|
||||
errno = EACCES;
|
||||
else if (!errno)
|
||||
errno = ENOENT;
|
||||
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
|
||||
done: if (path)
|
||||
free(path);
|
||||
return(-1);
|
||||
}
|
||||
+713
@@ -0,0 +1,713 @@
|
||||
/*
|
||||
* This file is part of ixemul.library for the Amiga.
|
||||
* Copyright (C) 1991, 1992 Markus M. Wild
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#define _KERNEL
|
||||
#include <string.h>
|
||||
#include "ixemul.h"
|
||||
#include "kprintf.h"
|
||||
#include <hardware/intbits.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <sys/exec.h>
|
||||
|
||||
#include "atexit.h"
|
||||
#define __atexit (u.u_atexit)
|
||||
|
||||
#define JMP_MAGIC_16(code) ((code[0] & 0xffff0000) == 0x4efa0000)
|
||||
#define JMP_MAGIC_32(code) ((code[0] & 0xffff0000) == 0x4efb0000)
|
||||
/* The following define tests for the 'bra' instruction which the
|
||||
current assembler generates at the start of a program that is
|
||||
compiled with crt0.o. The previous defines are for backwards
|
||||
compatibility with older assemblers. */
|
||||
#define JRA_MAGIC_16(code) ((code[0] & 0xffff0000) == 0x60000000)
|
||||
|
||||
#define MAGIC_16(code) \
|
||||
((JRA_MAGIC_16 (code) || JMP_MAGIC_16 (code)) && \
|
||||
(code[1] & 0xffff) == OMAGIC)
|
||||
|
||||
#define MAGIC_32(code) \
|
||||
(JMP_MAGIC_32 (code) && (code[2] & 0xffff) == OMAGIC)
|
||||
|
||||
static int compatible_startup (void *code, int argc, char **argv);
|
||||
static char *quote (char *orig);
|
||||
static void volatile on_real_stack (BPTR *segs, char **argv, char **environ, int omask);
|
||||
|
||||
BPTR dup2_BPTR (int);
|
||||
void readargs_kludge (BPTR);
|
||||
|
||||
int
|
||||
execve (const char *path, char * const *argv, char * const *environ)
|
||||
{
|
||||
BPTR *segs;
|
||||
u_int omask, err;
|
||||
char *extra_args = 0;
|
||||
struct Process *me = (struct Process *) FindTask (0);
|
||||
struct user *u_ptr = getuser(me);
|
||||
|
||||
KPRINTF (("execve (%s,...)\n", path));
|
||||
KPRINTF_ARGV ("argv", argv);
|
||||
KPRINTF_ARGV ("environ", environ);
|
||||
|
||||
omask = syscall (SYS_sigsetmask, ~0);
|
||||
|
||||
segs = __load_seg ((char *)path, &extra_args);
|
||||
|
||||
if (segs)
|
||||
{
|
||||
/* Now it gets somewhat nasty... since I have to revert to the `real'
|
||||
stack (since the parent will want its sp back ;-)), I have to save
|
||||
the values of this stack frame into registers, or I'll never be
|
||||
able to access them afterwards again.. */
|
||||
register BPTR *_segs asm ("d2");
|
||||
register char **_argv asm ("d3");
|
||||
register char **_environ asm ("d4");
|
||||
|
||||
/* if we got extra arguments, split them into a 2 el argument vector, and join
|
||||
* `argv' */
|
||||
if (extra_args && *extra_args)
|
||||
{
|
||||
char **ap;
|
||||
char **nargv;
|
||||
int size;
|
||||
|
||||
for (size = 0, ap = (char **)argv; *ap; size++, ap++) ;
|
||||
nargv = (char **) syscall(SYS_malloc, (size + 4) * sizeof(char *));
|
||||
ap = nargv;
|
||||
argv++; /* discard the program name */
|
||||
*ap = extra_args; /* new program name */
|
||||
|
||||
for(;;)
|
||||
{
|
||||
ap[1] = index(*ap, '\001');
|
||||
ap++;
|
||||
if (*ap)
|
||||
{
|
||||
**ap = 0;
|
||||
(*ap)++;
|
||||
}
|
||||
else break;
|
||||
}
|
||||
|
||||
while ((*ap++ = *argv++)) ;
|
||||
argv = (char * const *)nargv;
|
||||
}
|
||||
|
||||
_segs = segs;
|
||||
_argv = (char **)argv;
|
||||
_environ = (char **)environ;
|
||||
|
||||
KPRINTF (("execve: about to call on_real_stack ()\n"));
|
||||
if (u.p_vfork_msg)
|
||||
{
|
||||
me->pr_Task.tc_SPLower = (void *)u.p_vfork_msg->vm_clower;
|
||||
me->pr_Task.tc_SPUpper = (void *)u.p_vfork_msg->vm_cupper;
|
||||
set_sp ((u_int) u.u_save_sp);
|
||||
/* fool the optimizer... */
|
||||
asm volatile ("" : "=g" (_segs), "=g" (_argv), "=g" (_environ) : "0" (_segs), "1" (_argv), "2" (_environ));
|
||||
KPRINTF (("execve () restored native sp\n"));
|
||||
}
|
||||
on_real_stack (_segs, _argv, _environ, omask);
|
||||
/* never reached */
|
||||
}
|
||||
|
||||
err = errno;
|
||||
|
||||
syscall (SYS_sigsetmask, omask);
|
||||
|
||||
errno = err;
|
||||
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
char **
|
||||
dupvec (char **vec)
|
||||
{
|
||||
int n;
|
||||
char **vp;
|
||||
char **res;
|
||||
static char *empty[] = { NULL };
|
||||
|
||||
if (! vec)
|
||||
return empty;
|
||||
|
||||
for (n = 0, vp = vec; *vp; n++, vp++) ;
|
||||
|
||||
/* contrary to `real' vfork(), malloc() works in the child on its own
|
||||
data, that is it won't clobber anything in the parent */
|
||||
|
||||
res = (char **) syscall (SYS_malloc, (n + 1) * 4);
|
||||
if (res)
|
||||
{
|
||||
for (vp = res; n-- > 0; vp++, vec++)
|
||||
*vp = (char *) syscall (SYS_strdup, *vec);
|
||||
|
||||
*vp = 0;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void volatile
|
||||
on_real_stack (BPTR *segs, char **argv, char **environ, int omask)
|
||||
{
|
||||
int private_startup;
|
||||
u_int *code;
|
||||
int (*entry) (struct ixemul_base *, int, char **, char **, int) = NULL;
|
||||
struct exec *hdr = NULL;
|
||||
int f;
|
||||
int sg;
|
||||
jmp_buf old_exit;
|
||||
u_int old_a4 = 0;
|
||||
usetup;
|
||||
|
||||
KPRINTF (("entered on_real_stack()\n"));
|
||||
/* first make sure that we're later passing on `safe' data to our child, ie.
|
||||
copy it from wherever the data is currently stored into child malloc space */
|
||||
vfork_own_malloc ();
|
||||
if (environ)
|
||||
*u.u_environ = dupvec(environ);
|
||||
environ = *u.u_environ;
|
||||
argv = dupvec(argv);
|
||||
KPRINTF_ARGV ("copy of argv", argv);
|
||||
|
||||
u.u_segs = (struct my_seg *)segs;
|
||||
|
||||
sg = (long)*segs;
|
||||
sg <<= 2;
|
||||
u.u_start_pc = sg + 4;
|
||||
u.u_end_pc = sg + *(long *)(sg - 4) - 8;
|
||||
code = (void *)u.u_start_pc;
|
||||
|
||||
/* Check whether this program has our magic header. See crt0.c for details. */
|
||||
|
||||
if (code && MAGIC_16 (code))
|
||||
{
|
||||
private_startup = 1;
|
||||
hdr = (struct exec *) &code[1];
|
||||
}
|
||||
else if (code && MAGIC_32 (code))
|
||||
{
|
||||
private_startup = 1;
|
||||
hdr = (struct exec *) &code[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
private_startup = 0;
|
||||
}
|
||||
|
||||
KPRINTF (("magic header %s\n", private_startup ? "found" : "NOT found"));
|
||||
KPRINTF (("code[0] = %lx; code[1] = %lx; code[2] = %lx\n", code[0], code[1], code[2]));
|
||||
|
||||
#if 0
|
||||
{
|
||||
char **cp;
|
||||
KPRINTF (("execve ["));
|
||||
for (cp = argv; *cp; cp++) KPRINTF (("%s%s", *cp, cp[1] ? ", " : "], ["));
|
||||
for (cp = environ; *cp; cp++) KPRINTF (("%s%s", *cp, cp[1] ? ", " : "]\n"));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (private_startup)
|
||||
{
|
||||
entry = (void *) hdr->a_entry;
|
||||
|
||||
if (! entry) private_startup = 0;
|
||||
}
|
||||
|
||||
/* okay, get ready to turn us into a new process, as much as
|
||||
we can actually.. */
|
||||
|
||||
/* close all files with the close-on-exec flag set */
|
||||
for (f = 0; f < NOFILE; f++)
|
||||
{
|
||||
if (u.u_ofile[f] && (u.u_pofile[f] & UF_EXCLOSE))
|
||||
syscall (SYS_close, f);
|
||||
}
|
||||
|
||||
/* BIG question what to do with registered atexit() handlers before
|
||||
an exec.. Unix for sure does nothing, since the process space is
|
||||
physically written over. In the AmigaOS I could (!) imagine
|
||||
cases where calling some atexit() handlers (mostly in the case
|
||||
of destructors for C++ objects) would result in erronous
|
||||
behaving of the program. However, since atexit() handlers also
|
||||
serve to get rid of acquired Amiga resources, I morally feel
|
||||
obliged to call the handlers.. lets see if this results in
|
||||
incompatibilities with programs that expect Unix behavior. (Note
|
||||
that I don't call exit() after exeve() returns, I call _exit(),
|
||||
and _exit() does not walk the atexit() list).
|
||||
|
||||
There is one special case that I catch here, this is stdio. No
|
||||
Unix program would ever expect stdio buffers to be flushed by
|
||||
an execve() call. So since stdio is in the library I know the
|
||||
address of the handler to skip ;-)) */
|
||||
|
||||
while (__atexit)
|
||||
{
|
||||
while (__atexit->ind --)
|
||||
{
|
||||
/* this is the stdio function to flush all buffers */
|
||||
extern void _cleanup();
|
||||
|
||||
if (__atexit->fns[__atexit->ind] != _cleanup)
|
||||
{
|
||||
if (u.u_a4)
|
||||
asm volatile ("movel %0, a4" : : "g" (u.u_a4));
|
||||
__atexit->fns[__atexit->ind] ();
|
||||
}
|
||||
}
|
||||
__atexit = __atexit->next;
|
||||
}
|
||||
|
||||
/* `ignored signals remain ignored across an execve, but
|
||||
signals that are caught are reset to their default values.
|
||||
Blocked signals remain blocked regardless of changes to
|
||||
the signal action. The signal stack is reset to be
|
||||
undefined'. */
|
||||
|
||||
u.u_sigonstack = 0; /* default = on normal stack */
|
||||
u.u_sigintr = 0; /* default = don't interrupt syscalls */
|
||||
u.p_sigcatch = 0; /* no signals caught by user -> SIG_DFL */
|
||||
for (f = 0; f < NSIG; f++) /* reset handlers to SIG_DFL, except for SIG_IGN */
|
||||
if (u.u_signal[f] != SIG_IGN)
|
||||
u.u_signal[f] = SIG_DFL;
|
||||
|
||||
/* what happens when we execute execve() from a signal handler
|
||||
that executes on the signal stack? Better don't do this... */
|
||||
|
||||
/* deinstall our sigwinch input-handler */
|
||||
__ix_remove_sigwinch ();
|
||||
|
||||
/* clear the a4 pointers */
|
||||
bzero((char *)&u - u.u_a4_pointers_size * 4, u.u_a4_pointers_size * 4);
|
||||
|
||||
/* save the original exit-jmpbuf, as ix_exec_entry() will destroy
|
||||
* it later */
|
||||
bcopy (u.u_jmp_buf, old_exit, sizeof (old_exit));
|
||||
if (u.p_flag & SFREEA4)
|
||||
{
|
||||
old_a4 = u.u_a4;
|
||||
u.p_flag &= ~SFREEA4;
|
||||
}
|
||||
|
||||
/* count the arguments */
|
||||
for (f = 0; argv[f]; f++) ;
|
||||
KPRINTF (("found %ld args\n", f));
|
||||
|
||||
KPRINTF (("execve() having parent resume\n"));
|
||||
if (u.p_vfork_msg)
|
||||
{
|
||||
/* make the parent runable again */
|
||||
ReplyMsg ((struct Message *) u.p_vfork_msg);
|
||||
u.p_vfork_msg = 0;
|
||||
}
|
||||
|
||||
KPRINTF (("execve() calling entry()\n"));
|
||||
{
|
||||
BPTR origprogdir = 0;
|
||||
extern void ix_stack_usage(void);
|
||||
|
||||
/* to run as a `true' AmigaOS program, ProgramName should
|
||||
* only be that: the program name with no path. An ixemul
|
||||
* program retrieves its name from argv[0] anyway.
|
||||
*/
|
||||
char *programname = basename (argv[0]);
|
||||
SetProgramName(programname);
|
||||
if (u.u_segs->programdir)
|
||||
origprogdir = SetProgramDir(u.u_segs->programdir);
|
||||
|
||||
u.u_oldmask = omask;
|
||||
u.u_a4 = 0; /* assume it's not baserelative */
|
||||
|
||||
if (private_startup)
|
||||
{
|
||||
u.p_xstat = entry(ixemulbase, f, argv, environ, 0);
|
||||
if (u.p_flag & SFREEA4) /* free data segment allocated by a pure executable */
|
||||
{
|
||||
kfree ((void *)(u.u_a4 - 0x7ffe));
|
||||
u.p_flag &= ~SFREEA4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable ctrl-C handling, otherwise it would be possible that
|
||||
* this process would be killed, while the child was still running.
|
||||
*/
|
||||
omask = syscall(SYS_sigsetmask, ~0);
|
||||
compatible_startup (code, f, argv);
|
||||
syscall(SYS_sigsetmask, omask);
|
||||
}
|
||||
|
||||
ix_stack_usage();
|
||||
u.p_flag |= SUSAGE;
|
||||
|
||||
if (u.u_segs->programdir)
|
||||
SetProgramDir (origprogdir);
|
||||
}
|
||||
|
||||
__free_seg (segs);
|
||||
|
||||
if (old_a4)
|
||||
{
|
||||
u.u_a4 = old_a4;
|
||||
u.p_flag |= SFREEA4;
|
||||
}
|
||||
KPRINTF (("old program doing _exit(%ld)\n", f));
|
||||
/* and fake an _exit */
|
||||
_clean_longjmp (old_exit, 1);
|
||||
}
|
||||
|
||||
|
||||
struct user *safe_getuser(struct Process *task)
|
||||
{
|
||||
struct user *u_ptr = NULL;
|
||||
struct ixnode *node;
|
||||
|
||||
/* Check if the process has been 'detached' from ixemul first.
|
||||
If it is, getuser(task) is invalid. It is usually NULL, but it
|
||||
may be non-NULL too, if the non-ixemul task uses tc_TrapData. */
|
||||
|
||||
Forbid();
|
||||
for (node = ixemulbase->ix_detached_processes.head; node; node = node->next)
|
||||
{
|
||||
struct user *p = (struct user *)((char *)node - offsetof(struct user, u_detached_node));
|
||||
if (p->u_task == task)
|
||||
{
|
||||
u_ptr = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!u_ptr)
|
||||
u_ptr = getuser(task);
|
||||
Permit();
|
||||
|
||||
return u_ptr;
|
||||
}
|
||||
|
||||
|
||||
/* some rather rude support to start programs that don't have a struct exec
|
||||
* information at the beginning.
|
||||
* 1.3 NOTE: This will only start plain C programs, nothing that smells like
|
||||
* BCPL. Limited support for ReadArgs() style parsing is here, but not
|
||||
* everything is set up that would have to be set up for BCPL programs
|
||||
* to feel at home. Also don't use Exit() in those programs, it wouldn't
|
||||
* find what it expects on the stack....
|
||||
*/
|
||||
static int
|
||||
compatible_startup (void *code, int argc, char **argv)
|
||||
{
|
||||
char *al;
|
||||
int max, res;
|
||||
u_int oldsigalloc;
|
||||
struct Process *me = (struct Process *)FindTask(0);
|
||||
struct user *u_ptr = getuser(me);
|
||||
|
||||
KPRINTF (("entered compatible_startup()\n"));
|
||||
KPRINTF (("argc = %ld\n", argc));
|
||||
KPRINTF_ARGV ("argv", argv);
|
||||
|
||||
/* ignore the command name ;-) */
|
||||
argv++;
|
||||
|
||||
max = 1024;
|
||||
al = (char *) kmalloc (max);
|
||||
res = -1;
|
||||
if (al)
|
||||
{
|
||||
char *cp;
|
||||
BPTR old_cis, old_cos, old_ces;
|
||||
BPTR dup_cis, dup_cos, dup_ces;
|
||||
void *old_trapdata, *old_trapcode;
|
||||
int old_flags;
|
||||
void *old_launch, *old_switch;
|
||||
struct file *f;
|
||||
|
||||
for (cp = al; *argv; )
|
||||
{
|
||||
char *newel = quote (*argv);
|
||||
int elsize = strlen (newel ? newel : *argv) + 2;
|
||||
KPRINTF (("arg [%s] quoted as [%s]\n", *argv, newel ? newel : *argv));
|
||||
|
||||
if (cp + elsize >= al + max)
|
||||
{
|
||||
char *nal;
|
||||
max <<= 1;
|
||||
nal = (char *) krealloc (al, max);
|
||||
if (! nal) break;
|
||||
cp = nal + (cp-al);
|
||||
al = nal;
|
||||
}
|
||||
|
||||
strcpy (cp, newel ? newel : *argv);
|
||||
cp += elsize - 2;
|
||||
*cp++ = ' ';
|
||||
*cp = 0;
|
||||
if (newel) kfree (newel);
|
||||
++argv;
|
||||
}
|
||||
|
||||
/* BCPL weirdness ... */
|
||||
*cp++ = '\n';
|
||||
*cp = 0;
|
||||
|
||||
KPRINTF (("BCPL cmd line = [%s]\n", al));
|
||||
|
||||
/* problem with RunCommand: the allocated signal mask is not reset
|
||||
for the new process, thus if several RunCommands are nested, a
|
||||
late started process might run out of signals. This behavior makes
|
||||
no sense, since the starting process is *suspended* while the `child'
|
||||
is running, thus it doesn't need its signals in the meantime ! */
|
||||
|
||||
oldsigalloc = me->pr_Task.tc_SigAlloc & 0xffff0000; /* hacky...*/
|
||||
me->pr_Task.tc_SigAlloc &= 0xffff;
|
||||
|
||||
/* cleanup as much of ixemul.library as possible, so that the started
|
||||
process can take over */
|
||||
old_flags = me->pr_Task.tc_Flags;
|
||||
me->pr_Task.tc_Flags = u.u_otask_flags;
|
||||
old_launch = me->pr_Task.tc_Launch;
|
||||
me->pr_Task.tc_Launch = u.u_olaunch; /* restoring this disables our signals */
|
||||
old_switch = me->pr_Task.tc_Switch;
|
||||
me->pr_Task.tc_Switch = u.u_oswitch;
|
||||
RemIntServer (INTB_VERTB, & u.u_itimerint);
|
||||
Disable();
|
||||
ixremove(&timer_task_list, &u.u_user_node);
|
||||
Enable();
|
||||
|
||||
/* limited support (part 2 ;-)) for I/O redirection on old programs
|
||||
If we're redirecting to a plain file, don't go thru a IXPIPE,
|
||||
temporarily use our DOS files in that case. Any other file type
|
||||
is routed thru an IXPIPE though. */
|
||||
|
||||
f = u.u_ofile[0];
|
||||
old_cis = dup_cis = 0;
|
||||
|
||||
/* I do wish I knew why pty's need to go though ixpipe:. But if I don't
|
||||
do this, the output simply disappears :-( */
|
||||
|
||||
if (f && f->f_type == DTYPE_FILE && memcmp(f->f_name, "/fifo/pty", 9))
|
||||
{
|
||||
old_cis = SelectInput (CTOBPTR (f->f_fh));
|
||||
readargs_kludge (CTOBPTR (f->f_fh));
|
||||
}
|
||||
else if (!f)
|
||||
{
|
||||
int fd = syscall(SYS_open, "/dev/null", 0);
|
||||
|
||||
dup_cis = dup2_BPTR (fd);
|
||||
syscall(SYS_close, fd);
|
||||
}
|
||||
else
|
||||
dup_cis = dup2_BPTR (0);
|
||||
if (dup_cis)
|
||||
{
|
||||
old_cis = SelectInput (dup_cis);
|
||||
readargs_kludge (dup_cis);
|
||||
}
|
||||
|
||||
f = u.u_ofile[1];
|
||||
old_cos = dup_cos = 0;
|
||||
if (f && f->f_type == DTYPE_FILE && memcmp(f->f_name, "/fifo/pty", 9))
|
||||
{
|
||||
old_cos = SelectOutput (CTOBPTR (f->f_fh));
|
||||
}
|
||||
else if (!f)
|
||||
{
|
||||
int fd = syscall(SYS_open, "/dev/null", 1);
|
||||
|
||||
dup_cos = dup2_BPTR (fd);
|
||||
syscall(SYS_close, fd);
|
||||
}
|
||||
else
|
||||
dup_cos = dup2_BPTR (1);
|
||||
if (dup_cos)
|
||||
old_cos = SelectOutput (dup_cos);
|
||||
|
||||
old_ces = me->pr_CES;
|
||||
dup_ces = 0;
|
||||
f = u.u_ofile[2];
|
||||
if (f && f->f_type == DTYPE_FILE && memcmp(f->f_name, "/fifo/pty", 9))
|
||||
{
|
||||
me->pr_CES = CTOBPTR (f->f_fh);
|
||||
}
|
||||
else if (!f)
|
||||
{
|
||||
int fd = syscall(SYS_open, "/dev/null", 2);
|
||||
|
||||
dup_ces = dup2_BPTR (fd);
|
||||
syscall(SYS_close, fd);
|
||||
}
|
||||
else
|
||||
dup_ces = dup2_BPTR (2);
|
||||
me->pr_CES = dup_ces ? : old_ces;
|
||||
|
||||
/* BEWARE that after this reset no library functions can be
|
||||
called any longer until the moment where trapdata is
|
||||
reinstalled !! */
|
||||
|
||||
Forbid();
|
||||
ixaddtail(&ixemulbase->ix_detached_processes, &u.u_detached_node);
|
||||
#ifndef NOTRAP
|
||||
old_trapcode = me->pr_Task.tc_TrapCode;
|
||||
me->pr_Task.tc_TrapCode = u.u_otrap_code;
|
||||
#endif
|
||||
old_trapdata = getuser(me);
|
||||
getuser(me) = 0;
|
||||
Permit();
|
||||
|
||||
{
|
||||
struct CommandLineInterface *CLI = BTOCPTR (me->pr_CLI);
|
||||
u_int stack_size = CLI ? CLI->cli_DefaultStack * 4 : me->pr_StackSize;
|
||||
|
||||
/* Note: The use of RunCommand() here means, that we *waste* the
|
||||
entire stack space allocated for this process! If someone
|
||||
comes up with a clever trick (probably involving StackSwap ())
|
||||
where the stack of this process can be freed before calling
|
||||
RunCommand (), lots of users with memory problems would be
|
||||
thankful! */
|
||||
res = RunCommand (CTOBPTR (code) - 1, stack_size, al, cp - al);
|
||||
}
|
||||
/* reinstall enough of ixemul to be able to finish cleanly
|
||||
(the recent addition of an ix_sleep() at the end of a vfork'd
|
||||
process makes it necessary to reinstall the signalling facilities!) */
|
||||
Forbid();
|
||||
getuser(me) = old_trapdata;
|
||||
#ifndef NOTRAP
|
||||
me->pr_Task.tc_TrapCode = old_trapcode;
|
||||
#endif
|
||||
ixremove(&ixemulbase->ix_detached_processes, &u.u_detached_node);
|
||||
Permit();
|
||||
|
||||
/* have to do this, or ix_close() is not able to RemoveIntServer .. */
|
||||
AddIntServer (INTB_VERTB, & u.u_itimerint);
|
||||
Disable();
|
||||
ixaddhead(&timer_task_list, &u.u_user_node);
|
||||
Enable();
|
||||
me->pr_Task.tc_Launch = old_launch;
|
||||
me->pr_Task.tc_Switch = old_switch;
|
||||
me->pr_Task.tc_Flags = old_flags;
|
||||
|
||||
/* Some programs can set ixemul Signals. This can happen because
|
||||
ixemul resets the allocated signal mask in the Task structure.
|
||||
Make very sure they're off, or Enforcer hits will be the result
|
||||
because the 'deathmessage-handshake' returns too early. */
|
||||
SetSignal(0, ~0);
|
||||
|
||||
kfree (al);
|
||||
|
||||
if (old_cis)
|
||||
SelectInput (old_cis);
|
||||
if (old_cos)
|
||||
Flush (SelectOutput (old_cos));
|
||||
me->pr_CES = old_ces;
|
||||
|
||||
if (dup_cis)
|
||||
Close (dup_cis);
|
||||
if (dup_cos)
|
||||
Close (dup_cos);
|
||||
if (dup_ces)
|
||||
Close (dup_ces);
|
||||
|
||||
me->pr_Task.tc_SigAlloc |= oldsigalloc;
|
||||
}
|
||||
|
||||
u.p_xstat = W_EXITCODE(res, 0);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* try to obtain a DOS filehandle on the specified descriptor. This only
|
||||
works, if the user has mounted IXPIPE: */
|
||||
BPTR
|
||||
dup2_BPTR (int fd)
|
||||
{
|
||||
long id;
|
||||
char name[20];
|
||||
|
||||
id = syscall(SYS_fcntl, fd, F_EXTERNALIZE, 0);
|
||||
if (id >= 0)
|
||||
{
|
||||
sprintf (name, "IXPIPE:%x", (unsigned int)id);
|
||||
/* 0x4242 is a magic packet understood by IXPIPE: to F_INTERNALIZE id */
|
||||
return Open (name, 0x4242);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//* the mysteries of DOS seem to never want to take an end... */
|
||||
void
|
||||
readargs_kludge (BPTR bp)
|
||||
{
|
||||
int ch;
|
||||
static const int EOS_CHAR = -1;
|
||||
|
||||
#if 0
|
||||
/* the autodocs say this bug is fixed after v37, well, perhaps that was a
|
||||
very deep wish, nevertheless unheard by dos...
|
||||
Without this kludge, you have to actually press return if stdin is not
|
||||
redirected...
|
||||
Thanks mbs: without your shell code I would never have guessed that
|
||||
something that weird could be possible....
|
||||
*/
|
||||
if (ix.ix_dos_base->lib_Version <= 37)
|
||||
#endif
|
||||
{
|
||||
ch = UnGetC (bp, EOS_CHAR) ? 0 : '\n';
|
||||
while ((ch != '\n') && (ch != EOS_CHAR))
|
||||
ch = FGetC (bp);
|
||||
Flush (bp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
quote (char *orig)
|
||||
{
|
||||
int i;
|
||||
char *new, *cp;
|
||||
|
||||
i = strlen (orig);
|
||||
|
||||
if (strpbrk (orig, "\"\'\\ \t\n"))
|
||||
{
|
||||
/* worst case, each character needs quoting plus starting and ending " */
|
||||
new = (char *) kmalloc (i * 2 + 3);
|
||||
if (! new) return 0;
|
||||
|
||||
cp = new;
|
||||
*cp++ = '"';
|
||||
while (*orig)
|
||||
{
|
||||
if (index ("\"\\", *orig))
|
||||
*cp++ = '\\';
|
||||
*cp++ = *orig++;
|
||||
}
|
||||
*cp++ = '"';
|
||||
*cp = 0;
|
||||
|
||||
return new;
|
||||
}
|
||||
else
|
||||
return 0; /* means `just use the original string' */
|
||||
}
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 1987 Regents of the University of California.
|
||||
* 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)getenv.c 5.8 (Berkeley) 2/23/91";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#define _KERNEL
|
||||
#include "ixemul.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* _findenv --
|
||||
* Returns pointer to value associated with name, if any, else NULL.
|
||||
* Sets offset to be the offset of the name/value combination in the
|
||||
* environmental array, for use by setenv(3) and unsetenv(3).
|
||||
* Explicitly removes '=' in argument name.
|
||||
*
|
||||
* This routine *should* be a static; don't use it.
|
||||
*/
|
||||
char *
|
||||
_findenv(char **env, const char *name, int *offset)
|
||||
{
|
||||
int len;
|
||||
char **P;
|
||||
const char *C;
|
||||
|
||||
for (C = name, len = 0; *C && *C != '='; ++C, ++len);
|
||||
for (P = env; *P; ++P)
|
||||
if (!strncmp(*P, name, len))
|
||||
if (*(C = *P + len) == '=') {
|
||||
*offset = P - env;
|
||||
return (char *)++C;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* getenv --
|
||||
* Returns ptr to value associated with name, if any, else NULL.
|
||||
*/
|
||||
char progdir[]="./";
|
||||
char *
|
||||
getenv(const char *name)
|
||||
{
|
||||
usetup;
|
||||
int offset;
|
||||
int ret;
|
||||
if (u.u_parent_userdata)u_ptr = u.u_parent_userdata;
|
||||
char name2[256];
|
||||
char * r = _findenv(*u.u_environ, name, &offset);
|
||||
|
||||
strcpy (&name2[0],"env:"); // code so easy can see in snoopdos what env vars a ixemul program use.
|
||||
strncat (&name2[0],name,230);
|
||||
ret = Open(name2,MODE_OLDFILE);
|
||||
if (!r)if(!strcmp(name,"HOME"))return progdir;
|
||||
if (ret)Close(ret);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
/*-
|
||||
* Copyright (c) 1991 The Regents of the University of California.
|
||||
* 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)heapsort.c 5.1 (Berkeley) 6/4/91";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#define _KERNEL
|
||||
#include "ixemul.h"
|
||||
#include "kprintf.h"
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* Swap two areas of size number of bytes. Although qsort(3) permits random
|
||||
* blocks of memory to be sorted, sorting pointers is almost certainly the
|
||||
* common case (and, were it not, could easily be made so). Regardless, it
|
||||
* isn't worth optimizing; the SWAP's get sped up by the cache, and pointer
|
||||
* arithmetic gets lost in the time required for comparison function calls.
|
||||
*/
|
||||
#define SWAP(a, b) { \
|
||||
cnt = size; \
|
||||
do { \
|
||||
ch = *a; \
|
||||
*a++ = *b; \
|
||||
*b++ = ch; \
|
||||
} while (--cnt); \
|
||||
}
|
||||
|
||||
/*
|
||||
* Build the list into a heap, where a heap is defined such that for
|
||||
* the records K1 ... KN, Kj/2 >= Kj for 1 <= j/2 <= j <= N.
|
||||
*
|
||||
* There two cases. If j == nmemb, select largest of Ki and Kj. If
|
||||
* j < nmemb, select largest of Ki, Kj and Kj+1.
|
||||
*
|
||||
* The initial value depends on if we're building the initial heap or
|
||||
* reconstructing it after saving a value.
|
||||
*/
|
||||
#define HEAP(initval) { \
|
||||
for (i = initval; (j = i * 2) <= nmemb; i = j) { \
|
||||
p = (char *)bot + j * size; \
|
||||
if (j < nmemb && compar(p, p + size) < 0) { \
|
||||
p += size; \
|
||||
++j; \
|
||||
} \
|
||||
t = (char *)bot + i * size; \
|
||||
if (compar(p, t) <= 0) \
|
||||
break; \
|
||||
SWAP(t, p); \
|
||||
} \
|
||||
}
|
||||
|
||||
/*
|
||||
* Heapsort -- Knuth, Vol. 3, page 145. Runs in O (N lg N), both average
|
||||
* and worst. While heapsort is faster than the worst case of quicksort,
|
||||
* the BSD quicksort does median selection so that the chance of finding
|
||||
* a data set that will trigger the worst case is nonexistent. Heapsort's
|
||||
* only advantage over quicksort is that it requires no additional memory.
|
||||
*/
|
||||
int heapsort(bot, nmemb, size, compar)
|
||||
register void *bot;
|
||||
register size_t nmemb, size;
|
||||
int (*compar) __P((const void *, const void *));
|
||||
{
|
||||
register char *p, *t, ch;
|
||||
register int cnt, i, j, l;
|
||||
usetup;
|
||||
|
||||
if (nmemb <= 1)
|
||||
return (0);
|
||||
if (!size) {
|
||||
errno = EINVAL;
|
||||
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
|
||||
return (-1);
|
||||
}
|
||||
/*
|
||||
* Items are numbered from 1 to nmemb, so offset from size bytes
|
||||
* below the starting address.
|
||||
*/
|
||||
bot -= size;
|
||||
|
||||
for (l = nmemb / 2 + 1; --l;)
|
||||
HEAP(l);
|
||||
|
||||
/*
|
||||
* For each element of the heap, save the largest element into its
|
||||
* final slot, then recreate the heap.
|
||||
*/
|
||||
while (nmemb > 1) {
|
||||
p = (char *)bot + size;
|
||||
t = (char *)bot + nmemb * size;
|
||||
SWAP(p, t);
|
||||
--nmemb;
|
||||
HEAP(1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that: (1) source distributions retain this entire copyright
|
||||
* notice and comment, and (2) distributions including binaries display
|
||||
* the following acknowledgement: ``This product includes software
|
||||
* developed by the University of California, Berkeley and its contributors''
|
||||
* in the documentation or other materials provided with the distribution
|
||||
* and in all advertising materials mentioning features or use of this
|
||||
* software. Neither the name of the University nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)labs.c 5.2 (Berkeley) 5/17/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#define _KERNEL
|
||||
#include "ixemul.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
long
|
||||
labs(long j)
|
||||
{
|
||||
return(j < 0 ? -j : j);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 1990 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Chris Torek.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that: (1) source distributions retain this entire copyright
|
||||
* notice and comment, and (2) distributions including binaries display
|
||||
* the following acknowledgement: ``This product includes software
|
||||
* developed by the University of California, Berkeley and its contributors''
|
||||
* in the documentation or other materials provided with the distribution
|
||||
* and in all advertising materials mentioning features or use of this
|
||||
* software. Neither the name of the University nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)ldiv.c 5.1 (Berkeley) 5/16/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#define _KERNEL
|
||||
#include "ixemul.h"
|
||||
|
||||
#include <stdlib.h> /* ldiv_t */
|
||||
|
||||
/*
|
||||
* I AM NOT SURE THIS IS COMPLETELY PORTABLE
|
||||
* (or that it is even right)
|
||||
*/
|
||||
ldiv_t /* const */
|
||||
ldiv(long num, long denom)
|
||||
{
|
||||
ldiv_t r;
|
||||
|
||||
/* see div.c for comments */
|
||||
|
||||
if (num > 0 && denom < 0) {
|
||||
num = -num;
|
||||
denom = -denom;
|
||||
}
|
||||
r.quot = num / denom;
|
||||
r.rem = num % denom;
|
||||
if (num < 0 && denom > 0) {
|
||||
if (r.rem > 0) {
|
||||
r.quot++;
|
||||
r.rem -= denom;
|
||||
}
|
||||
}
|
||||
return (r);
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (c) 1991 The Regents of the University of California.
|
||||
* 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)multibyte.c 5.1 (Berkeley) 2/18/91";*/
|
||||
static char *rcsid = "$Id: multibyte.c,v 1.2 2005/08/26 18:33:55 emm Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* Stub multibyte character functions.
|
||||
* This cheezy implementation is fixed to the native single-byte
|
||||
* character set.
|
||||
*/
|
||||
|
||||
int
|
||||
__obsolete_mblen(s, n)
|
||||
const char *s;
|
||||
size_t n;
|
||||
{
|
||||
if (s == NULL || *s == '\0')
|
||||
return 0;
|
||||
if (n == 0)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
__obsolete_mbtowc(pwc, s, n)
|
||||
wchar_t *pwc;
|
||||
const char *s;
|
||||
size_t n;
|
||||
{
|
||||
if (s == NULL)
|
||||
return 0;
|
||||
if (n == 0)
|
||||
return -1;
|
||||
if (pwc)
|
||||
*pwc = (wchar_t) *s;
|
||||
return (*s != '\0');
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
#ifdef __STDC__
|
||||
__obsolete_wctomb(char *s, wchar_t wchar)
|
||||
#else
|
||||
__obsolete_wctomb(s, wchar)
|
||||
char *s;
|
||||
wchar_t wchar;
|
||||
#endif
|
||||
{
|
||||
if (s == NULL)
|
||||
return 0;
|
||||
|
||||
*s = (char) wchar;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
size_t
|
||||
__obsolete_mbstowcs(pwcs, s, n)
|
||||
wchar_t *pwcs;
|
||||
const char *s;
|
||||
size_t n;
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
if (n != 0) {
|
||||
do {
|
||||
if ((*pwcs++ = (wchar_t) *s++) == 0)
|
||||
break;
|
||||
count++;
|
||||
} while (--n != 0);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
size_t
|
||||
__obsolete_wcstombs(s, pwcs, n)
|
||||
char *s;
|
||||
const wchar_t *pwcs;
|
||||
size_t n;
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
if (n != 0) {
|
||||
do {
|
||||
if ((*s++ = (char) *pwcs++) == 0)
|
||||
break;
|
||||
count++;
|
||||
} while (--n != 0);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*-
|
||||
* Copyright (c) 1988 The Regents of the University of California.
|
||||
* 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)putenv.c 5.4 (Berkeley) 2/23/91";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#define _KERNEL
|
||||
#include "ixemul.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
putenv(str)
|
||||
const char *str;
|
||||
{
|
||||
register char *p, *equal;
|
||||
int rval;
|
||||
|
||||
if (!(p = strdup(str)))
|
||||
return(1);
|
||||
if (!(equal = index(p, '='))) {
|
||||
(void)free(p);
|
||||
return(1);
|
||||
}
|
||||
*equal = '\0';
|
||||
rval = setenv(p, equal + 1, 1);
|
||||
(void)free(p);
|
||||
return(rval);
|
||||
}
|
||||
+281
@@ -0,0 +1,281 @@
|
||||
/*-
|
||||
* Copyright (c) 1980, 1983 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that: (1) source distributions retain this entire copyright
|
||||
* notice and comment, and (2) distributions including binaries display
|
||||
* the following acknowledgement: ``This product includes software
|
||||
* developed by the University of California, Berkeley and its contributors''
|
||||
* in the documentation or other materials provided with the distribution
|
||||
* and in all advertising materials mentioning features or use of this
|
||||
* software. Neither the name of the University nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
/* Modified by PerOla Valfridsson 910215 */
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)qsort.c 5.7 (Berkeley) 5/17/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#define _KERNEL
|
||||
#include "ixemul.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef NATIVE_MORPHOS
|
||||
#define qsort _qsort
|
||||
#define FLAGPRM ,int is68k
|
||||
#define FLAGARG , is68k
|
||||
|
||||
/* code for:
|
||||
movem.l d0-d1,-(sp)
|
||||
jsr (a0)
|
||||
addq.l #8,sp
|
||||
rts
|
||||
*/
|
||||
static const UWORD cmp_gate[] = {
|
||||
0x48E7,0xC000,0x4E90,0x508F,0x4E75
|
||||
};
|
||||
|
||||
static inline int my_cmp(const void *p, const void *q, int (*qcmp)(), int is68k) {
|
||||
if (is68k) {
|
||||
REG_D0 = (ULONG)p;
|
||||
REG_D1 = (ULONG)q;
|
||||
REG_A0 = (ULONG)qcmp;
|
||||
//REG_A4 = REG_A4;
|
||||
return MyEmulHandle->EmulCallDirect68k((APTR)cmp_gate);
|
||||
} else {
|
||||
return qcmp(p, q);
|
||||
}
|
||||
}
|
||||
#define CMP(x, y) my_cmp(x, y, qcmp, is68k)
|
||||
|
||||
#else
|
||||
#define FLAGPRM
|
||||
#define FLAGARG
|
||||
#define CMP(x, y) qcmp(x, y)
|
||||
#endif
|
||||
|
||||
static void qst(char *base, char *max, int (*qcmp)(), int qsz FLAGPRM);
|
||||
|
||||
/*
|
||||
* qsort.c:
|
||||
* Our own version of the system qsort routine which is faster by an average
|
||||
* of 25%, with lows and highs of 10% and 50%.
|
||||
* The THRESHold below is the insertion sort threshold, and has been adjusted
|
||||
* for records of size 48 bytes.
|
||||
* The MTHREShold is where we stop finding a better median.
|
||||
*/
|
||||
|
||||
#define THRESH 4 /* threshold for insertion */
|
||||
#define MTHRESH 6 /* threshold for median */
|
||||
|
||||
/*
|
||||
* qsort:
|
||||
* First, set up some global parameters for qst to share. Then, quicksort
|
||||
* with qst(), and then a cleanup insertion sort ourselves. Sound simple?
|
||||
* It's not...
|
||||
*/
|
||||
|
||||
void
|
||||
qsort(void *base, size_t n, size_t qsz, int (*qcmp)() FLAGPRM)
|
||||
{
|
||||
register char c, *i, *j, *lo, *hi;
|
||||
char *min, *max;
|
||||
|
||||
if (n <= 1)
|
||||
return;
|
||||
|
||||
max = base + n * qsz;
|
||||
if (n >= THRESH) {
|
||||
qst(base, max, qcmp, qsz FLAGARG);
|
||||
hi = base + qsz * THRESH;
|
||||
} else {
|
||||
hi = max;
|
||||
}
|
||||
/*
|
||||
* First put smallest element, which must be in the first THRESH, in
|
||||
* the first position as a sentinel. This is done just by searching
|
||||
* the first THRESH elements (or the first n if n < THRESH), finding
|
||||
* the min, and swapping it into the first position.
|
||||
*/
|
||||
for (j = lo = base; (lo += qsz) < hi; )
|
||||
if (CMP(j, lo) > 0)
|
||||
j = lo;
|
||||
if (j != base) {
|
||||
/* swap j into place */
|
||||
for (i = base, hi = base + qsz; i < hi; ) {
|
||||
c = *j;
|
||||
*j++ = *i;
|
||||
*i++ = c;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* With our sentinel in place, we now run the following hyper-fast
|
||||
* insertion sort. For each remaining element, min, from [1] to [n-1],
|
||||
* set hi to the index of the element AFTER which this one goes.
|
||||
* Then, do the standard insertion sort shift on a character at a time
|
||||
* basis for each element in the frob.
|
||||
*/
|
||||
for (min = base; (hi = (min += qsz)) < max; ) {
|
||||
while (CMP((hi -= qsz), min) > 0)
|
||||
/* void */;
|
||||
if ((hi += qsz) != min) {
|
||||
for (lo = (min + qsz); --lo >= min; ) {
|
||||
c = *lo;
|
||||
for (i = j = lo; (j -= qsz) >= hi; i = j)
|
||||
*i = *j;
|
||||
*i = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* qst:
|
||||
* Do a quicksort
|
||||
* First, find the median element, and put that one in the first place as the
|
||||
* discriminator. (This "median" is just the median of the first, last and
|
||||
* middle elements). (Using this median instead of the first element is a big
|
||||
* win). Then, the usual partitioning/swapping, followed by moving the
|
||||
* discriminator into the right place. Then, figure out the sizes of the two
|
||||
* partions, do the smaller one recursively and the larger one via a repeat of
|
||||
* this code. Stopping when there are less than THRESH elements in a partition
|
||||
* and cleaning up with an insertion sort (in our caller) is a huge win.
|
||||
* All data swaps are done in-line, which is space-losing but time-saving.
|
||||
* (And there are only three places where this is done).
|
||||
*/
|
||||
|
||||
static void qst(char *base, char *max, int (*qcmp)(), int qsz FLAGPRM)
|
||||
{
|
||||
register char c, *i, *j, *jj;
|
||||
register int ii;
|
||||
char *mid, *tmp;
|
||||
int lo, hi;
|
||||
|
||||
/*
|
||||
* At the top here, lo is the number of characters of elements in the
|
||||
* current partition. (Which should be max - base).
|
||||
* Find the median of the first, last, and middle element and make
|
||||
* that the middle element. Set j to largest of first and middle.
|
||||
* If max is larger than that guy, then it's that guy, else compare
|
||||
* max with loser of first and take larger. Things are set up to
|
||||
* prefer the middle, then the first in case of ties.
|
||||
*/
|
||||
lo = max - base; /* number of elements as chars */
|
||||
do {
|
||||
mid = i = base + qsz * ((lo / qsz) >> 1);
|
||||
if (lo >= qsz * MTHRESH) {
|
||||
j = (CMP((jj = base), i) > 0 ? jj : i);
|
||||
if (CMP(j, (tmp = max - qsz)) > 0) {
|
||||
/* switch to first loser */
|
||||
j = (j == jj ? i : jj);
|
||||
if (CMP(j, tmp) < 0)
|
||||
j = tmp;
|
||||
}
|
||||
if (j != i) {
|
||||
ii = qsz;
|
||||
do {
|
||||
c = *i;
|
||||
*i++ = *j;
|
||||
*j++ = c;
|
||||
} while (--ii);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Semi-standard quicksort partitioning/swapping
|
||||
*/
|
||||
for (i = base, j = max - qsz; ; ) {
|
||||
while (i < mid && CMP(i, mid) <= 0)
|
||||
i += qsz;
|
||||
while (j > mid) {
|
||||
if (CMP(mid, j) <= 0) {
|
||||
j -= qsz;
|
||||
continue;
|
||||
}
|
||||
tmp = i + qsz; /* value of i after swap */
|
||||
if (i == mid) {
|
||||
/* j <-> mid, new mid is j */
|
||||
mid = jj = j;
|
||||
} else {
|
||||
/* i <-> j */
|
||||
jj = j;
|
||||
j -= qsz;
|
||||
}
|
||||
goto swap;
|
||||
}
|
||||
if (i == mid) {
|
||||
break;
|
||||
} else {
|
||||
/* i <-> mid, new mid is i */
|
||||
jj = mid;
|
||||
tmp = mid = i; /* value of i after swap */
|
||||
j -= qsz;
|
||||
}
|
||||
swap:
|
||||
ii = qsz;
|
||||
do {
|
||||
c = *i;
|
||||
*i++ = *jj;
|
||||
*jj++ = c;
|
||||
} while (--ii);
|
||||
i = tmp;
|
||||
}
|
||||
/*
|
||||
* Look at sizes of the two partitions, do the smaller
|
||||
* one first by recursion, then do the larger one by
|
||||
* making sure lo is its size, base and max are update
|
||||
* correctly, and branching back. But only repeat
|
||||
* (recursively or by branching) if the partition is
|
||||
* of at least size THRESH.
|
||||
*/
|
||||
i = (j = mid) + qsz;
|
||||
if ((lo = j - base) <= (hi = max - i)) {
|
||||
if (lo >= qsz * THRESH)
|
||||
qst(base, j, qcmp, qsz FLAGARG);
|
||||
base = i;
|
||||
lo = hi;
|
||||
} else {
|
||||
if (hi >= qsz * THRESH)
|
||||
qst(i, max, qcmp, qsz FLAGARG);
|
||||
max = j;
|
||||
}
|
||||
} while (lo >= qsz * THRESH);
|
||||
}
|
||||
|
||||
#ifdef NATIVE_MORPHOS
|
||||
#undef qsort
|
||||
#undef CMP
|
||||
#undef FLAGPRM
|
||||
#undef FLAGARG
|
||||
|
||||
void
|
||||
qsort(void *base, size_t n, size_t qsz, int (*qcmp)())
|
||||
{
|
||||
_qsort(base, n, qsz, qcmp, 0);
|
||||
}
|
||||
|
||||
void
|
||||
_trampoline_qsort(void)
|
||||
{
|
||||
int *p = (int *)REG_A7;
|
||||
void *base = (void *)p[1];
|
||||
size_t n = p[2];
|
||||
size_t qsz = p[3];
|
||||
int (*qcmp)() = (int(*)())p[4];
|
||||
|
||||
_qsort(base, n, qsz, qcmp, 1);
|
||||
}
|
||||
|
||||
const struct EmulLibEntry _gate_qsort = {
|
||||
TRAP_LIBNR, 0, (void(*)())_trampoline_qsort
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,281 @@
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)radixsort.c 5.7 (Berkeley) 2/23/91";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* __rspartition is the cutoff point for a further partitioning instead
|
||||
* of a shellsort. If it changes check __rsshell_increments. Both of
|
||||
* these are exported, as the best values are data dependent.
|
||||
*/
|
||||
#define NPARTITION 40
|
||||
int __rspartition = NPARTITION;
|
||||
int __rsshell_increments[] = { 4, 1, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
/*
|
||||
* Stackp points to context structures, where each structure schedules a
|
||||
* partitioning. Radixsort exits when the stack is empty.
|
||||
*
|
||||
* If the buckets are placed on the stack randomly, the worst case is when
|
||||
* all the buckets but one contain (npartitions + 1) elements and the bucket
|
||||
* pushed on the stack last contains the rest of the elements. In this case,
|
||||
* stack growth is bounded by:
|
||||
*
|
||||
* limit = (nelements / (npartitions + 1)) - 1;
|
||||
*
|
||||
* This is a very large number, 52,377,648 for the maximum 32-bit signed int.
|
||||
*
|
||||
* By forcing the largest bucket to be pushed on the stack first, the worst
|
||||
* case is when all but two buckets each contain (npartitions + 1) elements,
|
||||
* with the remaining elements split equally between the first and last
|
||||
* buckets pushed on the stack. In this case, stack growth is bounded when:
|
||||
*
|
||||
* for (partition_cnt = 0; nelements > npartitions; ++partition_cnt)
|
||||
* nelements =
|
||||
* (nelements - (npartitions + 1) * (nbuckets - 2)) / 2;
|
||||
* The bound is:
|
||||
*
|
||||
* limit = partition_cnt * (nbuckets - 1);
|
||||
*
|
||||
* This is a much smaller number, 4590 for the maximum 32-bit signed int.
|
||||
*/
|
||||
#define NBUCKETS (UCHAR_MAX + 1)
|
||||
|
||||
typedef struct _stack {
|
||||
const u_char **bot;
|
||||
int indx, nmemb;
|
||||
} CONTEXT;
|
||||
|
||||
#define STACKPUSH { \
|
||||
stackp->bot = p; \
|
||||
stackp->nmemb = nmemb; \
|
||||
stackp->indx = indx; \
|
||||
++stackp; \
|
||||
}
|
||||
#define STACKPOP { \
|
||||
if (stackp == stack) \
|
||||
break; \
|
||||
--stackp; \
|
||||
bot = stackp->bot; \
|
||||
nmemb = stackp->nmemb; \
|
||||
indx = stackp->indx; \
|
||||
}
|
||||
|
||||
/*
|
||||
* A variant of MSD radix sorting; see Knuth Vol. 3, page 177, and 5.2.5,
|
||||
* Ex. 10 and 12. Also, "Three Partition Refinement Algorithms, Paige
|
||||
* and Tarjan, SIAM J. Comput. Vol. 16, No. 6, December 1987.
|
||||
*
|
||||
* This uses a simple sort as soon as a bucket crosses a cutoff point,
|
||||
* rather than sorting the entire list after partitioning is finished.
|
||||
* This should be an advantage.
|
||||
*
|
||||
* This is pure MSD instead of LSD of some number of MSD, switching to
|
||||
* the simple sort as soon as possible. Takes linear time relative to
|
||||
* the number of bytes in the strings.
|
||||
*/
|
||||
int radixsort(const unsigned char **l1, int nmemb, const unsigned char *tab,
|
||||
unsigned endbyte)
|
||||
{
|
||||
register int i, indx, t1, t2;
|
||||
register const u_char **l2;
|
||||
register const u_char **p;
|
||||
register const u_char **bot;
|
||||
register const u_char *tr;
|
||||
CONTEXT *stack, *stackp;
|
||||
int c[NBUCKETS + 1], max;
|
||||
u_char ltab[NBUCKETS];
|
||||
static void shellsort();
|
||||
|
||||
if (nmemb <= 1)
|
||||
return(0);
|
||||
|
||||
/*
|
||||
* T1 is the constant part of the equation, the number of elements
|
||||
* represented on the stack between the top and bottom entries.
|
||||
* It doesn't get rounded as the divide by 2 rounds down (correct
|
||||
* for a value being subtracted). T2, the nelem value, has to be
|
||||
* rounded up before each divide because we want an upper bound;
|
||||
* this could overflow if nmemb is the maximum int.
|
||||
*/
|
||||
t1 = ((__rspartition + 1) * (NBUCKETS - 2)) >> 1;
|
||||
for (i = 0, t2 = nmemb; t2 > __rspartition; i += NBUCKETS - 1)
|
||||
t2 = ((t2 + 1) >> 1) - t1;
|
||||
if (i) {
|
||||
if (!(stack = stackp = (CONTEXT *)malloc(i * sizeof(CONTEXT))))
|
||||
return(-1);
|
||||
} else
|
||||
stack = stackp = NULL;
|
||||
|
||||
/*
|
||||
* There are two arrays, one provided by the user (l1), and the
|
||||
* temporary one (l2). The data is sorted to the temporary stack,
|
||||
* and then copied back. The speedup of using index to determine
|
||||
* which stack the data is on and simply swapping stacks back and
|
||||
* forth, thus avoiding the copy every iteration, turns out to not
|
||||
* be any faster than the current implementation.
|
||||
*/
|
||||
if (!(l2 = (const u_char **)malloc(sizeof(u_char *) * nmemb)))
|
||||
return(-1);
|
||||
|
||||
/*
|
||||
* Tr references a table of sort weights; multiple entries may
|
||||
* map to the same weight; EOS char must have the lowest weight.
|
||||
*/
|
||||
if (tab)
|
||||
tr = tab;
|
||||
else {
|
||||
for (t1 = 0, t2 = endbyte; t1 < t2; ++t1)
|
||||
ltab[t1] = t1 + 1;
|
||||
ltab[t2] = 0;
|
||||
for (t1 = endbyte + 1; t1 < NBUCKETS; ++t1)
|
||||
ltab[t1] = t1;
|
||||
tr = ltab;
|
||||
}
|
||||
|
||||
/* First sort is entire stack */
|
||||
bot = l1;
|
||||
indx = 0;
|
||||
|
||||
for (;;) {
|
||||
/* Clear bucket count array */
|
||||
bzero((char *)c, sizeof(c));
|
||||
|
||||
/*
|
||||
* Compute number of items that sort to the same bucket
|
||||
* for this index.
|
||||
*/
|
||||
for (p = bot, i = nmemb; --i >= 0;)
|
||||
++c[tr[(*p++)[indx]]];
|
||||
|
||||
/*
|
||||
* Sum the number of characters into c, dividing the temp
|
||||
* stack into the right number of buckets for this bucket,
|
||||
* this index. C contains the cumulative total of keys
|
||||
* before and included in this bucket, and will later be
|
||||
* used as an index to the bucket. c[NBUCKETS] contains
|
||||
* the total number of elements, for determining how many
|
||||
* elements the last bucket contains. At the same time
|
||||
* find the largest bucket so it gets pushed first.
|
||||
*/
|
||||
for (i = max = t1 = 0, t2 = __rspartition; i <= NBUCKETS; ++i) {
|
||||
if (c[i] > t2) {
|
||||
t2 = c[i];
|
||||
max = i;
|
||||
}
|
||||
t1 = c[i] += t1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Partition the elements into buckets; c decrements through
|
||||
* the bucket, and ends up pointing to the first element of
|
||||
* the bucket.
|
||||
*/
|
||||
for (i = nmemb; --i >= 0;) {
|
||||
--p;
|
||||
l2[--c[tr[(*p)[indx]]]] = *p;
|
||||
}
|
||||
|
||||
/* Copy the partitioned elements back to user stack */
|
||||
bcopy(l2, bot, nmemb * sizeof(u_char *));
|
||||
|
||||
++indx;
|
||||
/*
|
||||
* Sort buckets as necessary; don't sort c[0], it's the
|
||||
* EOS character bucket, and nothing can follow EOS.
|
||||
*/
|
||||
for (i = max; i; --i) {
|
||||
if ((nmemb = c[i + 1] - (t1 = c[i])) < 2)
|
||||
continue;
|
||||
p = bot + t1;
|
||||
if (nmemb > __rspartition)
|
||||
STACKPUSH
|
||||
else
|
||||
shellsort(p, indx, nmemb, tr);
|
||||
}
|
||||
for (i = max + 1; i < NBUCKETS; ++i) {
|
||||
if ((nmemb = c[i + 1] - (t1 = c[i])) < 2)
|
||||
continue;
|
||||
p = bot + t1;
|
||||
if (nmemb > __rspartition)
|
||||
STACKPUSH
|
||||
else
|
||||
shellsort(p, indx, nmemb, tr);
|
||||
}
|
||||
/* Break out when stack is empty */
|
||||
STACKPOP
|
||||
}
|
||||
|
||||
free((char *)l2);
|
||||
free((char *)stack);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Shellsort (diminishing increment sort) from Data Structures and
|
||||
* Algorithms, Aho, Hopcraft and Ullman, 1983 Edition, page 290;
|
||||
* see also Knuth Vol. 3, page 84. The increments are selected from
|
||||
* formula (8), page 95. Roughly O(N^3/2).
|
||||
*/
|
||||
static void
|
||||
shellsort(p, indx, nmemb, tr)
|
||||
register u_char **p, *tr;
|
||||
register int indx, nmemb;
|
||||
{
|
||||
register u_char ch, *s1, *s2;
|
||||
register int incr, *incrp, t1, t2;
|
||||
|
||||
for (incrp = __rsshell_increments; (incr = *incrp++); )
|
||||
for (t1 = incr; t1 < nmemb; ++t1)
|
||||
for (t2 = t1 - incr; t2 >= 0;) {
|
||||
s1 = p[t2] + indx;
|
||||
s2 = p[t2 + incr] + indx;
|
||||
while ((ch = tr[*s1++]) == tr[*s2] && ch)
|
||||
++s2;
|
||||
if (ch > tr[*s2]) {
|
||||
s1 = p[t2];
|
||||
p[t2] = p[t2 + incr];
|
||||
p[t2 + incr] = s1;
|
||||
t2 -= incr;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that: (1) source distributions retain this entire copyright
|
||||
* notice and comment, and (2) distributions including binaries display
|
||||
* the following acknowledgement: ``This product includes software
|
||||
* developed by the University of California, Berkeley and its contributors''
|
||||
* in the documentation or other materials provided with the distribution
|
||||
* and in all advertising materials mentioning features or use of this
|
||||
* software. Neither the name of the University nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)rand.c 5.3 (Berkeley) 5/15/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#define _KERNEL
|
||||
#include "ixemul.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
int rand(void)
|
||||
{
|
||||
usetup;
|
||||
|
||||
return ((u.u_rand_next = u.u_rand_next * 1103515245 + 12345) % RAND_MAX);
|
||||
}
|
||||
|
||||
void srand(u_int seed)
|
||||
{
|
||||
usetup;
|
||||
|
||||
u.u_rand_next = seed;
|
||||
}
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 1987 Regents of the University of California.
|
||||
* 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)setenv.c 5.6 (Berkeley) 6/4/91";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#define _KERNEL
|
||||
#include "ixemul.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define environ (*u.u_environ)
|
||||
|
||||
/*
|
||||
* setenv --
|
||||
* Set the value of the environmental variable "name" to be
|
||||
* "value". If rewrite is set, replace any current value.
|
||||
*/
|
||||
int setenv(const char *name, const char *value, int rewrite)
|
||||
{
|
||||
usetup;
|
||||
register char *C;
|
||||
int l_value, offset;
|
||||
|
||||
if (*value == '=') /* no `=' in value */
|
||||
++value;
|
||||
l_value = strlen(value);
|
||||
if ((C = _findenv(environ, name, &offset))) { /* find if already exists */
|
||||
if (!rewrite)
|
||||
return (0);
|
||||
if (strlen(C) >= l_value) { /* old larger; copy over */
|
||||
while ((*C++ = *value++)) ;
|
||||
return (0);
|
||||
}
|
||||
} else { /* create new slot */
|
||||
register int cnt;
|
||||
register char **P;
|
||||
|
||||
for (P = environ, cnt = 0; *P; ++P, ++cnt);
|
||||
if (u.u_env_alloced) { /* just increase size */
|
||||
environ = (char **)realloc((char *)environ,
|
||||
(size_t)(sizeof(char *) * (cnt + 2)));
|
||||
if (!environ)
|
||||
return (-1);
|
||||
}
|
||||
else { /* get new space */
|
||||
u.u_env_alloced = 1; /* copy old entries into it */
|
||||
P = (char **)malloc((size_t)(sizeof(char *) * (cnt + 2)));
|
||||
if (!P)
|
||||
return (-1);
|
||||
bcopy(environ, P, cnt * sizeof(char *));
|
||||
environ = P;
|
||||
}
|
||||
environ[cnt + 1] = NULL;
|
||||
offset = cnt;
|
||||
}
|
||||
for (C = (char *)name; *C && *C != '='; ++C); /* no `=' in name */
|
||||
if (!(environ[offset] = /* name + `=' + value */
|
||||
malloc((size_t)((int)(C - name) + l_value + 2))))
|
||||
return (-1);
|
||||
for (C = environ[offset]; (*C = *name++) && *C != '='; ++C)
|
||||
;
|
||||
for (*C++ = '='; (*C++ = *value++); )
|
||||
;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* unsetenv(name) --
|
||||
* Delete environmental variable "name".
|
||||
*/
|
||||
void unsetenv(const char *name)
|
||||
{
|
||||
usetup;
|
||||
register char **P;
|
||||
int offset;
|
||||
|
||||
while (_findenv(environ, name, &offset)) /* if set multiple times */
|
||||
for (P = &environ[offset];; ++P)
|
||||
if (!(*P = *(P + 1)))
|
||||
break;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* This file is part of ixemul.library for the Amiga.
|
||||
* Copyright (C) 1991, 1992 Markus M. Wild
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#define _KERNEL
|
||||
#include "ixemul.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
int __obsolete_ssystem(char *argline)
|
||||
{
|
||||
ix_panic ("ssystem() is no longer supported. See the README document for more information. If you are using gcc, then replace gcc with gccv.");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* $Id: stdlib_null_pointer_check.h,v 1.3 2006/01/08 12:04:26 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
* Portable ISO 'C' (1994) runtime library for the Amiga computer
|
||||
* Copyright (c) 2002-2006 by Olaf Barthel <olsen (at) sourcery.han.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Neither the name of Olaf Barthel nor the names of contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
#ifndef _STDLIB_NULL_POINTER_CHECK_H
|
||||
#define _STDLIB_NULL_POINTER_CHECK_H
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/*
|
||||
* Uncomment this to build a library which checks pointer parameters against
|
||||
* NULL upon entry.
|
||||
*/
|
||||
/*#define CHECK_FOR_NULL_POINTERS*/
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#endif /* _STDLIB_NULL_POINTER_CHECK_H */
|
||||
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* $Id: stdlib_strtoll.c,v 1.6 2006/01/08 12:04:26 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
* Portable ISO 'C' (1994) runtime library for the Amiga computer
|
||||
* Copyright (c) 2002-2006 by Olaf Barthel <olsen (at) sourcery.han.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Neither the name of Olaf Barthel nor the names of contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
|
||||
*
|
||||
* move and modify for ixemul by Bernd Roesch
|
||||
*
|
||||
*/
|
||||
//#define _KERNEL
|
||||
#define USE_64_BIT_INTS
|
||||
#include "ixemul.h"
|
||||
#include "kprintf.h"
|
||||
#include <sys/errno.h>
|
||||
|
||||
#ifndef _STDLIB_NULL_POINTER_CHECK_H
|
||||
//#include "stdlib_null_pointer_check.h"
|
||||
#endif /* _STDLIB_NULL_POINTER_CHECK_H */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
|
||||
|
||||
#ifndef _STDLIB_HEADERS_H
|
||||
#include <stdlib.h>
|
||||
#endif /* _STDLIB_HEADERS_H */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#if defined(USE_64_BIT_INTS)
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
|
||||
|
||||
long long
|
||||
strtoll(const char *str, char **ptr, int base)
|
||||
{
|
||||
const char * stop = str;
|
||||
size_t num_digits_converted = 0;
|
||||
BOOL is_negative;
|
||||
long long result = 0;
|
||||
long long new_sum;
|
||||
long long sum;
|
||||
char c;
|
||||
|
||||
//ENTER();
|
||||
|
||||
//SHOWSTRING(str);
|
||||
//SHOWPOINTER(ptr);
|
||||
//SHOWVALUE(base);
|
||||
|
||||
//assert(str != NULL && base >= 0);
|
||||
|
||||
//#if defined(CHECK_FOR_NULL_POINTERS)
|
||||
{
|
||||
if(str == NULL)
|
||||
{
|
||||
SHOWMSG("invalid str parameter in func strtoll");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
//#endif /* CHECK_FOR_NULL_POINTERS */
|
||||
|
||||
if(base < 0)
|
||||
{
|
||||
SHOWMSG("invalid base parameter in func strtoll ");
|
||||
|
||||
//errno = ERANGE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Skip all leading blanks. */
|
||||
while((c = (*str)) != '\0')
|
||||
{
|
||||
if(NOT isspace(c))
|
||||
break;
|
||||
|
||||
str++;
|
||||
}
|
||||
|
||||
/* The first character may be a sign. */
|
||||
if(c == '-')
|
||||
{
|
||||
/* It's a negative number. */
|
||||
is_negative = TRUE;
|
||||
|
||||
str++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It's not going to be negative. */
|
||||
is_negative = FALSE;
|
||||
|
||||
/* But there may be a sign we will choose to
|
||||
ignore. */
|
||||
if(c == '+')
|
||||
str++;
|
||||
}
|
||||
|
||||
c = (*str);
|
||||
|
||||
/* There may be a leading '0x' to indicate that what
|
||||
follows is a hexadecimal number. */
|
||||
if(base == 0 || base == 16)
|
||||
{
|
||||
if((c == '0') && (str[1] == 'x' || str[1] == 'X'))
|
||||
{
|
||||
base = 16;
|
||||
|
||||
str += 2;
|
||||
|
||||
c = (*str);
|
||||
}
|
||||
}
|
||||
|
||||
/* If we still don't know what base to use and the
|
||||
next letter to follow is a zero then this is
|
||||
probably a number in octal notation. */
|
||||
if(base == 0)
|
||||
{
|
||||
if(c == '0')
|
||||
base = 8;
|
||||
else
|
||||
base = 10;
|
||||
}
|
||||
|
||||
sum = 0;
|
||||
|
||||
if(1 <= base && base <= 36)
|
||||
{
|
||||
while(c != '\0')
|
||||
{
|
||||
if('0' <= c && c <= '9')
|
||||
c -= '0';
|
||||
else if ('a' <= c)
|
||||
c -= 'a' - 10;
|
||||
else if ('A' <= c)
|
||||
c -= 'A' - 10;
|
||||
else
|
||||
break;
|
||||
|
||||
/* Ignore invalid numbers. */
|
||||
if(c >= base)
|
||||
break;
|
||||
|
||||
new_sum = base * sum + c;
|
||||
if(new_sum < sum) /* overflow? */
|
||||
{
|
||||
//errno =ERANGE;
|
||||
SHOWMSG("Overflow in strtoll");
|
||||
if(is_negative)
|
||||
result = LONG_MIN;
|
||||
else
|
||||
result = LONG_MAX;
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
sum = new_sum;
|
||||
|
||||
str++;
|
||||
|
||||
c = (*str);
|
||||
|
||||
num_digits_converted++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Did we convert anything? */
|
||||
if(num_digits_converted == 0)
|
||||
goto out;
|
||||
|
||||
if(is_negative)
|
||||
result = (-sum);
|
||||
else
|
||||
result = sum;
|
||||
|
||||
stop = str;
|
||||
|
||||
out:
|
||||
|
||||
/* If desired, remember where we stopped reading the
|
||||
number from the buffer. */
|
||||
if(ptr != NULL)
|
||||
(*ptr) = (char *)stop;
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#endif /* USE_64_BIT_INTS */
|
||||
+2506
File diff suppressed because it is too large
Load Diff
+117
@@ -0,0 +1,117 @@
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that: (1) source distributions retain this entire copyright
|
||||
* notice and comment, and (2) distributions including binaries display
|
||||
* the following acknowledgement: ``This product includes software
|
||||
* developed by the University of California, Berkeley and its contributors''
|
||||
* in the documentation or other materials provided with the distribution
|
||||
* and in all advertising materials mentioning features or use of this
|
||||
* software. Neither the name of the University nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)strtol.c 5.3 (Berkeley) 5/17/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#define _KERNEL
|
||||
#include "ixemul.h"
|
||||
#include "kprintf.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
/*
|
||||
* Convert a string to a long integer.
|
||||
*
|
||||
* Ignores `locale' stuff. Assumes that the upper and lower case
|
||||
* alphabets and digits are each contiguous.
|
||||
*/
|
||||
long
|
||||
strtol(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
register const char *s = nptr;
|
||||
register unsigned long acc;
|
||||
register int c;
|
||||
register unsigned long cutoff;
|
||||
register int neg = 0, any, cutlim;
|
||||
usetup;
|
||||
|
||||
/*
|
||||
* Skip white space and pick up leading +/- sign if any.
|
||||
* If base is 0, allow 0x for hex and 0 for octal, else
|
||||
* assume decimal; if base is already 16, allow 0x.
|
||||
*/
|
||||
do {
|
||||
c = *s++;
|
||||
} while (isspace(c));
|
||||
if (c == '-') {
|
||||
neg = 1;
|
||||
c = *s++;
|
||||
} else if (c == '+')
|
||||
c = *s++;
|
||||
if ((base == 0 || base == 16) &&
|
||||
c == '0' && (*s == 'x' || *s == 'X')) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
if (base == 0)
|
||||
base = c == '0' ? 8 : 10;
|
||||
|
||||
/*
|
||||
* Compute the cutoff value between legal numbers and illegal
|
||||
* numbers. That is the largest legal value, divided by the
|
||||
* base. An input number that is greater than this value, if
|
||||
* followed by a legal input character, is too big. One that
|
||||
* is equal to this value may be valid or not; the limit
|
||||
* between valid and invalid numbers is then based on the last
|
||||
* digit. For instance, if the range for longs is
|
||||
* [-2147483648..2147483647] and the input base is 10,
|
||||
* cutoff will be set to 214748364 and cutlim to either
|
||||
* 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
|
||||
* a value > 214748364, or equal but the next digit is > 7 (or 8),
|
||||
* the number is too big, and we will return a range error.
|
||||
*
|
||||
* Set any if any `digits' consumed; make it negative to indicate
|
||||
* overflow.
|
||||
*/
|
||||
cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
|
||||
cutlim = cutoff % (unsigned long)base;
|
||||
cutoff /= (unsigned long)base;
|
||||
for (acc = 0, any = 0;; c = *s++) {
|
||||
if (isdigit(c))
|
||||
c -= '0';
|
||||
else if (isalpha(c))
|
||||
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
|
||||
else
|
||||
break;
|
||||
if (c >= base)
|
||||
break;
|
||||
if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
|
||||
any = -1;
|
||||
else {
|
||||
any = 1;
|
||||
acc *= base;
|
||||
acc += c;
|
||||
}
|
||||
}
|
||||
if (any < 0) {
|
||||
acc = neg ? LONG_MIN : LONG_MAX;
|
||||
errno = ERANGE;
|
||||
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
|
||||
} else if (neg)
|
||||
acc = -acc;
|
||||
if (endptr != 0)
|
||||
*endptr = (char *) (any ? s - 1 : nptr);
|
||||
return (acc);
|
||||
}
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
/*-
|
||||
* Copyright (c) 1992 The Regents of the University of California.
|
||||
* 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)strtoq.c 5.1 (Berkeley) 6/26/92";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#define _KERNEL
|
||||
#include "ixemul.h"
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* Convert a string to a quad integer.
|
||||
*
|
||||
* Ignores `locale' stuff. Assumes that the upper and lower case
|
||||
* alphabets and digits are each contiguous.
|
||||
*/
|
||||
quad_t
|
||||
strtoq(nptr, endptr, base)
|
||||
const char *nptr;
|
||||
char **endptr;
|
||||
register int base;
|
||||
{
|
||||
register const char *s;
|
||||
register u_quad_t acc;
|
||||
register int c;
|
||||
register u_quad_t qbase, cutoff;
|
||||
register int neg, any, cutlim;
|
||||
usetup;
|
||||
|
||||
/*
|
||||
* Skip white space and pick up leading +/- sign if any.
|
||||
* If base is 0, allow 0x for hex and 0 for octal, else
|
||||
* assume decimal; if base is already 16, allow 0x.
|
||||
*/
|
||||
s = nptr;
|
||||
do {
|
||||
c = *s++;
|
||||
} while (isspace(c));
|
||||
if (c == '-') {
|
||||
neg = 1;
|
||||
c = *s++;
|
||||
} else {
|
||||
neg = 0;
|
||||
if (c == '+')
|
||||
c = *s++;
|
||||
}
|
||||
if ((base == 0 || base == 16) &&
|
||||
c == '0' && (*s == 'x' || *s == 'X')) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
if (base == 0)
|
||||
base = c == '0' ? 8 : 10;
|
||||
|
||||
/*
|
||||
* Compute the cutoff value between legal numbers and illegal
|
||||
* numbers. That is the largest legal value, divided by the
|
||||
* base. An input number that is greater than this value, if
|
||||
* followed by a legal input character, is too big. One that
|
||||
* is equal to this value may be valid or not; the limit
|
||||
* between valid and invalid numbers is then based on the last
|
||||
* digit. For instance, if the range for quads is
|
||||
* [-9223372036854775808..9223372036854775807] and the input base
|
||||
* is 10, cutoff will be set to 922337203685477580 and cutlim to
|
||||
* either 7 (neg==0) or 8 (neg==1), meaning that if we have
|
||||
* accumulated a value > 922337203685477580, or equal but the
|
||||
* next digit is > 7 (or 8), the number is too big, and we will
|
||||
* return a range error.
|
||||
*
|
||||
* Set any if any `digits' consumed; make it negative to indicate
|
||||
* overflow.
|
||||
*/
|
||||
qbase = (unsigned)base;
|
||||
cutoff = neg ? -(u_quad_t)QUAD_MIN : QUAD_MAX;
|
||||
cutlim = cutoff % qbase;
|
||||
cutoff /= qbase;
|
||||
for (acc = 0, any = 0;; c = *s++) {
|
||||
if (isdigit(c))
|
||||
c -= '0';
|
||||
else if (isalpha(c))
|
||||
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
|
||||
else
|
||||
break;
|
||||
if (c >= base)
|
||||
break;
|
||||
if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
|
||||
any = -1;
|
||||
else {
|
||||
any = 1;
|
||||
acc *= qbase;
|
||||
acc += c;
|
||||
}
|
||||
}
|
||||
if (any < 0) {
|
||||
acc = neg ? QUAD_MIN : QUAD_MAX;
|
||||
errno = ERANGE;
|
||||
} else if (neg)
|
||||
acc = -acc;
|
||||
if (endptr != 0)
|
||||
*endptr = (char *) (any ? s - 1 : nptr);
|
||||
return (acc);
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 1990 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that: (1) source distributions retain this entire copyright
|
||||
* notice and comment, and (2) distributions including binaries display
|
||||
* the following acknowledgement: ``This product includes software
|
||||
* developed by the University of California, Berkeley and its contributors''
|
||||
* in the documentation or other materials provided with the distribution
|
||||
* and in all advertising materials mentioning features or use of this
|
||||
* software. Neither the name of the University nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)strtoul.c 5.2 (Berkeley) 5/17/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#define _KERNEL
|
||||
#include "ixemul.h"
|
||||
#include "kprintf.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* Convert a string to an unsigned long integer.
|
||||
*
|
||||
* Ignores `locale' stuff. Assumes that the upper and lower case
|
||||
* alphabets and digits are each contiguous.
|
||||
*/
|
||||
unsigned long
|
||||
strtoul(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
register const char *s = nptr;
|
||||
register unsigned long acc;
|
||||
register int c;
|
||||
register unsigned long cutoff;
|
||||
register int neg = 0, any, cutlim;
|
||||
usetup;
|
||||
|
||||
/*
|
||||
* See strtol for comments as to the logic used.
|
||||
*/
|
||||
do {
|
||||
c = *s++;
|
||||
} while (isspace(c));
|
||||
if (c == '-') {
|
||||
neg = 1;
|
||||
c = *s++;
|
||||
} else if (c == '+')
|
||||
c = *s++;
|
||||
if ((base == 0 || base == 16) &&
|
||||
c == '0' && (*s == 'x' || *s == 'X')) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
if (base == 0)
|
||||
base = c == '0' ? 8 : 10;
|
||||
cutoff = (unsigned long)ULONG_MAX / (unsigned long)base;
|
||||
cutlim = (unsigned long)ULONG_MAX % (unsigned long)base;
|
||||
for (acc = 0, any = 0;; c = *s++) {
|
||||
if (isdigit(c))
|
||||
c -= '0';
|
||||
else if (isalpha(c))
|
||||
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
|
||||
else
|
||||
break;
|
||||
if (c >= base)
|
||||
break;
|
||||
if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
|
||||
any = -1;
|
||||
else {
|
||||
any = 1;
|
||||
acc *= base;
|
||||
acc += c;
|
||||
}
|
||||
}
|
||||
if (any < 0) {
|
||||
acc = ULONG_MAX;
|
||||
errno = ERANGE;
|
||||
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
|
||||
} else if (neg)
|
||||
acc = -acc;
|
||||
if (endptr != 0)
|
||||
*endptr = (char *) (any ? s - 1 : nptr);
|
||||
return (acc);
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*-
|
||||
* Copyright (c) 1992 The Regents of the University of California.
|
||||
* 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)strtouq.c 5.1 (Berkeley) 6/26/92";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#define _KERNEL
|
||||
#include "ixemul.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* Convert a string to an unsigned quad integer.
|
||||
*
|
||||
* Ignores `locale' stuff. Assumes that the upper and lower case
|
||||
* alphabets and digits are each contiguous.
|
||||
*/
|
||||
u_quad_t
|
||||
strtouq(nptr, endptr, base)
|
||||
const char *nptr;
|
||||
char **endptr;
|
||||
register int base;
|
||||
{
|
||||
register const char *s = nptr;
|
||||
register u_quad_t acc;
|
||||
register int c;
|
||||
register u_quad_t qbase, cutoff;
|
||||
register int neg, any, cutlim;
|
||||
usetup;
|
||||
|
||||
/*
|
||||
* See strtoq for comments as to the logic used.
|
||||
*/
|
||||
s = nptr;
|
||||
do {
|
||||
c = *s++;
|
||||
} while (isspace(c));
|
||||
if (c == '-') {
|
||||
neg = 1;
|
||||
c = *s++;
|
||||
} else {
|
||||
neg = 0;
|
||||
if (c == '+')
|
||||
c = *s++;
|
||||
}
|
||||
if ((base == 0 || base == 16) &&
|
||||
c == '0' && (*s == 'x' || *s == 'X')) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
if (base == 0)
|
||||
base = c == '0' ? 8 : 10;
|
||||
qbase = (unsigned)base;
|
||||
cutoff = (u_quad_t)UQUAD_MAX / qbase;
|
||||
cutlim = (u_quad_t)UQUAD_MAX % qbase;
|
||||
for (acc = 0, any = 0;; c = *s++) {
|
||||
if (isdigit(c))
|
||||
c -= '0';
|
||||
else if (isalpha(c))
|
||||
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
|
||||
else
|
||||
break;
|
||||
if (c >= base)
|
||||
break;
|
||||
if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
|
||||
any = -1;
|
||||
else {
|
||||
any = 1;
|
||||
acc *= qbase;
|
||||
acc += c;
|
||||
}
|
||||
}
|
||||
if (any < 0) {
|
||||
acc = UQUAD_MAX;
|
||||
errno = ERANGE;
|
||||
} else if (neg)
|
||||
acc = -acc;
|
||||
if (endptr != 0)
|
||||
*endptr = (char *) (any ? s - 1 : nptr);
|
||||
return (acc);
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 1988 The Regents of the University of California.
|
||||
* 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)system.c 5.10 (Berkeley) 2/23/91";*/
|
||||
static char *rcsid = "$Id: system.c,v 1.1.1.1 2005/03/15 15:57:07 laire Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#define _KERNEL
|
||||
#include <ixemul.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <paths.h>
|
||||
|
||||
int
|
||||
system(command)
|
||||
const char *command;
|
||||
{
|
||||
pid_t pid;
|
||||
sig_t intsave, quitsave;
|
||||
int omask;
|
||||
int pstat;
|
||||
char *argp[] = {"sh", "-c", (char *) command, NULL};
|
||||
usetup;
|
||||
|
||||
if (!command) /* just checking... */
|
||||
return(1);
|
||||
|
||||
omask = sigblock(sigmask(SIGCHLD));
|
||||
switch(pid = vfork()) {
|
||||
case -1: /* error */
|
||||
(void)sigsetmask(omask);
|
||||
return(-1);
|
||||
case 0: /* child */
|
||||
(void)sigsetmask(omask);
|
||||
execve("sh", argp, *u.u_environ);
|
||||
_exit(127);
|
||||
}
|
||||
|
||||
intsave = (sig_t)signal(SIGINT, SIG_IGN);
|
||||
quitsave = (sig_t)signal(SIGQUIT, SIG_IGN);
|
||||
pid = waitpid(pid, (int *)&pstat, 0);
|
||||
(void)sigsetmask(omask);
|
||||
(void)signal(SIGINT, intsave);
|
||||
(void)signal(SIGQUIT, quitsave);
|
||||
return(pid == -1 ? -1 : pstat);
|
||||
}
|
||||
Reference in New Issue
Block a user