int main(int argc, char **argv)
{
int list = 0, next = 0, ret, reg = default_reg;
- char *device = NULL, *device_arg = NULL,
- *dso_name = default_dso_name, *dso_name_arg = NULL;
+ char *device = NULL, *dso_name = default_dso_name, *dso_name_arg = NULL;
- if (!parse_argv(argc, argv, &dso_name_arg, &device_arg, ®, &list))
+ if (!parse_argv(argc, argv, &dso_name_arg, &device, ®, &list))
exit(EXIT_FAILURE);
- if (dso_name_arg)
- dso_name = dso_name_arg;
- else
- dso_name_arg = dso_name;
-
- if (device_arg)
- device = device_arg;
-
if (list) {
+ dso_name = dso_name_arg;
+
do {
/* FIXME: dso_name and/or device name given. */
if (!(ret= dm_get_registered_device(&dso_name,
printf("%s %s 0x%x\n",
dso_name, device, events);
- if (!dso_name_arg) {
- free(dso_name);
- dso_name = NULL;
- }
-
- if (!device_arg) {
- free(device);
- device = NULL;
- }
-
- if (dso_name_arg && device_arg)
- break;
-
next = 1;
}
} while (!ret);
exit(EXIT_SUCCESS);
}
+ if (dso_name_arg)
+ dso_name = dso_name_arg;
+
if ((ret = reg ? dm_register_for_event(dso_name, device, events) :
dm_unregister_for_event(dso_name, device, events))) {
fprintf(stderr, "Failed to %sregister %s: %s\n",
log_print("%s: here\n", __func__);
fflush(stdout);
- memset(message_data, 0, sizeof(*message_data));
/*
* Retrieve application identifier, mapped device
list_iterate_items(thread, &thread_registry) {
dev = dso = 0;
+log_print("%s: working %s %s %u\n", __func__, thread->dso_data->dso_name, thread->device_path, thread->events);
/* If DSO name equals. */
if (message_data->dso_name &&
!strcmp(message_data->dso_name,
/* We've got both DSO name and device patch or either. */
/* FIXME: wrong logic! */
- if ((dso && dev) || dso || dev) {
+ if (message_data->dso_name && message_data->device_path &&
+ dso && dev)
hit = 1;
+ else if (message_data->dso_name && dso)
+ hit = 1;
+ else if (message_data->device_path &&
+ dev)
+ hit = 1;
+
+ if (hit)
+{log_print("%s: HIT %s %s %u\n", __func__, thread->dso_data->dso_name, thread->device_path, thread->events);
break;
- }
+}
}
/*
dbg_free(data);
}
-/* Fetch a string off src and duplicate it into *dest. */
+/*
+ * Fetch a string off src and duplicate it into *ptr.
+ * Pay attention to 0 lenght strings.
+ */
/* FIXME: move to separate module to share with the client lib. */
static const char delimiter = ' ';
-static char *fetch_string(char **src)
+static int fetch_string(char **ptr, char **src)
{
- char *p, *ret;
+ int ret = 0;
+ char *p;
+ size_t len;
if ((p = strchr(*src, delimiter)))
*p = 0;
- if ((ret = strdup(*src)))
- *src += strlen(ret) + 1;
+ if ((*ptr = dbg_strdup(*src))) {
+ if ((len = strlen(*ptr)))
+ *src += len;
+ else {
+ dbg_free(*ptr);
+ *ptr = NULL;
+ }
+
+ (*src)++;
+ ret = 1;
+ }
if (p)
*p = delimiter;
* Retrieve application identifier, mapped device
* path and events # string from message.
*/
- if ((message_data->dso_name = fetch_string(&p)) &&
- (message_data->device_path = fetch_string(&p)) &&
- (message_data->events.str = fetch_string(&p))) {
+ if (fetch_string(&message_data->dso_name, &p) &&
+ fetch_string(&message_data->device_path, &p) &&
+ fetch_string(&message_data->events.str, &p)) {
if (message_data->events.str) {
enum event_type i = atoi(message_data->events.str);
goto out;
}
- if (!(ret = do_register_device(thread_new)))
- goto out;
-
lock_mutex();
- if ((thread = lookup_thread_status(message_data)))
- ret = -EPERM;
- else {
+ if (!(thread = lookup_thread_status(message_data))) {
+ unlock_mutex();
+
+ /*
+ * FIXME: better do this asynchronously in the
+ * monitoring thread ?
+ */
+ if (!(ret = do_register_device(thread_new)))
+ goto out;
+
thread = thread_new;
thread_new = NULL;
/* Try to create the monitoring thread for this device. */
+ lock_mutex();
if ((ret = -create_thread(thread))) {
unlock_mutex();
free_thread_status(thread);
if (!(thread = lookup_thread_status(message_data))) {
unlock_mutex();
- ret = -ESRCH;
+ ret = -ENODEV;
goto out;
}
}
/*
- * Get next registered device.
+ * Get registered device.
*
* Only one caller at a time here as with register_for_event().
*/
return 0;
}
+static int want_registered_device(char *dso_name, char *device_path,
+ struct thread_status *thread)
+{
+ /* If DSO names and device paths are equal. */
+ if (dso_name && device_path)
+ return !strcmp(dso_name, thread->dso_data->dso_name) &&
+ !strcmp(device_path, thread->device_path);
+
+ /* If DSO names are equal. */
+ if (dso_name)
+ return !strcmp(dso_name, thread->dso_data->dso_name);
+
+ /* If device paths are equal. */
+ if (device_path)
+ return !strcmp(device_path, thread->device_path);
+
+ return 1;
+}
+
static int get_registered_device(struct message_data *message_data, int next)
{
- int dev, dso, hit = 0;
- struct thread_status *thread = list_item(thread_registry.n,
- struct thread_status);
+ int hit = 0;
+ struct thread_status *thread;
lock_mutex();
- if (!message_data->dso_name &&
- !message_data->device_path)
- goto out;
-
+ /* Iterate list of threads checking if we want a particular one. */
list_iterate_items(thread, &thread_registry) {
- dev = dso = 0;
-
- /* If DSO name equals. */
- if (message_data->dso_name &&
- !strcmp(message_data->dso_name,
- thread->dso_data->dso_name))
- dso = 1;
-
- /* If dev path equals. */
- if (message_data->device_path &&
- !strcmp(message_data->device_path,
- thread->device_path))
- dev = 1;
-
- /* We've got both DSO name and device patch or either. */
- /* FIXME: wrong logic! */
- if (message_data->dso_name && message_data->device_path &&
- dso && dev)
- hit = 1;
- else if (message_data->dso_name && dso)
- hit = 1;
- else if (message_data->device_path && dev)
- hit = 1;
-
- if (hit)
+ if ((hit = want_registered_device(message_data->dso_name,
+ message_data->device_path,
+ thread)))
break;
}
/*
* If we got a registered device and want the next one ->
- * fetch next element off the list.
+ * fetch next conforming element off the list.
*/
- if (hit && next)
- thread = list_item(&thread->list.n, struct thread_status);
+ if (hit) {
+ if (next) {
+ do {
+ if (list_end(&thread_registry, &thread->list))
+ goto out;
+
+ thread = list_item(thread->list.n,
+ struct thread_status);
+ } while (!want_registered_device(message_data->dso_name,
+ NULL, thread));
+ }
- out:
- if (list_empty(&thread->list) ||
- &thread->list == &thread_registry) {
- unlock_mutex();
- return -ENOENT;
+ return registered_device(message_data, thread);
}
-log_print("%s: return %s %s %u\n", __func__, thread->dso_data->dso_name, thread->device_path, thread->events);
- return registered_device(message_data, thread);
+ out:
+ unlock_mutex();
+
+ return -ENOENT;
}
/* Initialize a fifos structure with path names. */
msg.opcode.status = do_process_request(&msg);
-log_print("%s: status: %d\n", __func__, msg.opcode.status);
- memset(&msg.msg, 0, sizeof(msg.msg));
+log_print("%s: status: %s\n", __func__, strerror(-msg.opcode.status));
if (!client_write(fifos, &msg))
stack;
}
return EXIT_CHDIR_FAILURE;
/* FIXME: activate again after we're done with tracing.
- if((close(STDIN_FILENO) < 0) ||
- (close(STDOUT_FILENO) < 0) ||
- (close(STDERR_FILENO) < 0))
+ if ((close(STDIN_FILENO) < 0) ||
+ (close(STDOUT_FILENO) < 0) ||
+ (close(STDERR_FILENO) < 0))
return EXIT_DESC_CLOSE_FAILURE;
*/
bytes += ret > 0 ? ret : 0;
}
-log_print("%s: \"%s\"\n", __func__, msg->msg);
+// log_print("%s: \"%s\"\n", __func__, msg->msg);
return bytes == sizeof(*msg);
}
fd_set fds;
-log_print("%s: \"%s\"\n", __func__, msg->msg);
+// log_print("%s: \"%s\"\n", __func__, msg->msg);
errno = 0;
while (bytes < sizeof(*msg) && errno != EIO) {
do {
*/
msg->opcode.cmd = cmd;
snprintf(msg->msg, sizeof(msg->msg), "%s %s %u",
- dso_name, device, events);
+ dso_name ? dso_name : "", device ? device : "", events);
/*
* Write command and message to and
* Open the fifo used to read from the daemon.
* Allows daemon to create its write fifo...
*/
- if((fifos->server = open(fifos->server_path, O_RDWR)) < 0){
- log_err("%s: open server fifo %s\n", __func__, fifos->server_path);
+ if ((fifos->server = open(fifos->server_path, O_RDWR)) < 0) {
+ log_err("%s: open server fifo %s\n",
+ __func__, fifos->server_path);
stack;
return 0;
}
-log_print("%s: server path open\n", __func__);
/* Lock out anyone else trying to do communication with the daemon. */
if (flock(fifos->server, LOCK_EX) < 0){
close(fifos->server);
return 0;
}
-log_print("%s: server fifo locked\n", __func__);
/* Anyone listening? If not, errno will be ENXIO */
- if((fifos->client = open(fifos->client_path, O_WRONLY | O_NONBLOCK)) < 0){
+ if ((fifos->client = open(fifos->client_path,
+ O_WRONLY | O_NONBLOCK)) < 0) {
if(errno != ENXIO){
log_err("%s: open client fifo %s\n",
__func__, fifos->client_path);
stack;
return 0;
}
-log_print("%s: client path open\n", __func__);
if(!start_daemon()){
stack;
enum event_type *events, int next)
{
int ret;
+ char *dso_name_sav = *dso_name, *device_sav = *device;
struct daemon_message msg;
if (!(ret = do_event(next ? CMD_GET_NEXT_REGISTERED_DEVICE :
&msg, *dso_name, *device, *events)))
ret = parse_message(&msg, dso_name, device, events);
+ if (dso_name_sav)
+ free(dso_name_sav);
+
+ if (device_sav)
+ free(device_sav);
+
return ret;
}