예제 #1
0
static int file_cmd_delete(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    int force = Jim_CompareStringImmediate(interp, argv[0], "-force");

    if (force || Jim_CompareStringImmediate(interp, argv[0], "--")) {
        argc++;
        argv--;
    }

    while (argc--) {
        const char *path = Jim_String(argv[0]);

        if (unlink(path) == -1 && errno != ENOENT) {
            if (rmdir(path) == -1) {
                /* Maybe try using the script helper */
                if (!force || Jim_EvalPrefix(interp, "file delete force", 1, argv) != JIM_OK) {
                    Jim_SetResultFormatted(interp, "couldn't delete file \"%s\": %s", path,
                        strerror(errno));
                    return JIM_ERR;
                }
            }
        }
        argv++;
    }
    return JIM_OK;
}
예제 #2
0
static int aio_cmd_seek(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    AioFile *af = Jim_CmdPrivData(interp);
    int orig = SEEK_SET;
    long offset;

    if (argc == 2) {
        if (Jim_CompareStringImmediate(interp, argv[1], "start"))
            orig = SEEK_SET;
        else if (Jim_CompareStringImmediate(interp, argv[1], "current"))
            orig = SEEK_CUR;
        else if (Jim_CompareStringImmediate(interp, argv[1], "end"))
            orig = SEEK_END;
        else {
            return -1;
        }
    }
    if (Jim_GetLong(interp, argv[0], &offset) != JIM_OK) {
        return JIM_ERR;
    }
    if (fseek(af->fp, offset, orig) == -1) {
        JimAioSetError(interp, af->filename);
        return JIM_ERR;
    }
    return JIM_OK;
}
예제 #3
0
static int aio_cmd_puts(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    AioFile *af = Jim_CmdPrivData(interp);
    int wlen;
    const char *wdata;
    Jim_Obj *strObj;

    if (argc == 2) {
        if (!Jim_CompareStringImmediate(interp, argv[0], "-nonewline")) {
            return -1;
        }
        strObj = argv[1];
    }
    else {
        strObj = argv[0];
    }

    wdata = Jim_GetString(strObj, &wlen);
    if (fwrite(wdata, 1, wlen, af->fp) == (unsigned)wlen) {
        if (argc == 2 || putc('\n', af->fp) != EOF) {
            return JIM_OK;
        }
    }
    JimAioSetError(interp, af->filename);
    return JIM_ERR;
}
예제 #4
0
static int array_cmd_unset(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    int i;
    int len;
    Jim_Obj *resultObj;
    Jim_Obj *objPtr;
    Jim_Obj **dictValuesObj;

    if (argc == 1 || Jim_CompareStringImmediate(interp, argv[1], "*")) {
        /* Unset the whole array */
        Jim_UnsetVariable(interp, argv[0], JIM_NONE);
        return JIM_OK;
    }

    objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE);

    if (Jim_DictPairs(interp, objPtr, &dictValuesObj, &len) != JIM_OK) {
        return JIM_ERR;
    }

    /* Create a new object with the values which don't match */
    resultObj = Jim_NewDictObj(interp, NULL, 0);

    for (i = 0; i < len; i += 2) {
        if (!Jim_StringMatchObj(interp, argv[1], dictValuesObj[i], 0)) {
            Jim_DictAddElement(interp, resultObj, dictValuesObj[i], dictValuesObj[i + 1]);
        }
    }
    Jim_Free(dictValuesObj);

    Jim_SetVariable(interp, argv[0], resultObj);
    return JIM_OK;
}
예제 #5
0
static int array_cmd_get(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    Jim_Obj *objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE);

    if (!objPtr) {
        return JIM_OK;
    }

    if (argc == 1 || Jim_CompareStringImmediate(interp, argv[1], "*")) {
        /* Optimise the "all" case */
        if (Jim_IsList(objPtr)) {
            if (Jim_ListLength(interp, objPtr) % 2 != 0) {
                /* A list with an odd number of elements */
                return JIM_ERR;
            }
        }
        else if (Jim_DictSize(interp, objPtr) < 0) {
            /* Can't be converted to a dictionary */
            return JIM_ERR;
        }
        Jim_SetResult(interp, objPtr);
        return JIM_OK;
    }

    /* Return a list of keys and values where the keys match the pattern */
    return Jim_DictValues(interp, objPtr, argv[1]);
}
예제 #6
0
static int clock_cmd_format(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    /* How big is big enough? */
    char buf[100];
    time_t t;
    long seconds;

    const char *format = "%a %b %d %H:%M:%S %Z %Y";

    if (argc == 2 || (argc == 3 && !Jim_CompareStringImmediate(interp, argv[1], "-format"))) {
        return -1;
    }

    if (argc == 3) {
        format = Jim_String(argv[2]);
    }

    if (Jim_GetLong(interp, argv[0], &seconds) != JIM_OK) {
        return JIM_ERR;
    }
    t = seconds;

    /*@@if (strftime(buf, sizeof(buf), format, localtime(&t)) == 0) {
        Jim_SetResultString(interp, "format string too long", -1);
        return JIM_ERR;
    }*/

    Jim_SetResultString(interp, buf, -1);

    return JIM_OK;
}
예제 #7
0
파일: jim-posix.c 프로젝트: marrero/jimtcl
/*
 * os.wait ?-nohang? pid
 *
 * An interface to waitpid(2)
 *
 * Returns a 3 element list.
 *
 * If -nohang is specified, and the process is still alive, returns
 *
 *   {0 none 0}
 * 
 * If the process does not exist or has already been waited for, returns:
 *
 *   {-1 error <error-description>} 
 *
 * If the process exited normally, returns:
 *
 *   {<pid> exit <exit-status>} 
 *
 * If the process terminated on a signal, returns:
 *
 *   {<pid> signal <signal-number>} 
 *
 * Otherwise (core dump, stopped, continued, ...), returns:
 *
 *   {<pid> other 0}
 */
