/* The point of this file is to handle errno values in a system independent
* way so that they may be used in slang scripts.
*/
#include "config.h"
#include "sl-feat.h"
#include <stdio.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}
};
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++;
}
return "errno undefined";
}
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;
}