ikarus/src/ikarus-errno.c

202 lines
6.9 KiB
C

/*
* Ikarus Scheme -- A compiler for R6RS Scheme.
* Copyright (C) 2006,2007,2008 Abdulaziz Ghuloum
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "ikarus-data.h"
typedef struct errno_info {
int n;
char* s;
ikptr c;
} errno_info;
#ifndef ECANCELED
#define ECANCELED 140
#endif
#ifndef ENODATA
#define ENODATA 96
#endif
#ifndef ENOSR
#define ENOSR 98
#endif
#ifndef ENOSTR
#define ENOSTR 99
#endif
#ifndef ETIME
#define ETIME 101
#endif
static errno_info errno_table[] = {
/* errnos from POSIX IEEE Std 1003.1 2004 Edition */
{E2BIG, "E2BIG", fix(-1)},
{EACCES, "EACCES", fix(-2)},
{EADDRINUSE, "EADDRINUSE", fix(-3)},
{EADDRNOTAVAIL, "EADDRNOTAVAIL", fix(-4)},
{EAFNOSUPPORT, "EAFNOSUPPORT", fix(-5)},
{EAGAIN, "EAGAIN", fix(-6)},
{EALREADY, "EALREADY", fix(-7)},
{EBADF, "EBADF", fix(-8)},
{EBADMSG, "EBADMSG", fix(-9)},
{EBUSY, "EBUSY", fix(-10)},
{ECANCELED, "ECANCELED", fix(-11)},
{ECHILD, "ECHILD", fix(-12)},
{ECONNABORTED, "ECONNABORTED", fix(-13)},
{ECONNREFUSED, "ECONNREFUSED", fix(-14)},
{ECONNRESET, "ECONNRESET", fix(-15)},
{EDEADLK, "EDEADLK", fix(-16)},
{EDESTADDRREQ, "EDESTADDRREQ", fix(-17)},
{EDOM, "EDOM", fix(-18)},
{EDQUOT, "EDQUOT", fix(-19)},
{EEXIST, "EEXIST", fix(-20)},
{EFAULT, "EFAULT", fix(-21)},
{EFBIG, "EFBIG", fix(-22)},
{EHOSTUNREACH, "EHOSTUNREACH", fix(-23)},
{EIDRM, "EIDRM", fix(-24)},
{EILSEQ, "EILSEQ", fix(-25)},
{EINPROGRESS, "EINPROGRESS", fix(-26)},
{EINTR, "EINTR", fix(-27)},
{EINVAL, "EINVAL", fix(-28)},
{EIO, "EIO", fix(-29)},
{EISCONN, "EISCONN", fix(-30)},
{EISDIR, "EISDIR", fix(-31)},
{ELOOP, "ELOOP", fix(-32)},
{EMFILE, "EMFILE", fix(-33)},
{EMLINK, "EMLINK", fix(-34)},
{EMSGSIZE, "EMSGSIZE", fix(-35)},
{EMULTIHOP, "EMULTIHOP", fix(-36)},
{ENAMETOOLONG, "ENAMETOOLONG", fix(-37)},
{ENETDOWN, "ENETDOWN", fix(-38)},
{ENETRESET, "ENETRESET", fix(-39)},
{ENETUNREACH, "ENETUNREACH", fix(-40)},
{ENFILE, "ENFILE", fix(-41)},
{ENOBUFS, "ENOBUFS", fix(-42)},
{ENODATA, "ENODATA", fix(-43)},
{ENODEV, "ENODEV", fix(-44)},
{ENOENT, "ENOENT", fix(-45)},
{ENOEXEC, "ENOEXEC", fix(-46)},
{ENOLCK, "ENOLCK", fix(-47)},
{ENOLINK, "ENOLINK", fix(-48)},
{ENOMEM, "ENOMEM", fix(-49)},
{ENOMSG, "ENOMSG", fix(-50)},
{ENOPROTOOPT, "ENOPROTOOPT", fix(-51)},
{ENOSPC, "ENOSPC", fix(-52)},
{ENOSR, "ENOSR", fix(-53)},
{ENOSTR, "ENOSTR", fix(-54)},
{ENOSYS, "ENOSYS", fix(-55)},
{ENOTCONN, "ENOTCONN", fix(-56)},
{ENOTDIR, "ENOTDIR", fix(-57)},
{ENOTEMPTY, "ENOTEMPTY", fix(-58)},
{ENOTSOCK, "ENOTSOCK", fix(-59)},
{ENOTSUP, "ENOTSUP", fix(-60)},
{ENOTTY, "ENOTTY", fix(-61)},
{ENXIO, "ENXIO", fix(-62)},
{EOPNOTSUPP, "EOPNOTSUPP", fix(-63)},
{EOVERFLOW, "EOVERFLOW", fix(-64)},
{EPERM, "EPERM", fix(-65)},
{EPIPE, "EPIPE", fix(-66)},
{EPROTO, "EPROTO", fix(-67)},
{EPROTONOSUPPORT, "EPROTONOSUPPORT", fix(-68)},
{EPROTOTYPE, "EPROTOTYPE", fix(-69)},
{ERANGE, "ERANGE", fix(-70)},
{EROFS, "EROFS", fix(-71)},
{ESPIPE, "ESPIPE", fix(-72)},
{ESRCH, "ESRCH", fix(-73)},
{ESTALE, "ESTALE", fix(-74)},
{ETIME, "ETIME", fix(-75)},
{ETIMEDOUT, "ETIMEDOUT", fix(-76)},
{ETXTBSY, "ETXTBSY", fix(-77)},
{EWOULDBLOCK, "EWOULDBLOCK", fix(-78)},
{EXDEV, "EXDEV", fix(-79)}
};
#define errno_table_length 79
ikptr
ik_errno_num_to_code(int en){
/* Used by C to return Ikarus errno code to Scheme. */
errno_info* ei;
int i;
for(i=0; i < errno_table_length; i++){
ei = &errno_table[i];
if(ei->n == en){
return ei->c;
}
}
fprintf(stderr, "\n*** ikarus-errno.c: Don't know errno %d ***\n\n", en);
return fix(-99999); /* should always be less than last errno code */
}
ikptr
ik_errno_to_code(){
int en = errno;
return ik_errno_num_to_code(en);
}
ikptr
ikrt_errno_code_to_name(ikptr ec, ikpcb* pcb){
/* Used by Scheme to get the name of the errno corresponding
to the Ikarus errno code. */
errno_info* ei;
int i;
for(i=0; i < errno_table_length; i++){
ei = &errno_table[i];
if(ei->c == ec){
int len = strlen(ei->s);
ikptr bv = ik_safe_alloc(pcb, align(disp_bytevector_data+len+1))
+ bytevector_tag;
ref(bv, off_bytevector_length) = fix(len);
memcpy((char*)(bv+off_bytevector_data), ei->s, len+1);
return bv;
}
}
return false_object;
}
ikptr
ikrt_strerror(ikptr ec, ikpcb* pcb){
/* Used by Scheme to get the error message of the errno corresponding
to the Ikarus errno code. */
errno_info* ei;
int i;
for(i=0; i < errno_table_length; i++){
ei = &errno_table[i];
if(ei->c == ec){
errno = 0;
char* es = strerror(ei->n);
if(errno){
perror("ikrt_strerror: strerror failed");
exit(EXIT_FAILURE);
}
int len = strlen(es);
ikptr bv = ik_safe_alloc(pcb, align(disp_bytevector_data+len+1))
+ bytevector_tag;
ref(bv, off_bytevector_length) = fix(len);
memcpy((char*)(bv+off_bytevector_data), es, len+1);
return bv;
}
}
return false_object;
}