static int Jim_PosixWaitCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    int nohang = 0;
    long pid;
    int status;
    Jim_Obj *listObj;
    const char *type;
    int value;

    if (argc > 1 && Jim_CompareStringImmediate(interp, argv[1], "-nohang")) {
        nohang = 1;
    }
    if (argc != nohang + 2) {
        Jim_WrongNumArgs(interp, 1, argv, "?-nohang? pid");
        return JIM_ERR;
    }
    if (Jim_GetLong(interp, argv[nohang + 1], &pid) != JIM_OK) {
        return JIM_ERR;
    }

    pid = waitpid(pid, &status, nohang ? WNOHANG : 0);
    listObj = Jim_NewListObj(interp, NULL, 0);
    Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, pid));
    if (pid < 0) {
        type = "error";
        value = errno;
    }
    else if (pid == 0) {
        type = "none";
        value = 0;
    }
    else if (WIFEXITED(status)) {
        type = "exit";
        value = WEXITSTATUS(status);
    }
    else if (WIFSIGNALED(status)) {
        type = "signal";
        value = WTERMSIG(status);
    }
    else {
        type = "other";
        value = 0;
    }

    Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, type, -1));
    if (pid < 0) {
        Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, strerror(value), -1));
    }
    else {
        Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, value));
    }
    Jim_SetResult(interp, listObj);
    return JIM_OK;
}
예제 #8
0
/*
 *-----------------------------------------------------------------------------
 *
 * Jim_ReaddirCmd --
 *     Implements the rename TCL command:
 *         readdir ?-nocomplain? dirPath
 *
 * Results:
 *      Standard TCL result.
 *-----------------------------------------------------------------------------
 */
int Jim_ReaddirCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    const char *dirPath;
    DIR *dirPtr;
    struct dirent *entryPtr;
    int nocomplain = 0;

    if (argc == 3 && Jim_CompareStringImmediate(interp, argv[1], "-nocomplain")) {
        nocomplain = 1;
    }
    if (argc != 2 && !nocomplain) {
        Jim_WrongNumArgs(interp, 1, argv, "?-nocomplain? dirPath");
        return JIM_ERR;
    }

    dirPath = Jim_String(argv[1 + nocomplain]);

    dirPtr = opendir(dirPath);
    if (dirPtr == NULL) {
        if (nocomplain) {
            return JIM_OK;
        }
        Jim_SetResultString(interp, strerror(errno), -1);
        return JIM_ERR;
    }
    else {
        Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0);

        while ((entryPtr = readdir(dirPtr)) != NULL) {
            if (entryPtr->d_name[0] == '.') {
                if (entryPtr->d_name[1] == '\0') {
                    continue;
                }
                if ((entryPtr->d_name[1] == '.') && (entryPtr->d_name[2] == '\0'))
                    continue;
            }
            Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, entryPtr->d_name, -1));
        }
        closedir(dirPtr);

        Jim_SetResult(interp, listObj);

        return JIM_OK;
    }
}
예제 #9
0
파일: Tcl.cpp 프로젝트: wibbe/zum
  int BuiltInProc::call(struct Jim_Interp * interp, int argc, Jim_Obj * const * argv)
  {
    // Check for the help command
    if (argc == 2 && Jim_CompareStringImmediate(interp, argv[1], "-help"))
    {
      Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
      Jim_AppendStrings(interp, Jim_GetResult(interp), "Usage: \"", Jim_String(argv[0]), NULL);

      if (strlen(args_) > 0)
        Jim_AppendStrings(interp, Jim_GetResult(interp), " ", args_, NULL);
      
      Jim_AppendStrings(interp, Jim_GetResult(interp), "\"");

      if (strlen(desc_) > 0)
        Jim_AppendStrings(interp, Jim_GetResult(interp), " ", desc_, NULL);

      return JIM_OK;
    }

    return proc_(interp, argc, argv);
  }
