aboutsummaryrefslogtreecommitdiff
path: root/ecos/language/tcl/jim/current/src/jim-aio.c
diff options
context:
space:
mode:
Diffstat (limited to 'ecos/language/tcl/jim/current/src/jim-aio.c')
-rw-r--r--ecos/language/tcl/jim/current/src/jim-aio.c1548
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
+