diff options
author | Adriana Kobylak <anoo@us.ibm.com> | 2017-04-04 12:47:38 -0500 |
---|---|---|
committer | Adriana Kobylak <anoo@us.ibm.com> | 2017-04-23 17:27:43 -0500 |
commit | e4d6c79030ad7b7638d0fc5ea09cf13afe224cda (patch) | |
tree | 76629726a7a53de2e55b78d69201b4937f6b6ace | |
parent | 9f4c3c7c408a5f84a52416da99d0dd8035f1ae5a (diff) | |
download | phosphor-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.c | 51 | ||||
-rw-r--r-- | libmapper/mapper.c | 61 | ||||
-rw-r--r-- | libmapper/mapper.h | 2 |
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); |