File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libpdel / util / kernelglue.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 23:25:53 2012 UTC (12 years, 4 months ago) by misho
Branches: libpdel, MAIN
CVS tags: v0_5_3, HEAD
libpdel


/*
 * Copyright (c) 1988, 1993
 *	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.
 */

#include <sys/types.h>
#include <sys/errno.h>
#include <sys/param.h>
#include <sys/libkern.h>
#include <sys/systm.h>
#include <sys/ctype.h>
#include <net/ethernet.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>

#include "kernelglue.h"

/*
 * Kernelglue kernel memory type
 */
MALLOC_DEFINE(M_LIBPDEL, "LIBPDEL", "libpdel kernel memory");

/* Errno */
int	errno;

char *
strdup(const char *str)
{
	size_t len;
	char *copy;

	len = strlen(str) + 1;
	if ((copy = MALLOC(NULL, len)) == NULL)
		return (NULL);
	memcpy(copy, str, len);
	return (copy);
}

int
asprintf(char **ret, const char *format, ...)
{
	va_list args;
	int rtn;

	va_start(args, format);
	rtn = vasprintf(ret, format, args);
	va_end(args);
	return (rtn);
}

int
vasprintf(char **ret, const char *format, va_list ap)
{
	size_t buflen = 256;
	char *buf;
	int slen;

	/* Initialize return value in case of failure */
	*ret = NULL;

try_again:
	/* Allocate buffer */
	if ((buf = malloc(buflen, M_LIBPDEL, M_NOWAIT)) == NULL) {
		errno = ENOMEM;
		return (-1);
	}

	/* Format string */
	slen = vsnprintf(buf, buflen, format, ap);

	/* If buffer was big enough, we're done */
	if (slen < buflen) {
		*ret = buf;
		return (slen);
	}

	/* Increase buffer size and try again */
	free(buf, M_LIBPDEL);
	buflen = slen + 1;
	goto try_again;
}

char *
strchr(const char *s, int c)
{
	while (1) {
		if (*s == (char)c)
			return ((char *)s);
		if (*s == '\0')
			return (NULL);
		s++;
	}
}

int
strcasecmp(const char *s1, const char *s2)
{
	const u_char *s = s1;
	const u_char *t = s2;

        while (*s != '\0' && *t != '\0' && tolower(*s) == tolower(*t)) {
		s++;
		t++;
        }
        return (*s - *t);
}

size_t
strlcpy(char *dst, const char *src, size_t siz)
{
	char *d = dst;
	const char *s = src;
	size_t n = siz;

	/* Copy as many bytes as will fit */
	if (n != 0 && --n != 0) {
		do {
			if ((*d++ = *s++) == 0)
				break;
		} while (--n != 0);
	}

	/* Not enough room in dst, add NUL and traverse rest of src */
	if (n == 0) {
		if (siz != 0)
			*d = '\0';		/* NUL-terminate dst */
		while (*s++)
			;
	}

	return(s - src - 1);	/* count does not include NUL */
}

void *
memmove(void *dst, const void *src, size_t len)
{
	ovbcopy(src, dst, len);
	return (dst);
}

time_t 
time(time_t *newtime)
{
	struct timeval valtime;

	getmicrotime(&valtime);
	if (newtime)
		*newtime = valtime.tv_sec;
	return (valtime.tv_sec);
}