예제 #10
0
파일: jim-signal.c 프로젝트: dgsb/jimtcl
static int signal_cmd_check(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    int clear = 0;
    jim_wide mask = 0;
    jim_wide blocked;

    if (argc > 0 && Jim_CompareStringImmediate(interp, argv[0], "-clear")) {
        clear++;
    }
    if (argc > clear) {
        int i;

        /* Signals specified */
        for (i = clear; i < argc; i++) {
            int sig = find_signal_by_name(interp, Jim_String(argv[i]));

            if (sig < 0 || sig >= MAX_SIGNALS) {
                return -1;
            }
            mask |= sig_to_bit(sig);
        }
    }
    else {
        /* No signals specified, so check/clear all */
        mask = ~mask;
    }

    if ((sigsblocked & mask) == 0) {
        /* No matching signals, so empty result and nothing to do */
        return JIM_OK;
    }
    /* Be careful we don't have a race condition where signals are cleared but not returned */
    blocked = sigsblocked & mask;
    if (clear) {
        sigsblocked &= ~blocked;
    }
    /* Set the result */
    signal_set_sigmask_result(interp, blocked);
    return JIM_OK;
}
예제 #11
0
static int Jim_Gzip(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    long level = Z_DEFAULT_COMPRESSION;
    const char *in;
    int len;

    if (argc == 3) {
        if (!Jim_CompareStringImmediate(interp, argv[1], "-level")) {
            return -1;
        }

        if (Jim_GetLong(interp, argv[2], &level) != JIM_OK) {
            return -1;
        }

    }
    else if (argc != 1) {
        return -1;
    }

    in = Jim_GetString(argv[0], &len);
    return Jim_Compress(interp, in, len, level, WBITS_GZIP);
}
예제 #12
0
static int Jim_Gunzip(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    long bufsiz = DEF_DECOMPRESS_BUFSIZ;
    const char *in;
    int len;

    if (argc == 3) {
        if (!Jim_CompareStringImmediate(interp, argv[1], "-buffersize")) {
            return -1;
        }

        if (Jim_GetLong(interp, argv[2], &bufsiz) != JIM_OK) {
            return -1;
        }

    }
    else if (argc != 1) {
        return -1;
    }

    in = Jim_GetString(argv[0], &len);
    return Jim_Decompress(interp, in, len, bufsiz, WBITS_GZIP);
}
예제 #13
0
static int clock_cmd_scan(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    char *pt;
    struct tm tm;
    time_t now = time(0);

    if (!Jim_CompareStringImmediate(interp, argv[1], "-format")) {
        return -1;
    }

    /* Initialise with the current date/time */
    localtime_r(&now, &tm);

    /*@@pt = strptime(Jim_String(argv[0]), Jim_String(argv[2]), &tm);
    if (pt == 0 || *pt != 0) {
        Jim_SetResultString(interp, "Failed to parse time according to format", -1);
        return JIM_ERR;
    }*/

    /* Now convert into a time_t */
    Jim_SetResultInt(interp, mktime(&tm));

    return JIM_OK;
}
예제 #14
0
static int JimNamespaceCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    Jim_Obj *nsObj;
    Jim_Obj *objPtr;
    int option;
    static const char * const options[] = {
        "eval", "current", "canonical", "qualifiers", "parent", "tail", "delete",
        "origin", "code", "inscope", "import", "export",
        "which", "upvar", NULL
    };
    enum
    {
        OPT_EVAL, OPT_CURRENT, OPT_CANONICAL, OPT_QUALIFIERS, OPT_PARENT, OPT_TAIL, OPT_DELETE,
        OPT_ORIGIN, OPT_CODE, OPT_INSCOPE, OPT_IMPORT, OPT_EXPORT,
        OPT_WHICH, OPT_UPVAR,
    };

    if (argc < 2) {
        Jim_WrongNumArgs(interp, 1, argv, "subcommand ?arg ...?");
        return JIM_ERR;
    }

    if (Jim_GetEnum(interp, argv[1], options, &option, "subcommand", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) {
        return JIM_ERR;
    }

    switch (option) {
        case OPT_EVAL:
            if (argc < 4) {
                Jim_WrongNumArgs(interp, 2, argv, "name arg ?arg...?");
                return JIM_ERR;
            }
            if (argc == 4) {
                objPtr = argv[3];
            }
            else {
                objPtr = Jim_ConcatObj(interp, argc - 3, argv + 3);
            }

            nsObj = JimCanonicalNamespace(interp, interp->framePtr->nsObj, argv[2]);
            return Jim_EvalNamespace(interp, objPtr, nsObj);

        case OPT_CURRENT:
            if (argc != 2) {
                Jim_WrongNumArgs(interp, 2, argv, "");
                return JIM_ERR;
            }
            Jim_SetResult(interp, JimNamespaceCurrent(interp));
            return JIM_OK;

        case OPT_CANONICAL:
            if (argc > 4) {
                Jim_WrongNumArgs(interp, 2, argv, "?current? ?name?");
                return JIM_ERR;
            }
            if (argc == 2) {
                Jim_SetResult(interp, interp->framePtr->nsObj);
            }
            else if (argc == 3) {
                Jim_SetResult(interp, JimCanonicalNamespace(interp, interp->framePtr->nsObj, argv[2]));
            }
            else {
                Jim_SetResult(interp, JimCanonicalNamespace(interp, argv[2], argv[3]));
            }
            return JIM_OK;

        case OPT_QUALIFIERS:
            if (argc != 3) {
                Jim_WrongNumArgs(interp, 2, argv, "string");
                return JIM_ERR;
            }
            Jim_SetResult(interp, Jim_NamespaceQualifiers(interp, argv[2]));
            return JIM_OK;

        case OPT_EXPORT:
            return JIM_OK;

        case OPT_TAIL:
            if (argc != 3) {
                Jim_WrongNumArgs(interp, 2, argv, "string");
                return JIM_ERR;
            }
            Jim_SetResult(interp, Jim_NamespaceTail(interp, argv[2]));
            return JIM_OK;

        case OPT_PARENT:
            if (argc != 2 && argc != 3) {
                Jim_WrongNumArgs(interp, 2, argv, "?name?");
                return JIM_ERR;
            }
            else {
                const char *name;

                if (argc == 3) {
                    objPtr = argv[2];
                }
                else {
                    objPtr = interp->framePtr->nsObj;
                }
                if (Jim_Length(objPtr) == 0 || Jim_CompareStringImmediate(interp, objPtr, "::")) {
                    return JIM_OK;
                }
                objPtr = Jim_NamespaceQualifiers(interp, objPtr);

                name = Jim_String(objPtr);

                if (name[0] != ':' || name[1] != ':') {
                    /* Make it fully scoped */
                    Jim_SetResultString(interp, "::", 2);
                    Jim_AppendObj(interp, Jim_GetResult(interp), objPtr);
                    Jim_IncrRefCount(objPtr);
                    Jim_DecrRefCount(interp, objPtr);
                }
                else {
                    Jim_SetResult(interp, objPtr);
                }
            }
            return JIM_OK;
    }

    /* Implemented as a Tcl helper proc.
     * Note that calling a proc will change the current namespace,
     * so helper procs must call [uplevel namespace canon] to get the callers
     * namespace.
     */
    return Jim_EvalEnsemble(interp, "namespace", options[option], argc - 2, argv + 2);
}
예제 #15
0
파일: jim-aio.c 프로젝트: Johnicholas/Jim
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;
}
예제 #16
0
파일: jim-aio.c 프로젝트: Johnicholas/Jim
/* 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;
}
예제 #17
0
파일: jim-exec.c 프로젝트: dokterp/jimtcl
/*
 * The main [exec] command
 */
