Module: xenomai-forge
Branch: master
Commit: ee4256d5138bc96f901602f14e3aa81ecd310726
URL:    
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=ee4256d5138bc96f901602f14e3aa81ecd310726

Author: Philippe Gerum <r...@xenomai.org>
Date:   Fri Dec  9 17:24:40 2011 +0100

copperplate, lib: fix handling of command line options

This is a general fix aimed at allowing applications to receive an
argument vector expunged from all Xenomai core/skin options.

Applications may use short options freely (e.g. -f blah), only sharing
the long option namespace with Xenomai (e.g. --foo=blah).

---

 include/copperplate/init.h       |   15 ++-
 lib/alchemy/init.c               |   37 +++--
 lib/alchemy/testsuite/alarm-1.c  |    4 +-
 lib/alchemy/testsuite/buffer-1.c |    4 +-
 lib/alchemy/testsuite/event-1.c  |    4 +-
 lib/alchemy/testsuite/heap-1.c   |    4 +-
 lib/alchemy/testsuite/mq-1.c     |    4 +-
 lib/alchemy/testsuite/mq-2.c     |    4 +-
 lib/alchemy/testsuite/mq-3.c     |    4 +-
 lib/alchemy/testsuite/mutex-1.c  |    4 +-
 lib/alchemy/testsuite/sem-1.c    |    4 +-
 lib/alchemy/testsuite/sem-2.c    |    4 +-
 lib/alchemy/testsuite/task-1.c   |    4 +-
 lib/alchemy/testsuite/task-2.c   |    4 +-
 lib/alchemy/testsuite/task-3.c   |    4 +-
 lib/alchemy/testsuite/task-4.c   |    4 +-
 lib/alchemy/testsuite/task-5.c   |    4 +-
 lib/alchemy/testsuite/task-6.c   |    4 +-
 lib/alchemy/testsuite/task-7.c   |    4 +-
 lib/copperplate/init.c           |  338 ++++++++++++++++++++++++++++++++------
 lib/psos/init.c                  |   37 +++--
 lib/psos/testsuite/mq-1.c        |    4 +-
 lib/psos/testsuite/mq-2.c        |    4 +-
 lib/psos/testsuite/mq-3.c        |    4 +-
 lib/psos/testsuite/pt-1.c        |    4 +-
 lib/psos/testsuite/rn-1.c        |    4 +-
 lib/psos/testsuite/sem-1.c       |    4 +-
 lib/psos/testsuite/sem-2.c       |    4 +-
 lib/psos/testsuite/task-1.c      |    4 +-
 lib/psos/testsuite/task-2.c      |    4 +-
 lib/psos/testsuite/task-3.c      |    4 +-
 lib/psos/testsuite/task-4.c      |    4 +-
 lib/psos/testsuite/task-5.c      |    4 +-
 lib/psos/testsuite/task-6.c      |    4 +-
 lib/psos/testsuite/task-7.c      |    4 +-
 lib/psos/testsuite/tm-1.c        |    4 +-
 lib/psos/testsuite/tm-2.c        |    4 +-
 lib/psos/testsuite/tm-3.c        |    4 +-
 lib/psos/testsuite/tm-4.c        |    4 +-
 lib/psos/testsuite/tm-5.c        |    4 +-
 lib/psos/testsuite/tm-6.c        |    4 +-
 lib/psos/testsuite/tm-7.c        |    4 +-
 lib/vxworks/init.c               |   37 +++--
 lib/vxworks/testsuite/lst-1.c    |    4 +-
 lib/vxworks/testsuite/msgQ-1.c   |    4 +-
 lib/vxworks/testsuite/msgQ-2.c   |    4 +-
 lib/vxworks/testsuite/msgQ-3.c   |    4 +-
 lib/vxworks/testsuite/rng-1.c    |    4 +-
 lib/vxworks/testsuite/sem-1.c    |    4 +-
 lib/vxworks/testsuite/sem-2.c    |    4 +-
 lib/vxworks/testsuite/sem-3.c    |    4 +-
 lib/vxworks/testsuite/sem-4.c    |    4 +-
 lib/vxworks/testsuite/task-1.c   |    4 +-
 lib/vxworks/testsuite/task-2.c   |    4 +-
 lib/vxworks/testsuite/wd-1.c     |    4 +-
 testsuite/latency/latency.c      |    4 +-
 testsuite/unit/wakeup-time.c     |    4 +-
 57 files changed, 476 insertions(+), 196 deletions(-)

diff --git a/include/copperplate/init.h b/include/copperplate/init.h
index c2699b8..94c89b9 100644
--- a/include/copperplate/init.h
+++ b/include/copperplate/init.h
@@ -23,17 +23,26 @@
 #include <copperplate/core.h>
 #include <copperplate/list.h>
 
+struct option;
+
 struct copperskin {
        const char *name;
-       int (*init)(int argc, char *const argv[]);
-       struct pvholder next;
+       int (*init)(void);
+       const struct option *options;
+       int (*parse_option)(int optnum, const char *optarg);
+       void (*help)(void);
+       struct {
+               int opt_start;
+               int opt_end;
+               struct pvholder next;
+       } __reserved; /* Don't init, reserved to Copperplate. */
 };
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-void copperplate_init(int argc, char *const argv[]);
+void copperplate_init(int *argcp, char *const **argvp);
 
 void copperplate_register_skin(struct copperskin *p);
 
diff --git a/lib/alchemy/init.c b/lib/alchemy/init.c
index b94ee97..d14c2ed 100644
--- a/lib/alchemy/init.c
+++ b/lib/alchemy/init.c
@@ -51,23 +51,29 @@ static const struct option alchemy_options[] = {
        }
 };
 
