/
mudtem/
mudtem/area/scripts/
mudtem/bin/
mudtem/log/
mudtem/player/
mudtem/slang/autoconf/
mudtem/slang/doc/
mudtem/slang/doc/OLD/help/
mudtem/slang/doc/internal/
mudtem/slang/doc/text/
mudtem/slang/doc/tm/tools/
mudtem/slang/examples/
mudtem/slang/modules/
mudtem/slang/slsh/
mudtem/slang/slsh/lib/
mudtem/slang/slsh/scripts/
mudtem/slang/src/mkfiles/
mudtem/slang/src/util/
mudtem/src/CVS/
mudtem/src/include/
mudtem/src/include/CVS/
mudtem/src/var/CVS/
/* The point of this file is to handle errno values in a system independent
 * way so that they may be used in slang scripts.
 */
/* Copyright (c) 1998, 1999 John E. Davis
 * This file is part of the S-Lang library.
 *
 * You may distribute under the terms of either the GNU General Public
 * License or the Perl Artistic License.
 */
#include "slinclud.h"

#include <errno.h>
#include "slang.h"
#include "_slang.h"

typedef struct
{
   char *msg;
   int sys_errno;
   char *symbolic_name;
}
Errno_Map_Type;

static Errno_Map_Type Errno_Map [] =
{
#ifndef EPERM
# define EPERM	-1
#endif
   {"Not owner",			EPERM,	"EPERM"},
#ifndef ENOENT
# define ENOENT	-1
#endif
   {"No such file or directory",	ENOENT,	"ENOENT"},
#ifndef ESRCH
# define ESRCH	-1
#endif
   {"No such process",			ESRCH,	"ESRCH"},
#ifndef ENXIO
# define ENXIO	-1
#endif
   {"No such device or address",	ENXIO,	"ENXIO"},
#ifndef ENOEXEC
# define ENOEXEC	-1
#endif
   {"Exec format error",		ENOEXEC,	"ENOEXEC"},
#ifndef EBADF
# define EBADF	-1
#endif
   {"Bad file number",			EBADF,	"EBADF"},
#ifndef ECHILD
# define ECHILD	-1
#endif
   {"No children",			ECHILD,	"ECHILD"},
#ifndef ENOMEM
# define ENOMEM	-1
#endif
   {"Not enough core",			ENOMEM,	"ENOMEM"},
#ifndef EACCES
# define EACCES	-1
#endif
   {"Permission denied",		EACCES,	"EACCES"},
#ifndef EFAULT
# define EFAULT	-1
#endif
   {"Bad address",			EFAULT,	"EFAULT"},
#ifndef ENOTBLK
# define ENOTBLK	-1
#endif
   {"Block device required",		ENOTBLK,	"ENOTBLK"},
#ifndef EBUSY
# define EBUSY	-1
#endif
   {"Mount device busy",		EBUSY,	"EBUSY"},
#ifndef EEXIST
# define EEXIST	-1
#endif
   {"File exists",			EEXIST,	"EEXIST"},
#ifndef EXDEV
# define EXDEV	-1
#endif
   {"Cross-device link",		EXDEV,	"EXDEV"},
#ifndef ENODEV
# define ENODEV	-1
#endif
   {"No such device",			ENODEV,	"ENODEV"},
#ifndef ENOTDIR
# define ENOTDIR	-1
#endif
   {"Not a directory",			ENOTDIR,	"ENOTDIR"},
#ifndef EISDIR
# define EISDIR	-1
#endif
   {"Is a directory",			EISDIR,	"EISDIR"},
#ifndef EINVAL
# define EINVAL	-1
#endif
   {"Invalid argument",			EINVAL,	"EINVAL"},
#ifndef ENFILE
# define ENFILE	-1
#endif
   {"File table overflow",		ENFILE,	"ENFILE"},
#ifndef EMFILE
# define EMFILE	-1
#endif
   {"Too many open files",		EMFILE,	"EMFILE"},
#ifndef ENOTTY
# define ENOTTY	-1
#endif
   {"Not a typewriter",			ENOTTY,	"ENOTTY"},
#ifndef ETXTBSY
# define ETXTBSY	-1
#endif
   {"Text file busy",			ETXTBSY,	"ETXTBSY"},
#ifndef EFBIG
# define EFBIG	-1
#endif
   {"File too large",			EFBIG,	"EFBIG"},
#ifndef ENOSPC
# define ENOSPC	-1
#endif
   {"No space left on device",		ENOSPC,	"ENOSPC"},
#ifndef ESPIPE
# define ESPIPE	-1
#endif
   {"Illegal seek",			ESPIPE,	"ESPIPE"},
#ifndef EROFS
# define EROFS	-1
#endif
   {"Read-only file system",		EROFS,	"EROFS"},
#ifndef EMLINK
# define EMLINK	-1
#endif
   {"Too many links",			EMLINK,	"EMLINK"},
#ifndef EPIPE
# define EPIPE	-1
#endif
   {"Broken pipe",			EPIPE,	"EPIPE"},
#ifndef ELOOP
# define ELOOP	-1
#endif
   {"Too many levels of symbolic links",ELOOP,	"ELOOP"},
#ifndef ENAMETOOLONG
# define ENAMETOOLONG	-1
#endif
   {"File name too long",		ENAMETOOLONG,	"ENAMETOOLONG"},
   {NULL, 0, NULL}
};

int _SLerrno_errno;

char *SLerrno_strerror (int sys_errno)
{
   Errno_Map_Type *e;

   e = Errno_Map;
   while (e->msg != NULL)
     {
	if (e->sys_errno == sys_errno)
	  return e->msg;

	e++;
     }

   if (sys_errno == SL_ERRNO_NOT_IMPLEMENTED)
     return "System call not available for this platform";

   return "Unknown error";
}

static char *intrin_errno_string (int *sys_errno)
{
   return SLerrno_strerror (*sys_errno);
}

int _SLerrno_init (void)
{
   static Errno_Map_Type *e;

   if (e != NULL)		       /* already initialized */
     return 0;

   if ((-1 == SLadd_intrinsic_function ("errno_string", (FVOID_STAR) intrin_errno_string,
				       SLANG_STRING_TYPE, 1, SLANG_INT_TYPE))
       || (-1 == SLadd_intrinsic_variable ("errno", (VOID_STAR)&_SLerrno_errno, SLANG_INT_TYPE, 1)))
     return -1;

   e = Errno_Map;
   while (e->msg != NULL)
     {
	if (-1 == SLadd_intrinsic_variable (e->symbolic_name, (VOID_STAR) &e->sys_errno, SLANG_INT_TYPE, 1))
	  return -1;
	e++;
     }

   return 0;
}