summaryrefslogtreecommitdiff
path: root/src/lib/eina/eina_debug.c
diff options
context:
space:
mode:
authorDaniel Zaoui <daniel.zaoui@yahoo.com>2017-05-25 13:26:41 +0300
committerDaniel Zaoui <daniel.zaoui@yahoo.com>2017-06-05 08:55:37 +0300
commitd6e3ab67dbf652dcb90ce890ec779372f7db3e44 (patch)
tree20452ae44334fc031ebb231fe248c68b5e8eb641 /src/lib/eina/eina_debug.c
parent36959014d3f632bba52f20d185bb11be3c2889d6 (diff)
downloadefl-d6e3ab67dbf652dcb90ce890ec779372f7db3e44.tar.gz
Replace shell remote connection with localhost TCP connection
Diffstat (limited to 'src/lib/eina/eina_debug.c')
-rw-r--r--src/lib/eina/eina_debug.c397
1 files changed, 75 insertions, 322 deletions
diff --git a/src/lib/eina/eina_debug.c b/src/lib/eina/eina_debug.c
index 9ed8dc27b9..dcd707899d 100644
--- a/src/lib/eina/eina_debug.c
+++ b/src/lib/eina/eina_debug.c
@@ -36,6 +36,8 @@
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
#include <fcntl.h>
#include "eina_debug.h"
@@ -86,8 +88,6 @@ static int _module_init_opcode = EINA_DEBUG_OPCODE_INVALID;
static int _module_shutdown_opcode = EINA_DEBUG_OPCODE_INVALID;
static Eina_Hash *_modules_hash = NULL;
-static int _bridge_keep_alive_opcode = EINA_DEBUG_OPCODE_INVALID;
-
/* Semaphore used by the debug thread to wait for another thread to do the
* requested job.
* It is needed when packets are needed to be treated into a specific
@@ -95,10 +95,6 @@ static int _bridge_keep_alive_opcode = EINA_DEBUG_OPCODE_INVALID;
*/
static Eina_Semaphore _thread_cmd_ready_sem;
-/* Used to encode/decode data on sending/reception */
-typedef void *(*Eina_Debug_Encode_Cb)(const void *buffer, unsigned int size, unsigned int *ret_size);
-typedef void *(*Eina_Debug_Decode_Cb)(const void *buffer, unsigned int size, unsigned int *ret_size);
-
typedef struct
{
const Eina_Debug_Opcode *ops;
@@ -111,20 +107,9 @@ struct _Eina_Debug_Session
Eina_List **cbs; /* Table of callbacks lists indexed by opcode id */
Eina_List *opcode_reply_infos;
Eina_Debug_Dispatch_Cb dispatch_cb; /* Session dispatcher */
- Eina_Debug_Encode_Cb encode_cb; /* Packet encoder */
- Eina_Debug_Decode_Cb decode_cb; /* Packet decoder */
- Eina_List *cmds; /* List of shell commands to send before the communication
- * with the daemon. Only used when a shell remote
- * connection is requested.
- */
void *data; /* User data */
- double encoding_ratio; /* Encoding ratio */
int cbs_length; /* cbs table size */
- int fd_in; /* File descriptor to read */
- int fd_out; /* File descriptor to write */
- Eina_Bool wait_for_input : 1; /* Indicator to wait for input before
- * continuing sending commands.
- * Only used in shell remote connections */
+ int fd; /* File descriptor */
};
static void _opcodes_register_all(Eina_Debug_Session *session);
@@ -142,39 +127,16 @@ eina_debug_session_send_to_thread(Eina_Debug_Session *session, int dest_id, int
hdr.opcode = op;
hdr.cid = dest_id;
hdr.thread_id = thread_id;
- if (!session->encode_cb)
- {
- e_debug("socket: %d / opcode %X / bytes to send: %d",
- session->fd_out, op, hdr.size);
+ e_debug("socket: %d / opcode %X / bytes to send: %d",
+ session->fd, op, hdr.size);
#ifndef _WIN32
- eina_spinlock_take(&_eina_debug_lock);
- /* Sending header */
- write(session->fd_out, &hdr, sizeof(hdr));
- /* Sending payload */
- if (size) write(session->fd_out, data, size);
- eina_spinlock_release(&_eina_debug_lock);
+ eina_spinlock_take(&_eina_debug_lock);
+ /* Sending header */
+ write(session->fd, &hdr, sizeof(hdr));
+ /* Sending payload */
+ if (size) write(session->fd, data, size);
+ eina_spinlock_release(&_eina_debug_lock);
#endif
- }
- else
- {
- unsigned char *total_buf = NULL;
- void *new_buf;
- unsigned int total_size = size + sizeof(hdr), new_size = 0;
- total_buf = alloca(total_size);
- memcpy(total_buf, &hdr, sizeof(hdr));
- if (size > 0) memcpy(total_buf + sizeof(hdr), data, size);
-
- new_buf = session->encode_cb(total_buf, total_size, &new_size);
- e_debug("socket: %d / opcode %X / packet size %d / bytes to send: %d",
- session->fd_out, op, total_size, new_size);
-#ifndef _WIN32
- eina_spinlock_take(&_eina_debug_lock);
- write(session->fd_out, new_buf, new_size);
- eina_spinlock_release(&_eina_debug_lock);
-#endif
- free(new_buf);
- }
-
return hdr.size;
}
@@ -208,104 +170,18 @@ _daemon_greet(Eina_Debug_Session *session)
eina_debug_session_send(session, 0, EINA_DEBUG_OPCODE_HELLO, buf, size);
}
-static void
-_cmd_consume(Eina_Debug_Session *session)
-{
- const char *line = NULL;
- do {
- line = eina_list_data_get(session->cmds);
- session->cmds = eina_list_remove_list(session->cmds, session->cmds);
- if (line)
- {
- if (!strncmp(line, "WAIT", 4))
- {
- e_debug("Wait for input");
- session->wait_for_input = EINA_TRUE;
- return;
- }
- else if (!strncmp(line, "SLEEP_1", 7))
- {
- e_debug("Sleep 1s");
- sleep(1);
- }
- else
- {
- e_debug("Apply cmd line: %s", line);
- write(session->fd_out, line, strlen(line));
- write(session->fd_out, "\n", 1);
- }
- }
- }
- while (line);
- /* When all the cmd has been applied, we can begin to send debug packets */
- _daemon_greet(session);
- _opcodes_register_all(session);
-}
-
-static Eina_List *
-_parse_cmds(const char *cmds)
-{
- Eina_List *lines = NULL;
- while (cmds && *cmds)
- {
- char *tmp = strchr(cmds, '\n');
- Eina_Stringshare *line;
- if (tmp)
- {
- line = eina_stringshare_add_length(cmds, tmp - cmds);
- cmds = tmp + 1;
- }
- else
- {
- line = eina_stringshare_add(cmds);
- cmds = NULL;
- }
- lines = eina_list_append(lines, line);
- }
- return lines;
-}
-
#ifndef _WIN32
static int
_packet_receive(Eina_Debug_Session *session, unsigned char **buffer)
{
- unsigned char *packet_buf = NULL, *size_buf;
- int rret = -1, ratio, size_sz;
+ unsigned char *packet_buf = NULL;
+ int rret = -1;
+ unsigned int size = 0;
if (!session) goto end;
- if (session->wait_for_input)
+ if ((rret = read(session->fd, &size, 4)) == 4)
{
- /* Wait for input */
- char c;
- int flags = fcntl(session->fd_in, F_GETFL, 0);
- e_debug_begin("Characters received: ");
- if (fcntl(session->fd_in, F_SETFL, flags | O_NONBLOCK) == -1) perror(0);
- while (read(session->fd_in, &c, 1) == 1) e_debug_continue("%c", c);
- if (fcntl(session->fd_in, F_SETFL, flags) == -1) perror(0);
- e_debug_end();
- session->wait_for_input = EINA_FALSE;
- _cmd_consume(session);
- return 0;
- }
-
- ratio = session->decode_cb && session->encoding_ratio ? session->encoding_ratio : 1.0;
- size_sz = sizeof(int) * ratio;
- size_buf = alloca(size_sz);
- if ((rret = read(session->fd_in, size_buf, size_sz)) == size_sz)
- {
- unsigned int size;
- if (session->decode_cb)
- {
- /* Decode the size if needed */
- void *size_decoded_buf = session->decode_cb(size_buf, size_sz, NULL);
- size = (*(unsigned int *)size_decoded_buf) * session->encoding_ratio;
- free(size_decoded_buf);
- }
- else
- {
- size = *(unsigned int *)size_buf;
- }
if (size > EINA_DEBUG_MAX_PACKET_SIZE)
{
e_debug("Packet too big: %d. The maximum allowed is %d", size, EINA_DEBUG_MAX_PACKET_SIZE);
@@ -317,12 +193,12 @@ _packet_receive(Eina_Debug_Session *session, unsigned char **buffer)
packet_buf = malloc(size);
if (packet_buf)
{
- unsigned int cur_packet_size = size_sz;
- memcpy(packet_buf, size_buf, size_sz);
+ unsigned int cur_packet_size = 4;
+ memcpy(packet_buf, &size, 4);
/* Receive all the remaining packet bytes */
while (cur_packet_size < size)
{
- rret = read(session->fd_in, packet_buf + cur_packet_size, size - cur_packet_size);
+ rret = read(session->fd, packet_buf + cur_packet_size, size - cur_packet_size);
if (rret <= 0)
{
e_debug("Error on read: %d", rret);
@@ -331,13 +207,6 @@ _packet_receive(Eina_Debug_Session *session, unsigned char **buffer)
}
cur_packet_size += rret;
}
- if (session->decode_cb)
- {
- /* Decode the packet if needed */
- void *decoded_buf = session->decode_cb(packet_buf, size, &cur_packet_size);
- free(packet_buf);
- packet_buf = decoded_buf;
- }
*buffer = packet_buf;
rret = cur_packet_size;
e_debug("Received a packet of %d bytes", cur_packet_size);
@@ -372,7 +241,7 @@ eina_debug_session_terminate(Eina_Debug_Session *session)
{
/* Close fd here so the thread terminates its own session by itself */
if (!session) return;
- close(session->fd_in);
+ close(session->fd);
}
EAPI void
@@ -496,12 +365,6 @@ static const Eina_Debug_Opcode _MONITOR_OPS[] =
{NULL, NULL, NULL}
};
-static const Eina_Debug_Opcode _BRIDGE_OPS[] =
-{
- {"Bridge/Keep-Alive", &_bridge_keep_alive_opcode, NULL},
- {NULL, NULL, NULL}
-};
-
static void
_static_opcode_register(Eina_Debug_Session *session,
int op_id, Eina_Debug_Cb cb)
@@ -643,6 +506,53 @@ _socket_home_get()
(strlen((s)->sun_path) + (size_t)(((struct sockaddr_un *)NULL)->sun_path))
#endif
+static Eina_Debug_Session *
+_session_create(int fd)
+{
+ Eina_Debug_Session *session = calloc(1, sizeof(*session));
+ session->dispatch_cb = eina_debug_dispatch;
+ session->fd = fd;
+ // start the monitor thread
+ _thread_start(session);
+ _daemon_greet(session);
+ _opcodes_register_all(session);
+ return session;
+}
+
+EAPI Eina_Debug_Session *
+eina_debug_remote_connect(int port)
+{
+#ifndef _WIN32
+ int fd;
+ struct sockaddr_in server;
+
+ //Create socket
+ fd = socket(AF_INET, SOCK_STREAM, 0);
+ if (fd < 0) goto err;
+ // set the socket to close when we exec things so they don't inherit it
+ if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) goto err;
+
+ //Prepare the sockaddr_in structure
+ server.sin_family = AF_INET;
+ inet_pton(AF_INET, "127.0.0.1", &server.sin_addr.s_addr);
+ server.sin_port = htons(port);
+
+ if (connect(fd, (struct sockaddr *)&server, sizeof(server)) < 0)
+ {
+ perror("connect failed. Error");
+ goto err;
+ }
+ return _session_create(fd);
+err:
+ // some kind of connection failure here, so close a valid socket and
+ // get out of here
+ if (fd >= 0) close(fd);
+#else
+ (void) port;
+#endif
+ return NULL;
+}
+
EAPI Eina_Debug_Session *
eina_debug_local_connect(Eina_Bool is_master)
{
@@ -651,17 +561,14 @@ eina_debug_local_connect(Eina_Bool is_master)
int fd, socket_unix_len, curstate = 0;
struct sockaddr_un socket_unix;
- Eina_Debug_Session *session = calloc(1, sizeof(*session));
- session->dispatch_cb = eina_debug_dispatch;
- session->fd_out = session->fd_in = -1;
+ if (is_master) return eina_debug_remote_connect(REMOTE_SERVER_PORT);
+
// try this socket file - it will likely be:
// ~/.ecore/efl_debug/0
// or maybe
// /var/run/UID/.ecore/efl_debug/0
- // either way a 4k buffer should be ebough ( if it's not we're on an
- // insane system)
- snprintf(buf, sizeof(buf), "%s/%s/%s/%i", _socket_home_get(), SERVER_PATH, SERVER_NAME,
- is_master ? SERVER_MASTER_PORT : SERVER_SLAVE_PORT);
+ snprintf(buf, sizeof(buf), "%s/%s/%s/%i", _socket_home_get(),
+ LOCAL_SERVER_PATH, LOCAL_SERVER_NAME, LOCAL_SERVER_PORT);
// create the socket
fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0) goto err;
@@ -678,118 +585,21 @@ eina_debug_local_connect(Eina_Bool is_master)
// actually connect to efl_debugd service
if (connect(fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0)
goto err;
- // we succeeded
- session->fd_out = session->fd_in = fd;
- // start the monitor thread
- _thread_start(session);
- _daemon_greet(session);
- _opcodes_register_all(session);
- if (!is_master)
- eina_debug_opcodes_register(session, _MONITOR_OPS, NULL, NULL);
+ _last_local_session = _session_create(fd);
+ eina_debug_opcodes_register(_last_local_session, _MONITOR_OPS, NULL, NULL);
- _last_local_session = session;
- return session;
+ return _last_local_session;
err:
// some kind of connection failure here, so close a valid socket and
// get out of here
if (fd >= 0) close(fd);
- free(session);
#else
(void) is_master;
#endif
return NULL;
}
-EAPI Eina_Debug_Session *
-eina_debug_fds_attach(int fd_in, int fd_out)
-{
- Eina_Debug_Session *session = calloc(1, sizeof(*session));
- session->dispatch_cb = eina_debug_dispatch;
- session->fd_out = fd_out;
- session->fd_in = fd_in;
- // start the monitor thread
- _thread_start(session);
- _opcodes_register_all(session);
- _last_local_session = session;
- return session;
-}
-
-static Eina_Bool
-_bridge_keep_alive_send(void *data)
-{
- Eina_Debug_Session *s = data;
- eina_debug_session_send(s, 0, _bridge_keep_alive_opcode, NULL, 0);
- return EINA_TRUE;
-}
-
-EAPI Eina_Debug_Session *
-eina_debug_shell_remote_connect(const char *cmds_str)
-{
-#ifndef _WIN32
- Eina_List *cmds = _parse_cmds(cmds_str);
- char *cmd = eina_list_data_get(cmds);
- int pipeToShell[2], pipeFromShell[2];
- int pid = -1;
-
- cmds = eina_list_remove_list(cmds, cmds);
-
- pipe(pipeToShell);
- pipe(pipeFromShell);
- pid = fork();
- if (pid == -1) return EINA_FALSE;
- if (!pid)
- {
- int i = 0;
- const char *args[16] = { 0 };
- /* Child */
- close(STDIN_FILENO);
- dup2(pipeToShell[0], STDIN_FILENO);
- close(STDOUT_FILENO);
- dup2(pipeFromShell[1], STDOUT_FILENO);
- args[i++] = cmd;
- do
- {
- cmd = strchr(cmd, ' ');
- if (cmd)
- {
- *cmd = '\0';
- args[i++] = ++cmd;
- }
- }
- while (cmd);
- args[i++] = 0;
- execvpe(args[0], (char **)args, environ);
- perror("execvpe");
- exit(-1);
- }
- else
- {
- Eina_Debug_Session *session = calloc(1, sizeof(*session));
- /* Parent */
- session->dispatch_cb = eina_debug_dispatch;
- session->fd_in = pipeFromShell[0];
- session->fd_out = pipeToShell[1];
-
- int flags = fcntl(session->fd_in, F_GETFL, 0);
- flags &= ~O_NONBLOCK;
- if (fcntl(session->fd_in, F_SETFL, flags) == -1) perror(0);
-
- eina_debug_session_shell_codec_enable(session);
- session->cmds = cmds;
- _cmd_consume(session);
- eina_debug_opcodes_register(session, _BRIDGE_OPS, NULL, NULL);
- eina_debug_timer_add(10000, _bridge_keep_alive_send, session);
- // start the monitor thread
- _thread_start(session);
- return session;
- }
-#else
- (void) cmds_str;
- return NULL;
-#endif
-}
-
// this is a DEDICATED debug thread to monitor the application so it works
// even if the mainloop is blocked or the app otherwise deadlocked in some
// way. this is an alternative to using external debuggers so we can get
@@ -833,7 +643,7 @@ _monitor(void *_data)
}
else
{
- close(session->fd_in);
+ close(session->fd);
_opcodes_unregister_all(session);
free(session);
session = NULL;
@@ -898,67 +708,10 @@ eina_debug_opcodes_register(Eina_Debug_Session *session, const Eina_Debug_Opcode
/* Send only if session's fd connected.
* Otherwise, it will be sent when connected */
- if(session && session->fd_in != -1 && !session->cmds)
+ if(session && session->fd!= -1)
_opcodes_registration_send(session, info);
}
-/*
- * Encoder for shell sessions
- * Each byte is encoded in two bytes.
- */
-static void *
-_shell_encode_cb(const void *data, unsigned int src_size, unsigned int *dest_size)
-{
- const char *src = data;
- unsigned int new_size = src_size * 2;
- char *dest = malloc(new_size);
- unsigned int i;
- for (i = 0; i < src_size; i++)
- {
- dest[(i << 1) + 0] = ((src[i] & 0xF0) >> 4) + 0x40;
- dest[(i << 1) + 1] = ((src[i] & 0x0F) >> 0) + 0x40;
- }
- if (dest_size) *dest_size = new_size;
- return dest;
-}
-
-/*
- * Decoder for shell sessions
- * Each two bytes are merged into one byte.
- */
-static void *
-_shell_decode_cb(const void *data, unsigned int src_size, unsigned int *dest_size)
-{
- const char *src = data;
- unsigned int i = 0, j;
- char *dest = malloc(src_size / 2);
- if (!dest) goto error;
- for (i = 0, j = 0; j < src_size; j++)
- {
- if ((src[j] & 0xF0) == 0x40 && (src[j + 1] & 0xF0) == 0x40)
- {
- dest[i++] = ((src[j] - 0x40) << 4) | ((src[j + 1] - 0x40));
- j++;
- }
- }
- goto end;
-error:
- free(dest);
- dest = NULL;
-end:
- if (dest_size) *dest_size = i;
- return dest;
-}
-
-EAPI void
-eina_debug_session_shell_codec_enable(Eina_Debug_Session *session)
-{
- if (!session) return;
- session->encode_cb = _shell_encode_cb;
- session->decode_cb = _shell_decode_cb;
- session->encoding_ratio = 2.0;
-}
-
static Eina_Debug_Error
_self_dispatch(Eina_Debug_Session *session, void *buffer)
{