static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    fdtype outputId;               /* File id for output pipe.  -1
                                 * means command overrode. */
    fdtype errorId;                /* File id for temporary file
                                 * containing error output. */
    pidtype *pidPtr;
    int numPids, result;

    /*
     * See if the command is to be run in background;  if so, create
     * the command, detach it, and return.
     */
    if (argc > 1 && Jim_CompareStringImmediate(interp, argv[argc - 1], "&")) {
        Jim_Obj *listObj;
        int i;

        argc--;
        numPids = JimCreatePipeline(interp, argc - 1, argv + 1, &pidPtr, NULL, NULL, NULL);
        if (numPids < 0) {
            return JIM_ERR;
        }
        /* The return value is a list of the pids */
        listObj = Jim_NewListObj(interp, NULL, 0);
        for (i = 0; i < numPids; i++) {
            Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, (long)pidPtr[i]));
        }
        Jim_SetResult(interp, listObj);
        JimDetachPids(interp, numPids, pidPtr);
        Jim_Free(pidPtr);
        return JIM_OK;
    }

    /*
     * Create the command's pipeline.
     */
    numPids =
        JimCreatePipeline(interp, argc - 1, argv + 1, &pidPtr, NULL, &outputId, &errorId);

    if (numPids < 0) {
        return JIM_ERR;
    }

    /*
     * Read the child's output (if any) and put it into the result.
     */
    Jim_SetResultString(interp, "", 0);

    result = JIM_OK;
    if (outputId != JIM_BAD_FD) {
        result = JimAppendStreamToString(interp, outputId, Jim_GetResult(interp));
        if (result < 0) {
            Jim_SetResultErrno(interp, "error reading from output pipe");
        }
    }

    if (JimCleanupChildren(interp, numPids, pidPtr, errorId) != JIM_OK) {
        result = JIM_ERR;
    }
    return result;
}
예제 #18
0
파일: jim-syslog.c 프로젝트: marrero/jimtcl
/* Syslog_Log -
 * implements syslog tcl command. General format: syslog ?options? level text
 * options -facility -ident -options
 * 
 * syslog ?-facility cron|daemon|...? ?-ident string? ?-options int? ?debug|info|...? text
 */