-static int alchemy_init(int argc, char *const argv[])
+static int alchemy_parse_option(int optnum, const char *optarg)
 {
-       int ret, lindex, c;
-
-       for (;;) {
-               c = getopt_long_only(argc, argv, "", alchemy_options, &lindex);
-               if (c == EOF)
-                       break;
-               if (c > 0)
-                       continue;
-               switch (lindex) {
-               case clock_resolution_opt:
-                       clock_resolution = atoi(optarg);
-                       break;
-               }
+       switch (optnum) {
+       case clock_resolution_opt:
+               clock_resolution = atoi(optarg);
+               break;
+       default:
+               /* Paranoid, can't happen. */
+               return -EINVAL;
        }
 
+       return 0;
+}
+
+static void alchemy_help(void)
+{
+        fprintf(stderr, "--alchemy-clock-resolution=<ns>  tick value (default 
1ns, tickless)\n");
+}
+
+static int alchemy_init(void)
+{
+       int ret;
+
        syncluster_init(&alchemy_task_table, "alchemy.task");
        syncluster_init(&alchemy_sem_table, "alchemy.sem");
        syncluster_init(&alchemy_event_table, "alchemy.event");
@@ -91,6 +97,9 @@ static int alchemy_init(int argc, char *const argv[])
 static struct copperskin alchemy_skin = {
        .name = "alchemy",
        .init = alchemy_init,
+       .options = alchemy_options,
+       .parse_option = alchemy_parse_option,
+       .help = alchemy_help,
 };
 
 static __attribute__ ((constructor)) void register_alchemy(void)
diff --git a/lib/alchemy/testsuite/alarm-1.c b/lib/alchemy/testsuite/alarm-1.c
index 22ea19d..e29ed4d 100644
--- a/lib/alchemy/testsuite/alarm-1.c
+++ b/lib/alchemy/testsuite/alarm-1.c
@@ -72,11 +72,11 @@ static void main_task(void *arg)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/alchemy/testsuite/buffer-1.c b/lib/alchemy/testsuite/buffer-1.c
index cec04e7..8d46d8a 100644
--- a/lib/alchemy/testsuite/buffer-1.c
+++ b/lib/alchemy/testsuite/buffer-1.c
@@ -66,11 +66,11 @@ static void background_task(void *arg)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], 0);
 
diff --git a/lib/alchemy/testsuite/event-1.c b/lib/alchemy/testsuite/event-1.c
index 9f6be4d..63a0e73 100644
--- a/lib/alchemy/testsuite/event-1.c
+++ b/lib/alchemy/testsuite/event-1.c
@@ -60,11 +60,11 @@ static void foreground_task(void *arg)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], 0);
 
diff --git a/lib/alchemy/testsuite/heap-1.c b/lib/alchemy/testsuite/heap-1.c
index 7a2bd48..008f73f 100644
--- a/lib/alchemy/testsuite/heap-1.c
+++ b/lib/alchemy/testsuite/heap-1.c
@@ -66,12 +66,12 @@ static void foreground_task(void *arg)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        RT_HEAP heap;
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], 0);
 
diff --git a/lib/alchemy/testsuite/mq-1.c b/lib/alchemy/testsuite/mq-1.c
index 1a7d00e..41b4fc0 100644
--- a/lib/alchemy/testsuite/mq-1.c
+++ b/lib/alchemy/testsuite/mq-1.c
@@ -88,12 +88,12 @@ static void main_task(void *arg)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        RT_TASK t_main;
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], 0);
 
diff --git a/lib/alchemy/testsuite/mq-2.c b/lib/alchemy/testsuite/mq-2.c
index 5a069e7..7810275 100644
--- a/lib/alchemy/testsuite/mq-2.c
+++ b/lib/alchemy/testsuite/mq-2.c
@@ -94,12 +94,12 @@ static void main_task(void *arg)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        RT_TASK t_main;
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/alchemy/testsuite/mq-3.c b/lib/alchemy/testsuite/mq-3.c
index 8a702d5..9b70d93 100644
--- a/lib/alchemy/testsuite/mq-3.c
+++ b/lib/alchemy/testsuite/mq-3.c
@@ -91,12 +91,12 @@ static void peer_task(void *arg)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        RT_TASK t_main, t_peer;
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/alchemy/testsuite/mutex-1.c b/lib/alchemy/testsuite/mutex-1.c
index 17f111e..2378909 100644
--- a/lib/alchemy/testsuite/mutex-1.c
+++ b/lib/alchemy/testsuite/mutex-1.c
@@ -119,11 +119,11 @@ static void task_b(void *arg)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/alchemy/testsuite/sem-1.c b/lib/alchemy/testsuite/sem-1.c
index 8155652..06e042d 100644
--- a/lib/alchemy/testsuite/sem-1.c
+++ b/lib/alchemy/testsuite/sem-1.c
@@ -126,11 +126,11 @@ static void task_b(void *arg)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/alchemy/testsuite/sem-2.c b/lib/alchemy/testsuite/sem-2.c
index 93c1d5f..3e57714 100644
--- a/lib/alchemy/testsuite/sem-2.c
+++ b/lib/alchemy/testsuite/sem-2.c
@@ -40,11 +40,11 @@ static void main_task(void *arg)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/alchemy/testsuite/task-1.c b/lib/alchemy/testsuite/task-1.c
index 4bdb2ef..e34eb0f 100644
--- a/lib/alchemy/testsuite/task-1.c
+++ b/lib/alchemy/testsuite/task-1.c
@@ -15,11 +15,11 @@ static void main_task(void *arg)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], 0);
 
diff --git a/lib/alchemy/testsuite/task-2.c b/lib/alchemy/testsuite/task-2.c
index bb65c64..9e0038d 100644
--- a/lib/alchemy/testsuite/task-2.c
+++ b/lib/alchemy/testsuite/task-2.c
@@ -62,11 +62,11 @@ static void foreground_task(void *arg)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/alchemy/testsuite/task-3.c b/lib/alchemy/testsuite/task-3.c
index 5601fb5..ea63149 100644
--- a/lib/alchemy/testsuite/task-3.c
+++ b/lib/alchemy/testsuite/task-3.c
@@ -8,12 +8,12 @@ static struct traceobj trobj;
 
 static RT_TASK t_a, t_b;
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        RT_TASK t;
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], 0);
 
