Пример #1
0
static int
native_inout_popen(FILE **fr, FILE **fw, char *cmd)
{
    char   buf[NFILEN + 128];
    HANDLE handles[3];
    int    i, rc, rp[3], tmpin_fd, wp[3];

    TRACE((T_CALLED "native_inout_popen cmd=%s\n", cmd));
    proc_handle   = BAD_PROC_HANDLE;
    rp[0] = rp[1] = rp[2] = wp[0] = wp[1] = wp[2] = BAD_FD;
    handles[0]    = handles[1] = handles[2] = INVALID_HANDLE_VALUE;
    tmpin_fd      = BAD_FD;
    tmpin_name    = NULL;
    set_console_title(cmd);
    if (is_win95())
    {
        char *cmdp;

        /*
         * If w32pipes is set on a win95 host, you don't ever want slowreadf()
         * to periodically update the display while an intrinisic, high
         * bandwidth DOS command is in progress.  Reason:  the win95 shell,
         * command.com, will simply hang in the following scenario:
         *
         *    ^X!<high_bandwidth_cmd>
         *
         *         and
         *
         *    PIPESIZ < output of <high_bandwidth_cmd>
         *
         * I'm assuming that what's going on here is that command.com is
         * written in ASM and is using very low level BIOS/DOS calls to
         * effect output and, furthermore, that these low level calls don't
         * block when the input consumer is busy.
         */

        cmdp = skip_blanks(cmd);
        nowait_pipe_cmd = (strnicmp(cmdp, "dir", 3) == 0)  ||
                          (strnicmp(cmdp, "type", 4) == 0);
    }
    do
    {
        if (fr)
        {
            *fr = NULL;

            /*
             * Open (parent's) input pipe in TEXT mode, which will force
             * translation of the child's CR/LF record delimiters to NL
             * and keep the dreaded ^M chars from temporarily appearing
             * in a vile buffer (ugly).
             */
            if (_pipe(rp, PIPESIZ, O_TEXT|O_NOINHERIT) == -1)
                break;
            if ((rp[2] = _dup(rp[1])) == -1)
                break;
            handles[2] = handles[1] = (HANDLE) _get_osfhandle(rp[2]);
            (void) close(rp[1]);
            rp[1] = BAD_FD;
            if (! fw)
            {
                /*
                 * This is a read pipe (only).  Connect child's stdin to
                 * an empty file.  Under no circumstances should the
                 * child's stdin be connected to a device (else lots of
                 * screwy things will occur).  In particular, connecting
                 * the child's stdin to the parent's stdin will cause
                 * aborts and hangs on the various Win32 hosts.  You've
                 * been warned.
                 */

                if ((tmpin_name = _tempnam(getenv("TEMP"), "vile")) == NULL)
                    break;
                if ((tmpin_fd = open(tmpin_name,
                                     O_RDONLY|O_CREAT|O_TRUNC,
                                     _S_IWRITE|_S_IREAD)) == BAD_FD)
                {
                    break;
                }
                handles[0] = (HANDLE) _get_osfhandle(tmpin_fd);
            }
            if ((*fr = fdopen(rp[0], "r")) == 0)
                break;
        }
        if (fw)
        {
            *fw = NULL;

            /*
             * Open (child's) output pipe in binary mode, which will
             * prevent translation of the parent's CR/LF record delimiters
             * to NL.  Apparently, many apps want those delimiters :-) .
             */
            if (_pipe(wp, PIPESIZ, O_BINARY|O_NOINHERIT) == -1)
                break;
            if ((wp[2] = _dup(wp[0])) == -1)
                break;
            handles[0] = (HANDLE)_get_osfhandle(wp[2]);
            (void) close(wp[0]);
            wp[0] = BAD_FD;
            if (! fr)
                handles[1] = handles[2] = GetStdHandle(STD_OUTPUT_HANDLE);
            if ((*fw = fdopen(wp[1], "w")) == 0)
                break;
        }
        rc = (exec_shell(cmd,
                         handles,
                         fr != NULL  /* Child wdw hidden unless write pipe. */
                        ) == BAD_PROC_HANDLE) ? FALSE : TRUE;
        if (fw)
        {
            if (! rc)
            {
                /* Shell process failed, put complaint in user's face. */

                sprintf(buf, SHELL_ERR_MSG, get_shell());
                lastditch_msg(buf);
            }
            w32_close_handle(handles[0]);
        }
        if (fr)
        {
            if (! rc)
            {
                unsigned len;

                /*
                 * Shell process failed, put complaint in user's buffer.
                 * Can't write to handles[1] on a win2k host because the
                 * previously failed CreateProcess() call damaged the
                 * handle.
                 */
                len = (unsigned) (lsprintf(buf, SHELL_ERR_MSG, get_shell()) - buf);
                (void) write(rp[2], buf, len);
                (void) close(rp[2]);   /* in weird state; why not? */
            }
            w32_close_handle(handles[1]);
            close_fd(tmpin_fd);
        }
        returnCode(rc);
    }
    while (FALSE);

    /* If we get here -- some operation has failed.  Clean up. */

    close_fd(wp[0]);
    close_fd(wp[1]);
    close_fd(wp[2]);
    close_fd(rp[0]);
    close_fd(rp[1]);
    close_fd(rp[2]);
    close_fd(tmpin_fd);
    for (i = 0; i < 3; i++)
    {
        if (handles[i] != INVALID_HANDLE_VALUE)
            w32_close_handle(handles[i]);
    }
    common_cleanup();
    returnCode(FALSE);
}
Пример #2
0
static int
tmp_inout_popen(FILE **fr, FILE **fw, char *cmd)
{
    char  buf[NFILEN + 128];
    DWORD dummy, len;
    int   rc, term_status, tmpin_fd;

    TRACE(("tmp_inout_popen cmd=%s\n", cmd));
    proc_handle = BAD_PROC_HANDLE;
    handles[0]  = handles[1] = handles[2]  = INVALID_HANDLE_VALUE;
    tmpin_fd    = stdin_fd   = stdout_fd   = BAD_FD;
    tmpin_name  = stdin_name = stdout_name = NULL;
    set_console_title(cmd);
    do
    {
        if (fr)
        {
            *fr = NULL;
            if ((stdin_name = _tempnam(getenv("TEMP"), "vile")) == NULL)
                break;
            if ((stdin_fd = open(stdin_name,
                                 O_RDWR|O_CREAT|O_TRUNC|O_TEXT,
                                 _S_IWRITE|_S_IREAD)) == BAD_FD)
            {
                break;
            }
            handles[2] = handles[1] = (HANDLE) _get_osfhandle(stdin_fd);
            if (! fw)
            {
                /*
                 * This is a read pipe (only).  Connect child's stdin to
                 * an empty file.  Under no circumstances should the
                 * child's stdin be connected to a device (else lots of
                 * screwy things will occur).  In particular, connecting
                 * the child's stdin to the parent's stdin will cause
                 * aborts and hangs on the various Win32 hosts.  You've
                 * been warned.
                 */

                if ((tmpin_name = _tempnam(getenv("TEMP"), "vile")) == NULL)
                    break;
                if ((tmpin_fd = open(tmpin_name,
                                     O_RDONLY|O_CREAT|O_TRUNC,
                                     _S_IWRITE|_S_IREAD)) == BAD_FD)
                {
                    break;
                }
                handles[0] = (HANDLE) _get_osfhandle(tmpin_fd);
            }
            else
            {
                /*
                 * Set up descriptor for filter operation.   Note the
                 * sublteties here:  exec'd shell is passed a descriptor
                 * to the temp file that's opened "w".  The editor
                 * receives a descriptor to the file that's opened "r".
                 */

                if ((*fr = fopen(stdin_name, "r")) == NULL)
                    break;
            }
        }
        if (fw)
        {
            *fw = NULL;

            /* create a temp file to receive data from the editor */
            if ((stdout_name = _tempnam(getenv("TEMP"), "vile")) == NULL)
                break;
            if ((stdout_fd = open(stdout_name,
                                  O_RDWR|O_CREAT|O_TRUNC|O_BINARY,
                                  _S_IWRITE|_S_IREAD)) == BAD_FD)
            {
                break;
            }
            if ((*fw = fdopen(stdout_fd, "w")) == 0)
                break;

            /*
             * we're all set up, but can't exec "cmd" until the editor
             * writes data to the temp file connected to stdout.
             */
            shcmd = cmd;   /* remember this */
            return (TRUE);
        }

        /* This must be a read (only) pipe.  Appropriate to exec "cmd". */
        rc = (exec_shell(cmd,
                         handles,
                         TRUE       /* hide child wdw */
                        ) == BAD_PROC_HANDLE) ? FALSE : TRUE;

        if (! rc)
        {
            /*
             * Shell process failed, put complaint in user's buffer, which
             * is currently proxied by a temp file that the editor will
             * suck in shortly.
             */

            len = (DWORD) (lsprintf(buf, SHELL_ERR_MSG, get_shell()) - buf);
            (void) WriteFile(handles[1], buf, len, &dummy, NULL);
            FlushFileBuffers(handles[1]);
        }
        else
        {
            /* wait for exec'd process to exit */

            (void) cwait(&term_status, (CWAIT_PARAM_TYPE) proc_handle, 0);
            TRACE(("...CreateProcess finished waiting in tmp_inout_popen\n"));
            close_proc_handle();
        }

        /*
         * When closing descriptors shared between parent and child, order
         * is quite important when $shell == command.com .  In this
         * situation, the descriptors can't be closed until the exec'd
         * process exits (I kid you not).
         */
        close_fd(stdin_fd);
        (void) close(tmpin_fd);

        /* let the editor consume the output of the read pipe */
        if ((*fr = fopen(stdin_name, "r")) == NULL)
        {
            /*
             * impossible to put error in user's buffer since that file
             * descriptor is closed.
             */

            sprintf(buf,
                    "[error opening temp file \"%s\": %s]",
                    stdin_name,
                    strerror(errno));
            lastditch_msg(buf);
            break;
        }
        return (rc);
    }
    while (FALSE);

    /* If we get here -- some operation has failed.  Clean up. */
    tmp_cleanup();
    return (FALSE);
}
Пример #3
0
/* int main(int argc, char *argv[], char *environ[]) */
int main(int argc, char *argv[])
{
	char tmpbuf[MAX_OBJNAMELEN + 1];
	obj_t *tobj;
	int i;
	char *p;
	char c;
	short intstatus = 0;
	short preload = 1;
	char *fn=NULL;

	setvbuf(stdout, NULL, _IONBF, 0);
	if (argc < 2) {
		do_banner();
		do_help(argv[0]);
		return -1;
	}
	if ((N = nsp_newstate()) == NULL) return -1;
	setsigs();
	N->debug = 0;
	//nspbase_register_all(N);
	/* add env */
	tobj = nsp_settable(N, &N->g, "_ENV");
	for (i = 0;environ[i] != NULL;i++) {
		strncpy(tmpbuf, environ[i], MAX_OBJNAMELEN);
		p = strchr(tmpbuf, '=');
		if (!p) continue;
		*p = '\0';
		p = strchr(environ[i], '=') + 1;
		nsp_setstr(N, tobj, tmpbuf, p, -1);
	}
	/* add args */
	tobj = nsp_settable(N, &N->g, "_ARGS");
	for (i = 0;i < argc;i++) {
		n_ntoa(N, tmpbuf, i, 10, 0);
		nsp_setstr(N, tobj, tmpbuf, argv[i], -1);
	}
	tobj = nsp_settable(N, &N->g, "io");
	nsp_setcfunc(N, tobj, "gets", (NSP_CFUNC)neslib_io_gets);
	for (i = 1;i < argc;i++) {
		if (argv[i] == NULL) break;
		if (argv[i][0] == '-') {
			c = argv[i][1];
			if (!c) {
				break;
			}
			else if ((c == 'd') || (c == 'D')) {
				N->debug = 1;
			}
			else if ((c == 's') || (c == 'S')) {
				intstatus = 1;
			}
			else if ((c == 'b') || (c == 'B')) {
				preload = 0;
			}
			else if ((c == 'e') || (c == 'E')) {
				if (++i < argc) {
					if (preload) do_preload(N);
					nsp_exec(N, argv[i]);
					if (N->err) goto err;
				}
			}
			else if ((c == 'f') || (c == 'F')) {
				if (++i < argc) {
					preppath(N, argv[i]);
					set_console_title(N);
					if (preload) do_preload(N);
					fn=argv[i];
					nsp_execfile(N, fn);
					if (N->err) goto err;
				}
			}
			else if ((c == 'v') || (c == 'V')) {
				printf(NSP_VERSION "\r\n");
				return 0;
			}
			else {
				do_help(argv[0]);
				return -1;
			}
		}
		else {
			preppath(N, argv[i]);
			set_console_title(N);
			if (preload) do_preload(N);
			fn=argv[i];
			nsp_execfile(N, fn);
			if (N->err) goto err;
		}
	}
err:
	if (N->err) printf("%s\r\n", N->errbuf);
	nsp_freestate(N);
	if (intstatus || N->allocs != N->frees) printstate(N, fn);
	nsp_endstate(N);
	return 0;
}