int Jim_SyslogCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    int priority = LOG_INFO;
    int i = 1;
    SyslogInfo *info = Jim_CmdPrivData(interp);

    if (argc <= 1) {
      wrongargs:
        Jim_WrongNumArgs(interp, 1, argv,
            "?-facility cron|daemon|...? ?-ident string? ?-options int? ?debug|info|...? message");
        return JIM_ERR;
    }
    while (i < argc - 1) {
        if (Jim_CompareStringImmediate(interp, argv[i], "-facility")) {
            int entry =
                Jim_FindByName(Jim_String(argv[i + 1]), facilities,
                sizeof(facilities) / sizeof(*facilities));
            if (entry < 0) {
                Jim_SetResultString(interp, "Unknown facility", -1);
                return JIM_ERR;
            }
            if (info->facility != entry) {
                info->facility = entry;
                if (info->logOpened) {
                    closelog();
                    info->logOpened = 0;
                }
            }
        }
        else if (Jim_CompareStringImmediate(interp, argv[i], "-options")) {
            long tmp;

            if (Jim_GetLong(interp, argv[i + 1], &tmp) == JIM_ERR) {
                return JIM_ERR;
            }
            info->options = tmp;
            if (info->logOpened) {
                closelog();
                info->logOpened = 0;
            }
        }
        else if (Jim_CompareStringImmediate(interp, argv[i], "-ident")) {
            strncpy(info->ident, Jim_String(argv[i + 1]), sizeof(info->ident));
            info->ident[sizeof(info->ident) - 1] = 0;
            if (info->logOpened) {
                closelog();
                info->logOpened = 0;
            }
        }
        else {
            break;
        }
        i += 2;
    }

    /* There should be either 0, 1 or 2 args left */
    if (i == argc) {
        /* No args, but they have set some options, so OK */
        return JIM_OK;
    }

    if (i < argc - 1) {
        priority =
            Jim_FindByName(Jim_String(argv[i]), priorities,
            sizeof(priorities) / sizeof(*priorities));
        if (priority < 0) {
            Jim_SetResultString(interp, "Unknown priority", -1);
            return JIM_ERR;
        }
        i++;
    }

    if (i != argc - 1) {
        goto wrongargs;
    }
    if (!info->logOpened) {
        if (!info->ident[0]) {
            Jim_Obj *argv0 = Jim_GetGlobalVariableStr(interp, "argv0", JIM_NONE);

            if (argv0) {
                strncpy(info->ident, Jim_String(argv0), sizeof(info->ident));
            }
            else {
                strcpy(info->ident, "Tcl script");
            }
            info->ident[sizeof(info->ident) - 1] = 0;
        }
        openlog(info->ident, info->options, info->facility);
        info->logOpened = 1;
    }
    syslog(priority, "%s", Jim_String(argv[i]));

    return JIM_OK;
}
예제 #19
0
/* Calls to [sqlite.open] create commands that are implemented by this
 * C command. */