char *
strerror(int errnum)
{
	static char buf[32];
	const char *s;

	switch (errnum) {
	case EPERM:		s = "Operation not permitted"; break;
	case ENOENT:		s = "No such file or directory"; break;
	case ESRCH:		s = "No such process"; break;
	case EINTR:		s = "Interrupted system call"; break;
	case EIO:		s = "Input/output error"; break;
	case ENXIO:		s = "Device not configured"; break;
	case E2BIG:		s = "Argument list too long"; break;
	case ENOEXEC:		s = "Exec format error"; break;
	case EBADF:		s = "Bad file descriptor"; break;
	case ECHILD:		s = "No child processes"; break;
	case EDEADLK:		s = "Resource deadlock avoided"; break;
	case ENOMEM:		s = "Cannot allocate memory"; break;
	case EACCES:		s = "Permission denied"; break;
	case EFAULT:		s = "Bad address"; break;
	case ENOTBLK:		s = "Block device required"; break;
	case EBUSY:		s = "Device busy"; break;
	case EEXIST:		s = "File exists"; break;
	case EXDEV:		s = "Cross-device link"; break;
	case ENODEV:		s = "Operation not supported by device"; break;
	case ENOTDIR:		s = "Not a directory"; break;
	case EISDIR:		s = "Is a directory"; break;
	case EINVAL:		s = "Invalid argument"; break;
	case ENFILE:		s = "Too many open files in system"; break;
	case EMFILE:		s = "Too many open files"; break;
	case ENOTTY:		s = "Inappropriate ioctl for device"; break;
	case ETXTBSY:		s = "Text file busy"; break;
	case EFBIG:		s = "File too large"; break;
	case ENOSPC:		s = "No space left on device"; break;
	case ESPIPE:		s = "Illegal seek"; break;
	case EROFS:		s = "Read-only file system"; break;
	case EMLINK:		s = "Too many links"; break;
	case EPIPE:		s = "Broken pipe"; break;
	case EDOM:		s = "Numerical argument out of domain"; break;
	case ERANGE:		s = "Result too large"; break;
	case EAGAIN:		s = "Resource temporarily unavailable"; break;
	case EINPROGRESS:	s = "Operation now in progress"; break;
	case EALREADY:		s = "Operation already in progress"; break;
	case ENOTSOCK:		s = "Socket operation on non-socket"; break;
	case EDESTADDRREQ:	s = "Destination address required"; break;
	case EMSGSIZE:		s = "Message too long"; break;
	case EPROTOTYPE:	s = "Protocol wrong type for socket"; break;
	case ENOPROTOOPT:	s = "Protocol not available"; break;
	case EPROTONOSUPPORT:	s = "Protocol not supported"; break;
	case ESOCKTNOSUPPORT:	s = "Socket type not supported"; break;
	case EOPNOTSUPP:	s = "Operation not supported"; break;
	case EPFNOSUPPORT:	s = "Protocol family not supported"; break;
	case EAFNOSUPPORT:
		s = "Address family not supported by protocol family"; break;
	case EADDRINUSE:	s = "Address already in use"; break;
	case EADDRNOTAVAIL:	s = "Can't assign requested address"; break;
	case ENETDOWN:		s = "Network is down"; break;
	case ENETUNREACH:	s = "Network is unreachable"; break;
	case ENETRESET:	
		s = "Network dropped connection on reset"; break;
	case ECONNABORTED:	s = "Software caused connection abort"; break;
	case ECONNRESET:	s = "Connection reset by peer"; break;
	case ENOBUFS:		s = "No buffer space available"; break;
	case EISCONN:		s = "Socket is already connected"; break;
	case ENOTCONN:		s = "Socket is not connected"; break;
	case ESHUTDOWN:		s = "Can't send after socket shutdown"; break;
	case ETOOMANYREFS:	s = "Too many references: can't splice"; break;
	case ETIMEDOUT:		s = "Operation timed out"; break;
	case ECONNREFUSED:	s = "Connection refused"; break;
	case ELOOP:		s = "Too many levels of symbolic links"; break;
	case ENAMETOOLONG:	s = "File name too long"; break;
	case EHOSTDOWN:		s = "Host is down"; break;
	case EHOSTUNREACH:	s = "No route to host"; break;
	case ENOTEMPTY:		s = "Directory not empty"; break;
	case EPROCLIM:		s = "Too many processes"; break;
	case EUSERS:		s = "Too many users"; break;
	case EDQUOT:		s = "Disc quota exceeded"; break;
	case ESTALE:		s = "Stale NFS file handle"; break;
	case EREMOTE:		s = "Too many levels of remote in path"; break;
	case EBADRPC:		s = "RPC struct is bad"; break;
	case ERPCMISMATCH:	s = "RPC version wrong"; break;
	case EPROGUNAVAIL:	s = "RPC prog. not avail"; break;
	case EPROGMISMATCH:	s = "Program version wrong"; break;
	case EPROCUNAVAIL:	s = "Bad procedure for program"; break;
	case ENOLCK:		s = "No locks available"; break;
	case ENOSYS:		s = "Function not implemented"; break;
	case EFTYPE:		s = "Inappropriate file type or format"; break;
	case EAUTH:		s = "Authentication error"; break;
	case ENEEDAUTH:		s = "Need authenticator"; break;
	case EIDRM:		s = "Identifier removed"; break;
	case ENOMSG:		s = "No message of desired type"; break;
	case EOVERFLOW:		s =
		"Value too large to be stored in data type"; break;
	case ECANCELED:		s = "Operation canceled"; break;
	case EILSEQ:		s = "Illegal byte sequence"; break;
	default:
		snprintf(buf, sizeof(buf), "Unknown error: %d", errnum);
		errno = EINVAL;
		return (buf);
	}
	strlcpy(buf, s, sizeof(buf));
	return (buf);
}

void *
kern_malloc(size_t size)
{
	void *mem;

	if ((mem = malloc((u_long)size, M_LIBPDEL, M_NOWAIT)) == NULL)
		errno = ENOMEM;
	return (mem);
}

void *
kern_realloc(void *mem, size_t size)
{
	if ((mem = realloc(mem,
	    (u_long)size, M_LIBPDEL, M_NOWAIT)) == NULL)
		errno = ENOMEM;
	return (mem);
}

void
kern_free(void *mem)
{
	free(mem, M_LIBPDEL);
}


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>