common: change wait objs to use 'pipe' and remove per process temp directories in /tmp/.xrdp/

This commit is contained in:
Jay Sorg 2015-10-06 20:55:47 -07:00
parent 7889ee638e
commit ab3b8edf4a
2 changed files with 192 additions and 251 deletions

View File

@ -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;
}
g_chmod_hex("/tmp/.xrdp", 0x1777);
}
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);
}
}
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)
@ -1290,94 +1235,92 @@ g_tcp_select(int sck1, int sck2)
return rv;
}
/*****************************************************************************/
/* returns boolean */
static int APP_CC
g_fd_can_read(int fd)
{
fd_set rfds;
struct timeval time;
int rv;
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 1;
}
return 0;
}
/*****************************************************************************/
/* returns error */
/* O_NONBLOCK = 0x00000800 */
static int APP_CC
g_set_nonblock(int fd)
{
int error;
int flags;
error = fcntl(fd, F_GETFL);
if (error < 0)
{
return 1;
}
flags = error;
if ((flags & O_NONBLOCK) != O_NONBLOCK)
{
flags |= O_NONBLOCK;
error = fcntl(fd, F_SETFL, flags);
if (error < 0)
{
return 1;
}
}
return 0;
}
/*****************************************************************************/
/* returns 0 on error */
tbus APP_CC
tintptr APP_CC
g_create_wait_obj(char *name)
{
#ifdef _WIN32
tbus obj;
tintptr obj;
obj = (tbus)CreateEvent(0, 1, 0, name);
obj = (tintptr)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;
int fds[2];
int error;
if (g_temp_base[0] == 0)
error = pipe(fds);
if (error != 0)
{
return 0;
}
sck = socket(PF_UNIX, SOCK_DGRAM, 0);
if (sck < 0)
if (g_set_nonblock(fds[0]) != 0)
{
close(fds[0]);
close(fds[1]);
return 0;
}
safety = 0;
g_memset(&sa, 0, sizeof(sa));
sa.sun_family = AF_UNIX;
unnamed = 1;
if (name != 0)
if (g_set_nonblock(fds[1]) != 0)
{
if (name[0] != 0)
{
unnamed = 0;
}
close(fds[0]);
close(fds[1]);
return 0;
}
if (unnamed)
{
do
{
if (safety > 100)
{
break;
}
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);
}
else
{
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);
}
obj = (tbus)sck;
return obj;
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)
fd = obj >> 16;
to_write = 4;
written = 0;
while (written < to_write)
{
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;
}
}
s = socket(PF_UNIX, SOCK_DGRAM, 0);
if (s < 0)
{
return 1;
}
if (sendto(s, "sig", 4, 0, (struct sockaddr *)&sa, sa_size) < 0)
{
close(s);
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)
{

View File

@ -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);