diff --git a/lib/alchemy/testsuite/task-4.c b/lib/alchemy/testsuite/task-4.c
index ca1f163..907c39b 100644
--- a/lib/alchemy/testsuite/task-4.c
+++ b/lib/alchemy/testsuite/task-4.c
@@ -59,11 +59,11 @@ static void foreground_task(void *arg)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/alchemy/testsuite/task-5.c b/lib/alchemy/testsuite/task-5.c
index e641695..a50176a 100644
--- a/lib/alchemy/testsuite/task-5.c
+++ b/lib/alchemy/testsuite/task-5.c
@@ -68,11 +68,11 @@ static void foreground_task(void *arg)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/alchemy/testsuite/task-6.c b/lib/alchemy/testsuite/task-6.c
index 47f5d22..a4afaac 100644
--- a/lib/alchemy/testsuite/task-6.c
+++ b/lib/alchemy/testsuite/task-6.c
@@ -54,11 +54,11 @@ static void foreground_task(void *arg)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], 0);
 
diff --git a/lib/alchemy/testsuite/task-7.c b/lib/alchemy/testsuite/task-7.c
index f71e089..7517737 100644
--- a/lib/alchemy/testsuite/task-7.c
+++ b/lib/alchemy/testsuite/task-7.c
@@ -87,11 +87,11 @@ static void foreground_task_b(void *arg)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], 0);
 
diff --git a/lib/copperplate/init.c b/lib/copperplate/init.c
index 720e1b2..b05b1d2 100644
--- a/lib/copperplate/init.c
+++ b/lib/copperplate/init.c
@@ -24,6 +24,8 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
+#include <memory.h>
+#include <malloc.h>
 #include <assert.h>
 #include <signal.h>
 #include <errno.h>
