a34b05d2e6
This opens an OpenBSD-mirabile (aka MirBSD) repository. ### MirBSD is: # Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de> # Copyright © 1968-2003 The authors of And contributors to UNIX®, the # C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD. # # Anyone who obtained a copy of this work is hereby permitted to freely use, # distribute, modify, merge, sublicence, give away or sell it as long as the # authors are given due credit and the following notice is retained: # # This work is provided "as is", with no explicit or implicit warranty what- # soever. Use it only at your own risk. In no event may an author or contri- # butor be held liable for any damage, directly or indirectly, that origina- # ted through or is caused by creation or modification of this work. MirBSD is my private tree. MirBSD does not differ very much from OpenBSD and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the official one. It's like with DarrenBSD. At time of this writing, no advertising for MirBSD must be done, because the advertising clause has not yet been sorted out. http://templeofhate.com/tglaser/MirBSD/index.php
296 lines
6.4 KiB
C
296 lines
6.4 KiB
C
/* $OpenBSD: missing.c,v 1.4 1999/06/15 01:18:35 millert Exp $ */
|
|
|
|
/*
|
|
* Routines which may be missing on some machines
|
|
*/
|
|
|
|
#include "sh.h"
|
|
#include "ksh_stat.h"
|
|
#include "ksh_dir.h"
|
|
|
|
|
|
#ifndef HAVE_MEMSET
|
|
void *
|
|
memset(d, c, n)
|
|
void *d;
|
|
int c;
|
|
size_t n;
|
|
{
|
|
unsigned char *p = (unsigned char *) d;
|
|
|
|
/* Not amazingly fast.. */
|
|
for (; n > 0; --n)
|
|
*p++ = c;
|
|
return d;
|
|
}
|
|
#endif /* !HAVE_MEMSET */
|
|
|
|
#if !defined(HAVE_MEMMOVE) && !defined(HAVE_BCOPY)
|
|
void *
|
|
memmove(d, s, n)
|
|
void *d;
|
|
const void *s;
|
|
size_t n;
|
|
{
|
|
char *dp = (char *) d, *sp = (char *) s;
|
|
|
|
if (n <= 0)
|
|
;
|
|
else if (dp < sp)
|
|
do
|
|
*dp++ = *sp++;
|
|
while (--n > 0);
|
|
else if (dp > sp) {
|
|
dp += n;
|
|
sp += n;
|
|
do
|
|
*--dp = *--sp;
|
|
while (--n > 0);
|
|
}
|
|
return d;
|
|
}
|
|
#endif /* !HAVE_MEMMOVE && !HAVE_BCOPY */
|
|
|
|
|
|
#ifndef HAVE_STRCASECMP
|
|
/*
|
|
* Case insensitive string compare routines, same semantics as str[n]cmp()
|
|
* (assumes ASCII..).
|
|
*/
|
|
static const char ichars[256] = {
|
|
0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
|
|
0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
|
|
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
|
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
|
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
|
|
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
|
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
|
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
|
0x40, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
|
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
|
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
|
|
'x', 'y', 'z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
|
0x60, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
|
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
|
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
|
|
'x', 'y', 'z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
|
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
|
|
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
|
|
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
|
|
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
|
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
|
|
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
|
|
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
|
|
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
|
|
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
|
|
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
|
|
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
|
|
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
|
|
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
|
|
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
|
|
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
|
|
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
|
|
};
|
|
|
|
int
|
|
strcasecmp(s1, s2)
|
|
const char *s1;
|
|
const char *s2;
|
|
{
|
|
const unsigned char *us1 = (const unsigned char *) s1;
|
|
const unsigned char *us2 = (const unsigned char *) s2;
|
|
|
|
while (ichars[*us1] == ichars[*us2++])
|
|
if (!*us1++)
|
|
return 0;
|
|
|
|
return ichars[*us1] - ichars[*--us2];
|
|
}
|
|
|
|
int
|
|
strncasecmp(s1, s2, n)
|
|
const char *s1;
|
|
const char *s2;
|
|
int n;
|
|
{
|
|
const unsigned char *us1 = (const unsigned char *) s1;
|
|
const unsigned char *us2 = (const unsigned char *) s2;
|
|
|
|
while (--n >= 0 && ichars[*us1] == ichars[*us2++])
|
|
if (!*us1++)
|
|
return 0;
|
|
|
|
return n < 0 ? 0 : ichars[*us1] - ichars[*--us2];
|
|
}
|
|
#endif /* HAVE_STRCASECMP */
|
|
|
|
|
|
#ifndef HAVE_STRSTR
|
|
char *
|
|
strstr(s, p)
|
|
const char *s;
|
|
const char *p;
|
|
{
|
|
int len;
|
|
|
|
if (s && p)
|
|
for (len = strlen(p); *s; s++)
|
|
if (*s == *p && strncmp(s, p, len) == 0)
|
|
return (char *) s;
|
|
|
|
return 0;
|
|
}
|
|
#endif /* HAVE_STRSTR */
|
|
|
|
|
|
#ifndef HAVE_STRERROR
|
|
char *
|
|
strerror(err)
|
|
int err;
|
|
{
|
|
static char buf[64];
|
|
# ifdef HAVE_SYS_ERRLIST
|
|
# ifndef SYS_ERRLIST_DECLARED
|
|
extern int sys_nerr;
|
|
extern char *sys_errlist[];
|
|
# endif
|
|
char *p;
|
|
|
|
if (err < 0 || err >= sys_nerr)
|
|
shf_snprintf(p = buf, sizeof(buf), "Unknown system error %d",
|
|
err);
|
|
else
|
|
p = sys_errlist[err];
|
|
return p;
|
|
# else /* HAVE_SYS_ERRLIST */
|
|
switch (err) {
|
|
case EINVAL:
|
|
return "Invalid argument";
|
|
case EACCES:
|
|
return "Permission denied";
|
|
case ESRCH:
|
|
return "No such process";
|
|
case EPERM:
|
|
return "Not owner";
|
|
case ENOENT:
|
|
return "No such file or directory";
|
|
case ENOTDIR:
|
|
return "Not a directory";
|
|
case ENOEXEC:
|
|
return "Exec format error";
|
|
case ENOMEM:
|
|
return "Not enough memory";
|
|
case E2BIG:
|
|
return "Argument list too long";
|
|
default:
|
|
shf_snprintf(buf, sizeof(buf), "Unknown system error %d", err);
|
|
return buf;
|
|
}
|
|
# endif /* HAVE_SYS_ERRLIST */
|
|
}
|
|
#endif /* !HAVE_STRERROR */
|
|
|
|
|
|
#ifdef TIMES_BROKEN
|
|
# include "ksh_time.h"
|
|
# include "ksh_times.h"
|
|
# ifdef HAVE_GETRUSAGE
|
|
# include <sys/resource.h>
|
|
# else /* HAVE_GETRUSAGE */
|
|
# include <sys/timeb.h>
|
|
# endif /* HAVE_GETRUSAGE */
|
|
|
|
clock_t
|
|
ksh_times(tms)
|
|
struct tms *tms;
|
|
{
|
|
static clock_t base_sec;
|
|
clock_t rv;
|
|
|
|
# ifdef HAVE_GETRUSAGE
|
|
{
|
|
struct timeval tv;
|
|
struct rusage ru;
|
|
|
|
getrusage(RUSAGE_SELF, &ru);
|
|
tms->tms_utime = ru.ru_utime.tv_sec * CLK_TCK
|
|
+ ru.ru_utime.tv_usec * CLK_TCK / 1000000;
|
|
tms->tms_stime = ru.ru_stime.tv_sec * CLK_TCK
|
|
+ ru.ru_stime.tv_usec * CLK_TCK / 1000000;
|
|
|
|
getrusage(RUSAGE_CHILDREN, &ru);
|
|
tms->tms_cutime = ru.ru_utime.tv_sec * CLK_TCK
|
|
+ ru.ru_utime.tv_usec * CLK_TCK / 1000000;
|
|
tms->tms_cstime = ru.ru_stime.tv_sec * CLK_TCK
|
|
+ ru.ru_stime.tv_usec * CLK_TCK / 1000000;
|
|
|
|
gettimeofday(&tv, (struct timezone *) 0);
|
|
if (base_sec == 0)
|
|
base_sec = tv.tv_sec;
|
|
rv = (tv.tv_sec - base_sec) * CLK_TCK;
|
|
rv += tv.tv_usec * CLK_TCK / 1000000;
|
|
}
|
|
# else /* HAVE_GETRUSAGE */
|
|
/* Assume times() available, but always returns 0
|
|
* (also assumes ftime() available)
|
|
*/
|
|
{
|
|
struct timeb tb;
|
|
|
|
if (times(tms) == (clock_t) -1)
|
|
return (clock_t) -1;
|
|
ftime(&tb);
|
|
if (base_sec == 0)
|
|
base_sec = tb.time;
|
|
rv = (tb.time - base_sec) * CLK_TCK;
|
|
rv += tb.millitm * CLK_TCK / 1000;
|
|
}
|
|
# endif /* HAVE_GETRUSAGE */
|
|
return rv;
|
|
}
|
|
#endif /* TIMES_BROKEN */
|
|
|
|
#ifdef OPENDIR_DOES_NONDIR
|
|
/* Prevent opendir() from attempting to open non-directories. Such
|
|
* behavior can cause problems if it attempts to open special devices...
|
|
*/
|
|
DIR *
|
|
ksh_opendir(d)
|
|
const char *d;
|
|
{
|
|
struct stat statb;
|
|
|
|
if (stat(d, &statb) != 0)
|
|
return (DIR *) 0;
|
|
if (!S_ISDIR(statb.st_mode)) {
|
|
errno = ENOTDIR;
|
|
return (DIR *) 0;
|
|
}
|
|
return opendir(d);
|
|
}
|
|
#endif /* OPENDIR_DOES_NONDIR */
|
|
|
|
#ifndef HAVE_DUP2
|
|
int
|
|
dup2(oldd, newd)
|
|
int oldd;
|
|
int newd;
|
|
{
|
|
int old_errno;
|
|
|
|
if (fcntl(oldd, F_GETFL, 0) == -1)
|
|
return -1; /* errno == EBADF */
|
|
|
|
if (oldd == newd)
|
|
return newd;
|
|
|
|
old_errno = errno;
|
|
|
|
close(newd); /* in case its open */
|
|
|
|
errno = old_errno;
|
|
|
|
return fcntl(oldd, F_DUPFD, newd);
|
|
}
|
|
#endif /* !HAVE_MEMSET */
|