static int JimSqliteHandlerCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    sqlite3 *db = Jim_CmdPrivData(interp);
    int option;
    static const char * const options[] = {
        "close", "query", "lastid", "changes", NULL
    };
    enum
    { OPT_CLOSE, OPT_QUERY, OPT_LASTID, OPT_CHANGES };

    if (argc < 2) {
        Jim_WrongNumArgs(interp, 1, argv, "method ?args ...?");
        return JIM_ERR;
    }
    if (Jim_GetEnum(interp, argv[1], options, &option, "Sqlite 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_String(argv[0]));
        return JIM_OK;
    }
    else if (option == OPT_QUERY) {
        /* QUERY */
        Jim_Obj *objPtr, *rowsListPtr;
        sqlite3_stmt *stmt;
        const char *query, *tail;
        int columns, rows, len;
        int retcode = JIM_ERR;
        Jim_Obj *nullStrObj;

        if (argc >= 4 && Jim_CompareStringImmediate(interp, argv[2], "-null")) {
            nullStrObj = argv[3];
            argv += 2;
            argc -= 2;
        }
        else {
            nullStrObj = Jim_NewEmptyStringObj(interp);
        }
        Jim_IncrRefCount(nullStrObj);
        if (argc < 3) {
            Jim_WrongNumArgs(interp, 2, argv, "query ?args?");
            goto err;
        }
        objPtr = JimSqliteFormatQuery(interp, argv[2], argc - 3, argv + 3);
        if (objPtr == NULL) {
            return JIM_ERR;
        }
        query = Jim_GetString(objPtr, &len);
        Jim_IncrRefCount(objPtr);
        /* Compile the query into VM code */
        if (sqlite3_prepare_v2(db, query, len, &stmt, &tail) != SQLITE_OK) {
            Jim_DecrRefCount(interp, objPtr);
            Jim_SetResultString(interp, sqlite3_errmsg(db), -1);
            goto err;
        }
        Jim_DecrRefCount(interp, objPtr);       /* query no longer needed. */
        /* Build a list of rows (that are lists in turn) */
        rowsListPtr = Jim_NewListObj(interp, NULL, 0);
        Jim_IncrRefCount(rowsListPtr);
        rows = 0;
        columns = sqlite3_column_count(stmt);
        while (sqlite3_step(stmt) == SQLITE_ROW) {
            int i;

            objPtr = Jim_NewListObj(interp, NULL, 0);
            for (i = 0; i < columns; i++) {
                Jim_Obj *vObj = NULL;

                Jim_ListAppendElement(interp, objPtr,
                    Jim_NewStringObj(interp, sqlite3_column_name(stmt, i), -1));
                switch (sqlite3_column_type(stmt, i)) {
                    case SQLITE_NULL:
                        vObj = nullStrObj;
                        break;
                    case SQLITE_INTEGER:
                        vObj = Jim_NewIntObj(interp, sqlite3_column_int(stmt, i));
                        break;
                    case SQLITE_FLOAT:
                        vObj = Jim_NewDoubleObj(interp, sqlite3_column_double(stmt, i));
                        break;
                    case SQLITE_TEXT:
                    case SQLITE_BLOB:
                        vObj = Jim_NewStringObj(interp,
                            sqlite3_column_blob(stmt, i), sqlite3_column_bytes(stmt, i));
                        break;
                }
                Jim_ListAppendElement(interp, objPtr, vObj);
            }
            Jim_ListAppendElement(interp, rowsListPtr, objPtr);
            rows++;
        }
        /* Finalize */
        if (sqlite3_finalize(stmt) != SQLITE_OK) {
            Jim_SetResultString(interp, sqlite3_errmsg(db), -1);
        }
        else {
            Jim_SetResult(interp, rowsListPtr);
            retcode = JIM_OK;
        }
        Jim_DecrRefCount(interp, rowsListPtr);
err:
        Jim_DecrRefCount(interp, nullStrObj);

        return retcode;
    }
    else if (option == OPT_LASTID) {
        if (argc != 2) {
            Jim_WrongNumArgs(interp, 2, argv, "");
            return JIM_ERR;
        }
        Jim_SetResult(interp, Jim_NewIntObj(interp, sqlite3_last_insert_rowid(db)));
        return JIM_OK;
    }
    else if (option == OPT_CHANGES) {
        if (argc != 2) {
            Jim_WrongNumArgs(interp, 2, argv, "");
            return JIM_ERR;
        }
        Jim_SetResult(interp, Jim_NewIntObj(interp, sqlite3_changes(db)));
        return JIM_OK;
    }
    return JIM_OK;
}
예제 #20
0
static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    const char *hdlfmt = "aio.unknown%ld";
    const char *socktypes[] = {
        "unix",
        "unix.server",
        "dgram",
        "dgram.server",
        "stream",
        "stream.server",
        "pipe",
        NULL
    };
    enum
    {
        SOCK_UNIX,
        SOCK_UNIX_SERVER,
        SOCK_DGRAM_CLIENT,
        SOCK_DGRAM_SERVER,
        SOCK_STREAM_CLIENT,
        SOCK_STREAM_SERVER,
        SOCK_STREAM_PIPE,
        SOCK_DGRAM6_CLIENT,
        SOCK_DGRAM6_SERVER,
        SOCK_STREAM6_CLIENT,
        SOCK_STREAM6_SERVER,
    };
    int socktype;
    int sock;
    const char *hostportarg = NULL;
    int res;
    int on = 1;
    const char *mode = "r+";
    int family = PF_INET;
    Jim_Obj *argv0 = argv[0];
    int ipv6 = 0;

    if (argc > 1 && Jim_CompareStringImmediate(interp, argv[1], "-ipv6")) {
        if (!IPV6) {
            Jim_SetResultString(interp, "ipv6 not supported", -1);
            return JIM_ERR;
        }
        ipv6 = 1;
        family = PF_INET6;
    }
    argc -= ipv6;
    argv += ipv6;

    if (argc < 2) {
      wrongargs:
        Jim_WrongNumArgs(interp, 1, &argv0, "?-ipv6? type ?address?");
        return JIM_ERR;
    }

    if (Jim_GetEnum(interp, argv[1], socktypes, &socktype, "socket type", JIM_ERRMSG) != JIM_OK)
        return JIM_ERR;

    Jim_SetEmptyResult(interp);

    hdlfmt = "aio.sock%ld";

    if (argc > 2) {
        hostportarg = Jim_String(argv[2]);
    }

    switch (socktype) {
        case SOCK_DGRAM_CLIENT:
            if (argc == 2) {
                /* No address, so an unconnected dgram socket */
                sock = socket(family, SOCK_DGRAM, 0);
                if (sock < 0) {
                    JimAioSetError(interp, NULL);
                    return JIM_ERR;
                }
                break;
            }
            /* fall through */
        case SOCK_STREAM_CLIENT:
            {
                union sockaddr_any sa;
                int salen;

                if (argc != 3) {
                    goto wrongargs;
                }

                if (ipv6) {
                    if (JimParseIPv6Address(interp, hostportarg, &sa, &salen) != JIM_OK) {
                        return JIM_ERR;
                    }
                }
                else if (JimParseIpAddress(interp, hostportarg, &sa, &salen) != JIM_OK) {
                    return JIM_ERR;
                }
                sock = socket(family, (socktype == SOCK_DGRAM_CLIENT) ? SOCK_DGRAM : SOCK_STREAM, 0);
                if (sock < 0) {
                    JimAioSetError(interp, NULL);
                    return JIM_ERR;
                }
                res = connect(sock, &sa.sa, salen);
                if (res) {
                    JimAioSetError(interp, argv[2]);
                    close(sock);
                    return JIM_ERR;
                }
            }
            break;

        case SOCK_STREAM_SERVER:
        case SOCK_DGRAM_SERVER:
            {
                union sockaddr_any sa;
                int salen;

                if (argc != 3) {
                    goto wrongargs;
                }

                if (ipv6) {
                    if (JimParseIPv6Address(interp, hostportarg, &sa, &salen) != JIM_OK) {
                        return JIM_ERR;
                    }
                }
                else if (JimParseIpAddress(interp, hostportarg, &sa, &salen) != JIM_OK) {
                    return JIM_ERR;
                }
                sock = socket(family, (socktype == SOCK_DGRAM_SERVER) ? SOCK_DGRAM : SOCK_STREAM, 0);
                if (sock < 0) {
                    JimAioSetError(interp, NULL);
                    return JIM_ERR;
                }

                /* Enable address reuse */
                setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on));

                res = bind(sock, &sa.sa, salen);
                if (res) {
                    JimAioSetError(interp, argv[2]);
                    close(sock);
                    return JIM_ERR;
                }
                if (socktype == SOCK_STREAM_SERVER) {
                    res = listen(sock, 5);
                    if (res) {
                        JimAioSetError(interp, NULL);
                        close(sock);
                        return JIM_ERR;
                    }
                }
                hdlfmt = "aio.socksrv%ld";
            }
            break;

