diff options
Diffstat (limited to 'ecos/language/tcl/jim/current/src/jim-aio.c')
-rw-r--r-- | ecos/language/tcl/jim/current/src/jim-aio.c | 1548 |
1 files changed, 775 insertions, 773 deletions
diff --git a/ecos/language/tcl/jim/current/src/jim-aio.c b/ecos/language/tcl/jim/current/src/jim-aio.c index 88ec687..b81feca 100644 --- a/ecos/language/tcl/jim/current/src/jim-aio.c +++ b/ecos/language/tcl/jim/current/src/jim-aio.c @@ -1,773 +1,775 @@ -/* Jim - A small embeddable Tcl interpreter - * - * Copyright 2005 Salvatore Sanfilippo <antirez@invece.org> - * Copyright 2005 Clemens Hintze <c.hintze@gmx.net> - * Copyright 2005 patthoyts - Pat Thoyts <patthoyts@users.sf.net> - * Copyright 2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com - * Copyright 2008 Andrew Lunn <andrew@lunn.ch> - * Copyright 2008 Duane Ellis <openocd@duaneellis.com> - * Copyright 2008 Uwe Klein <uklein@klein-messgeraete.de> - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``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 - * JIM TCL PROJECT 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. - * - * The views and conclusions contained in the software and documentation - * are those of the authors and should not be interpreted as representing - * official policies, either expressed or implied, of the Jim Tcl Project. - **/ - -#include <unistd.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <fcntl.h> - -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <netdb.h> - -#ifdef __ECOS -#include <pkgconf/jimtcl.h> -#endif -#ifndef JIM_STATICEXT -#define JIM_EXTENSION -#endif - -/* FIX!!! add #if's to make JIM_SUPPORT_EVENTLOOP enable/disable - * eventloop support compile time! */ -#ifndef JIM_SUPPORT_EVENTLOOP -#define JIM_SUPPORT_EVENTLOOP 1 -#endif - -#ifdef __ECOS -#include <cyg/jimtcl/jim.h> -#include <cyg/jimtcl/jim-eventloop.h> -#else -#include "jim.h" -#include "jim-eventloop.h" -#endif - - - - -#define AIO_CMD_LEN 128 -#define AIO_BUF_LEN 1024 - -#define AIO_KEEPOPEN 1 -#define AIO_FDOPEN 2 - - -typedef struct AioFile { - FILE *fp; - int type; - int OpenFlags; /* AIO_KEEPOPEN? keep FILE*, AIO_FDOPEN? FILE* created via fdopen */ - int fd; - int flags; - Jim_Obj *rEvent; - Jim_Obj *wEvent; - Jim_Obj *eEvent; - struct sockaddr sa; - struct hostent *he; -} AioFile; - -static int JimAioAcceptHelper(Jim_Interp *interp, AioFile *serv_af ); - -static void JimAioFileEventFinalizer(Jim_Interp *interp, void *clientData) -{ - Jim_Obj *objPtr = clientData; - - Jim_DecrRefCount(interp, objPtr); -} - -static int JimAioFileEventHandler(Jim_Interp *interp, void *clientData, int mask) -{ - Jim_Obj *objPtr = clientData; - Jim_Obj *scrPtr = NULL ; - if ( mask == (JIM_EVENT_READABLE | JIM_EVENT_FEOF)) { - Jim_ListIndex(interp, objPtr, 1, &scrPtr, 0); - } else { - Jim_ListIndex(interp, objPtr, 0, &scrPtr, 0); - } - // fprintf(stderr,"mask:%d\n",mask); - Jim_EvalObjBackground(interp, scrPtr); - return 0; -} - -static void JimAioSetError(Jim_Interp *interp) -{ - Jim_SetResultString(interp, strerror(errno), -1); -} - -static void JimAioDelProc(Jim_Interp *interp, void *privData) -{ - AioFile *af = privData; - JIM_NOTUSED(interp); - - if (!(af->OpenFlags & AIO_KEEPOPEN)) - fclose(af->fp); - if (!af->OpenFlags == AIO_FDOPEN) // fp = fdopen(fd) !! - close(af->fd); - if (af->rEvent) { // remove existing EventHandlers - fprintf(stderr,"deleting ReadEvent\n"); - Jim_DeleteFileHandler(interp,af->fp); - Jim_DecrRefCount(interp,af->rEvent); - } - if (af->wEvent) { - fprintf(stderr,"deleting WriteEvent\n"); - Jim_DeleteFileHandler(interp,af->fp); - Jim_DecrRefCount(interp,af->wEvent); - } - if (af->eEvent) { - fprintf(stderr,"deleting ExceptionEvent\n"); - Jim_DeleteFileHandler(interp,af->fp); - Jim_DecrRefCount(interp,af->eEvent); - } - Jim_Free(af); -} - -/* Calls to [aio.file] create commands that are implemented by this - * C command. */ -static int JimAioHandlerCommand(Jim_Interp *interp, int argc, - Jim_Obj *const *argv) -{ - AioFile *af = Jim_CmdPrivData(interp); - int option; - const char *options[] = { - "close", - "seek", "tell", - "gets", "read", "puts", - "flush", "eof", - "ndelay", - "readable", "writable", "onexception", - "accept", - NULL - }; - enum {OPT_CLOSE, - OPT_SEEK, OPT_TELL, - OPT_GETS, OPT_READ, OPT_PUTS, - OPT_FLUSH, OPT_EOF, - OPT_NDELAY, - OPT_READABLE, OPT_WRITABLE, OPT_EXCEPTION, - OPT_ACCEPT - }; - - if (argc < 2) { - Jim_WrongNumArgs(interp, 1, argv, "method ?args ...?"); - return JIM_ERR; - } - if (Jim_GetEnum(interp, argv[1], options, &option, "AIO method", - JIM_ERRMSG) != JIM_OK) - return JIM_ERR; - /* CLOSE */ - if (option == OPT_CLOSE) { - if (argc != 2) { - Jim_WrongNumArgs(interp, 2, argv, ""); - return JIM_ERR; - } - Jim_DeleteCommand(interp, Jim_GetString(argv[0], NULL)); - return JIM_OK; - } else if (option == OPT_SEEK) { - /* SEEK */ - int orig = SEEK_SET; - long offset; - - if (argc != 3 && argc != 4) { - Jim_WrongNumArgs(interp, 2, argv, "offset ?origin?"); - return JIM_ERR; - } - if (argc == 4) { - if (Jim_CompareStringImmediate(interp, argv[3], "start")) - orig = SEEK_SET; - else if (Jim_CompareStringImmediate(interp, argv[3], "current")) - orig = SEEK_CUR; - else if (Jim_CompareStringImmediate(interp, argv[3], "end")) - orig = SEEK_END; - else { - Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); - Jim_AppendStrings(interp, Jim_GetResult(interp), - "bad origin \"", Jim_GetString(argv[3], NULL), - "\" must be: start, current, or end", NULL); - return JIM_ERR; - } - } - if (Jim_GetLong(interp, argv[2], &offset) != JIM_OK) - return JIM_ERR; - if (fseek(af->fp, offset, orig) == -1) { - JimAioSetError(interp); - return JIM_ERR; - } - return JIM_OK; - } else if (option == OPT_TELL) { - /* TELL */ - long position; - - if (argc != 2) { - Jim_WrongNumArgs(interp, 2, argv, ""); - return JIM_ERR; - } - position = ftell(af->fp); - Jim_SetResult(interp, Jim_NewIntObj(interp, position)); - return JIM_OK; - } else if (option == OPT_GETS) { - /* GETS */ - char buf[AIO_BUF_LEN]; - Jim_Obj *objPtr; - - if (argc != 2 && argc != 3) { - Jim_WrongNumArgs(interp, 2, argv, "?varName?"); - return JIM_ERR; - } - objPtr = Jim_NewStringObj(interp, NULL, 0); - while (1) { - int more = 0; - buf[AIO_BUF_LEN-1] = '_'; - if (fgets(buf, AIO_BUF_LEN, af->fp) == NULL) - break; - if (buf[AIO_BUF_LEN-1] == '\0' && buf[AIO_BUF_LEN-2] != '\n') - more = 1; - if (more) { - Jim_AppendString(interp, objPtr, buf, AIO_BUF_LEN-1); - } else { - /* strip "\n" */ - Jim_AppendString(interp, objPtr, buf, strlen(buf)-1); - } - if (!more) - break; - } - if (ferror(af->fp) && (errno != EAGAIN)) { - /* I/O error */ - Jim_IncrRefCount(objPtr); - Jim_DecrRefCount(interp, objPtr); - JimAioSetError(interp); - return JIM_ERR; - } - /* On EOF returns -1 if varName was specified, or the empty string. */ - if (feof(af->fp) && Jim_Length(objPtr) == 0) { - Jim_IncrRefCount(objPtr); - Jim_DecrRefCount(interp, objPtr); - if (argc == 3) - Jim_SetResult(interp, Jim_NewIntObj(interp, -1)); - return JIM_OK; - } - if (argc == 3) { - int totLen; - - Jim_GetString(objPtr, &totLen); - if (Jim_SetVariable(interp, argv[2], objPtr) != JIM_OK) { - Jim_IncrRefCount(objPtr); - Jim_DecrRefCount(interp, objPtr); - return JIM_ERR; - } - Jim_SetResult(interp, Jim_NewIntObj(interp, totLen)); - } else { - Jim_SetResult(interp, objPtr); - } - return JIM_OK; - } else if (option == OPT_READ) { - /* READ */ - char buf[AIO_BUF_LEN]; - Jim_Obj *objPtr; - int nonewline = 0; - int neededLen = -1; /* -1 is "read as much as possible" */ - - if (argc != 2 && argc != 3) { - Jim_WrongNumArgs(interp, 2, argv, "?-nonewline? ?len?"); - return JIM_ERR; - } - if (argc == 3 && - Jim_CompareStringImmediate(interp, argv[2], "-nonewline")) - { - nonewline = 1; - argv++; - argc--; - } - if (argc == 3) { - jim_wide wideValue; - if (Jim_GetWide(interp, argv[2], &wideValue) != JIM_OK) - return JIM_ERR; - if (wideValue < 0) { - Jim_SetResultString(interp, "invalid parameter: negative len", - -1); - return JIM_ERR; - } - neededLen = (int) wideValue; - } - objPtr = Jim_NewStringObj(interp, NULL, 0); - while (neededLen != 0) { - int retval; - int readlen; - - if (neededLen == -1) { - readlen = AIO_BUF_LEN; - } else { - readlen = (neededLen > AIO_BUF_LEN ? AIO_BUF_LEN : neededLen); - } - retval = fread(buf, 1, readlen, af->fp); - if (retval > 0) { - Jim_AppendString(interp, objPtr, buf, retval); - if (neededLen != -1) { - neededLen -= retval; - } - } - if (retval != readlen) break; - } - /* Check for error conditions */ - if (ferror(af->fp)) { - /* I/O error */ - Jim_FreeNewObj(interp, objPtr); - JimAioSetError(interp); - return JIM_ERR; - } - if (nonewline) { - int len; - const char *s = Jim_GetString(objPtr, &len); - - if (len > 0 && s[len-1] == '\n') { - objPtr->length--; - objPtr->bytes[objPtr->length] = '\0'; - } - } - Jim_SetResult(interp, objPtr); - return JIM_OK; - } else if (option == OPT_PUTS) { - /* PUTS */ - int wlen; - const char *wdata; - - if (argc != 3 && (argc != 4 || !Jim_CompareStringImmediate( - interp, argv[2], "-nonewline"))) { - Jim_WrongNumArgs(interp, 2, argv, "?-nonewline? string"); - return JIM_ERR; - } - wdata = Jim_GetString(argv[2+(argc==4)], &wlen); - if (fwrite(wdata, 1, wlen, af->fp) != (unsigned)wlen || - (argc == 3 && fwrite("\n", 1, 1, af->fp) != 1)) { - JimAioSetError(interp); - return JIM_ERR; - } - return JIM_OK; - } else if (option == OPT_FLUSH) { - /* FLUSH */ - if (argc != 2) { - Jim_WrongNumArgs(interp, 2, argv, ""); - return JIM_ERR; - } - if (fflush(af->fp) == EOF) { - JimAioSetError(interp); - return JIM_ERR; - } - return JIM_OK; - } else if (option == OPT_EOF) { - /* EOF */ - if (argc != 2) { - Jim_WrongNumArgs(interp, 2, argv, ""); - return JIM_ERR; - } - Jim_SetResult(interp, Jim_NewIntObj(interp, feof(af->fp))); - return JIM_OK; - } else if (option == OPT_NDELAY) { -#ifdef O_NDELAY - int fmode = af->flags; - - if (argc == 3) { - jim_wide wideValue; - - if (Jim_GetWide(interp, argv[2], &wideValue) != JIM_OK) - return JIM_ERR; - switch (wideValue) { - case 0: - fmode &= ~O_NDELAY; break ; - case 1: - fmode |= O_NDELAY; break ; - } - fcntl(af->fd,F_SETFL,fmode); - af->flags = fmode; - } - Jim_SetResult(interp, Jim_NewIntObj(interp, (fmode & O_NONBLOCK)?1:0)); - return JIM_OK; -#else - return JIM_ERR; -#endif - } else if ( (option == OPT_READABLE) - || (option == OPT_WRITABLE) - || (option == OPT_EXCEPTION) - ) { - int mask = 0; - Jim_Obj **scrListObjpp = NULL; - Jim_Obj *listObj; - const char *dummy = NULL; - int scrlen = 0; - - if (!(Jim_CreateFileHandler && Jim_DeleteFileHandler)) { - Jim_SetResultString(interp, "Eventloop not present ( or loaded too late ) !", -1); - return JIM_ERR; - } - switch (option) { - case OPT_READABLE: mask = JIM_EVENT_READABLE; scrListObjpp = &af->rEvent; - if (argc == 4) mask |= JIM_EVENT_FEOF ; break; - case OPT_WRITABLE: mask = JIM_EVENT_WRITABLE; scrListObjpp = &af->wEvent; break; - case OPT_EXCEPTION: mask = JIM_EVENT_EXCEPTION; scrListObjpp = &af->eEvent; break; - } - switch (argc) { - case 4: - case 3: - if (*scrListObjpp) { - Jim_DeleteFileHandler(interp, af->fp); //,mask); - Jim_DecrRefCount(interp, *scrListObjpp); - *scrListObjpp = NULL; - } - if ( dummy = Jim_GetString(argv[2],&scrlen),(scrlen == 0)) { - break; - } else { - *scrListObjpp = Jim_NewListObj(interp, NULL, 0); - Jim_IncrRefCount(*scrListObjpp); - // fprintf(stderr,"0 %p \n",*scrListObjpp); - listObj = argv[2]; - if (Jim_IsShared(listObj)) - listObj = Jim_DuplicateObj(interp, listObj); - // Jim_IncrRefCount(listObj); - // fprintf(stderr,"script:\"%s\" argp: %p objp1: %p\n", Jim_GetString(argv[2], NULL),argv[2],listObj); - // fprintf(stderr,"1"); - Jim_ListAppendElement(interp,*scrListObjpp,listObj); - // fprintf(stderr,"2"); - if (mask & JIM_EVENT_FEOF) { - listObj = argv[3]; - if (Jim_IsShared(listObj)) - listObj = Jim_DuplicateObj(interp, listObj); - // Jim_IncrRefCount(listObj); - // fprintf(stderr,"script:\"%s\" argp: %p objp2: %p\n", Jim_GetString(argv[3], NULL),argv[3],listObj); - // fprintf(stderr,"3"); - Jim_ListAppendElement(interp,*scrListObjpp,listObj); - // fprintf(stderr,"4"); - } - // fprintf(stderr,"event readable fd: %d, script:\"%s\" objp3: %p\n",af->fd, Jim_GetString(argv[2], NULL),argv[2]); - Jim_IncrRefCount(*scrListObjpp); - // fprintf(stderr,"6 %p \n",Jim_CreateFileHandler); - Jim_CreateFileHandler(interp, af->fp, mask, - JimAioFileEventHandler, - *scrListObjpp, - JimAioFileEventFinalizer); - // fprintf(stderr,"7"); - } - break; - case 2: - if (*scrListObjpp) - Jim_SetResult(interp,*scrListObjpp); - return JIM_OK; - default: - Jim_WrongNumArgs(interp, 2, argv, ""); - return JIM_ERR; - } - } else if (option == OPT_ACCEPT) { - int ret; - fprintf(stderr,"ACCEPT\n"); - ret = JimAioAcceptHelper(interp,af); - fprintf(stderr,"ret %d\n",ret); - return (ret); - } - return JIM_OK; -} - -static int JimAioOpenCommand(Jim_Interp *interp, int argc, - Jim_Obj *const *argv) -{ - FILE *fp; - AioFile *af; - char buf[AIO_CMD_LEN]; - const char *mode = "r"; - Jim_Obj *objPtr; - long fileId; - const char *options[] = {"input", "output", "error", NULL}; - enum {OPT_INPUT, OPT_OUTPUT, OPT_ERROR}; - int OpenFlags = 0; - int modeLen; - - if (argc != 2 && argc != 3) { - Jim_WrongNumArgs(interp, 1, argv, "filename ?mode?"); - return JIM_ERR; - } - if (argc == 3) - mode = Jim_GetString(argv[2], &modeLen); - if (argc == 3 && Jim_CompareStringImmediate(interp, argv[1], "standard") && - modeLen >= 3) { - int option; - if (Jim_GetEnum(interp, argv[2], options, &option, "standard channel", - JIM_ERRMSG) != JIM_OK) - return JIM_ERR; - OpenFlags |= AIO_KEEPOPEN; - switch (option) { - case OPT_INPUT: fp = stdin; break; - case OPT_OUTPUT: fp = stdout; break; - case OPT_ERROR: fp = stderr; break; - default: fp = NULL; Jim_Panic(interp,"default reached in JimAioOpenCommand()"); - break; - } - } else { - fp = fopen(Jim_GetString(argv[1], NULL), mode); - if (fp == NULL) { - JimAioSetError(interp); - return JIM_ERR; - } - } - /* Get the next file id */ - if (Jim_EvalGlobal(interp, - "if {[catch {incr aio.fileId}]} {set aio.fileId 0}") != JIM_OK) - return JIM_ERR; - objPtr = Jim_GetGlobalVariableStr(interp, "aio.fileId", JIM_ERRMSG); - if (objPtr == NULL) return JIM_ERR; - if (Jim_GetLong(interp, objPtr, &fileId) != JIM_OK) return JIM_ERR; - - /* Create the file command */ - af = Jim_Alloc(sizeof(*af)); - af->fp = fp; - af->fd = fileno(fp); - af->flags = fcntl(af->fd,F_GETFL); - af->OpenFlags = OpenFlags; - // fprintf(stderr,"hallo\n"); - af->rEvent = NULL; - af->wEvent = NULL; - af->eEvent = NULL; - sprintf(buf, "aio.handle%ld", fileId); - Jim_CreateCommand(interp, buf, JimAioHandlerCommand, af, JimAioDelProc); - Jim_SetResultString(interp, buf, -1); - return JIM_OK; -} - -static int JimAioSockCommand(Jim_Interp *interp, int argc, - Jim_Obj *const *argv) -{ - FILE *fp; - AioFile *af; - char buf[AIO_CMD_LEN]; - char *hdlfmt; - // const char *mode = "r"; - Jim_Obj *objPtr; - long fileId; - const char *socktypes[] = { - "file", - "pipe", - "tty", - "domain", - "dgram", - "stream", - "stream.server", - - NULL - }; - enum { - FILE_FILE, - FILE_PIPE, - FILE_TTY, - SOCK_DOMAIN, - SOCK_DGRAM_CL, - SOCK_STREAM_CL, - SOCK_STREAM_SERV - }; - int socktype; - int sock; - const char *hostportarg; - int hostportlen; - char a[0x20]; - char b[0x20]; - char c[0x20]; - char np[] = "0"; - char nh[] = "0.0.0.0"; - char* stsrcport; - char* sthost; - char* stport; - unsigned int srcport; - unsigned int port; - struct sockaddr_in sa; - struct hostent *he; - int res; - - if (argc <= 2 ) { - Jim_WrongNumArgs(interp, 1, argv, "sockspec ?script?"); - return JIM_ERR; - } - - if (Jim_GetEnum(interp, argv[1], socktypes, &socktype, "socket type", - JIM_ERRMSG) != JIM_OK) - return JIM_ERR; - fprintf(stderr,"socktype: %s \n",socktypes[socktype]); - hostportarg = Jim_GetString(argv[2], &hostportlen); - fprintf(stderr,"hostportarg: %s %d \n",hostportarg,hostportlen); - switch (sscanf(hostportarg,"%[^:]:%[^:]:%[^:]",a,b,c)) { - case 3: stsrcport = a; sthost = b; stport = c; break; - case 2: stsrcport = np; sthost = a; stport = b; break; - case 1: stsrcport = np; sthost = nh; stport = a; break; - default: - return JIM_ERR; - } - fprintf(stderr,"socktype: %d srcport: %s host:%s port %s \n", - socktype,stsrcport,sthost,stport); - if (0 == strncmp(sthost,"ANY",3)) - sthost = "0.0.0.0"; - srcport = atol(stsrcport); - port = atol(stport); - he = gethostbyname(sthost); - /* FIX!!!! this still results in null pointer exception here. - /* FIXED!!!! debug output but no JIM_ERR done UK. - if (!he) { - Jim_SetResultString(interp,hstrerror(h_errno),-1); - return JIM_ERR; - } - - fprintf(stderr,"Official name is: %s\n", he->h_name); - fprintf(stderr,"IP address: %s\n", inet_ntoa(*(struct in_addr*)he->h_addr)); - */ - - sock = socket(PF_INET,SOCK_STREAM,0); - fprintf(stderr,"srcp: %x port: %x IP: %x sock: %d type: %d\n",srcport,port,he->h_addr,sock,socktype); - switch (socktype) { - case SOCK_DGRAM_CL: - hdlfmt = "aio.sockdgram%ld" ; - break; - case SOCK_STREAM_CL: - fprintf(stderr,"setting up client socket\n"); - sa.sin_family= he->h_addrtype; - bcopy(he->h_addr,(char *)&sa.sin_addr,he->h_length); /* set address */ - sa.sin_port = htons(port); - res = connect(sock,(struct sockaddr*)&sa,sizeof(sa)); - if (res) { - close(sock); - JimAioSetError(interp); - return JIM_ERR; - } - hdlfmt = "aio.sockstrm%ld" ; - break; - case SOCK_STREAM_SERV: - fprintf(stderr,"setting up listening socket\n"); - sa.sin_family= he->h_addrtype; - bcopy(he->h_addr,(char *)&sa.sin_addr,he->h_length); /* set address */ - sa.sin_port = htons(port); - res = bind(sock,(struct sockaddr*)&sa,sizeof(sa)); - if (res) { - close(sock); - JimAioSetError(interp); - return JIM_ERR; - } - res = listen(sock,5); - if (res) { - close(sock); - JimAioSetError(interp); - return JIM_ERR; - } - hdlfmt = "aio.socksrv%ld" ; - break; - } - fp = fdopen(sock, "r+" ); - fprintf(stderr,"fp: %p \n",fp); - if (fp == NULL) { - close(sock); - JimAioSetError(interp); - return JIM_ERR; - } - /* Get the next file id */ - if (Jim_EvalGlobal(interp, - "if {[catch {incr aio.fileId}]} {set aio.fileId 0}") != JIM_OK) - return JIM_ERR; - objPtr = Jim_GetGlobalVariableStr(interp, "aio.fileId", JIM_ERRMSG); - if (objPtr == NULL) return JIM_ERR; - if (Jim_GetLong(interp, objPtr, &fileId) != JIM_OK) return JIM_ERR; - - /* Create the file command */ - af = Jim_Alloc(sizeof(*af)); - af->fp = fp; - af->fd = sock; - af->OpenFlags = AIO_FDOPEN; - af->flags = fcntl(af->fd,F_GETFL); - fprintf(stderr,"hallo\n"); - af->rEvent = NULL; - af->wEvent = NULL; - af->eEvent = NULL; - sprintf(buf, hdlfmt, fileId); - fprintf(stderr,"hallo:%s\n",buf); - Jim_CreateCommand(interp, buf, JimAioHandlerCommand, af, JimAioDelProc); - Jim_SetResultString(interp, buf, -1); - return JIM_OK; -} - -static int JimAioAcceptHelper(Jim_Interp *interp, AioFile *serv_af ) -{ - int sock; - int addrlen = sizeof(struct sockaddr_in); - AioFile *af; - char buf[AIO_CMD_LEN]; - Jim_Obj *objPtr; - long fileId; - fprintf(stderr,"accepting connection for %d \n",serv_af->fd); - sock = accept(serv_af->fd,(struct sockaddr*)&serv_af->sa,&addrlen); - fprintf(stderr,"done, got %d \n",sock); - if (sock < 0) - return JIM_ERR; - - /* Get the next file id */ - fprintf(stderr,"getting fileid:"); - if (Jim_EvalGlobal(interp, - "if {[catch {incr aio.fileId}]} {set aio.fileId 0}") != JIM_OK) - return JIM_ERR; - objPtr = Jim_GetGlobalVariableStr(interp, "aio.fileId", JIM_ERRMSG); - if (objPtr == NULL) return JIM_ERR; - if (Jim_GetLong(interp, objPtr, &fileId) != JIM_OK) return JIM_ERR; - fprintf(stderr," %ld\n", fileId); - - /* Create the file command */ - af = Jim_Alloc(sizeof(*af)); - af->fd = sock; - af->fp = fdopen(sock,"r+"); - af->OpenFlags = AIO_FDOPEN; - af->flags = fcntl(af->fd,F_GETFL); - // fprintf(stderr,"hallo\n"); - af->rEvent = NULL; - af->wEvent = NULL; - af->eEvent = NULL; - sprintf(buf, "aio.sockstream%ld", fileId); - Jim_CreateCommand(interp, buf, JimAioHandlerCommand, af, JimAioDelProc); - Jim_SetResultString(interp, buf, -1); - fprintf(stderr,"returning\n"); - return JIM_OK; -} - -DLLEXPORT int -#ifndef JIM_STATICEXT -Jim_OnLoad(Jim_Interp *interp) -#else -Jim_AioInit(Jim_Interp *interp) -#endif -{ -#ifndef JIM_STATICEXT - Jim_InitExtension(interp); - Jim_ImportEventloopAPI(interp); -#endif - if (Jim_PackageProvide(interp, "aio", "1.0", JIM_ERRMSG) != JIM_OK) - return JIM_ERR; - Jim_CreateCommand(interp, "aio.open", JimAioOpenCommand, NULL, NULL); - Jim_CreateCommand(interp, "aio.socket", JimAioSockCommand, NULL, NULL); - return JIM_OK; -} - -// end - +/* Jim - A small embeddable Tcl interpreter
+ *
+ * Copyright 2005 Salvatore Sanfilippo <antirez@invece.org>
+ * Copyright 2005 Clemens Hintze <c.hintze@gmx.net>
+ * Copyright 2005 patthoyts - Pat Thoyts <patthoyts@users.sf.net>
+ * Copyright 2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com
+ * Copyright 2008 Andrew Lunn <andrew@lunn.ch>
+ * Copyright 2008 Duane Ellis <openocd@duaneellis.com>
+ * Copyright 2008 Uwe Klein <uklein@klein-messgeraete.de>
+ *
+ * The FreeBSD license
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``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
+ * JIM TCL PROJECT 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.
+ *
+ * The views and conclusions contained in the software and documentation
+ * are those of the authors and should not be interpreted as representing
+ * official policies, either expressed or implied, of the Jim Tcl Project.
+ **/
+
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#ifdef __ECOS
+#include <pkgconf/jimtcl.h>
+#endif
+#ifndef JIM_STATICEXT
+#define JIM_EXTENSION
+#endif
+
+/* FIX!!! add #if's to make JIM_SUPPORT_EVENTLOOP enable/disable
+ * eventloop support compile time! */
+#ifndef JIM_SUPPORT_EVENTLOOP
+#define JIM_SUPPORT_EVENTLOOP 1
+#endif
+
+#ifdef __ECOS
+#include <cyg/jimtcl/jim.h>
+#include <cyg/jimtcl/jim-eventloop.h>
+#else
+#include "jim.h"
+#include "jim-eventloop.h"
+#endif
+
+
+
+
+#define AIO_CMD_LEN 128
+#define AIO_BUF_LEN 1024
+
+#define AIO_KEEPOPEN 1
+#define AIO_FDOPEN 2
+
+
+typedef struct AioFile {
+ FILE *fp;
+ int type;
+ int OpenFlags; /* AIO_KEEPOPEN? keep FILE*, AIO_FDOPEN? FILE* created via fdopen */
+ int fd;
+ int flags;
+ Jim_Obj *rEvent;
+ Jim_Obj *wEvent;
+ Jim_Obj *eEvent;
+ struct sockaddr sa;
+ struct hostent *he;
+} AioFile;
+
+static int JimAioAcceptHelper(Jim_Interp *interp, AioFile *serv_af );
+
+static void JimAioFileEventFinalizer(Jim_Interp *interp, void *clientData)
+{
+ Jim_Obj *objPtr = clientData;
+
+ Jim_DecrRefCount(interp, objPtr);
+}
+
+static int JimAioFileEventHandler(Jim_Interp *interp, void *clientData, int mask)
+{
+ Jim_Obj *objPtr = clientData;
+ Jim_Obj *scrPtr = NULL ;
+ if ( mask == (JIM_EVENT_READABLE | JIM_EVENT_FEOF)) {
+ Jim_ListIndex(interp, objPtr, 1, &scrPtr, 0);
+ } else {
+ Jim_ListIndex(interp, objPtr, 0, &scrPtr, 0);
+ }
+ // fprintf(stderr,"mask:%d\n",mask);
+ Jim_EvalObjBackground(interp, scrPtr);
+ return 0;
+}
+
+static void JimAioSetError(Jim_Interp *interp)
+{
+ Jim_SetResultString(interp, strerror(errno), -1);
+}
+
+static void JimAioDelProc(Jim_Interp *interp, void *privData)
+{
+ AioFile *af = privData;
+ JIM_NOTUSED(interp);
+
+ if (!(af->OpenFlags & AIO_KEEPOPEN))
+ fclose(af->fp);
+ if (!af->OpenFlags == AIO_FDOPEN) // fp = fdopen(fd) !!
+ close(af->fd);
+ if (af->rEvent) { // remove existing EventHandlers
+ fprintf(stderr,"deleting ReadEvent\n");
+ Jim_DeleteFileHandler(interp,af->fp);
+ Jim_DecrRefCount(interp,af->rEvent);
+ }
+ if (af->wEvent) {
+ fprintf(stderr,"deleting WriteEvent\n");
+ Jim_DeleteFileHandler(interp,af->fp);
+ Jim_DecrRefCount(interp,af->wEvent);
+ }
+ if (af->eEvent) {
+ fprintf(stderr,"deleting ExceptionEvent\n");
+ Jim_DeleteFileHandler(interp,af->fp);
+ Jim_DecrRefCount(interp,af->eEvent);
+ }
+ Jim_Free(af);
+}
+
+/* Calls to [aio.file] create commands that are implemented by this
+ * C command. */
+static int JimAioHandlerCommand(Jim_Interp *interp, int argc,
+ Jim_Obj *const *argv)
+{
+ AioFile *af = Jim_CmdPrivData(interp);
+ int option;
+ const char *options[] = {
+ "close",
+ "seek", "tell",
+ "gets", "read", "puts",
+ "flush", "eof",
+ "ndelay",
+ "readable", "writable", "onexception",
+ "accept",
+ NULL
+ };
+ enum {OPT_CLOSE,
+ OPT_SEEK, OPT_TELL,
+ OPT_GETS, OPT_READ, OPT_PUTS,
+ OPT_FLUSH, OPT_EOF,
+ OPT_NDELAY,
+ OPT_READABLE, OPT_WRITABLE, OPT_EXCEPTION,
+ OPT_ACCEPT
+ };
+
+ if (argc < 2) {
+ Jim_WrongNumArgs(interp, 1, argv, "method ?args ...?");
+ return JIM_ERR;
+ }
+ if (Jim_GetEnum(interp, argv[1], options, &option, "AIO method",
+ JIM_ERRMSG) != JIM_OK)
+ return JIM_ERR;
+ /* CLOSE */
+ if (option == OPT_CLOSE) {
+ if (argc != 2) {
+ Jim_WrongNumArgs(interp, 2, argv, "");
+ return JIM_ERR;
+ }
+ Jim_DeleteCommand(interp, Jim_GetString(argv[0], NULL));
+ return JIM_OK;
+ } else if (option == OPT_SEEK) {
+ /* SEEK */
+ int orig = SEEK_SET;
+ long offset;
+
+ if (argc != 3 && argc != 4) {
+ Jim_WrongNumArgs(interp, 2, argv, "offset ?origin?");
+ return JIM_ERR;
+ }
+ if (argc == 4) {
+ if (Jim_CompareStringImmediate(interp, argv[3], "start"))
+ orig = SEEK_SET;
+ else if (Jim_CompareStringImmediate(interp, argv[3], "current"))
+ orig = SEEK_CUR;
+ else if (Jim_CompareStringImmediate(interp, argv[3], "end"))
+ orig = SEEK_END;
+ else {
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ Jim_AppendStrings(interp, Jim_GetResult(interp),
+ "bad origin \"", Jim_GetString(argv[3], NULL),
+ "\" must be: start, current, or end", NULL);
+ return JIM_ERR;
+ }
+ }
+ if (Jim_GetLong(interp, argv[2], &offset) != JIM_OK)
+ return JIM_ERR;
+ if (fseek(af->fp, offset, orig) == -1) {
+ JimAioSetError(interp);
+ return JIM_ERR;
+ }
+ return JIM_OK;
+ } else if (option == OPT_TELL) {
+ /* TELL */
+ long position;
+
+ if (argc != 2) {
+ Jim_WrongNumArgs(interp, 2, argv, "");
+ return JIM_ERR;
+ }
+ position = ftell(af->fp);
+ Jim_SetResult(interp, Jim_NewIntObj(interp, position));
+ return JIM_OK;
+ } else if (option == OPT_GETS) {
+ /* GETS */
+ char buf[AIO_BUF_LEN];
+ Jim_Obj *objPtr;
+
+ if (argc != 2 && argc != 3) {
+ Jim_WrongNumArgs(interp, 2, argv, "?varName?");
+ return JIM_ERR;
+ }
+ objPtr = Jim_NewStringObj(interp, NULL, 0);
+ while (1) {
+ int more = 0;
+ buf[AIO_BUF_LEN-1] = '_';
+ if (fgets(buf, AIO_BUF_LEN, af->fp) == NULL)
+ break;
+ if (buf[AIO_BUF_LEN-1] == '\0' && buf[AIO_BUF_LEN-2] != '\n')
+ more = 1;
+ if (more) {
+ Jim_AppendString(interp, objPtr, buf, AIO_BUF_LEN-1);
+ } else {
+ /* strip "\n" */
+ Jim_AppendString(interp, objPtr, buf, strlen(buf)-1);
+ }
+ if (!more)
+ break;
+ }
+ if (ferror(af->fp) && (errno != EAGAIN)) {
+ /* I/O error */
+ Jim_IncrRefCount(objPtr);
+ Jim_DecrRefCount(interp, objPtr);
+ JimAioSetError(interp);
+ return JIM_ERR;
+ }
+ /* On EOF returns -1 if varName was specified, or the empty string. */
+ if (feof(af->fp) && Jim_Length(objPtr) == 0) {
+ Jim_IncrRefCount(objPtr);
+ Jim_DecrRefCount(interp, objPtr);
+ if (argc == 3)
+ Jim_SetResult(interp, Jim_NewIntObj(interp, -1));
+ return JIM_OK;
+ }
+ if (argc == 3) {
+ int totLen;
+
+ Jim_GetString(objPtr, &totLen);
+ if (Jim_SetVariable(interp, argv[2], objPtr) != JIM_OK) {
+ Jim_IncrRefCount(objPtr);
+ Jim_DecrRefCount(interp, objPtr);
+ return JIM_ERR;
+ }
+ Jim_SetResult(interp, Jim_NewIntObj(interp, totLen));
+ } else {
+ Jim_SetResult(interp, objPtr);
+ }
+ return JIM_OK;
+ } else if (option == OPT_READ) {
+ /* READ */
+ char buf[AIO_BUF_LEN];
+ Jim_Obj *objPtr;
+ int nonewline = 0;
+ int neededLen = -1; /* -1 is "read as much as possible" */
+
+ if (argc != 2 && argc != 3) {
+ Jim_WrongNumArgs(interp, 2, argv, "?-nonewline? ?len?");
+ return JIM_ERR;
+ }
+ if (argc == 3 &&
+ Jim_CompareStringImmediate(interp, argv[2], "-nonewline"))
+ {
+ nonewline = 1;
+ argv++;
+ argc--;
+ }
+ if (argc == 3) {
+ jim_wide wideValue;
+ if (Jim_GetWide(interp, argv[2], &wideValue) != JIM_OK)
+ return JIM_ERR;
+ if (wideValue < 0) {
+ Jim_SetResultString(interp, "invalid parameter: negative len",
+ -1);
+ return JIM_ERR;
+ }
+ neededLen = (int) wideValue;
+ }
+ objPtr = Jim_NewStringObj(interp, NULL, 0);
+ while (neededLen != 0) {
+ int retval;
+ int readlen;
+
+ if (neededLen == -1) {
+ readlen = AIO_BUF_LEN;
+ } else {
+ readlen = (neededLen > AIO_BUF_LEN ? AIO_BUF_LEN : neededLen);
+ }
+ retval = fread(buf, 1, readlen, af->fp);
+ if (retval > 0) {
+ Jim_AppendString(interp, objPtr, buf, retval);
+ if (neededLen != -1) {
+ neededLen -= retval;
+ }
+ }
+ if (retval != readlen) break;
+ }
+ /* Check for error conditions */
+ if (ferror(af->fp)) {
+ /* I/O error */
+ Jim_FreeNewObj(interp, objPtr);
+ JimAioSetError(interp);
+ return JIM_ERR;
+ }
+ if (nonewline) {
+ int len;
+ const char *s = Jim_GetString(objPtr, &len);
+
+ if (len > 0 && s[len-1] == '\n') {
+ objPtr->length--;
+ objPtr->bytes[objPtr->length] = '\0';
+ }
+ }
+ Jim_SetResult(interp, objPtr);
+ return JIM_OK;
+ } else if (option == OPT_PUTS) {
+ /* PUTS */
+ int wlen;
+ const char *wdata;
+
+ if (argc != 3 && (argc != 4 || !Jim_CompareStringImmediate(
+ interp, argv[2], "-nonewline"))) {
+ Jim_WrongNumArgs(interp, 2, argv, "?-nonewline? string");
+ return JIM_ERR;
+ }
+ wdata = Jim_GetString(argv[2+(argc==4)], &wlen);
+ if (fwrite(wdata, 1, wlen, af->fp) != (unsigned)wlen ||
+ (argc == 3 && fwrite("\n", 1, 1, af->fp) != 1)) {
+ JimAioSetError(interp);
+ return JIM_ERR;
+ }
+ return JIM_OK;
+ } else if (option == OPT_FLUSH) {
+ /* FLUSH */
+ if (argc != 2) {
+ Jim_WrongNumArgs(interp, 2, argv, "");
+ return JIM_ERR;
+ }
+ if (fflush(af->fp) == EOF) {
+ JimAioSetError(interp);
+ return JIM_ERR;
+ }
+ return JIM_OK;
+ } else if (option == OPT_EOF) {
+ /* EOF */
+ if (argc != 2) {
+ Jim_WrongNumArgs(interp, 2, argv, "");
+ return JIM_ERR;
+ }
+ Jim_SetResult(interp, Jim_NewIntObj(interp, feof(af->fp)));
+ return JIM_OK;
+ } else if (option == OPT_NDELAY) {
+#ifdef O_NDELAY
+ int fmode = af->flags;
+
+ if (argc == 3) {
+ jim_wide wideValue;
+
+ if (Jim_GetWide(interp, argv[2], &wideValue) != JIM_OK)
+ return JIM_ERR;
+ switch (wideValue) {
+ case 0:
+ fmode &= ~O_NDELAY; break ;
+ case 1:
+ fmode |= O_NDELAY; break ;
+ }
+ fcntl(af->fd,F_SETFL,fmode);
+ af->flags = fmode;
+ }
+ Jim_SetResult(interp, Jim_NewIntObj(interp, (fmode & O_NONBLOCK)?1:0));
+ return JIM_OK;
+#else
+ return JIM_ERR;
+#endif
+ } else if ( (option == OPT_READABLE)
+ || (option == OPT_WRITABLE)
+ || (option == OPT_EXCEPTION)
+ ) {
+ int mask = 0;
+ Jim_Obj **scrListObjpp = NULL;
+ Jim_Obj *listObj;
+ const char *dummy = NULL;
+ int scrlen = 0;
+
+ if (!(Jim_CreateFileHandler && Jim_DeleteFileHandler)) {
+ Jim_SetResultString(interp, "Eventloop not present ( or loaded too late ) !", -1);
+ return JIM_ERR;
+ }
+ switch (option) {
+ case OPT_READABLE: mask = JIM_EVENT_READABLE; scrListObjpp = &af->rEvent;
+ if (argc == 4) mask |= JIM_EVENT_FEOF ; break;
+ case OPT_WRITABLE: mask = JIM_EVENT_WRITABLE; scrListObjpp = &af->wEvent; break;
+ case OPT_EXCEPTION: mask = JIM_EVENT_EXCEPTION; scrListObjpp = &af->eEvent; break;
+ }
+ switch (argc) {
+ case 4:
+ case 3:
+ if (*scrListObjpp) {
+ Jim_DeleteFileHandler(interp, af->fp); //,mask);
+ Jim_DecrRefCount(interp, *scrListObjpp);
+ *scrListObjpp = NULL;
+ }
+ if ( dummy = Jim_GetString(argv[2],&scrlen),(scrlen == 0)) {
+ break;
+ } else {
+ *scrListObjpp = Jim_NewListObj(interp, NULL, 0);
+ Jim_IncrRefCount(*scrListObjpp);
+ // fprintf(stderr,"0 %p \n",*scrListObjpp);
+ listObj = argv[2];
+ if (Jim_IsShared(listObj))
+ listObj = Jim_DuplicateObj(interp, listObj);
+ // Jim_IncrRefCount(listObj);
+ // fprintf(stderr,"script:\"%s\" argp: %p objp1: %p\n", Jim_GetString(argv[2], NULL),argv[2],listObj);
+ // fprintf(stderr,"1");
+ Jim_ListAppendElement(interp,*scrListObjpp,listObj);
+ // fprintf(stderr,"2");
+ if (mask & JIM_EVENT_FEOF) {
+ listObj = argv[3];
+ if (Jim_IsShared(listObj))
+ listObj = Jim_DuplicateObj(interp, listObj);
+ // Jim_IncrRefCount(listObj);
+ // fprintf(stderr,"script:\"%s\" argp: %p objp2: %p\n", Jim_GetString(argv[3], NULL),argv[3],listObj);
+ // fprintf(stderr,"3");
+ Jim_ListAppendElement(interp,*scrListObjpp,listObj);
+ // fprintf(stderr,"4");
+ }
+ // fprintf(stderr,"event readable fd: %d, script:\"%s\" objp3: %p\n",af->fd, Jim_GetString(argv[2], NULL),argv[2]);
+ Jim_IncrRefCount(*scrListObjpp);
+ // fprintf(stderr,"6 %p \n",Jim_CreateFileHandler);
+ Jim_CreateFileHandler(interp, af->fp, mask,
+ JimAioFileEventHandler,
+ *scrListObjpp,
+ JimAioFileEventFinalizer);
+ // fprintf(stderr,"7");
+ }
+ break;
+ case 2:
+ if (*scrListObjpp)
+ Jim_SetResult(interp,*scrListObjpp);
+ return JIM_OK;
+ default:
+ Jim_WrongNumArgs(interp, 2, argv, "");
+ return JIM_ERR;
+ }
+ } else if (option == OPT_ACCEPT) {
+ int ret;
+ fprintf(stderr,"ACCEPT\n");
+ ret = JimAioAcceptHelper(interp,af);
+ fprintf(stderr,"ret %d\n",ret);
+ return (ret);
+ }
+ return JIM_OK;
+}
+
+static int JimAioOpenCommand(Jim_Interp *interp, int argc,
+ Jim_Obj *const *argv)
+{
+ FILE *fp;
+ AioFile *af;
+ char buf[AIO_CMD_LEN];
+ const char *mode = "r";
+ Jim_Obj *objPtr;
+ long fileId;
+ const char *options[] = {"input", "output", "error", NULL};
+ enum {OPT_INPUT, OPT_OUTPUT, OPT_ERROR};
+ int OpenFlags = 0;
+ int modeLen;
+
+ if (argc != 2 && argc != 3) {
+ Jim_WrongNumArgs(interp, 1, argv, "filename ?mode?");
+ return JIM_ERR;
+ }
+ if (argc == 3)
+ mode = Jim_GetString(argv[2], &modeLen);
+ if (argc == 3 && Jim_CompareStringImmediate(interp, argv[1], "standard") &&
+ modeLen >= 3) {
+ int option;
+ if (Jim_GetEnum(interp, argv[2], options, &option, "standard channel",
+ JIM_ERRMSG) != JIM_OK)
+ return JIM_ERR;
+ OpenFlags |= AIO_KEEPOPEN;
+ switch (option) {
+ case OPT_INPUT: fp = stdin; break;
+ case OPT_OUTPUT: fp = stdout; break;
+ case OPT_ERROR: fp = stderr; break;
+ default: fp = NULL; Jim_Panic(interp,"default reached in JimAioOpenCommand()");
+ break;
+ }
+ } else {
+ fp = fopen(Jim_GetString(argv[1], NULL), mode);
+ if (fp == NULL) {
+ JimAioSetError(interp);
+ return JIM_ERR;
+ }
+ }
+ /* Get the next file id */
+ if (Jim_EvalGlobal(interp,
+ "if {[catch {incr aio.fileId}]} {set aio.fileId 0}") != JIM_OK)
+ return JIM_ERR;
+ objPtr = Jim_GetGlobalVariableStr(interp, "aio.fileId", JIM_ERRMSG);
+ if (objPtr == NULL) return JIM_ERR;
+ if (Jim_GetLong(interp, objPtr, &fileId) != JIM_OK) return JIM_ERR;
+
+ /* Create the file command */
+ af = Jim_Alloc(sizeof(*af));
+ af->fp = fp;
+ af->fd = fileno(fp);
+ af->flags = fcntl(af->fd,F_GETFL);
+ af->OpenFlags = OpenFlags;
+ // fprintf(stderr,"hallo\n");
+ af->rEvent = NULL;
+ af->wEvent = NULL;
+ af->eEvent = NULL;
+ sprintf(buf, "aio.handle%ld", fileId);
+ Jim_CreateCommand(interp, buf, JimAioHandlerCommand, af, JimAioDelProc);
+ Jim_SetResultString(interp, buf, -1);
+ return JIM_OK;
+}
+
+static int JimAioSockCommand(Jim_Interp *interp, int argc,
+ Jim_Obj *const *argv)
+{
+ FILE *fp;
+ AioFile *af;
+ char buf[AIO_CMD_LEN];
+ char *hdlfmt;
+ // const char *mode = "r";
+ Jim_Obj *objPtr;
+ long fileId;
+ const char *socktypes[] = {
+ "file",
+ "pipe",
+ "tty",
+ "domain",
+ "dgram",
+ "stream",
+ "stream.server",
+
+ NULL
+ };
+ enum {
+ FILE_FILE,
+ FILE_PIPE,
+ FILE_TTY,
+ SOCK_DOMAIN,
+ SOCK_DGRAM_CL,
+ SOCK_STREAM_CL,
+ SOCK_STREAM_SERV
+ };
+ int socktype;
+ int sock;
+ const char *hostportarg;
+ int hostportlen;
+ char a[0x20];
+ char b[0x20];
+ char c[0x20];
+ char np[] = "0";
+ char nh[] = "0.0.0.0";
+ char* stsrcport;
+ char* sthost;
+ char* stport;
+ unsigned int srcport;
+ unsigned int port;
+ struct sockaddr_in sa;
+ struct hostent *he;
+ int res;
+
+ if (argc <= 2 ) {
+ Jim_WrongNumArgs(interp, 1, argv, "sockspec ?script?");
+ return JIM_ERR;
+ }
+
+ if (Jim_GetEnum(interp, argv[1], socktypes, &socktype, "socket type",
+ JIM_ERRMSG) != JIM_OK)
+ return JIM_ERR;
+ fprintf(stderr,"socktype: %s \n",socktypes[socktype]);
+ hostportarg = Jim_GetString(argv[2], &hostportlen);
+ fprintf(stderr,"hostportarg: %s %d \n",hostportarg,hostportlen);
+ switch (sscanf(hostportarg,"%[^:]:%[^:]:%[^:]",a,b,c)) {
+ case 3: stsrcport = a; sthost = b; stport = c; break;
+ case 2: stsrcport = np; sthost = a; stport = b; break;
+ case 1: stsrcport = np; sthost = nh; stport = a; break;
+ default:
+ return JIM_ERR;
+ }
+ fprintf(stderr,"socktype: %d srcport: %s host:%s port %s \n",
+ socktype,stsrcport,sthost,stport);
+ if (0 == strncmp(sthost,"ANY",3))
+ sthost = "0.0.0.0";
+ srcport = atol(stsrcport);
+ port = atol(stport);
+ he = gethostbyname(sthost);
+ /* FIX!!!! this still results in null pointer exception here.
+ /* FIXED!!!! debug output but no JIM_ERR done UK.
+ if (!he) {
+ Jim_SetResultString(interp,hstrerror(h_errno),-1);
+ return JIM_ERR;
+ }
+
+ fprintf(stderr,"Official name is: %s\n", he->h_name);
+ fprintf(stderr,"IP address: %s\n", inet_ntoa(*(struct in_addr*)he->h_addr));
+ */
+
+ sock = socket(PF_INET,SOCK_STREAM,0);
+ fprintf(stderr,"srcp: %x port: %x IP: %x sock: %d type: %d\n",srcport,port,he->h_addr,sock,socktype);
+ switch (socktype) {
+ case SOCK_DGRAM_CL:
+ hdlfmt = "aio.sockdgram%ld" ;
+ break;
+ case SOCK_STREAM_CL:
+ fprintf(stderr,"setting up client socket\n");
+ sa.sin_family= he->h_addrtype;
+ bcopy(he->h_addr,(char *)&sa.sin_addr,he->h_length); /* set address */
+ sa.sin_port = htons(port);
+ res = connect(sock,(struct sockaddr*)&sa,sizeof(sa));
+ if (res) {
+ close(sock);
+ JimAioSetError(interp);
+ return JIM_ERR;
+ }
+ hdlfmt = "aio.sockstrm%ld" ;
+ break;
+ case SOCK_STREAM_SERV:
+ fprintf(stderr,"setting up listening socket\n");
+ sa.sin_family= he->h_addrtype;
+ bcopy(he->h_addr,(char *)&sa.sin_addr,he->h_length); /* set address */
+ sa.sin_port = htons(port);
+ res = bind(sock,(struct sockaddr*)&sa,sizeof(sa));
+ if (res) {
+ close(sock);
+ JimAioSetError(interp);
+ return JIM_ERR;
+ }
+ res = listen(sock,5);
+ if (res) {
+ close(sock);
+ JimAioSetError(interp);
+ return JIM_ERR;
+ }
+ hdlfmt = "aio.socksrv%ld" ;
+ break;
+ }
+ fp = fdopen(sock, "r+" );
+ fprintf(stderr,"fp: %p \n",fp);
+ if (fp == NULL) {
+ close(sock);
+ JimAioSetError(interp);
+ return JIM_ERR;
+ }
+ /* Get the next file id */
+ if (Jim_EvalGlobal(interp,
+ "if {[catch {incr aio.fileId}]} {set aio.fileId 0}") != JIM_OK)
+ return JIM_ERR;
+ objPtr = Jim_GetGlobalVariableStr(interp, "aio.fileId", JIM_ERRMSG);
+ if (objPtr == NULL) return JIM_ERR;
+ if (Jim_GetLong(interp, objPtr, &fileId) != JIM_OK) return JIM_ERR;
+
+ /* Create the file command */
+ af = Jim_Alloc(sizeof(*af));
+ af->fp = fp;
+ af->fd = sock;
+ af->OpenFlags = AIO_FDOPEN;
+ af->flags = fcntl(af->fd,F_GETFL);
+ fprintf(stderr,"hallo\n");
+ af->rEvent = NULL;
+ af->wEvent = NULL;
+ af->eEvent = NULL;
+ sprintf(buf, hdlfmt, fileId);
+ fprintf(stderr,"hallo:%s\n",buf);
+ Jim_CreateCommand(interp, buf, JimAioHandlerCommand, af, JimAioDelProc);
+ Jim_SetResultString(interp, buf, -1);
+ return JIM_OK;
+}
+
+static int JimAioAcceptHelper(Jim_Interp *interp, AioFile *serv_af )
+{
+ int sock;
+ int addrlen = sizeof(struct sockaddr_in);
+ AioFile *af;
+ char buf[AIO_CMD_LEN];
+ Jim_Obj *objPtr;
+ long fileId;
+ fprintf(stderr,"accepting connection for %d \n",serv_af->fd);
+ sock = accept(serv_af->fd,(struct sockaddr*)&serv_af->sa,&addrlen);
+ fprintf(stderr,"done, got %d \n",sock);
+ if (sock < 0)
+ return JIM_ERR;
+
+ /* Get the next file id */
+ fprintf(stderr,"getting fileid:");
+ if (Jim_EvalGlobal(interp,
+ "if {[catch {incr aio.fileId}]} {set aio.fileId 0}") != JIM_OK)
+ return JIM_ERR;
+ objPtr = Jim_GetGlobalVariableStr(interp, "aio.fileId", JIM_ERRMSG);
+ if (objPtr == NULL) return JIM_ERR;
+ if (Jim_GetLong(interp, objPtr, &fileId) != JIM_OK) return JIM_ERR;
+ fprintf(stderr," %ld\n", fileId);
+
+ /* Create the file command */
+ af = Jim_Alloc(sizeof(*af));
+ af->fd = sock;
+ af->fp = fdopen(sock,"r+");
+ af->OpenFlags = AIO_FDOPEN;
+ af->flags = fcntl(af->fd,F_GETFL);
+ // fprintf(stderr,"hallo\n");
+ af->rEvent = NULL;
+ af->wEvent = NULL;
+ af->eEvent = NULL;
+ sprintf(buf, "aio.sockstream%ld", fileId);
+ Jim_CreateCommand(interp, buf, JimAioHandlerCommand, af, JimAioDelProc);
+ Jim_SetResultString(interp, buf, -1);
+ fprintf(stderr,"returning\n");
+ return JIM_OK;
+}
+
+DLLEXPORT int
+#ifndef JIM_STATICEXT
+Jim_OnLoad(Jim_Interp *interp)
+#else
+Jim_AioInit(Jim_Interp *interp)
+#endif
+{
+#ifndef JIM_STATICEXT
+ Jim_InitExtension(interp);
+ Jim_ImportEventloopAPI(interp);
+#endif
+ if (Jim_PackageProvide(interp, "aio", "1.0", JIM_ERRMSG) != JIM_OK)
+ return JIM_ERR;
+ Jim_CreateCommand(interp, "aio.open", JimAioOpenCommand, NULL, NULL);
+ Jim_CreateCommand(interp, "aio.socket", JimAioSockCommand, NULL, NULL);
+ return JIM_OK;
+}
+
+// end
+
|