summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdriana Kobylak <anoo@us.ibm.com>2017-04-04 12:47:38 -0500
committerAdriana Kobylak <anoo@us.ibm.com>2017-04-23 17:27:43 -0500
commite4d6c79030ad7b7638d0fc5ea09cf13afe224cda (patch)
tree76629726a7a53de2e55b78d69201b4937f6b6ace
parent9f4c3c7c408a5f84a52416da99d0dd8035f1ae5a (diff)
downloadphosphor-objmgr-e4d6c79030ad7b7638d0fc5ea09cf13afe224cda.tar.gz
phosphor-objmgr-e4d6c79030ad7b7638d0fc5ea09cf13afe224cda.zip
wait-until-removed: Add Interface parameter
The additional interface parameter can be a string (ex. "intf" "obj1"), or be in a single string with the obj parameter (ex. "intf obj1 obj2..."). The latter is used when passing the parameters from a systemd unit. The wait-until-removed option will block until the requested interface is not present in the specified dbus object. Change-Id: Ia935af5721e2aec8c271eff483cff9c3a1f1fa24 Signed-off-by: Adriana Kobylak <anoo@us.ibm.com>
-rw-r--r--libmapper/app.c51
-rw-r--r--libmapper/mapper.c61
-rw-r--r--libmapper/mapper.h2
3 files changed, 110 insertions, 4 deletions
diff --git a/libmapper/app.c b/libmapper/app.c
index aa42461..e4aea03 100644
--- a/libmapper/app.c
+++ b/libmapper/app.c
@@ -84,16 +84,57 @@ static void quit(int r, void *loop)
sd_event_exit((sd_event *)loop, r);
}
+static char** split_args(char* arg)
+{
+ int i = 0;
+ int count = 0;
+ char* p = arg;
+
+ while((p = strchr(p, ' ')) != NULL) {
+ count++;
+ p++;
+ }
+ if (count == 0)
+ return NULL;
+
+ /* Need to allocate space for count+1 number of arguments */
+ count++;
+ char** args = (char**)malloc(sizeof(*args) * count);
+ if (args != NULL) {
+ i = 0;
+ p = strtok(arg, " ");
+ while((p != NULL) && (i < count)) {
+ args[i++] = p;
+ p = strtok(NULL, " ");
+ }
+ }
+
+ return args;
+}
+
static int wait_main(int argc, char *argv[])
{
int r;
+ bool free_args = false;
+ char** args = argv + 2;
sd_bus *conn = NULL;
sd_event *loop = NULL;
mapper_async_wait *wait = NULL;
- if(argc < 3) {
+ if((!strcmp(argv[1], "wait")) && argc < 3) {
fprintf(stderr, "Usage: %s wait OBJECTPATH...\n", argv[0]);
exit(EXIT_FAILURE);
+ } else if((!strcmp(argv[1], "wait-until-removed")) && argc < 4) {
+ /* The arguments can be passed by a single string, ex: "intf obj1..." */
+ /* Try to split the single into the multiple arguments */
+ args = split_args(argv[2]);
+ if (args != NULL)
+ free_args = true;
+ else {
+ fprintf(stderr, "Usage: %s wait-until-removed \
+ INTERFACE OBJECTPATH...\n", argv[0]);
+ exit(EXIT_FAILURE);
+ }
}
r = sd_bus_default_system(&conn);
@@ -120,9 +161,11 @@ static int wait_main(int argc, char *argv[])
}
if (!strcmp(argv[1], "wait"))
- r = mapper_wait_async(conn, loop, argv+2, quit, loop, &wait, true);
+ r = mapper_wait_async(conn, loop, NULL, args, quit, loop, &wait,
+ true);
else if (!strcmp(argv[1], "wait-until-removed"))
- r = mapper_wait_async(conn, loop, argv+2, quit, loop, &wait, false);
+ r = mapper_wait_async(conn, loop, args[0], args+1, quit, loop, &wait,
+ false);
if(r < 0) {
fprintf(stderr, "Error configuring waitlist: %s\n",
strerror(-r));
@@ -137,6 +180,8 @@ static int wait_main(int argc, char *argv[])
}
finish:
+ if (free_args)
+ free(args);
exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
}
diff --git a/libmapper/mapper.c b/libmapper/mapper.c
index ad64d4a..4f2d022 100644
--- a/libmapper/mapper.c
+++ b/libmapper/mapper.c
@@ -45,6 +45,7 @@ static const uint64_t mapper_busy_delay_interval_usec = 1000000;
struct mapper_async_wait
{
+ char *intf;
char **objs;
void (*callback)(int, void *);
void *userdata;
@@ -150,6 +151,49 @@ static int async_wait_timeout_callback(sd_event_source *s,
return 0;
}
+static int get_interface(sd_bus_message *m,
+ mapper_async_wait *wait, char* interface)
+{
+ int r = 0;
+ char* tmp_intf = NULL;
+
+ for(int i = 0; i<wait->count; ++i) {
+ sd_bus_error error = SD_BUS_ERROR_NULL;
+ r = sd_bus_call_method(
+ wait->conn,
+ MAPPER_BUSNAME,
+ MAPPER_PATH,
+ MAPPER_INTERFACE,
+ "GetSubTreePaths",
+ &error,
+ &m,
+ "sias",
+ wait->objs[i],
+ 0, 1,
+ wait->intf);
+ if (r < 0) {
+ fprintf(stderr, "Error invoking method: %s\n",
+ strerror(-r));
+ return r;
+ }
+
+ r = sd_bus_message_read(m, "as", 1, &tmp_intf);
+ if (r < 0) {
+ // Ignore the errno when the intf does not exist (ENXIO)
+ if (r == -ENXIO) {
+ r = 0;
+ continue;
+ }
+ } else
+ break;
+ }
+
+ if (tmp_intf)
+ strcpy(interface, tmp_intf);
+
+ return r;
+}
+
static int async_wait_getobject_callback(sd_bus_message *m,
void *userdata,
sd_bus_error *e)
@@ -163,6 +207,18 @@ static int async_wait_getobject_callback(sd_bus_message *m,
goto exit;
r = sd_bus_message_get_errno(m);
+
+ if (!r && !wait->added) {
+ // Dbus object exists, need to check if it has the requested interface
+ char intf[256];
+ intf[0] = '\0';
+ r = get_interface(m, wait, intf);
+ if ((r < 0) || (strlen(intf) != 0))
+ goto exit;
+ else
+ r = 0;
+ }
+
if(r == ENOENT) {
if (wait->added)
goto exit;
@@ -303,6 +359,7 @@ void mapper_wait_async_free(mapper_async_wait *w)
int mapper_wait_async(sd_bus *conn,
sd_event *loop,
+ const char *intf,
char *objs[],
void (*callback)(int, void *),
void *userdata,
@@ -325,6 +382,10 @@ int mapper_wait_async(sd_bus *conn,
if(!wait->count)
return 0;
wait->added = added;
+ if (intf != NULL)
+ wait->intf = strdup(intf);
+ else
+ wait->intf = NULL;
wait->objs = sarraydup(objs);
if(!wait->objs) {
diff --git a/libmapper/mapper.h b/libmapper/mapper.h
index 9f85c5f..b3fed6b 100644
--- a/libmapper/mapper.h
+++ b/libmapper/mapper.h
@@ -8,7 +8,7 @@ extern "C" {
typedef struct mapper_async_wait mapper_async_wait;
void mapper_wait_async_free(mapper_async_wait *);
-int mapper_wait_async(sd_bus *, sd_event *, char *[],
+int mapper_wait_async(sd_bus *, sd_event *, const char *, char *[],
void (*)(int, void *), void *, mapper_async_wait **,
bool);
int mapper_get_service(sd_bus *conn, const char *obj, char **service);
OpenPOWER on IntegriCloud