@@ -117,20 +119,27 @@ static const struct option base_options[] = {
 
 static void usage(void)
 {
-       fprintf(stderr, "usage: program <options>, where options may be:\n");
-       fprintf(stderr, "--mem-pool-size=<sizeK>        size of the main heap 
(kbytes)\n");
-       fprintf(stderr, "--no-mlock                     do not lock memory at 
init\n");
-       fprintf(stderr, "--registry-mountpt=<path>      mount point of 
registry\n");
-       fprintf(stderr, "--no-registry                  suppress object 
registration\n");
-       fprintf(stderr, "--session=<label>              label of shared 
multi-processing session\n");
-       fprintf(stderr, "--reset                        remove any older 
session\n");
-       fprintf(stderr, "--cpu-affinity=<cpu[,cpu]...>  set CPU affinity of 
threads\n");
-       fprintf(stderr, "--silent                       tame down verbosity\n");
+       struct copperskin *skin;
+
+        fprintf(stderr, "usage: program <options>, where options may be:\n");
+        fprintf(stderr, "--mem-pool-size=<sizeK>          size of the main 
heap (kbytes)\n");
+        fprintf(stderr, "--no-mlock                       do not lock memory 
at init\n");
+        fprintf(stderr, "--registry-mountpt=<path>        mount point of 
registry\n");
+        fprintf(stderr, "--no-registry                    suppress object 
registration\n");
+        fprintf(stderr, "--session=<label>                label of shared 
multi-processing session\n");
+        fprintf(stderr, "--reset                          remove any older 
session\n");
+        fprintf(stderr, "--cpu-affinity=<cpu[,cpu]...>    set CPU affinity of 
threads\n");
+        fprintf(stderr, "--silent                         tame down 
verbosity\n");
+       
+       pvlist_for_each_entry(skin, &skins, __reserved.next) {
+               if (skin->help)
+                       skin->help();
+       }
 }
 
 static void do_cleanup(void)
 {
-       if (!__node_info.no_registry)
+       if (__node_info.no_registry == 0)
                registry_pkg_destroy();
 }
 
@@ -163,7 +172,8 @@ static int collect_cpu_affinity(const char *cpu_list)
         * this routine to allow cumulative --cpu-affinity options to
         * appear in the command line arguments.
         */
-       ret = sched_setaffinity(0, sizeof(__node_info.cpu_affinity), 
&__node_info.cpu_affinity);
+       ret = sched_setaffinity(0, sizeof(__node_info.cpu_affinity),
+                               &__node_info.cpu_affinity);
        if (ret) {
                warning("no valid CPU in affinity list '%s'", cpu_list);
                return __bt(-ret);
@@ -172,38 +182,141 @@ static int collect_cpu_affinity(const char *cpu_list)
        return 0;
 }
 
-void copperplate_init(int argc, char *const argv[])
+static inline char **prep_args(int argc, char *const argv[], int *largcp)
 {
-       struct copperskin *skin;
-       int c, lindex, ret;
+       int in, out, n, maybe_arg, lim;
+       char **uargv, *p;
 
-       __RT(clock_gettime(CLOCK_COPPERPLATE, &__init_date));
+       uargv = malloc(argc * sizeof(char *));
+       if (uargv == NULL)
+               return NULL;
 
-       /* Our node id. is the tid of the main thread. */
-       __node_id = copperplate_get_tid();
+       for (n = 0; n < argc; n++) {
+               uargv[n] = strdup(argv[n]);
+               if (uargv[n] == NULL)
+                       return NULL;
+       }
 
-       /* No ifs, no buts: we must be called over the main thread. */
-       assert(getpid() == __node_id);
+       lim = argc;
+       in = maybe_arg = 0;
+       while (in < lim) {
+               if ((uargv[in][0] == '-' && uargv[in][1] != '-') ||
+                   (maybe_arg && uargv[in][0] != '-')) {
+                       p = strdup(uargv[in]);
+                       for (n = in, out = in + 1; out < argc; out++, n++) {
+                               free(uargv[n]);
+                               uargv[n] = strdup(uargv[out]);
+                       }
+                       free(uargv[argc - 1]);
+                       uargv[argc - 1] = p;
+                       if (*p == '-')
+                               maybe_arg = 1;
+                       lim--;
+               } else {
+                       in++;
+                       maybe_arg = 0;
+               }
+       }
 
-       /* Set a reasonable default value for the registry mount point. */
-       ret = asprintf(&__node_info.registry_mountpt,
-                      "/mnt/xenomai/%d", getpid());
-       if (ret < 0) {
-               ret = -ENOMEM;
-               goto fail;
+       *largcp = lim;
+
+       return uargv;
+}
+
+static inline void pack_args(int *argcp, int *largcp, char **argv)
+{
+       int in, out;
+
+       for (in = out = 0; in < *argcp; in++) {
+               if (*argv[in])
+                       argv[out++] = argv[in];
+               else {
+                       free(argv[in]);
+                       (*largcp)--;
+               }
        }
 
-       /* Define default CPU affinity, i.e. no particular affinity. */
-       CPU_ZERO(&__node_info.cpu_affinity);
+       *argcp = out;
+}
+
+static struct option *build_option_array(int *base_opt_startp)
+{
+       struct option *options, *q;
+       struct copperskin *skin;
+       const struct option *p;
+       int nopts;
+
+       nopts = sizeof(base_options) / sizeof(base_options[0]);
+       pvlist_for_each_entry(skin, &skins, __reserved.next) {
+               p = skin->options;
+               if (p) {
+                       while (p->name) {
+                               nopts++;
+                               p++;
+                       }
+               }
+       }
+       options = malloc(sizeof(*options) * nopts);
+       if (options == NULL)
+               return NULL;
+
+       q = options;
+       pvlist_for_each_entry(skin, &skins, __reserved.next) {
+               p = skin->options;
+               if (p) {
+                       skin->__reserved.opt_start = q - options;
+                       while (p->name)
+                               memcpy(q++, p++, sizeof(*q));
+               }
+               skin->__reserved.opt_end = q - options;
+       }
+
+       *base_opt_startp = q - options;
+       memcpy(q, base_options, sizeof(base_options));
+
+       return options;
+}
+
+static int parse_base_options(int *argcp, char *const **argvp,
+                             int *largcp, char ***uargvp,
+                             const struct option *options,
+                             int base_opt_start)
+{
+       int c, lindex, ret, n;
+       char **uargv;
+
+       /*
+        * Prepare a user argument vector we can modify, copying the
+        * one we have been given by the application code in
+        * copperplate_init(). This vector will be expunged from
+        * Xenomai proper options as we discover them.
+        */
+       uargv = prep_args(*argcp, *argvp, largcp);
+       if (uargv == NULL)
+               return -ENOMEM;
+
+       *uargvp = uargv;
        opterr = 0;
 
+       /*
+        * NOTE: since we pack the argument vector on the fly while
+        * processing the options, optarg should be considered as
+        * volatile by skin option handlers; i.e. strdup() is required
+        * if the value has to be retained. Values from the user
+        * vector returned by copperplate_init() live in permanent
+        * memory though.
+        */
+
        for (;;) {
-               c = getopt_long_only(argc, argv, "", base_options, &lindex);
+               lindex = -1;
+               c = getopt_long(*largcp, uargv, "", options, &lindex);
                if (c == EOF)
                        break;
-               if (c > 0)
-                       continue;
-               switch (lindex) {
+               if (lindex == -1) {
+                       usage();
+                       exit(1);
+               }
+               switch (lindex - base_opt_start) {
                case mempool_opt:
                        __node_info.mem_pool = atoi(optarg) * 1024;
                        break;
@@ -215,7 +328,7 @@ void copperplate_init(int argc, char *const argv[])
 #endif
                        break;
                case session_opt:
-                       __node_info.session_label = optarg;
+                       __node_info.session_label = strdup(optarg);
 #ifndef CONFIG_XENO_PSHARED
                        warning("Xenomai compiled without shared 
multi-processing support");
 #endif
@@ -223,7 +336,7 @@ void copperplate_init(int argc, char *const argv[])
                case affinity_opt:
                        ret = collect_cpu_affinity(optarg);
                        if (ret)
-                               goto fail;
+                               return ret;
                        break;
                case no_mlock_opt:
                case no_registry_opt:
@@ -233,9 +346,130 @@ void copperplate_init(int argc, char *const argv[])
                case help_opt:
                        usage();
                        exit(0);
+               default:
+                       /* Skin option, don't process yet. */
+                       continue;
                }
+
+               /*
+                * Clear the first byte of the base option we found
+                * (including any companion argument), pack_args()
+                * will expunge all options we have already handled.
+                *
+                * NOTE: this code relies on the fact that only long
+                * options with double-dash markers can be parsed here
+                * after prep_args() did its job (we do not support
+                * -foo as a long option). This is aimed at reserving
+                * use of short options to the application layer,
+                * sharing only the long option namespace with the
+                * Xenomai core libs.
+                */
+               n = optind - 1;
+               if (uargv[n][0] != '-' || uargv[n][1] != '-')
+                       /* Clear the separate argument value. */
+                       uargv[n--][0] = '\0';
+               uargv[n][0] = '\0'; /* Clear the option switch. */
        }
 
+       pack_args(argcp, largcp, uargv);
+
+       optind = 0;
+
+       return 0;
+}
+
+static int parse_skin_options(int *argcp, int largc, char **uargv,
+                             const struct option *options)
+{
+       struct copperskin *skin;
+       int lindex, n, c, ret;
+
+       for (;;) {
+               lindex = -1;
+               c = getopt_long(largc, uargv, "", options, &lindex);
+               if (c == EOF)
+                       break;
+               if (lindex == -1) {
+                       usage();
+                       exit(1);
+               }
+               pvlist_for_each_entry(skin, &skins, __reserved.next) {
+                       if (skin->parse_option == NULL)
+                               continue;
+                       if (lindex < skin->__reserved.opt_start ||
+                           lindex >= skin->__reserved.opt_end)
+                               continue;
+                       lindex -= skin->__reserved.opt_start;
+                       ret = skin->parse_option(lindex, optarg);
+                       if (ret == 0)
+                               break;
+                       return ret;
+               }
+               n = optind - 1;
+               if (uargv[n][0] != '-' || uargv[n][1] != '-')
+                       /* Clear the separate argument value. */
+                       uargv[n--][0] = '\0';
+               uargv[n][0] = '\0'; /* Clear the option switch. */
+       }
+
+       pack_args(argcp, &largc, uargv);
+
+       optind = 0;
+
+       return 0;
+}
+
+void copperplate_init(int *argcp, char *const **argvp)
+{
+       int ret, largc, base_opt_start;
+       struct copperskin *skin;
+       struct option *options;
+       char **uargv;
+
+       __RT(clock_gettime(CLOCK_COPPERPLATE, &__init_date));
+
+       /* Our node id. is the tid of the main thread. */
+       __node_id = copperplate_get_tid();
+
+       /* No ifs, no buts: we must be called over the main thread. */
+       assert(getpid() == __node_id);
+
+       if (pvlist_empty(&skins)) {
+               warning("no skin detected in program");
+               ret = -EINVAL;
+               goto fail;
+       }
+
+       /* Set a reasonable default value for the registry mount point. */
+       ret = asprintf(&__node_info.registry_mountpt,
+                      "/mnt/xenomai/%d", getpid());
+       if (ret < 0) {
+               ret = -ENOMEM;
+               goto fail;
+       }
+
+       /* Define default CPU affinity, i.e. no particular affinity. */
+       CPU_ZERO(&__node_info.cpu_affinity);
+
+       /*
+        * Build the global option array, merging the base and
+        * per-skin option sets.
+        */
+       options = build_option_array(&base_opt_start);
+       if (options == NULL) {
+               ret = -ENOMEM;
+               goto fail;
+       }
+
+       /*
+        * Parse the base options first, to bootstrap the core with
+        * the right config values.
+        */
+       ret = parse_base_options(argcp, argvp, &largc, &uargv,
+                                options, base_opt_start);
+       if (ret)
+               goto fail;
+
        ret = debug_pkg_init();
        if (ret) {
                warning("failed to initialize debugging features");
@@ -254,8 +488,8 @@ void copperplate_init(int argc, char *const argv[])
                goto fail;
        }
 
-       if (!__node_info.no_registry) {
-               ret = registry_pkg_init(argv[0], __node_info.registry_mountpt,
+       if (__node_info.no_registry == 0) {
+               ret = registry_pkg_init(uargv[0], __node_info.registry_mountpt,
                                        mkdir_mountpt);
                if (ret)
                        goto fail;
@@ -269,7 +503,7 @@ void copperplate_init(int argc, char *const argv[])
                goto fail;
        }
 
-       if (!__node_info.no_mlock) {
+       if (__node_info.no_mlock == 0) {
                ret = mlockall(MCL_CURRENT | MCL_FUTURE);
                if (ret) {
                        ret = -errno;
@@ -278,15 +512,19 @@ void copperplate_init(int argc, char *const argv[])
                }
        }
 
-       if (pvlist_empty(&skins)) {
-               warning("no skin detected in program");
-               ret = -EINVAL;
+       /*
+        * Now that we have bootstrapped the core, we may call the
+        * skin handlers for parsing their own options, which in turn
+        * may create system objects on the fly.
+        */
+       ret = parse_skin_options(argcp, largc, uargv, options);
+       if (ret)
                goto fail;
-       }
 
-       pvlist_for_each_entry(skin, &skins, next) {
-               optind = 0;
-               ret = skin->init(argc, argv);
+       free(options);
+
+       pvlist_for_each_entry(skin, &skins, __reserved.next) {
+               ret = skin->init();
                if (ret) {
                        warning("skin %s won't initialize", skin->name);
                        goto fail;
@@ -294,9 +532,9 @@ void copperplate_init(int argc, char *const argv[])
        }
 
 #ifdef __XENO_DEBUG__
-       if (!__node_info.silent_mode) {
+       if (__node_info.silent_mode == 0) {
                warning("Xenomai compiled with %s debug enabled,\n"
-                       "                                     "
+                       "                              "
                        "%shigh latencies expected [--enable-debug=%s]",
 #ifdef __XENO_DEBUG_FULL__
                        "full", "very ", "full"
@@ -306,7 +544,13 @@ void copperplate_init(int argc, char *const argv[])
                        );
        }
 #endif
-       optind = 0;
+
+       /*
+        * The final user arg vector only contains options we could
+        * not handle. The caller should be able to process them, or
+        * bail out.
+        */
+       *argvp = uargv;
 
        return;
 fail:
@@ -315,5 +559,5 @@ fail:
 
 void copperplate_register_skin(struct copperskin *p)
 {
-       pvlist_append(&p->next, &skins);
+       pvlist_append(&p->__reserved.next, &skins);
 }
diff --git a/lib/psos/init.c b/lib/psos/init.c
index cd36d00..8120eae 100644
--- a/lib/psos/init.c
+++ b/lib/psos/init.c
@@ -55,23 +55,29 @@ static const struct option psos_options[] = {
        }
 };
 
-static int psos_init(int argc, char *const argv[])
+static int psos_parse_option(int optnum, const char *optarg)
 {
-       int ret, lindex, c;
-
-       for (;;) {
-               c = getopt_long_only(argc, argv, "", psos_options, &lindex);
-               if (c == EOF)
-                       break;
-               if (c > 0)
-                       continue;
-               switch (lindex) {
-               case clock_resolution_opt:
-                       clock_resolution = atoi(optarg);
-                       break;
-               }
+       switch (optnum) {
+       case clock_resolution_opt:
+               clock_resolution = atoi(optarg);
+               break;
+       default:
+               /* Paranoid, can't happen. */
+               return -EINVAL;
        }
 
+       return 0;
+}
+
+static void psos_help(void)
+{
+        fprintf(stderr, "--psos-clock-resolution=<ns>  tick value (default 
1ms)\n");
+}
+
+static int psos_init(void)
+{
+       int ret;
+
        registry_add_dir("/psos");
        registry_add_dir("/psos/tasks");
        registry_add_dir("/psos/semaphores");
@@ -102,6 +108,9 @@ static int psos_init(int argc, char *const argv[])
 static struct copperskin psos_skin = {
        .name = "psos",
        .init = psos_init,
+       .options = psos_options,
+       .parse_option = psos_parse_option,
+       .help = psos_help,
 };
 
 static __attribute__ ((constructor)) void register_psos(void)
diff --git a/lib/psos/testsuite/mq-1.c b/lib/psos/testsuite/mq-1.c
index f4793e8..5406ee1 100644
--- a/lib/psos/testsuite/mq-1.c
+++ b/lib/psos/testsuite/mq-1.c
@@ -34,12 +34,12 @@ static void root_task(u_long a0, u_long a1, u_long a2, 
u_long a3)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        u_long args[] = { 1, 2, 3, 4 }, _qid;
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], 0);
 
diff --git a/lib/psos/testsuite/mq-2.c b/lib/psos/testsuite/mq-2.c
index f2b4a06..ebe2335 100644
--- a/lib/psos/testsuite/mq-2.c
+++ b/lib/psos/testsuite/mq-2.c
@@ -88,12 +88,12 @@ static void task_B(u_long a0, u_long a1, u_long a2, u_long 
a3)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        u_long args[] = { 1, 2, 3, 4 };
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/psos/testsuite/mq-3.c b/lib/psos/testsuite/mq-3.c
index df981e1..2481516 100644
--- a/lib/psos/testsuite/mq-3.c
+++ b/lib/psos/testsuite/mq-3.c
@@ -70,12 +70,12 @@ static void task_B(u_long a0, u_long a1, u_long a2, u_long 
a3)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        u_long args[] = { 1, 2, 3, 4 }, msgbuf[4], count;
        int ret, n;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/psos/testsuite/pt-1.c b/lib/psos/testsuite/pt-1.c
index 789634e..80ed66d 100644
--- a/lib/psos/testsuite/pt-1.c
+++ b/lib/psos/testsuite/pt-1.c
@@ -9,13 +9,13 @@ static struct traceobj trobj;
 
 static char pt_mem[65536];
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        u_long nbufs, ptid, _ptid, n;
        void *buf, *lbuf;
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], 0);
 
diff --git a/lib/psos/testsuite/rn-1.c b/lib/psos/testsuite/rn-1.c
index 9495f9d..d33cbfd 100644
--- a/lib/psos/testsuite/rn-1.c
+++ b/lib/psos/testsuite/rn-1.c
@@ -31,12 +31,12 @@ static void alloc_task(u_long a1, u_long a2, u_long a3, 
u_long a4)
        }
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        u_long args[] = { 1, 2, 3, 4 }, asize, _rnid;
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], 0);
 
diff --git a/lib/psos/testsuite/sem-1.c b/lib/psos/testsuite/sem-1.c
index b5d8385..5e6e9ce 100644
--- a/lib/psos/testsuite/sem-1.c
+++ b/lib/psos/testsuite/sem-1.c
@@ -123,12 +123,12 @@ static void task_B(u_long a0, u_long a1, u_long a2, 
u_long a3)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        u_long args[] = { 1, 2, 3, 4 };
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/psos/testsuite/sem-2.c b/lib/psos/testsuite/sem-2.c
index 9805c14..4253a23 100644
--- a/lib/psos/testsuite/sem-2.c
+++ b/lib/psos/testsuite/sem-2.c
@@ -38,12 +38,12 @@ static void task_A(u_long a0, u_long a1, u_long a2, u_long 
a3)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        u_long args[] = { 1, 2, 3, 4 };
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/psos/testsuite/task-1.c b/lib/psos/testsuite/task-1.c
index 18fb62a..45af79d 100644
--- a/lib/psos/testsuite/task-1.c
+++ b/lib/psos/testsuite/task-1.c
@@ -20,12 +20,12 @@ static void root_task(u_long a0, u_long a1, u_long a2, 
u_long a3)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        u_long args[] = { 1, 2, 3, 4 };
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], 0);
 
diff --git a/lib/psos/testsuite/task-2.c b/lib/psos/testsuite/task-2.c
index 9657bd0..014888f 100644
--- a/lib/psos/testsuite/task-2.c
+++ b/lib/psos/testsuite/task-2.c
@@ -61,12 +61,12 @@ static void foregroundTask(u_long a1, u_long a2, u_long a3, 
u_long a4)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        u_long args[] = { 1, 2, 3, 4 };
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/psos/testsuite/task-3.c b/lib/psos/testsuite/task-3.c
index 3c59728..71f85ec 100644
--- a/lib/psos/testsuite/task-3.c
+++ b/lib/psos/testsuite/task-3.c
@@ -8,12 +8,12 @@ static struct traceobj trobj;
 
 static u_long tidA, tidB;
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        u_long tid;
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], 0);
 
diff --git a/lib/psos/testsuite/task-4.c b/lib/psos/testsuite/task-4.c
index cb1ab99..0cf1eb9 100644
--- a/lib/psos/testsuite/task-4.c
+++ b/lib/psos/testsuite/task-4.c
@@ -47,12 +47,12 @@ static void task(u_long a1, u_long a2, u_long a3, u_long a4)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        u_long args[] = { 1, 2, 3, 4 };
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/psos/testsuite/task-5.c b/lib/psos/testsuite/task-5.c
index 19a6504..253d5c7 100644
--- a/lib/psos/testsuite/task-5.c
+++ b/lib/psos/testsuite/task-5.c
@@ -58,12 +58,12 @@ static void foregroundTask(u_long a1, u_long a2, u_long a3, 
u_long a4)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        u_long args[] = { 1, 2, 3, 4 };
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/psos/testsuite/task-6.c b/lib/psos/testsuite/task-6.c
index 8193435..b0119bb 100644
--- a/lib/psos/testsuite/task-6.c
+++ b/lib/psos/testsuite/task-6.c
@@ -67,12 +67,12 @@ static void foregroundTask(u_long a1, u_long a2, u_long a3, 
u_long a4)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        u_long args[] = { 1, 2, 3, 4 };
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/psos/testsuite/task-7.c b/lib/psos/testsuite/task-7.c
index 7e2c826..3badcc9 100644
--- a/lib/psos/testsuite/task-7.c
+++ b/lib/psos/testsuite/task-7.c
@@ -30,12 +30,12 @@ static void task2(u_long a1, u_long a2, u_long a3, u_long 
a4)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        u_long args[] = { 1, 2, 3, 4 };
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/psos/testsuite/tm-1.c b/lib/psos/testsuite/tm-1.c
index 912b86f..c0da465 100644
--- a/lib/psos/testsuite/tm-1.c
+++ b/lib/psos/testsuite/tm-1.c
@@ -10,12 +10,12 @@
 
 static struct traceobj trobj;
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        unsigned long date, time, ticks;
        int ret, tries = 0;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], 0);
 
diff --git a/lib/psos/testsuite/tm-2.c b/lib/psos/testsuite/tm-2.c
index 02e8551..ff40cd6 100644
--- a/lib/psos/testsuite/tm-2.c
+++ b/lib/psos/testsuite/tm-2.c
@@ -43,12 +43,12 @@ static void task(u_long a0, u_long a1, u_long a2, u_long a3)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        u_long args[] = { 1, 2, 3, 4 };
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/psos/testsuite/tm-3.c b/lib/psos/testsuite/tm-3.c
index 9145da6..e1e0480 100644
--- a/lib/psos/testsuite/tm-3.c
+++ b/lib/psos/testsuite/tm-3.c
@@ -52,12 +52,12 @@ static void task(u_long a0, u_long a1, u_long a2, u_long a3)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        u_long args[] = { 1, 2, 3, 4 };
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/psos/testsuite/tm-4.c b/lib/psos/testsuite/tm-4.c
index 5afaecd..155391a 100644
--- a/lib/psos/testsuite/tm-4.c
+++ b/lib/psos/testsuite/tm-4.c
@@ -49,12 +49,12 @@ static void task(u_long a0, u_long a1, u_long a2, u_long a3)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        u_long args[] = { 1, 2, 3, 4 };
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/psos/testsuite/tm-5.c b/lib/psos/testsuite/tm-5.c
index 97b9fac..803eaf3 100644
--- a/lib/psos/testsuite/tm-5.c
+++ b/lib/psos/testsuite/tm-5.c
@@ -45,12 +45,12 @@ static void task(u_long a0, u_long a1, u_long a2, u_long a3)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        u_long args[] = { 1, 2, 3, 4 };
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/psos/testsuite/tm-6.c b/lib/psos/testsuite/tm-6.c
index 19605d0..42719d0 100644
--- a/lib/psos/testsuite/tm-6.c
+++ b/lib/psos/testsuite/tm-6.c
@@ -23,13 +23,13 @@ static void task(u_long a0, u_long a1, u_long a2, u_long a3)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        u_long args[] = { 1, 2, 3, 4 };
        unsigned long tid;
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], 0);
 
diff --git a/lib/psos/testsuite/tm-7.c b/lib/psos/testsuite/tm-7.c
index 21235b8..52bde8f 100644
--- a/lib/psos/testsuite/tm-7.c
+++ b/lib/psos/testsuite/tm-7.c
@@ -21,13 +21,13 @@ static void task(u_long a0, u_long a1, u_long a2, u_long a3)
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        u_long args[] = { 1, 2, 3, 4 };
        unsigned long tid;
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], 0);
 
diff --git a/lib/vxworks/init.c b/lib/vxworks/init.c
index 1b24344..a26f230 100644
--- a/lib/vxworks/init.c
+++ b/lib/vxworks/init.c
@@ -44,23 +44,29 @@ static const struct option vxworks_options[] = {
        }
 };
 
-static int vxworks_init(int argc, char *const argv[])
+static int vxworks_parse_option(int optnum, const char *optarg)
 {
-       int ret, lindex, c;
-
-       for (;;) {
-               c = getopt_long_only(argc, argv, "", vxworks_options, &lindex);
-               if (c == EOF)
-                       break;
-               if (c > 0)
-                       continue;
-               switch (lindex) {
-               case clock_resolution_opt:
-                       clock_resolution = atoi(optarg);
-                       break;
-               }
+       switch (optnum) {
+       case clock_resolution_opt:
+               clock_resolution = atoi(optarg);
+               break;
+       default:
+               /* Paranoid, can't happen. */
+               return -EINVAL;
        }
 
+       return 0;
+}
+
+static void vxworks_help(void)
+{
+        fprintf(stderr, "--vxworks-clock-resolution=<ns>  tick value (default 
1ms)\n");
+}
+
+static int vxworks_init(void)
+{
+       int ret;
+
        registry_add_dir("/vxworks");
        registry_add_dir("/vxworks/tasks");
        registry_add_dir("/vxworks/semaphores");
@@ -82,6 +88,9 @@ static int vxworks_init(int argc, char *const argv[])
 static struct copperskin vxworks_skin = {
        .name = "vxworks",
        .init = vxworks_init,
+       .options = vxworks_options,
+       .parse_option = vxworks_parse_option,
+       .help = vxworks_help,
 };
 
 static __attribute__ ((constructor)) void register_vxworks(void)
diff --git a/lib/vxworks/testsuite/lst-1.c b/lib/vxworks/testsuite/lst-1.c
index d17ed57..d336f6b 100644
--- a/lib/vxworks/testsuite/lst-1.c
+++ b/lib/vxworks/testsuite/lst-1.c
@@ -130,11 +130,11 @@ static void rootTask(long a0, long a1, long a2, long a3, 
long a4,
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        TASK_ID tid;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], 0);
 
diff --git a/lib/vxworks/testsuite/msgQ-1.c b/lib/vxworks/testsuite/msgQ-1.c
index 8f2a893..e69322a 100644
--- a/lib/vxworks/testsuite/msgQ-1.c
+++ b/lib/vxworks/testsuite/msgQ-1.c
@@ -83,11 +83,11 @@ static void rootTask(long a0, long a1, long a2, long a3, 
long a4,
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        TASK_ID tid;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], 0);
 
diff --git a/lib/vxworks/testsuite/msgQ-2.c b/lib/vxworks/testsuite/msgQ-2.c
index 97cdcec..47e43a1 100644
--- a/lib/vxworks/testsuite/msgQ-2.c
+++ b/lib/vxworks/testsuite/msgQ-2.c
@@ -97,11 +97,11 @@ static void rootTask(long a0, long a1, long a2, long a3, 
long a4,
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        TASK_ID tid;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/vxworks/testsuite/msgQ-3.c b/lib/vxworks/testsuite/msgQ-3.c
index 503b399..a298cdd 100644
--- a/lib/vxworks/testsuite/msgQ-3.c
+++ b/lib/vxworks/testsuite/msgQ-3.c
@@ -85,11 +85,11 @@ static void peerTask(long a0, long a1, long a2, long a3, 
long a4,
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        TASK_ID rtid, ptid;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/vxworks/testsuite/rng-1.c b/lib/vxworks/testsuite/rng-1.c
index 1f4d7b9..1c96f45 100644
--- a/lib/vxworks/testsuite/rng-1.c
+++ b/lib/vxworks/testsuite/rng-1.c
@@ -199,11 +199,11 @@ static void rootTask(long a0, long a1, long a2, long a3, 
long a4,
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        TASK_ID tid;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], 0);
 
diff --git a/lib/vxworks/testsuite/sem-1.c b/lib/vxworks/testsuite/sem-1.c
index e6c9151..07df9a5 100644
--- a/lib/vxworks/testsuite/sem-1.c
+++ b/lib/vxworks/testsuite/sem-1.c
@@ -138,11 +138,11 @@ static void rootTask(long a0, long a1, long a2, long a3, 
long a4,
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        TASK_ID rtid, ptid;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/vxworks/testsuite/sem-2.c b/lib/vxworks/testsuite/sem-2.c
index c89642e..c672703 100644
--- a/lib/vxworks/testsuite/sem-2.c
+++ b/lib/vxworks/testsuite/sem-2.c
@@ -121,11 +121,11 @@ static void rootTask(long a0, long a1, long a2, long a3, 
long a4,
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        TASK_ID rtid, ptid;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/vxworks/testsuite/sem-3.c b/lib/vxworks/testsuite/sem-3.c
index 904c06b..55aa1d4 100644
--- a/lib/vxworks/testsuite/sem-3.c
+++ b/lib/vxworks/testsuite/sem-3.c
@@ -44,12 +44,12 @@ static void rootTask(long a0, long a1, long a2, long a3, 
long a4,
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        TASK_ID tid;
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/vxworks/testsuite/sem-4.c b/lib/vxworks/testsuite/sem-4.c
index e7df2df..da1b72e 100644
--- a/lib/vxworks/testsuite/sem-4.c
+++ b/lib/vxworks/testsuite/sem-4.c
@@ -56,12 +56,12 @@ static void rootTask(long a0, long a1, long a2, long a3, 
long a4,
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        TASK_ID tid;
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], 0);
 
diff --git a/lib/vxworks/testsuite/task-1.c b/lib/vxworks/testsuite/task-1.c
index 00eb108..3866f63 100644
--- a/lib/vxworks/testsuite/task-1.c
+++ b/lib/vxworks/testsuite/task-1.c
@@ -30,11 +30,11 @@ static void windTask(long a1, long a2, long a3, long a4, 
long a5,
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        TASK_ID tid;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/vxworks/testsuite/task-2.c b/lib/vxworks/testsuite/task-2.c
index 16bddfe..0d3d112 100644
--- a/lib/vxworks/testsuite/task-2.c
+++ b/lib/vxworks/testsuite/task-2.c
@@ -72,11 +72,11 @@ static void foregroundTask(long a1, long a2, long a3, long 
a4, long a5,
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        int ret;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/lib/vxworks/testsuite/wd-1.c b/lib/vxworks/testsuite/wd-1.c
index 5e2e7c3..5b13102 100644
--- a/lib/vxworks/testsuite/wd-1.c
+++ b/lib/vxworks/testsuite/wd-1.c
@@ -76,11 +76,11 @@ static void rootTask(long a0, long a1, long a2, long a3, 
long a4,
        traceobj_exit(&trobj);
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *const argv[])
 {
        TASK_ID tid;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        traceobj_init(&trobj, argv[0], sizeof(tseq) / sizeof(int));
 
diff --git a/testsuite/latency/latency.c b/testsuite/latency/latency.c
index 2d2b78e..148b10d 100644
--- a/testsuite/latency/latency.c
+++ b/testsuite/latency/latency.c
@@ -452,13 +452,13 @@ void mode_sw(int sig)
        kill(getpid(), sig);
 }
 
-int main(int argc, char **argv)
+int main(int argc, char *const *argv)
 {
        int cpu = 0, c, err, sig;
        char task_name[16];
        sigset_t mask;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        while ((c = getopt(argc, argv, "hp:l:T:qH:B:sD:t:fc:P:b")) != EOF)
                switch (c) {
diff --git a/testsuite/unit/wakeup-time.c b/testsuite/unit/wakeup-time.c
index ec6f554..dd98b97 100644
--- a/testsuite/unit/wakeup-time.c
+++ b/testsuite/unit/wakeup-time.c
@@ -182,11 +182,11 @@ void worker(void *cookie)
        exit(0);
 }
 
-int main(int argc, char **argv)
+int main(int argc, char *const *argv)
 {
        int err, c;
 
-       copperplate_init(argc, argv);
+       copperplate_init(&argc, &argv);
 
        while ((c = getopt(argc, argv, "hp:n:i:")) != EOF)
                switch (c) {


_______________________________________________
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to