Revision 64 at sourceforge.net

This commit is contained in:
llsth
2015-04-16 09:16:48 +02:00
commit fc791692f4
1275 changed files with 213167 additions and 0 deletions
+106
View File
@@ -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
+105
View File
@@ -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
+10
View File
@@ -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);
}
+40
View File
@@ -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
View File
@@ -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
+55
View File
@@ -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
+49
View File
@@ -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));
}
+34
View File
@@ -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));
}
+34
View File
@@ -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));
}
+130
View File
@@ -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
+45
View File
@@ -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);
}
+61
View File
@@ -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
View File
@@ -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
View File
@@ -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' */
}
+93
View File
@@ -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;
}
+129
View File
@@ -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);
}
+33
View File
@@ -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);
}
+56
View File
@@ -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);
}
+131
View File
@@ -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;
}
+61
View File
@@ -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
View File
@@ -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
+281
View File
@@ -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;
}
}
+41
View File
@@ -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
View File
@@ -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;
}
+28
View File
@@ -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);
}
+47
View File
@@ -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 */
+219
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+117
View File
@@ -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
View File
@@ -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);
}
+95
View File
@@ -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);
}
+118
View File
@@ -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);
}
+81
View File
@@ -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);
}