Merge pull request #357 from KLuka/issue-222

Issue #222: LOGIN service (can't reopen tty)
This commit is contained in:
Luka Krajger 2016-01-04 10:56:18 -05:00
commit 2c93404bd0
3 changed files with 32 additions and 2 deletions

View file

@ -116,9 +116,11 @@ void initSession(struct Session *session, const char *sessionKey,
session->http = NULL;
session->done = 0;
session->pty = -1;
session->ptyFirstRead = 1;
session->width = 0;
session->height = 0;
session->buffered = NULL;
session->useLogin = 0;
session->len = 0;
session->pid = 0;
session->cleanup = 0;

View file

@ -58,9 +58,11 @@ struct Session {
HttpConnection *http;
int done;
int pty;
int ptyFirstRead;
int width;
int height;
char *buffered;
int useLogin;
int len;
pid_t pid;
int cleanup;

View file

@ -63,7 +63,7 @@
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <time.h>
#include <unistd.h>
#ifdef HAVE_SYS_PRCTL_H
@ -291,6 +291,13 @@ static void sessionDone(void *arg) {
completePendingRequest(session, "", 0, INT_MAX);
}
static void delaySession(void) {
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = 200 * 1000; // Delay for 0.2 ms
nanosleep(&ts, NULL);
}
static int handleSession(struct ServerConnection *connection, void *arg,
short *events, short revents) {
struct Session *session = (struct Session *)arg;
@ -310,7 +317,7 @@ static int handleSession(struct ServerConnection *connection, void *arg,
int timedOut = serverGetTimeout(connection) < 0;
if (bytes || timedOut) {
if (!session->http && timedOut) {
debug("[server] Timeout. Closing session!");
debug("[server] Timeout. Closing session %s!", session->sessionKey);
session->cleanup = 1;
return 0;
}
@ -324,8 +331,26 @@ static int handleSession(struct ServerConnection *connection, void *arg,
*events = 0;
}
serverSetTimeout(connection, AJAX_TIMEOUT);
session->ptyFirstRead = 0;
return 1;
} else {
if (revents & POLLHUP) {
if (session->useLogin && session->ptyFirstRead) {
// Workaround for random "Session closed" issues related to /bin/login
// closing and reopening our pty during initialization. This happens only
// on some systems like Fedora for example.
// Here we allow that our pty is closed by ignoring POLLHUP on first read.
// Delay is also needed so that login process has some time to reopen pty.
// Note that the issue may occur anyway but with workaround we reduce the
// chances.
debug("[server] POLLHUP received on login PTY first read!");
session->ptyFirstRead = 0;
delaySession();
return 1;
}
debug("[server] POLLHUP received on PTY! Closing session %s!",
session->sessionKey);
}
return 0;
}
}
@ -402,6 +427,7 @@ static int dataHandler(HttpConnection *http, struct Service *service,
goto bad_new_session;
}
session->http = http;
session->useLogin = service->useLogin;
if (launchChild(service->id, session,
rootURL && *rootURL ? rootURL : urlGetURL(url)) < 0) {
abandonSession(session);