diff --git a/CMakeLists.txt b/CMakeLists.txt index 45c9e1baf..98c23176f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -208,6 +208,7 @@ if(NOT ANDROID) endif() if(UNIX OR CYGWIN) + check_include_files(sys/eventfd.h HAVE_EVENTFD_H) set(X11_FEATURE_TYPE "RECOMMENDED") else() set(X11_FEATURE_TYPE "DISABLED") diff --git a/channels/serial/client/serial_main.c b/channels/serial/client/serial_main.c index 71eefe61d..f222c400a 100644 --- a/channels/serial/client/serial_main.c +++ b/channels/serial/client/serial_main.c @@ -340,13 +340,13 @@ static void* serial_thread_func(void* arg) while (1) { - freerdp_thread_wait(serial->thread); + freerdp_thread_wait_timeout(serial->thread, 500); serial->nfds = 1; FD_ZERO(&serial->read_fds); FD_ZERO(&serial->write_fds); - serial->tv.tv_sec = 20; + serial->tv.tv_sec = 1; serial->tv.tv_usec = 0; serial->select_timeout = 0; @@ -356,10 +356,13 @@ static void* serial_thread_func(void* arg) freerdp_thread_reset(serial->thread); serial_process_irp_list(serial); - if (WaitForSingleObject(serial->in_event, 0) == WAIT_OBJECT_0) - { - if (serial_check_fds(serial)) - ResetEvent(serial->in_event); + switch (WaitForSingleObject(serial->in_event, 0)) { + case WAIT_OBJECT_0: + case WAIT_TIMEOUT: + { + if (serial_check_fds(serial)) + ResetEvent(serial->in_event); + } } } @@ -683,6 +686,7 @@ static BOOL serial_check_fds(SERIAL_DEVICE* serial) case 0: if (serial->select_timeout) { + __serial_check_fds(serial); serial_abort_single_io(serial, serial->timeout_id, SERIAL_ABORT_IO_NONE, STATUS_TIMEOUT); serial_abort_single_io(serial, serial->timeout_id, SERIAL_ABORT_IO_READ, STATUS_TIMEOUT); serial_abort_single_io(serial, serial->timeout_id, SERIAL_ABORT_IO_WRITE, STATUS_TIMEOUT); diff --git a/channels/tsmf/client/ffmpeg/CMakeLists.txt b/channels/tsmf/client/ffmpeg/CMakeLists.txt index ddb4e7c62..827c52234 100644 --- a/channels/tsmf/client/ffmpeg/CMakeLists.txt +++ b/channels/tsmf/client/ffmpeg/CMakeLists.txt @@ -32,9 +32,18 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MODULE freerdp MODULES freerdp-utils) -set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${FFMPEG_LIBRARIES}) -target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) +if(APPLE) + # For this to work on apple, we need to add some frameworks + FIND_LIBRARY(COREFOUNDATION_LIBRARY CoreFoundation ) + FIND_LIBRARY(COREVIDEO_LIBRARY CoreVideo ) + FIND_LIBRARY(COREVIDEODECODE_LIBRARY VideoDecodeAcceleration ) + set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${FFMPEG_LIBRARIES} ${COREFOUNDATION_LIBRARY} ${COREVIDEO_LIBRARY} ${COREVIDEODECODE_LIBRARY} ) + target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) +else() + set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${FFMPEG_LIBRARIES}) + target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) +endif() if(NOT STATIC_CHANNELS) install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH}) diff --git a/client/common/compatibility.c b/client/common/compatibility.c index f89860bfe..a916d15bf 100644 --- a/client/common/compatibility.c +++ b/client/common/compatibility.c @@ -269,6 +269,11 @@ int freerdp_client_old_command_line_pre_filter(void* context, int index, int arg index++; i++; } + } else { + if (settings->instance) + { + freerdp_client_old_process_plugin(settings, args); + } } return (index - old_index); diff --git a/config.h.in b/config.h.in index d8717f3a5..8cbaf2620 100644 --- a/config.h.in +++ b/config.h.in @@ -28,7 +28,7 @@ #cmakedefine HAVE_SYS_MODEM_H #cmakedefine HAVE_SYS_FILIO_H #cmakedefine HAVE_SYS_STRTIO_H - +#cmakedefine HAVE_EVENTFD_H #cmakedefine HAVE_TM_GMTOFF diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index 59f0822b7..e29a095ca 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -324,17 +324,22 @@ int rfx_tile_pool_return(RFX_CONTEXT* context, RFX_TILE* tile) return 0; } -static void rfx_process_message_sync(RFX_CONTEXT* context, STREAM* s) +static BOOL rfx_process_message_sync(RFX_CONTEXT* context, STREAM* s) { UINT32 magic; /* RFX_SYNC */ + if (stream_get_left(s) < 6) + { + DEBUG_WARN("RfxSync packet too small"); + return FALSE; + } stream_read_UINT32(s, magic); /* magic (4 bytes), 0xCACCACCA */ if (magic != WF_MAGIC) { DEBUG_WARN("invalid magic number 0x%X", magic); - return; + return FALSE; } stream_read_UINT16(s, context->version); /* version (2 bytes), WF_VERSION_1_0 (0x0100) */ @@ -342,22 +347,34 @@ static void rfx_process_message_sync(RFX_CONTEXT* context, STREAM* s) if (context->version != WF_VERSION_1_0) { DEBUG_WARN("unknown version number 0x%X", context->version); - return; + return FALSE; } DEBUG_RFX("version 0x%X", context->version); + return TRUE; } -static void rfx_process_message_codec_versions(RFX_CONTEXT* context, STREAM* s) +static BOOL rfx_process_message_codec_versions(RFX_CONTEXT* context, STREAM* s) { BYTE numCodecs; + if (stream_get_left(s) < 1) + { + DEBUG_WARN("RfxCodecVersion packet too small"); + return FALSE; + } stream_read_BYTE(s, numCodecs); /* numCodecs (1 byte), must be set to 0x01 */ if (numCodecs != 1) { DEBUG_WARN("numCodecs: %d, expected:1", numCodecs); - return; + return FALSE; + } + + if (stream_get_left(s) < 2 * numCodecs) + { + DEBUG_WARN("RfxCodecVersion packet too small for numCodecs=%d", numCodecs); + return FALSE; } /* RFX_CODEC_VERSIONT */ @@ -365,13 +382,20 @@ static void rfx_process_message_codec_versions(RFX_CONTEXT* context, STREAM* s) stream_read_BYTE(s, context->codec_version); /* version (2 bytes) */ DEBUG_RFX("id %d version 0x%X.", context->codec_id, context->codec_version); + return TRUE; } -static void rfx_process_message_channels(RFX_CONTEXT* context, STREAM* s) +static BOOL rfx_process_message_channels(RFX_CONTEXT* context, STREAM* s) { BYTE channelId; BYTE numChannels; + if (stream_get_left(s) < 1) + { + DEBUG_WARN("RfxMessageChannels packet too small"); + return FALSE; + } + stream_read_BYTE(s, numChannels); /* numChannels (1 byte), must bet set to 0x01 */ /* In RDVH sessions, numChannels will represent the number of virtual monitors @@ -380,7 +404,13 @@ static void rfx_process_message_channels(RFX_CONTEXT* context, STREAM* s) if (numChannels < 1) { DEBUG_WARN("numChannels:%d, expected:1", numChannels); - return; + return TRUE; + } + + if (stream_get_left(s) < numChannels * 5) + { + DEBUG_WARN("RfxMessageChannels packet too small for numChannels=%d", numChannels); + return FALSE; } /* RFX_CHANNELT */ @@ -393,14 +423,21 @@ static void rfx_process_message_channels(RFX_CONTEXT* context, STREAM* s) DEBUG_RFX("numChannels %d id %d, %dx%d.", numChannels, channelId, context->width, context->height); + return TRUE; } -static void rfx_process_message_context(RFX_CONTEXT* context, STREAM* s) +static BOOL rfx_process_message_context(RFX_CONTEXT* context, STREAM* s) { BYTE ctxId; UINT16 tileSize; UINT16 properties; + if (stream_get_left(s) < 5) + { + DEBUG_WARN("RfxMessageContext packet too small"); + return FALSE; + } + stream_read_BYTE(s, ctxId); /* ctxId (1 byte), must be set to 0x00 */ stream_read_UINT16(s, tileSize); /* tileSize (2 bytes), must be set to CT_TILE_64x64 (0x0040) */ stream_read_UINT16(s, properties); /* properties (2 bytes) */ @@ -431,17 +468,24 @@ static void rfx_process_message_context(RFX_CONTEXT* context, STREAM* s) DEBUG_WARN("unknown RLGR algorithm."); break; } + return TRUE; } -static void rfx_process_message_frame_begin(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s) +static BOOL rfx_process_message_frame_begin(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s) { UINT32 frameIdx; UINT16 numRegions; + if (stream_get_left(s) < 6) + { + DEBUG_WARN("RfxMessageFrameBegin packet too small"); + return FALSE; + } stream_read_UINT32(s, frameIdx); /* frameIdx (4 bytes), if codec is in video mode, must be ignored */ stream_read_UINT16(s, numRegions); /* numRegions (2 bytes) */ DEBUG_RFX("RFX_FRAME_BEGIN: frameIdx:%d numRegions:%d", frameIdx, numRegions); + return TRUE; } static void rfx_process_message_frame_end(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s) @@ -449,17 +493,29 @@ static void rfx_process_message_frame_end(RFX_CONTEXT* context, RFX_MESSAGE* mes DEBUG_RFX("RFX_FRAME_END"); } -static void rfx_process_message_region(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s) +static BOOL rfx_process_message_region(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s) { int i; + if (stream_get_left(s) < 3) + { + DEBUG_WARN("RfxMessageRegion packet too small"); + return FALSE; + } + stream_seek_BYTE(s); /* regionFlags (1 byte) */ stream_read_UINT16(s, message->num_rects); /* numRects (2 bytes) */ if (message->num_rects < 1) { DEBUG_WARN("no rects."); - return; + return TRUE; + } + + if (stream_get_left(s) < 8 * message->num_rects) + { + DEBUG_WARN("RfxMessageRegion packet too small for num_rects=%d", message->num_rects); + return FALSE; } if (message->rects != NULL) @@ -479,9 +535,10 @@ static void rfx_process_message_region(RFX_CONTEXT* context, RFX_MESSAGE* messag DEBUG_RFX("rect %d (%d %d %d %d).", i, message->rects[i].x, message->rects[i].y, message->rects[i].width, message->rects[i].height); } + return TRUE; } -static void rfx_process_message_tile(RFX_CONTEXT* context, RFX_TILE* tile, STREAM* s) +static BOOL rfx_process_message_tile(RFX_CONTEXT* context, RFX_TILE* tile, STREAM* s) { BYTE quantIdxY; BYTE quantIdxCb; @@ -489,6 +546,12 @@ static void rfx_process_message_tile(RFX_CONTEXT* context, RFX_TILE* tile, STREA UINT16 xIdx, yIdx; UINT16 YLen, CbLen, CrLen; + if (stream_get_left(s) < 13) + { + DEBUG_WARN("RfxMessageTile packet too small"); + return FALSE; + } + /* RFX_TILE */ stream_read_BYTE(s, quantIdxY); /* quantIdxY (1 byte) */ stream_read_BYTE(s, quantIdxCb); /* quantIdxCb (1 byte) */ @@ -505,7 +568,7 @@ static void rfx_process_message_tile(RFX_CONTEXT* context, RFX_TILE* tile, STREA tile->x = xIdx * 64; tile->y = yIdx * 64; - rfx_decode_rgb(context, s, + return rfx_decode_rgb(context, s, YLen, context->quants + (quantIdxY * 10), CbLen, context->quants + (quantIdxCb * 10), CrLen, context->quants + (quantIdxCr * 10), @@ -526,7 +589,7 @@ void CALLBACK rfx_process_message_tile_work_callback(PTP_CALLBACK_INSTANCE insta rfx_process_message_tile(param->context, param->tile, &(param->s)); } -static void rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s) +static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s) { int i; int pos; @@ -539,12 +602,18 @@ static void rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa PTP_WORK* work_objects = NULL; RFX_TILE_WORK_PARAM* params = NULL; + if (stream_get_left(s) < 14) + { + DEBUG_WARN("RfxMessageTileSet packet too small"); + return FALSE; + } + stream_read_UINT16(s, subtype); /* subtype (2 bytes) must be set to CBT_TILESET (0xCAC2) */ if (subtype != CBT_TILESET) { DEBUG_WARN("invalid subtype, expected CBT_TILESET."); - return; + return FALSE; } stream_seek_UINT16(s); /* idx (2 bytes), must be set to 0x0000 */ @@ -556,7 +625,7 @@ static void rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa if (context->num_quants < 1) { DEBUG_WARN("no quantization value."); - return; + return TRUE; } stream_read_UINT16(s, message->num_tiles); /* numTiles (2 bytes) */ @@ -564,7 +633,7 @@ static void rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa if (message->num_tiles < 1) { DEBUG_WARN("no tiles."); - return; + return TRUE; } stream_read_UINT32(s, tilesDataSize); /* tilesDataSize (4 bytes) */ @@ -576,6 +645,12 @@ static void rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa quants = context->quants; /* quantVals */ + if (stream_get_left(s) < context->num_quants * 5) + { + DEBUG_WARN("RfxMessageTileSet packet too small for num_quants=%d", context->num_quants); + return FALSE; + } + for (i = 0; i < context->num_quants; i++) { /* RFX_CODEC_QUANT */ @@ -616,9 +691,21 @@ static void rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa for (i = 0; i < message->num_tiles; i++) { /* RFX_TILE */ + if (stream_get_left(s) < 6) + { + DEBUG_WARN("RfxMessageTileSet packet too small to read tile %d/%d", i, message->num_tiles); + return FALSE; + } + stream_read_UINT16(s, blockType); /* blockType (2 bytes), must be set to CBT_TILE (0xCAC3) */ stream_read_UINT32(s, blockLen); /* blockLen (4 bytes) */ + if (stream_get_left(s) < blockLen - 6) + { + DEBUG_WARN("RfxMessageTileSet not enough bytes to read tile %d/%d with blocklen=%d", i, message->num_tiles, blockLen); + return FALSE; + } + pos = stream_get_pos(s) - 6 + blockLen; if (blockType != CBT_TILE) @@ -656,6 +743,7 @@ static void rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa free(work_objects); free(params); } + return TRUE; } RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, BYTE* data, UINT32 length) @@ -686,6 +774,13 @@ RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, BYTE* data, UINT32 length break; } + if (stream_get_left(s) < blockLen - 6) + { + DEBUG_WARN("rfx_process_message: packet too small for blocklen=%d", blockLen); + break; + } + + pos = stream_get_pos(s) - 6 + blockLen; if (blockType >= WBT_CONTEXT && blockType <= WBT_EXTENSION) @@ -693,7 +788,11 @@ RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, BYTE* data, UINT32 length /* RFX_CODEC_CHANNELT */ /* codecId (1 byte) must be set to 0x01 */ /* channelId (1 byte) must be set to 0x00 */ - stream_seek(s, 2); + if (!stream_skip(s, 2)) + { + DEBUG_WARN("rfx_process_message: unable to skip RFX_CODEC_CHANNELT"); + break; + } } switch (blockType) diff --git a/libfreerdp/codec/rfx_decode.c b/libfreerdp/codec/rfx_decode.c index 8af33be6c..2d9cf3481 100644 --- a/libfreerdp/codec/rfx_decode.c +++ b/libfreerdp/codec/rfx_decode.c @@ -142,7 +142,7 @@ void CALLBACK rfx_decode_component_work_callback(PTP_CALLBACK_INSTANCE instance, } /* stride is bytes between rows in the output buffer. */ -void rfx_decode_rgb(RFX_CONTEXT* context, STREAM* data_in, +BOOL rfx_decode_rgb(RFX_CONTEXT* context, STREAM* data_in, int y_size, const UINT32* y_quants, int cb_size, const UINT32* cb_quants, int cr_size, const UINT32* cr_quants, BYTE* rgb_buffer, int stride) @@ -202,6 +202,11 @@ void rfx_decode_rgb(RFX_CONTEXT* context, STREAM* data_in, else #endif { + if (stream_get_left(data_in) < y_size+cb_size+cr_size) + { + DEBUG_WARN("rfx_decode_rgb: packet too small for y_size+cb_size+cr_size"); + return FALSE; + } rfx_decode_component(context, y_quants, stream_get_tail(data_in), y_size, pSrcDst[0]); /* YData */ stream_seek(data_in, y_size); @@ -225,4 +230,5 @@ void rfx_decode_rgb(RFX_CONTEXT* context, STREAM* data_in, BufferPool_Return(context->priv->BufferPool, pSrcDst[0]); BufferPool_Return(context->priv->BufferPool, pSrcDst[1]); BufferPool_Return(context->priv->BufferPool, pSrcDst[2]); + return TRUE; } diff --git a/libfreerdp/codec/rfx_decode.h b/libfreerdp/codec/rfx_decode.h index e96eb66e2..fa957cd69 100644 --- a/libfreerdp/codec/rfx_decode.h +++ b/libfreerdp/codec/rfx_decode.h @@ -23,7 +23,7 @@ #include /* stride is bytes between rows in the output buffer. */ -void rfx_decode_rgb(RFX_CONTEXT* context, STREAM* data_in, +BOOL rfx_decode_rgb(RFX_CONTEXT* context, STREAM* data_in, int y_size, const UINT32 * y_quants, int cb_size, const UINT32 * cb_quants, int cr_size, const UINT32 * cr_quants, BYTE* rgb_buffer, diff --git a/libfreerdp/core/fastpath.c b/libfreerdp/core/fastpath.c index 4ab569623..af727fd16 100644 --- a/libfreerdp/core/fastpath.c +++ b/libfreerdp/core/fastpath.c @@ -276,7 +276,7 @@ static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 s return status; } -static BOOL fastpath_recv_update_data(rdpFastPath* fastpath, STREAM* s) +static int fastpath_recv_update_data(rdpFastPath* fastpath, STREAM* s) { int status; UINT16 size; diff --git a/libfreerdp/core/fastpath.h b/libfreerdp/core/fastpath.h index 7a7d8477c..3aa897a07 100644 --- a/libfreerdp/core/fastpath.h +++ b/libfreerdp/core/fastpath.h @@ -105,8 +105,8 @@ struct rdp_fastpath UINT16 fastpath_header_length(STREAM* s); UINT16 fastpath_read_header(rdpFastPath* fastpath, STREAM* s); BOOL fastpath_read_header_rdp(rdpFastPath* fastpath, STREAM* s, UINT16 *length); -BOOL fastpath_recv_updates(rdpFastPath* fastpath, STREAM* s); -BOOL fastpath_recv_inputs(rdpFastPath* fastpath, STREAM* s); +int fastpath_recv_updates(rdpFastPath* fastpath, STREAM* s); +int fastpath_recv_inputs(rdpFastPath* fastpath, STREAM* s); STREAM* fastpath_input_pdu_init(rdpFastPath* fastpath, BYTE eventFlags, BYTE eventCode); BOOL fastpath_send_input_pdu(rdpFastPath* fastpath, STREAM* s); diff --git a/libfreerdp/core/peer.c b/libfreerdp/core/peer.c index 8b5a651e5..88a296b57 100644 --- a/libfreerdp/core/peer.c +++ b/libfreerdp/core/peer.c @@ -255,7 +255,7 @@ static int peer_recv_pdu(freerdp_peer* client, STREAM* s) return peer_recv_fastpath_pdu(client, s); } -static BOOL peer_recv_callback(rdpTransport* transport, STREAM* s, void* extra) +static int peer_recv_callback(rdpTransport* transport, STREAM* s, void* extra) { freerdp_peer* client = (freerdp_peer*) extra; rdpRdp* rdp = client->context->rdp; diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c index edd2e8edf..54738910b 100644 --- a/libfreerdp/core/rdp.c +++ b/libfreerdp/core/rdp.c @@ -510,6 +510,11 @@ int rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s) if (compressed_type & PACKET_COMPRESSED) { + if (stream_get_left(s) < compressed_len - 18) + { + printf("decompress_rdp: not enough bytes for compressed_len=%d\n", compressed_len); + return -1; + } if (decompress_rdp(rdp->mppc_dec, s->p, compressed_len - 18, compressed_type, &roff, &rlen)) { comp_stream = stream_new(0); @@ -575,7 +580,7 @@ int rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s) case DATA_PDU_TYPE_SAVE_SESSION_INFO: if(!rdp_recv_save_session_info(rdp, comp_stream)) - return FALSE; + return -1; break; case DATA_PDU_TYPE_FONT_LIST: diff --git a/libfreerdp/core/rdp.h b/libfreerdp/core/rdp.h index 2443c5f19..76789bd97 100644 --- a/libfreerdp/core/rdp.h +++ b/libfreerdp/core/rdp.h @@ -178,7 +178,7 @@ BOOL rdp_send_pdu(rdpRdp* rdp, STREAM* s, UINT16 type, UINT16 channel_id); STREAM* rdp_data_pdu_init(rdpRdp* rdp); BOOL rdp_send_data_pdu(rdpRdp* rdp, STREAM* s, BYTE type, UINT16 channel_id); -BOOL rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s); +int rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s); BOOL rdp_send(rdpRdp* rdp, STREAM* s, UINT16 channel_id); void rdp_recv(rdpRdp* rdp); diff --git a/libfreerdp/core/transport.h b/libfreerdp/core/transport.h index cca3d090b..e584d0dad 100644 --- a/libfreerdp/core/transport.h +++ b/libfreerdp/core/transport.h @@ -45,7 +45,7 @@ typedef struct rdp_transport rdpTransport; #include #include -typedef BOOL (*TransportRecv) (rdpTransport* transport, STREAM* stream, void* extra); +typedef int (*TransportRecv) (rdpTransport* transport, STREAM* stream, void* extra); struct rdp_transport { diff --git a/winpr/libwinpr/synch/event.c b/winpr/libwinpr/synch/event.c index dd9463fca..9ce02230b 100644 --- a/winpr/libwinpr/synch/event.c +++ b/winpr/libwinpr/synch/event.c @@ -35,6 +35,12 @@ #include #endif + +#ifdef HAVE_EVENTFD_H +#include +#include +#endif + CRITICAL_SECTION cs = { NULL, 0, 0, NULL, NULL, 0 }; HANDLE CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCWSTR lpName) @@ -57,11 +63,20 @@ HANDLE CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, event->pipe_fd[0] = -1; event->pipe_fd[1] = -1; +#ifdef HAVE_EVENTFD_H + event->pipe_fd[0] = eventfd(0, EFD_NONBLOCK); + if (event->pipe_fd[0] < 0) + { + printf("CreateEventW: failed to create event\n"); + return NULL; + } +#else if (pipe(event->pipe_fd) < 0) { printf("CreateEventW: failed to create event\n"); return NULL; } +#endif handle = winpr_Handle_Insert(HANDLE_TYPE_EVENT, event); } @@ -113,7 +128,16 @@ BOOL SetEvent(HANDLE hEvent) { event = (WINPR_EVENT*) Object; - if (!(WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0)) +#ifdef HAVE_EVENTFD_H + eventfd_t val = 1; + do + { + length = eventfd_write(event->pipe_fd[0], val); + } + while(length < 0 && errno == EINTR); + status = (length == 0) ? TRUE : FALSE; +#else + if (WaitForSingleObject(hEvent, 0) != WAIT_OBJECT_0) { length = write(event->pipe_fd[1], "-", 1); @@ -124,6 +148,7 @@ BOOL SetEvent(HANDLE hEvent) { status = TRUE; } +#endif } LeaveCriticalSection(&cs); @@ -149,13 +174,23 @@ BOOL ResetEvent(HANDLE hEvent) while (WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0) { - length = read(event->pipe_fd[0], &length, 1); +#ifdef HAVE_EVENTFD_H + eventfd_t value; + do + { + length = eventfd_read(event->pipe_fd[0], &value); + } + while(length < 0 && errno == EINTR); + status = (length > 0) ? TRUE : FALSE; +#else + length = read(event->pipe_fd[0], &length, 1); if (length == 1) status = TRUE; if (length != 1) break; +#endif } }