// backtrace_symbols_fd(buffer, result, STDERR_FILENO);
//}
+char *strdup_malloc(const char *s)
+{
+ char *retval;
+
+ if(s == NULL)
+ return NULL;
+
+ retval = (char *) malloc(strlen(s)+1);
+
+ strcpy(retval, s);
+
+ return retval;
+}
+
static void signal_process(pid_t pid)
{
int result;
sleep(1);
}
+int send_message_fd(int fd, const char *msg, char **reply)
+{
+ int result;
+
+ result = send(fd, msg, strlen(msg), 0);
+ if(result == -1) {
+ PERROR("send");
+ return -1;
+ }
+ else if(result == 0) {
+ return 0;
+ }
+
+ if(!reply)
+ return 1;
+
+ *reply = (char *) malloc(MSG_MAX+1);
+ result = recv(fd, *reply, MSG_MAX, 0);
+ if(result == -1) {
+ PERROR("recv");
+ return -1;
+ }
+ else if(result == 0) {
+ return 0;
+ }
+
+ (*reply)[result] = '\0';
+
+ return 1;
+}
+
int send_message_path(const char *path, const char *msg, char **reply, int signalpid)
{
int fd;
return -1;
}
- result = send(fd, msg, strlen(msg), 0);
- if(result == -1) {
- PERROR("send");
- return -1;
- }
-
- if(!reply)
- return 0;
-
- *reply = (char *) malloc(MSG_MAX+1);
- result = recvfrom(fd, *reply, MSG_MAX, 0, NULL, NULL);
- if(result == -1) {
- PERROR("recvfrom");
- return -1;
- }
-
- (*reply)[result] = '\0';
-
- return 0;
+ return send_message_fd(fd, msg, reply);
}
/* pid: the pid of the trace process that must receive the msg
return 0;
}
+/* returns 1 to indicate a message was received
+ * returns 0 to indicate no message was received (cannot happen)
+ * returns -1 to indicate an error
+ */
+
static int recv_message_fd(int fd, char **msg, struct ustcomm_source *src)
{
int result;
result = recv(fd, *msg, MSG_MAX, 0);
if(result == -1) {
- PERROR("recvfrom");
+ PERROR("recv");
return -1;
}
DBG("ustcomm_app_recv_message: result is %d, message is %s", result, (*msg));
- return 0;
+ if(src)
+ src->fd = fd;
+
+ return 1;
}
-int ustcomm_ustd_recv_message(struct ustcomm_ustd *ustd, char **msg, struct ustcomm_source *src)
+int ustcomm_send_reply(struct ustcomm_server *server, char *msg, struct ustcomm_source *src)
+{
+ int result;
+
+ result = send_message_fd(src->fd, msg, NULL);
+ if(result < 0) {
+ ERR("error in send_message_fd");
+ return -1;
+ }
+
+ return 0;
+}
+
+/* @timeout: max blocking time in milliseconds, -1 means infinity
+ *
+ * returns 1 to indicate a message was received
+ * returns 0 to indicate no message was received
+ * returns -1 to indicate an error
+ */
+
+int ustcomm_recv_message(struct ustcomm_server *server, char **msg, struct ustcomm_source *src, int timeout)
{
struct pollfd *fds;
struct ustcomm_connection *conn;
int idx = 0;
int n_fds = 1;
- list_for_each_entry(conn, &ustd->connections, list) {
+ list_for_each_entry(conn, &server->connections, list) {
n_fds++;
}
}
/* special idx 0 is for listening socket */
- fds[idx].fd = ustd->listen_fd;
+ fds[idx].fd = server->listen_fd;
fds[idx].events = POLLIN;
idx++;
- list_for_each_entry(conn, &ustd->connections, list) {
+ list_for_each_entry(conn, &server->connections, list) {
fds[idx].fd = conn->fd;
fds[idx].events = POLLIN;
idx++;
}
- result = poll(fds, n_fds, -1);
+ result = poll(fds, n_fds, timeout);
if(result == -1) {
PERROR("poll");
return -1;
}
+ if(result == 0)
+ return 0;
+
if(fds[0].revents) {
struct ustcomm_connection *newconn;
int newfd;
- result = newfd = accept(ustd->listen_fd, NULL, NULL);
+ result = newfd = accept(server->listen_fd, NULL, NULL);
if(result == -1) {
PERROR("accept");
return -1;
newconn->fd = newfd;
- list_add(&newconn->list, &ustd->connections);
+ list_add(&newconn->list, &server->connections);
}
for(idx=1; idx<n_fds; idx++) {
/* connection finished */
close(fds[idx].fd);
- list_for_each_entry(conn, &ustd->connections, list) {
+ list_for_each_entry(conn, &server->connections, list) {
if(conn->fd == fds[idx].fd) {
list_del(&conn->list);
break;
return retval;
}
-int ustcomm_app_recv_message(struct ustcomm_app *app, char **msg, struct ustcomm_source *src)
+int ustcomm_ustd_recv_message(struct ustcomm_ustd *ustd, char **msg, struct ustcomm_source *src, int timeout)
+{
+ return ustcomm_recv_message(&ustd->server, msg, src, timeout);
+}
+
+int ustcomm_app_recv_message(struct ustcomm_app *app, char **msg, struct ustcomm_source *src, int timeout)
+{
+ return ustcomm_recv_message(&app->server, msg, src, timeout);
+}
+
+/* This removes src from the list of active connections of app.
+ */
+
+int ustcomm_app_detach_client(struct ustcomm_app *app, struct ustcomm_source *src)
{
- return ustcomm_ustd_recv_message((struct ustcomm_ustd *)app, msg, src);
+ struct ustcomm_server *server = (struct ustcomm_server *)app;
+ struct ustcomm_connection *conn;
+
+ list_for_each_entry(conn, &server->connections, list) {
+ if(conn->fd == src->fd) {
+ list_del(&conn->list);
+ goto found;
+ }
+ }
+
+ return -1;
+found:
+ return src->fd;
}
static int init_named_socket(char *name, char **path_out)
return -1;
}
- handle->listen_fd = init_named_socket(name, &(handle->socketpath));
- if(handle->listen_fd < 0) {
+ handle->server.listen_fd = init_named_socket(name, &(handle->server.socketpath));
+ if(handle->server.listen_fd < 0) {
ERR("error initializing named socket");
goto free_name;
}
free(name);
- INIT_LIST_HEAD(&handle->connections);
+ INIT_LIST_HEAD(&handle->server.connections);
return 0;
return -1;
}
- handle->listen_fd = init_named_socket(name, &handle->socketpath);
- if(handle->listen_fd < 0) {
+ handle->server.listen_fd = init_named_socket(name, &handle->server.socketpath);
+ if(handle->server.listen_fd < 0) {
ERR("error initializing named socket");
goto free_name;
}
free(name);
- INIT_LIST_HEAD(&handle->connections);
+ INIT_LIST_HEAD(&handle->server.connections);
return 0;