From ab3b8edf4a6b88adf3e40b481a116668678b5ec8 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Tue, 6 Oct 2015 20:55:47 -0700 Subject: [PATCH] common: change wait objs to use 'pipe' and remove per process temp directories in /tmp/.xrdp/ --- common/os_calls.c | 382 +++++++++++++++++++--------------------------- common/os_calls.h | 59 ++++--- 2 files changed, 191 insertions(+), 250 deletions(-) diff --git a/common/os_calls.c b/common/os_calls.c index de879fa5..3e3a1683 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -100,23 +100,10 @@ extern char **environ; #define INADDR_NONE ((unsigned long)-1) #endif -static char g_temp_base[128] = ""; -static char g_temp_base_org[128] = ""; - /*****************************************************************************/ int APP_CC g_rm_temp_dir(void) { - if (g_temp_base[0] != 0) - { - if (!g_remove_dir(g_temp_base)) - { - printf("g_rm_temp_dir: removing temp directory [%s] failed\n", g_temp_base); - } - - g_temp_base[0] = 0; - } - return 0; } @@ -124,58 +111,19 @@ g_rm_temp_dir(void) int APP_CC g_mk_temp_dir(const char *app_name) { - if (app_name != 0) + if (!g_directory_exist("/tmp/.xrdp")) { - if (app_name[0] != 0) + if (!g_create_dir("/tmp/.xrdp")) { + /* if failed, still check if it got created by someone else */ if (!g_directory_exist("/tmp/.xrdp")) { - if (!g_create_dir("/tmp/.xrdp")) - { - /* if failed, still check if it got created by someone else */ - if (!g_directory_exist("/tmp/.xrdp")) - { - printf("g_mk_temp_dir: g_create_dir failed\n"); - return 1; - } - } - - g_chmod_hex("/tmp/.xrdp", 0x1777); - } - - snprintf(g_temp_base, sizeof(g_temp_base), - "/tmp/.xrdp/%s-XXXXXX", app_name); - snprintf(g_temp_base_org, sizeof(g_temp_base_org), - "/tmp/.xrdp/%s-XXXXXX", app_name); - - if (mkdtemp(g_temp_base) == 0) - { - printf("g_mk_temp_dir: mkdtemp failed [%s]\n", g_temp_base); + printf("g_mk_temp_dir: g_create_dir failed\n"); return 1; } } - else - { - printf("g_mk_temp_dir: bad app name\n"); - return 1; - } - } - else - { - if (g_temp_base_org[0] == 0) - { - printf("g_mk_temp_dir: g_temp_base_org not set\n"); - return 1; - } - - g_strncpy(g_temp_base, g_temp_base_org, 127); - - if (mkdtemp(g_temp_base) == 0) - { - printf("g_mk_temp_dir: mkdtemp failed [%s]\n", g_temp_base); - } + g_chmod_hex("/tmp/.xrdp", 0x1777); } - return 0; } @@ -617,7 +565,7 @@ g_sck_get_recv_buffer_bytes(int sck, int *bytes) /*****************************************************************************/ int APP_CC -g_tcp_local_socket(void) +g_sck_local_socket(void) { #if defined(_WIN32) return 0; @@ -691,7 +639,7 @@ g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid) /*****************************************************************************/ void APP_CC -g_tcp_close(int sck) +g_sck_close(int sck) { char ip[256]; @@ -794,7 +742,7 @@ g_tcp_connect(int sck, const char* address, const char* port) /*****************************************************************************/ /* returns error, zero is good */ int APP_CC -g_tcp_local_connect(int sck, const char *port) +g_sck_local_connect(int sck, const char *port) { #if defined(_WIN32) return -1; @@ -812,7 +760,7 @@ g_tcp_local_connect(int sck, const char *port) /*****************************************************************************/ int APP_CC -g_tcp_set_non_blocking(int sck) +g_sck_set_non_blocking(int sck) { unsigned long i; @@ -824,7 +772,7 @@ g_tcp_set_non_blocking(int sck) i = i | O_NONBLOCK; if (fcntl(sck, F_SETFL, i) < 0) { - log_message(LOG_LEVEL_ERROR, "g_tcp_set_non_blocking: fcntl() failed\n"); + log_message(LOG_LEVEL_ERROR, "g_sck_set_non_blocking: fcntl() failed\n"); } #endif return 0; @@ -956,7 +904,7 @@ g_tcp_bind(int sck, const char* port) /*****************************************************************************/ int APP_CC -g_tcp_local_bind(int sck, const char *port) +g_sck_local_bind(int sck, const char *port) { #if defined(_WIN32) return -1; @@ -1004,7 +952,7 @@ g_tcp_bind_address(int sck, const char* port, const char* address) /*****************************************************************************/ /* returns error, zero is good */ int APP_CC -g_tcp_listen(int sck) +g_sck_listen(int sck) { return listen(sck, 2); } @@ -1120,7 +1068,7 @@ g_sleep(int msecs) /*****************************************************************************/ int APP_CC -g_tcp_last_error_would_block(int sck) +g_sck_last_error_would_block(int sck) { #if defined(_WIN32) return WSAGetLastError() == WSAEWOULDBLOCK; @@ -1131,7 +1079,7 @@ g_tcp_last_error_would_block(int sck) /*****************************************************************************/ int APP_CC -g_tcp_recv(int sck, void *ptr, int len, int flags) +g_sck_recv(int sck, void *ptr, int len, int flags) { #if defined(_WIN32) return recv(sck, (char *)ptr, len, flags); @@ -1142,7 +1090,7 @@ g_tcp_recv(int sck, void *ptr, int len, int flags) /*****************************************************************************/ int APP_CC -g_tcp_send(int sck, const void *ptr, int len, int flags) +g_sck_send(int sck, const void *ptr, int len, int flags) { #if defined(_WIN32) return send(sck, (const char *)ptr, len, flags); @@ -1154,7 +1102,7 @@ g_tcp_send(int sck, const void *ptr, int len, int flags) /*****************************************************************************/ /* returns boolean */ int APP_CC -g_tcp_socket_ok(int sck) +g_sck_socket_ok(int sck) { #if defined(_WIN32) int opt; @@ -1181,7 +1129,7 @@ g_tcp_socket_ok(int sck) /* wait 'millis' milliseconds for the socket to be able to write */ /* returns boolean */ int APP_CC -g_tcp_can_send(int sck, int millis) +g_sck_can_send(int sck, int millis) { fd_set wfds; struct timeval time; @@ -1198,7 +1146,7 @@ g_tcp_can_send(int sck, int millis) if (rv > 0) { - return g_tcp_socket_ok(sck); + return 1; } } @@ -1209,12 +1157,13 @@ g_tcp_can_send(int sck, int millis) /* wait 'millis' milliseconds for the socket to be able to receive */ /* returns boolean */ int APP_CC -g_tcp_can_recv(int sck, int millis) +g_sck_can_recv(int sck, int millis) { fd_set rfds; struct timeval time; int rv; + g_memset(&time, 0, sizeof(time)); time.tv_sec = millis / 1000; time.tv_usec = (millis * 1000) % 1000000; FD_ZERO(&rfds); @@ -1226,7 +1175,7 @@ g_tcp_can_recv(int sck, int millis) if (rv > 0) { - return g_tcp_socket_ok(sck); + return 1; } } @@ -1235,18 +1184,14 @@ g_tcp_can_recv(int sck, int millis) /*****************************************************************************/ int APP_CC -g_tcp_select(int sck1, int sck2) +g_sck_select(int sck1, int sck2) { fd_set rfds; struct timeval time; - int max = 0; - int rv = 0; + int max; + int rv; - g_memset(&rfds, 0, sizeof(fd_set)); g_memset(&time, 0, sizeof(struct timeval)); - - time.tv_sec = 0; - time.tv_usec = 0; FD_ZERO(&rfds); if (sck1 > 0) @@ -1291,93 +1236,91 @@ g_tcp_select(int sck1, int sck2) } /*****************************************************************************/ -/* returns 0 on error */ -tbus APP_CC -g_create_wait_obj(char *name) +/* returns boolean */ +static int APP_CC +g_fd_can_read(int fd) { -#ifdef _WIN32 - tbus obj; - - obj = (tbus)CreateEvent(0, 1, 0, name); - return obj; -#else - tbus obj; - struct sockaddr_un sa; - size_t len; - tbus sck; - int i; - int safety; - int unnamed; + fd_set rfds; + struct timeval time; + int rv; - if (g_temp_base[0] == 0) + g_memset(&time, 0, sizeof(time)); + FD_ZERO(&rfds); + FD_SET(((unsigned int)fd), &rfds); + rv = select(fd + 1, &rfds, 0, 0, &time); + if (rv == 1) { - return 0; + return 1; } + return 0; +} - sck = socket(PF_UNIX, SOCK_DGRAM, 0); +/*****************************************************************************/ +/* returns error */ +/* O_NONBLOCK = 0x00000800 */ +static int APP_CC +g_set_nonblock(int fd) +{ + int error; + int flags; - if (sck < 0) + error = fcntl(fd, F_GETFL); + if (error < 0) { - return 0; + return 1; } - - safety = 0; - g_memset(&sa, 0, sizeof(sa)); - sa.sun_family = AF_UNIX; - unnamed = 1; - - if (name != 0) + flags = error; + if ((flags & O_NONBLOCK) != O_NONBLOCK) { - if (name[0] != 0) + flags |= O_NONBLOCK; + error = fcntl(fd, F_SETFL, flags); + if (error < 0) { - unnamed = 0; + return 1; } } + return 0; +} - if (unnamed) - { - do - { - if (safety > 100) - { - break; - } +/*****************************************************************************/ +/* returns 0 on error */ +tintptr APP_CC +g_create_wait_obj(char *name) +{ +#ifdef _WIN32 + tintptr obj; - safety++; - g_random((char *)&i, sizeof(i)); - len = sizeof(sa.sun_path); - g_snprintf(sa.sun_path, len, "%s/auto_%8.8x", g_temp_base, i); - len = sizeof(sa); - } - while (bind(sck, (struct sockaddr *)&sa, len) < 0); + obj = (tintptr)CreateEvent(0, 1, 0, name); + return obj; +#else + int fds[2]; + int error; + + error = pipe(fds); + if (error != 0) + { + return 0; } - else + if (g_set_nonblock(fds[0]) != 0) { - do - { - if (safety > 100) - { - break; - } - - safety++; - g_random((char *)&i, sizeof(i)); - len = sizeof(sa.sun_path); - g_snprintf(sa.sun_path, len, "%s/%s_%8.8x", g_temp_base, name, i); - len = sizeof(sa); - } - while (bind(sck, (struct sockaddr *)&sa, len) < 0); + close(fds[0]); + close(fds[1]); + return 0; } - - obj = (tbus)sck; - return obj; + if (g_set_nonblock(fds[1]) != 0) + { + close(fds[0]); + close(fds[1]); + return 0; + } + return (fds[1] << 16) | fds[0]; #endif } /*****************************************************************************/ /* returns 0 on error */ -tbus APP_CC -g_create_wait_obj_from_socket(tbus socket, int write) +tintptr APP_CC +g_create_wait_obj_from_socket(tintptr socket, int write) { #ifdef _WIN32 /* Create and return corresponding event handle for WaitForMultipleObjets */ @@ -1405,7 +1348,7 @@ g_create_wait_obj_from_socket(tbus socket, int write) /*****************************************************************************/ void APP_CC -g_delete_wait_obj_from_socket(tbus wait_obj) +g_delete_wait_obj_from_socket(tintptr wait_obj) { #ifdef _WIN32 @@ -1422,54 +1365,60 @@ g_delete_wait_obj_from_socket(tbus wait_obj) /*****************************************************************************/ /* returns error */ int APP_CC -g_set_wait_obj(tbus obj) +g_set_wait_obj(tintptr obj) { #ifdef _WIN32 - if (obj == 0) { return 0; } - SetEvent((HANDLE)obj); return 0; #else - socklen_t sa_size; - int s; - struct sockaddr_un sa; + int error; + int fd; + int written; + int to_write; + char buf[4] = "sig"; if (obj == 0) { return 0; } - - if (g_tcp_can_recv((int)obj, 0)) + fd = obj & 0xffff; + if (g_fd_can_read(fd)) { /* already signalled */ return 0; } - - sa_size = sizeof(sa); - - if (getsockname((int)obj, (struct sockaddr *)&sa, &sa_size) < 0) - { - return 1; - } - - s = socket(PF_UNIX, SOCK_DGRAM, 0); - - if (s < 0) + fd = obj >> 16; + to_write = 4; + written = 0; + while (written < to_write) { - return 1; - } - - if (sendto(s, "sig", 4, 0, (struct sockaddr *)&sa, sa_size) < 0) - { - close(s); - return 1; + error = write(fd, buf + written, to_write - written); + if (error == -1) + { + error = errno; + if ((error == EAGAIN) || (error == EWOULDBLOCK) || + (error == EINPROGRESS) || (error == EINTR)) + { + /* ok */ + } + else + { + return 1; + } + } + else if (error > 0) + { + written += error; + } + else + { + return 1; + } } - - close(s); return 0; #endif } @@ -1477,30 +1426,46 @@ g_set_wait_obj(tbus obj) /*****************************************************************************/ /* returns error */ int APP_CC -g_reset_wait_obj(tbus obj) +g_reset_wait_obj(tintptr obj) { #ifdef _WIN32 - if (obj == 0) { return 0; } - ResetEvent((HANDLE)obj); return 0; #else - char buf[64]; + char buf[4]; + int error; + int fd; if (obj == 0) { return 0; } - - while (g_tcp_can_recv((int)obj, 0)) + fd = obj & 0xffff; + while (g_fd_can_read(fd)) { - recvfrom((int)obj, &buf, 64, 0, 0, 0); + error = read(fd, buf, 4); + if (error == -1) + { + error = errno; + if ((error == EAGAIN) || (error == EWOULDBLOCK) || + (error == EINPROGRESS) || (error == EINTR)) + { + /* ok */ + } + else + { + return 1; + } + } + else if (error == 0) + { + return 1; + } } - return 0; #endif } @@ -1508,86 +1473,55 @@ g_reset_wait_obj(tbus obj) /*****************************************************************************/ /* returns boolean */ int APP_CC -g_is_wait_obj_set(tbus obj) +g_is_wait_obj_set(tintptr obj) { #ifdef _WIN32 - if (obj == 0) { return 0; } - if (WaitForSingleObject((HANDLE)obj, 0) == WAIT_OBJECT_0) { return 1; } - return 0; #else - if (obj == 0) { return 0; } - - return g_tcp_can_recv((int)obj, 0); + return g_fd_can_read(obj & 0xffff); #endif } /*****************************************************************************/ /* returns error */ int APP_CC -g_delete_wait_obj(tbus obj) +g_delete_wait_obj(tintptr obj) { #ifdef _WIN32 - if (obj == 0) { return 0; } - /* Close event handle */ CloseHandle((HANDLE)obj); return 0; #else - socklen_t sa_size; - struct sockaddr_un sa; - if (obj == 0) { return 0; } - - sa_size = sizeof(sa); - - if (getsockname((int)obj, (struct sockaddr *)&sa, &sa_size) < 0) - { - return 1; - } - - close((int)obj); - unlink(sa.sun_path); + close(obj & 0xffff); + close(obj >> 16); return 0; #endif } /*****************************************************************************/ /* returns error */ -/* close but do not delete the wait obj, used after fork */ int APP_CC -g_close_wait_obj(tbus obj) -{ -#ifdef _WIN32 -#else - close((int)obj); -#endif - return 0; -} - -/*****************************************************************************/ -/* returns error */ -int APP_CC -g_obj_wait(tbus *read_objs, int rcount, tbus *write_objs, int wcount, +g_obj_wait(tintptr *read_objs, int rcount, tintptr *write_objs, int wcount, int mstimeout) { #ifdef _WIN32 @@ -1627,24 +1561,20 @@ g_obj_wait(tbus *read_objs, int rcount, tbus *write_objs, int wcount, fd_set rfds; fd_set wfds; struct timeval time; - struct timeval *ptime = (struct timeval *)NULL; + struct timeval *ptime; int i = 0; int res = 0; int max = 0; int sck = 0; - g_memset(&rfds, 0, sizeof(fd_set)); - g_memset(&wfds, 0, sizeof(fd_set)); - g_memset(&time, 0, sizeof(struct timeval)); - max = 0; - if (mstimeout < 1) { - ptime = (struct timeval *)NULL; + ptime = 0; } else { + g_memset(&time, 0, sizeof(struct timeval)); time.tv_sec = mstimeout / 1000; time.tv_usec = (mstimeout % 1000) * 1000; ptime = &time; @@ -1658,7 +1588,7 @@ g_obj_wait(tbus *read_objs, int rcount, tbus *write_objs, int wcount, { for (i = 0; i < rcount; i++) { - sck = (int)(read_objs[i]); + sck = read_objs[i] & 0xffff; if (sck > 0) { diff --git a/common/os_calls.h b/common/os_calls.h index 0682195a..acfbe475 100644 --- a/common/os_calls.h +++ b/common/os_calls.h @@ -27,6 +27,20 @@ #include "arch.h" +#define g_tcp_can_recv g_sck_can_recv +#define g_tcp_can_send g_sck_can_send +#define g_tcp_recv g_sck_recv +#define g_tcp_send g_sck_send +#define g_tcp_close g_sck_close +#define g_tcp_last_error_would_block g_sck_last_error_would_block +#define g_tcp_set_non_blocking g_sck_set_non_blocking +#define g_tcp_local_socket g_sck_local_socket +#define g_tcp_local_connect g_sck_local_connect +#define g_tcp_listen g_sck_listen +#define g_tcp_local_bind g_sck_local_bind +#define g_tcp_select g_sck_select +#define g_close_wait_obj g_delete_wait_obj + int APP_CC g_rm_temp_dir(void); int APP_CC g_mk_temp_dir(const char* app_name); void APP_CC g_init(const char* app_name); @@ -49,39 +63,36 @@ int APP_CC g_sck_set_send_buffer_bytes(int sck, int bytes); int APP_CC g_sck_get_send_buffer_bytes(int sck, int *bytes); int APP_CC g_sck_set_recv_buffer_bytes(int sck, int bytes); int APP_CC g_sck_get_recv_buffer_bytes(int sck, int *bytes); -int APP_CC g_tcp_local_socket(void); +int APP_CC g_sck_local_socket(void); int APP_CC g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid); -void APP_CC g_tcp_close(int sck); +void APP_CC g_sck_close(int sck); int APP_CC g_tcp_connect(int sck, const char* address, const char* port); -int APP_CC g_tcp_local_connect(int sck, const char* port); -int APP_CC g_tcp_force_send(int sck, char* data, int len); -int APP_CC g_tcp_force_recv(int sck, char* data, int len); -int APP_CC g_tcp_set_non_blocking(int sck); +int APP_CC g_sck_local_connect(int sck, const char* port); +int APP_CC g_sck_set_non_blocking(int sck); int APP_CC g_tcp_bind(int sck, const char *port); -int APP_CC g_tcp_local_bind(int sck, const char* port); +int APP_CC g_sck_local_bind(int sck, const char* port); int APP_CC g_tcp_bind_address(int sck, const char* port, const char* address); -int APP_CC g_tcp_listen(int sck); +int APP_CC g_sck_listen(int sck); int APP_CC g_tcp_accept(int sck); int APP_CC g_sck_accept(int sck, char *addr, int addr_bytes, char *port, int port_bytes); -int APP_CC g_tcp_recv(int sck, void* ptr, int len, int flags); -int APP_CC g_tcp_send(int sck, const void* ptr, int len, int flags); -int APP_CC g_tcp_last_error_would_block(int sck); -int APP_CC g_tcp_socket_ok(int sck); -int APP_CC g_tcp_can_send(int sck, int millis); -int APP_CC g_tcp_can_recv(int sck, int millis); -int APP_CC g_tcp_select(int sck1, int sck2); +int APP_CC g_sck_recv(int sck, void* ptr, int len, int flags); +int APP_CC g_sck_send(int sck, const void* ptr, int len, int flags); +int APP_CC g_sck_last_error_would_block(int sck); +int APP_CC g_sck_socket_ok(int sck); +int APP_CC g_sck_can_send(int sck, int millis); +int APP_CC g_sck_can_recv(int sck, int millis); +int APP_CC g_sck_select(int sck1, int sck2); void APP_CC g_write_ip_address(int rcv_sck, char* ip_address, int bytes); void APP_CC g_sleep(int msecs); -tbus APP_CC g_create_wait_obj(char* name); -tbus APP_CC g_create_wait_obj_from_socket(tbus socket, int write); -void APP_CC g_delete_wait_obj_from_socket(tbus wait_obj); -int APP_CC g_set_wait_obj(tbus obj); -int APP_CC g_reset_wait_obj(tbus obj); -int APP_CC g_is_wait_obj_set(tbus obj); -int APP_CC g_delete_wait_obj(tbus obj); -int APP_CC g_close_wait_obj(tbus obj); -int APP_CC g_obj_wait(tbus* read_objs, int rcount, tbus* write_objs, +tintptr APP_CC g_create_wait_obj(char* name); +tintptr APP_CC g_create_wait_obj_from_socket(tintptr socket, int write); +void APP_CC g_delete_wait_obj_from_socket(tintptr wait_obj); +int APP_CC g_set_wait_obj(tintptr obj); +int APP_CC g_reset_wait_obj(tintptr obj); +int APP_CC g_is_wait_obj_set(tintptr obj); +int APP_CC g_delete_wait_obj(tintptr obj); +int APP_CC g_obj_wait(tintptr* read_objs, int rcount, tintptr* write_objs, int wcount,int mstimeout); void APP_CC g_random(char* data, int len); int APP_CC g_abs(int i);