summaryrefslogtreecommitdiff
path: root/channels
diff options
context:
space:
mode:
authorArmin Novak <anovak@thinstuff.com>2013-08-14 15:14:40 +0200
committerBernhard Miklautz <bmiklautz@thinstuff.at>2013-08-26 20:10:43 +0200
commitcf6b9d44ac4d3b512af1d090f72c6f6006716f42 (patch)
treea52fd0d720f005d3edbc6063d29c651b992d7878 /channels
parent4a5b19e8163550c5d3c08b17237f758f1ce08df0 (diff)
downloadfreerdp-cf6b9d44ac4d3b512af1d090f72c6f6006716f42.tar.gz
freerdp-cf6b9d44ac4d3b512af1d090f72c6f6006716f42.tar.bz2
freerdp-cf6b9d44ac4d3b512af1d090f72c6f6006716f42.zip
Fixed invalid access to tty in thread, which was already removed by
serial_process_irp_close Retry read now, if non blocking IO returns EAGAIN.
Diffstat (limited to 'channels')
-rw-r--r--channels/serial/client/serial_main.c35
-rw-r--r--channels/serial/client/serial_tty.c14
2 files changed, 47 insertions, 2 deletions
diff --git a/channels/serial/client/serial_main.c b/channels/serial/client/serial_main.c
index d62ca7a91..d2ff16a48 100644
--- a/channels/serial/client/serial_main.c
+++ b/channels/serial/client/serial_main.c
@@ -370,6 +370,8 @@ static void serial_free(DEVICE* device)
SetEvent(serial->stopEvent);
WaitForSingleObject(serial->thread, INFINITE);
+ serial_tty_free(serial->tty);
+
/* Clean up resources */
Stream_Free(serial->device.data, TRUE);
Queue_Free(serial->queue);
@@ -388,6 +390,11 @@ static void serial_abort_single_io(SERIAL_DEVICE* serial, UINT32 file_id, UINT32
DEBUG_SVC("[in] pending size %d", list_size(serial->pending_irps));
tty = serial->tty;
+ if(!tty)
+ {
+ DEBUG_WARN("tty = %p", tty);
+ return;
+ }
switch (abort_io)
{
@@ -438,6 +445,11 @@ static void serial_check_for_events(SERIAL_DEVICE* serial)
SERIAL_TTY* tty;
tty = serial->tty;
+ if(!tty)
+ {
+ DEBUG_WARN("tty = %p", tty);
+ return;
+ }
DEBUG_SVC("[in] pending size %d", list_size(serial->pending_irps));
@@ -483,6 +495,11 @@ void serial_get_timeouts(SERIAL_DEVICE* serial, IRP* irp, UINT32* timeout, UINT3
DEBUG_SVC("length read %u", Length);
tty = serial->tty;
+ if(!tty)
+ {
+ DEBUG_WARN("tty = %p", tty);
+ return;
+ }
*timeout = (tty->read_total_timeout_multiplier * Length) + tty->read_total_timeout_constant;
*interval_timeout = tty->read_interval_timeout;
@@ -497,6 +514,11 @@ static void serial_handle_async_irp(SERIAL_DEVICE* serial, IRP* irp)
SERIAL_TTY* tty;
tty = serial->tty;
+ if(!tty)
+ {
+ DEBUG_WARN("tty = %p", tty);
+ return;
+ }
switch (irp->MajorFunction)
{
@@ -547,6 +569,11 @@ static void __serial_check_fds(SERIAL_DEVICE* serial)
ZeroMemory(&serial->tv, sizeof(struct timeval));
tty = serial->tty;
+ if(!tty)
+ {
+ DEBUG_WARN("tty = %p", tty);
+ return;
+ }
/* scan every pending */
irp = list_peek(serial->pending_irps);
@@ -609,6 +636,11 @@ static void serial_set_fds(SERIAL_DEVICE* serial)
DEBUG_SVC("[in] pending size %d", list_size(serial->pending_irps));
tty = serial->tty;
+ if(!tty)
+ {
+ DEBUG_WARN("tty = %p", tty);
+ return;
+ }
irp = (IRP*) list_peek(serial->pending_irps);
while (irp)
@@ -710,7 +742,8 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) serial);
- serial->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) serial_thread_func, (void*) serial, 0, NULL);
+ serial->thread = CreateThread(NULL, 0,
+ (LPTHREAD_START_ROUTINE) serial_thread_func, (void*) serial, 0, NULL);
}
return 0;
diff --git a/channels/serial/client/serial_tty.c b/channels/serial/client/serial_tty.c
index 23445b2ca..9da45bdb0 100644
--- a/channels/serial/client/serial_tty.c
+++ b/channels/serial/client/serial_tty.c
@@ -409,10 +409,19 @@ BOOL serial_tty_read(SERIAL_TTY* tty, BYTE* buffer, UINT32* Length)
ZeroMemory(buffer, *Length);
- status = read(tty->fd, buffer, *Length);
+ do
+ {
+ errno = 0;
+ status = read(tty->fd, buffer, *Length);
+ }
+ while(EAGAIN == errno);
if (status < 0)
+ {
+ DEBUG_WARN("failed with %zd, errno=[%d] %s\n",
+ status, errno, strerror(errno));
return FALSE;
+ }
tty->event_txempty = status;
*Length = status;
@@ -456,6 +465,9 @@ void serial_tty_free(SERIAL_TTY* tty)
{
DEBUG_SVC("in");
+ if(!tty)
+ return;
+
if (tty->fd >= 0)
{
if (tty->pold_termios)