#ifdef HAVE_SYS_UN_H
        case SOCK_UNIX:
            {
                struct sockaddr_un sa;
                socklen_t len;

                if (argc != 3 || ipv6) {
                    goto wrongargs;
                }

                if (JimParseDomainAddress(interp, hostportarg, &sa) != JIM_OK) {
                    JimAioSetError(interp, argv[2]);
                    return JIM_ERR;
                }
                family = PF_UNIX;
                sock = socket(PF_UNIX, SOCK_STREAM, 0);
                if (sock < 0) {
                    JimAioSetError(interp, NULL);
                    return JIM_ERR;
                }
                len = strlen(sa.sun_path) + 1 + sizeof(sa.sun_family);
                res = connect(sock, (struct sockaddr *)&sa, len);
                if (res) {
                    JimAioSetError(interp, argv[2]);
                    close(sock);
                    return JIM_ERR;
                }
                hdlfmt = "aio.sockunix%ld";
                break;
            }

        case SOCK_UNIX_SERVER:
            {
                struct sockaddr_un sa;
                socklen_t len;

                if (argc != 3 || ipv6) {
                    goto wrongargs;
                }

                if (JimParseDomainAddress(interp, hostportarg, &sa) != JIM_OK) {
                    JimAioSetError(interp, argv[2]);
                    return JIM_ERR;
                }
                family = PF_UNIX;
                sock = socket(PF_UNIX, SOCK_STREAM, 0);
                if (sock < 0) {
                    JimAioSetError(interp, NULL);
                    return JIM_ERR;
                }
                len = strlen(sa.sun_path) + 1 + sizeof(sa.sun_family);
                res = bind(sock, (struct sockaddr *)&sa, len);
                if (res) {
                    JimAioSetError(interp, argv[2]);
                    close(sock);
                    return JIM_ERR;
                }
                res = listen(sock, 5);
                if (res) {
                    JimAioSetError(interp, NULL);
                    close(sock);
                    return JIM_ERR;
                }
                hdlfmt = "aio.sockunixsrv%ld";
                break;
            }
#endif

#ifdef HAVE_PIPE
        case SOCK_STREAM_PIPE:
            {
                int p[2];

                if (argc != 2 || ipv6) {
                    goto wrongargs;
                }

                if (pipe(p) < 0) {
                    JimAioSetError(interp, NULL);
                    return JIM_ERR;
                }

                if (JimMakeChannel(interp, NULL, p[0], argv[1], "aio.pipe%ld", 0, "r") == JIM_OK) {
                    Jim_Obj *objPtr = Jim_NewListObj(interp, NULL, 0);
                    Jim_ListAppendElement(interp, objPtr, Jim_GetResult(interp));

                    if (JimMakeChannel(interp, NULL, p[1], argv[1], "aio.pipe%ld", 0, "w") == JIM_OK) {
                        Jim_ListAppendElement(interp, objPtr, Jim_GetResult(interp));
                        Jim_SetResult(interp, objPtr);
                        return JIM_OK;
                    }
                }
                /* Can only be here if fdopen() failed */
                close(p[0]);
                close(p[1]);
                JimAioSetError(interp, NULL);
                return JIM_ERR;
            }
            break;
#endif
        default:
            Jim_SetResultString(interp, "Unsupported socket type", -1);
            return JIM_ERR;
    }

    return JimMakeChannel(interp, NULL, sock, argv[1], hdlfmt, family, mode);
}
예제 #21
0
파일: Tcl.cpp 프로젝트: wibbe/zum
  int BuiltInSubProc::call(struct Jim_Interp * interp, int argc, Jim_Obj * const * argv)
  {
    bool help = false;
    const char * cmdName = Jim_String(argv[0]);

    if (argc < 2)
    {
      Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
      Jim_AppendStrings(interp, Jim_GetResult(interp), "wrong # args: should be \"", cmdName, " command ...\"\n", NULL);
      Jim_AppendStrings(interp, Jim_GetResult(interp), "Use \"", cmdName, " -help ?command?\" for help about the command", NULL);    
      return JIM_ERR;
    }

    Jim_Obj * cmd = argv[1];

    // Check for the help command
    if (Jim_CompareStringImmediate(interp, cmd, "-help"))
    {
      if (argc == 2)
      {
        showCommandUsage(interp, argc, argv, subCommands_);
        return JIM_OK;
      }

      help = true;
      cmd = argv[2];
    }

    // Check for special builtin '-commands' command first
    if (Jim_CompareStringImmediate(interp, cmd, "-commands"))
    {
        /* Build the result here */
        Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
        addSubCommands(interp, subCommands_, " ");
        return JIM_OK;
    }

    for (int i = 0; i < subCommands_.size() / 3; ++i)
    {
      if (Jim_CompareStringImmediate(interp, cmd, subCommands_[i * 3]))
      {
        if (help)
        {
          Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
          Jim_AppendStrings(interp, Jim_GetResult(interp), "Usage: \"", cmdName, " ", subCommands_[i * 3], NULL);

          if (strlen(subCommands_[i * 3 + 1]) > 0)
            Jim_AppendStrings(interp, Jim_GetResult(interp), " ", subCommands_[i * 3 + 1], NULL);
          
          Jim_AppendStrings(interp, Jim_GetResult(interp), "\"");

          if (strlen(subCommands_[i * 3 + 2]) > 0)
            Jim_AppendStrings(interp, Jim_GetResult(interp), " ", subCommands_[i * 3 + 2], NULL);

          return JIM_OK;
        }
        else
        {
          return proc_(interp, i, argc - 2, argv + 2);
        }
      }
    }

    Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
    Jim_AppendStrings(interp, Jim_GetResult(interp), cmdName, ", unknown command \"", Jim_String(cmd), "\" should be one of: ", NULL);
    addSubCommands(interp, subCommands_, ", ");

    return JIM_ERR;
  }
