예제 #1
0
파일: rlogin.c 프로젝트: 4myPAL/PuTTYTray
static int rlogin_closing(Plug plug, const char *error_msg, int error_code,
			  int calling_back)
{
    Rlogin rlogin = (Rlogin) plug;

    /*
     * We don't implement independent EOF in each direction for Telnet
     * connections; as soon as we get word that the remote side has
     * sent us EOF, we wind up the whole connection.
     */

    if (rlogin->s) {
        sk_close(rlogin->s);
        rlogin->s = NULL;
        if (error_msg)
            rlogin->closed_on_socket_error = TRUE;
	notify_remote_exit(rlogin->frontend);
    }
    if (error_msg) {
	/* A socket error has occurred. */
	logevent(rlogin->frontend, error_msg);
	connection_fatal(rlogin->frontend, "%s", error_msg);
    }				       /* Otherwise, the remote side closed the connection normally. */
    return 0;
}
예제 #2
0
파일: winser.c 프로젝트: rdebath/sgt
static int serial_gotdata(struct handle *h, void *data, int len)
{
    Serial serial = (Serial)handle_get_privdata(h);
    if (len <= 0) {
	const char *error_msg;

	/*
	 * Currently, len==0 should never happen because we're
	 * ignoring EOFs. However, it seems not totally impossible
	 * that this same back end might be usable to talk to named
	 * pipes or some other non-serial device, in which case EOF
	 * may become meaningful here.
	 */
	if (len == 0)
	    error_msg = "End of file reading from serial device";
	else
	    error_msg = "Error reading from serial device";

	serial_terminate(serial);

	notify_remote_exit(serial->frontend);

	logevent(serial->frontend, error_msg);

	connection_fatal(serial->frontend, "%s", error_msg);

	return 0;		       /* placate optimiser */
    } else {
	return from_backend(serial->frontend, 0, data, len);
    }
}
예제 #3
0
static int raw_closing(Plug plug, const char *error_msg, int error_code,
		       int calling_back)
{
    Raw raw = (Raw) plug;

    if (error_msg) {
        /* A socket error has occurred. */
        if (raw->s) {
            sk_close(raw->s);
            raw->s = NULL;
            notify_remote_exit(raw->frontend);
        }
        logevent(raw->frontend, error_msg);
        connection_fatal(raw->frontend, "%s", error_msg);
    } else {
        /* Otherwise, the remote side closed the connection normally. */
        if (!raw->sent_console_eof && from_backend_eof(raw->frontend)) {
            /*
             * The front end wants us to close the outgoing side of the
             * connection as soon as we see EOF from the far end.
             */
            if (!raw->sent_socket_eof) {
                if (raw->s)
                    sk_write_eof(raw->s);
                raw->sent_socket_eof= TRUE;
            }
        }
        raw->sent_console_eof = TRUE;
        raw_check_close(raw);
    }
    return 0;
}
예제 #4
0
파일: uxser.c 프로젝트: halcy/PuTTY
static int serial_select_result(int fd, int event)
{
    Serial serial;
    char buf[4096];
    int ret;
    int finished = FALSE;

    serial = find234(serial_by_fd, &fd, serial_find_by_fd);

    if (!serial)
	return 1;		       /* spurious event; keep going */

    if (event == 1) {
	ret = read(serial->fd, buf, sizeof(buf));

	if (ret == 0) {
	    /*
	     * Shouldn't happen on a real serial port, but I'm open
	     * to the idea that there might be two-way devices we
	     * can treat _like_ serial ports which can return EOF.
	     */
	    finished = TRUE;
	} else if (ret < 0) {
#ifdef EAGAIN
	    if (errno == EAGAIN)
		return 1;	       /* spurious */
#endif
#ifdef EWOULDBLOCK
	    if (errno == EWOULDBLOCK)
		return 1;	       /* spurious */
#endif
	    perror("read serial port");
	    exit(1);
	} else if (ret > 0) {
	    serial->inbufsize = from_backend(serial->frontend, 0, buf, ret);
	    serial_uxsel_setup(serial); /* might acquire backlog and freeze */
	}
    } else if (event == 2) {
	/*
	 * Attempt to send data down the pty.
	 */
	serial_try_write(serial);
    }

    if (finished) {
	serial_close(serial);

	serial->finished = TRUE;

	notify_remote_exit(serial->frontend);
    }

    return !finished;
}
예제 #5
0
static void raw_check_close(Raw raw)
{
    /*
     * Called after we send EOF on either the socket or the console.
     * Its job is to wind up the session once we have sent EOF on both.
     */
    if (raw->sent_console_eof && raw->sent_socket_eof) {
        if (raw->s) {
            sk_close(raw->s);
            raw->s = NULL;
            notify_remote_exit(raw->frontend);
        }
    }
}
예제 #6
0
static int rlogin_closing(Plug plug, const char *error_msg, int error_code,
			  int calling_back)
{
    Rlogin rlogin = (Rlogin) plug;
    if (rlogin->s) {
        sk_close(rlogin->s);
        rlogin->s = NULL;
	notify_remote_exit(rlogin->frontend);
    }
    if (error_msg) {
	/* A socket error has occurred. */
	logevent(rlogin->frontend, error_msg);
	connection_fatal(rlogin->frontend, "%s", error_msg);
    }				       /* Otherwise, the remote side closed the connection normally. */
    return 0;
}
예제 #7
0
파일: winser.c 프로젝트: rdebath/sgt
static void serial_sentdata(struct handle *h, int new_backlog)
{
    Serial serial = (Serial)handle_get_privdata(h);
    if (new_backlog < 0) {
	const char *error_msg = "Error writing to serial device";

	serial_terminate(serial);

	notify_remote_exit(serial->frontend);

	logevent(serial->frontend, error_msg);

	connection_fatal(serial->frontend, "%s", error_msg);
    } else {
	serial->bufsize = new_backlog;
    }
}
예제 #8
0
파일: cygterm.c 프로젝트: Chaz6/futty
static int
cygterm_closing(Plug plug, const char *error_msg, int error_code, int calling_back)
{
	Local local = (Local)plug;
	cygterm_debug("top");
	if (local->s) {
		sk_close(local->s);
		local->s = NULL;
	}
	/* check for errors from cthelper */
	CloseHandle(local->ctl);
	/* wait for cthelper */
	if (local->pi.hProcess != INVALID_HANDLE_VALUE) {
		if (WAIT_OBJECT_0 == WaitForSingleObject(local->pi.hProcess, 2000)) {
			DWORD status;
			GetExitCodeProcess(local->pi.hProcess, &status);
			switch (status) {
			case CthelperSuccess:
				break;
			case CthelperInvalidUsage:
			case CthelperInvalidPort:
			case CthelperConnectFailed:
				local->exitcode = INT_MAX;
				error_msg = "Internal error";
				break;
			case CthelperPtyforkFailure:
				local->exitcode = INT_MAX;
				error_msg = "Failed to allocate pseudoterminal";
				break;
			case CthelperExecFailure:
				local->exitcode = INT_MAX;
				error_msg = "Failed to execute command";
				break;
			}
		}
	}
	/* this calls cygterm_exitcode() */
	notify_remote_exit(local->frontend);
	if (error_msg) {
		cygterm_debug("error_msg: %s", error_msg);
		connection_fatal(local->frontend, "%s", error_msg);
	}
	return 0;
}
예제 #9
0
int pty_real_select_result(Pty pty, int event, int status)
{
    char buf[4096];
    int ret;
    int finished = FALSE;

    if (event < 0) {
	/*
	 * We've been called because our child process did
	 * something. `status' tells us what.
	 */
	if ((WIFEXITED(status) || WIFSIGNALED(status))) {
	    /*
	     * The primary child process died. We could keep
	     * the terminal open for remaining subprocesses to
	     * output to, but conventional wisdom seems to feel
	     * that that's the Wrong Thing for an xterm-alike,
	     * so we bail out now (though we don't necessarily
	     * _close_ the window, depending on the state of
	     * Close On Exit). This would be easy enough to
	     * change or make configurable if necessary.
	     */
	    pty->exit_code = status;
	    pty->child_dead = TRUE;
	    del234(ptys_by_pid, pty);
	    finished = TRUE;
	}
    } else {
	if (event == 1) {

	    ret = read(pty->master_fd, buf, sizeof(buf));

	    /*
	     * Clean termination condition is that either ret == 0, or ret
	     * < 0 and errno == EIO. Not sure why the latter, but it seems
	     * to happen. Boo.
	     */
	    if (ret == 0 || (ret < 0 && errno == EIO)) {
		/*
		 * We assume a clean exit if the pty has closed but the
		 * actual child process hasn't. The only way I can
		 * imagine this happening is if it detaches itself from
		 * the pty and goes daemonic - in which case the
		 * expected usage model would precisely _not_ be for
		 * the pterm window to hang around!
		 */
		finished = TRUE;
		if (!pty->child_dead)
		    pty->exit_code = 0;
	    } else if (ret < 0) {
		perror("read pty master");
		exit(1);
	    } else if (ret > 0) {
		from_backend(pty->frontend, 0, buf, ret);
	    }
	} else if (event == 2) {
            /*
             * Attempt to send data down the pty.
             */
            pty_try_write(pty);
        }
    }

    if (finished && !pty->finished) {
	int close_on_exit;

	uxsel_del(pty->master_fd);
	pty_close(pty);
	pty->master_fd = -1;

	pty->finished = TRUE;

	/*
	 * This is a slight layering-violation sort of hack: only
	 * if we're not closing on exit (COE is set to Never, or to
	 * Only On Clean and it wasn't a clean exit) do we output a
	 * `terminated' message.
	 */
	close_on_exit = conf_get_int(pty->conf, CONF_close_on_exit);
	if (close_on_exit == FORCE_OFF ||
	    (close_on_exit == AUTO && pty->exit_code != 0)) {
	    char message[512];
            message[0] = '\0';
	    if (WIFEXITED(pty->exit_code))
		sprintf(message, "\r\n[pterm: process terminated with exit"
			" code %d]\r\n", WEXITSTATUS(pty->exit_code));
	    else if (WIFSIGNALED(pty->exit_code))
#ifdef HAVE_NO_STRSIGNAL
		sprintf(message, "\r\n[pterm: process terminated on signal"
			" %d]\r\n", WTERMSIG(pty->exit_code));
#else
		sprintf(message, "\r\n[pterm: process terminated on signal"
			" %d (%.400s)]\r\n", WTERMSIG(pty->exit_code),
			strsignal(WTERMSIG(pty->exit_code)));
#endif
	    from_backend(pty->frontend, 0, message, strlen(message));
	}

	notify_remote_exit(pty->frontend);
    }

    return !finished;
}