예제 #22
0
static int aio_cmd_read(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    AioFile *af = Jim_CmdPrivData(interp);
    char buf[AIO_BUF_LEN];
    Jim_Obj *objPtr;
    int nonewline = 0;
    int neededLen = -1;         /* -1 is "read as much as possible" */

    if (argc && Jim_CompareStringImmediate(interp, argv[0], "-nonewline")) {
        nonewline = 1;
        argv++;
        argc--;
    }
    if (argc == 1) {
        jim_wide wideValue;

        if (Jim_GetWide(interp, argv[0], &wideValue) != JIM_OK)
            return JIM_ERR;
        if (wideValue < 0) {
            Jim_SetResultString(interp, "invalid parameter: negative len", -1);
            return JIM_ERR;
        }
        neededLen = (int)wideValue;
    }
    else if (argc) {
        return -1;
    }
    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 (JimCheckStreamError(interp, af)) {
        Jim_FreeNewObj(interp, objPtr);
        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;
}
예제 #23
0
/* 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", NULL
    };
    enum {OPT_CLOSE, OPT_SEEK, OPT_TELL, OPT_GETS, OPT_READ, OPT_PUTS,
          OPT_FLUSH, OPT_EOF
         };

    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] == '\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)) {
            /* 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;
    }
    return JIM_OK;
}
예제 #24
0
const jim_subcmd_type *Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type * command_table,
    int argc, Jim_Obj *const *argv)
{
    const jim_subcmd_type *ct;
    const jim_subcmd_type *partial = 0;
    int cmdlen;
    Jim_Obj *cmd;
    const char *cmdstr;
    const char *cmdname;
    int help = 0;

    cmdname = Jim_String(argv[0]);

    if (argc < 2) {
        Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
        Jim_AppendStrings(interp, Jim_GetResult(interp), "wrong # args: should be \"", cmdname,
            " command ...\"\n", NULL);
        Jim_AppendStrings(interp, Jim_GetResult(interp), "Use \"", cmdname, " -help ?command?\" for help", NULL);
        return 0;
    }

    cmd = argv[1];

    /* Check for the help command */
    if (Jim_CompareStringImmediate(interp, cmd, "-help")) {
        if (argc == 2) {
            /* Usage for the command, not the subcommand */
            show_cmd_usage(interp, command_table, argc, argv);
            return &dummy_subcmd;
        }
        help = 1;

        /* Skip the 'help' command */
        cmd = argv[2];
    }

    /* Check for special builtin '-commands' command first */
    if (Jim_CompareStringImmediate(interp, cmd, "-commands")) {
        /* Build the result here */
        Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
        add_commands(interp, command_table, " ");
        return &dummy_subcmd;
    }

    cmdstr = Jim_GetString(cmd, &cmdlen);

    for (ct = command_table; ct->cmd; ct++) {
        if (Jim_CompareStringImmediate(interp, cmd, ct->cmd)) {
            /* Found an exact match */
            break;
        }
        if (strncmp(cmdstr, ct->cmd, cmdlen) == 0) {
            if (partial) {
                /* Ambiguous */
                if (help) {
                    /* Just show the top level help here */
                    show_cmd_usage(interp, command_table, argc, argv);
                    return &dummy_subcmd;
                }
                bad_subcmd(interp, command_table, "ambiguous", argv[0], argv[1 + help]);
                return 0;
            }
            partial = ct;
        }
        continue;
    }

    /* If we had an unambiguous partial match */
    if (partial && !ct->cmd) {
        ct = partial;
    }

    if (!ct->cmd) {
        /* No matching command */
        if (help) {
            /* Just show the top level help here */
            show_cmd_usage(interp, command_table, argc, argv);
            return &dummy_subcmd;
        }
        bad_subcmd(interp, command_table, "unknown", argv[0], argv[1 + help]);
        return 0;
    }

    if (help) {
        Jim_SetResultString(interp, "Usage: ", -1);
        /* subcmd */
        add_cmd_usage(interp, ct, argv[0]);
        return &dummy_subcmd;
    }

    /* Check the number of args */
    if (argc - 2 < ct->minargs || (ct->maxargs >= 0 && argc - 2 > ct->maxargs)) {
        Jim_SetResultString(interp, "wrong # args: should be \"", -1);
        /* subcmd */
        add_cmd_usage(interp, ct, argv[0]);
        Jim_AppendStrings(interp, Jim_GetResult(interp), "\"", NULL);

        return 0;
    }

    /* Good command */
    return ct;
}