summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2006-09-30 14:39:18 +0000
committerpjd <pjd@FreeBSD.org>2006-09-30 14:39:18 +0000
commit0160abf37e504cadfab0fa306c38183ba8262fea (patch)
treeec2fc43ca3f7e02971862a9f9fce76779ceb2e6c
parent59b61d5e58bd9b862fa7c64115efd0e04d5c177b (diff)
downloadFreeBSD-src-0160abf37e504cadfab0fa306c38183ba8262fea.zip
FreeBSD-src-0160abf37e504cadfab0fa306c38183ba8262fea.tar.gz
MFp4:
- Print proper error message when argument is specified twice. Before the change it was detected properly, because of how G_OPT_DONE() macro worked. - Use err(3) functions where appropriate. - Add some assertions. - Bump version number, because G_TYPE_BOOL addition breaks API and ABI. Changes: 98721,98722,98723,101360,106985
-rw-r--r--sbin/geom/core/geom.c78
-rw-r--r--sbin/geom/core/geom.h16
2 files changed, 47 insertions, 47 deletions
diff --git a/sbin/geom/core/geom.c b/sbin/geom/core/geom.c
index 06cd2f6..edcdc99 100644
--- a/sbin/geom/core/geom.c
+++ b/sbin/geom/core/geom.c
@@ -75,7 +75,7 @@ struct g_command std_commands[] = {
},
{ "status", 0, std_status,
{
- { 's', "script", NULL, G_TYPE_NONE },
+ { 's', "script", NULL, G_TYPE_BOOL },
G_OPT_SENTINEL
},
"[-s] [name ...]"
@@ -102,14 +102,14 @@ usage_command(struct g_command *cmd, const char *prefix)
opt = &cmd->gc_options[i];
if (opt->go_name == NULL)
break;
- if (opt->go_val != NULL || opt->go_type == G_TYPE_NONE)
+ if (opt->go_val != NULL || G_OPT_TYPE(opt) == G_TYPE_BOOL)
fprintf(stderr, " [");
else
fprintf(stderr, " ");
fprintf(stderr, "-%c", opt->go_char);
- if (opt->go_type != G_TYPE_NONE)
+ if (G_OPT_TYPE(opt) != G_TYPE_BOOL)
fprintf(stderr, " %s", opt->go_name);
- if (opt->go_val != NULL || opt->go_type == G_TYPE_NONE)
+ if (opt->go_val != NULL || G_OPT_TYPE(opt) == G_TYPE_BOOL)
fprintf(stderr, "]");
}
fprintf(stderr, "\n");
@@ -218,7 +218,7 @@ static void
set_option(struct gctl_req *req, struct g_option *opt, const char *val)
{
- if (opt->go_type == G_TYPE_NUMBER) {
+ if (G_OPT_TYPE(opt) == G_TYPE_NUMBER) {
intmax_t number;
errno = 0;
@@ -233,9 +233,9 @@ set_option(struct gctl_req *req, struct g_option *opt, const char *val)
*(intmax_t *)opt->go_val = number;
gctl_ro_param(req, opt->go_name, sizeof(intmax_t), opt->go_val);
- } else if (opt->go_type == G_TYPE_STRING) {
+ } else if (G_OPT_TYPE(opt) == G_TYPE_STRING) {
gctl_ro_param(req, opt->go_name, -1, optarg);
- } else /* if (opt->go_type == G_TYPE_NONE) */ {
+ } else if (G_OPT_TYPE(opt) == G_TYPE_BOOL) {
opt->go_val = malloc(sizeof(int));
if (opt->go_val == NULL)
errx(EXIT_FAILURE, "No memory.");
@@ -243,6 +243,8 @@ set_option(struct gctl_req *req, struct g_option *opt, const char *val)
gctl_ro_param(req, opt->go_name, sizeof(int),
opt->go_val);
+ } else {
+ assert(!"Invalid type");
}
}
@@ -267,8 +269,10 @@ parse_arguments(struct g_command *cmd, struct gctl_req *req, int *argc,
opt = &cmd->gc_options[i];
if (opt->go_name == NULL)
break;
+ assert(G_OPT_TYPE(opt) != 0);
+ assert((opt->go_type & ~G_TYPE_MASK) == 0);
strlcatf(opts, sizeof(opts), "%c", opt->go_char);
- if (opt->go_type != G_TYPE_NONE)
+ if (G_OPT_TYPE(opt) != G_TYPE_BOOL)
strlcat(opts, ":", sizeof(opts));
}
@@ -287,13 +291,12 @@ parse_arguments(struct g_command *cmd, struct gctl_req *req, int *argc,
if (opt == NULL)
usage();
if (G_OPT_ISDONE(opt)) {
- fprintf(stderr, "Flag '%c' specified twice.\n",
- opt->go_char);
+ warnx("Option '%c' specified twice.", opt->go_char);
usage();
}
G_OPT_DONE(opt);
- if (opt->go_type == G_TYPE_NONE)
+ if (G_OPT_TYPE(opt) == G_TYPE_BOOL)
set_option(req, opt, "1");
else
set_option(req, opt, optarg);
@@ -311,21 +314,23 @@ parse_arguments(struct g_command *cmd, struct gctl_req *req, int *argc,
if (G_OPT_ISDONE(opt))
continue;
- if (opt->go_type == G_TYPE_NONE) {
+ if (G_OPT_TYPE(opt) == G_TYPE_BOOL) {
assert(opt->go_val == NULL);
set_option(req, opt, "0");
} else {
if (opt->go_val == NULL) {
- fprintf(stderr, "Flag '%c' not specified.\n",
+ warnx("Option '%c' not specified.",
opt->go_char);
usage();
} else {
- if (opt->go_type == G_TYPE_NUMBER) {
+ if (G_OPT_TYPE(opt) == G_TYPE_NUMBER) {
gctl_ro_param(req, opt->go_name,
sizeof(intmax_t), opt->go_val);
- } else /* if (opt->go_type == G_TYPE_STRING)*/ {
+ } else if (G_OPT_TYPE(opt) == G_TYPE_STRING) {
gctl_ro_param(req, opt->go_name, -1,
opt->go_val);
+ } else {
+ assert(!"Invalid type");
}
}
}
@@ -406,12 +411,11 @@ run_command(int argc, char *argv[])
/* Now, try to find a standard command. */
cmd = find_command(argv[0], GEOM_STD_CMDS);
if (cmd == NULL) {
- fprintf(stderr, "Unknown command: %s\n", argv[0]);
+ warnx("Unknown command: %s.", argv[0]);
usage();
}
if (!std_available(cmd->gc_name)) {
- fprintf(stderr, "Command '%s' not available.\n",
- argv[0]);
+ warnx("Command '%s' not available.", argv[0]);
exit(EXIT_FAILURE);
}
}
@@ -437,7 +441,7 @@ run_command(int argc, char *argv[])
errstr = gctl_issue(req);
}
if (errstr != NULL && errstr[0] != '\0') {
- fprintf(stderr, "%s\n", errstr);
+ warnx("%s", errstr);
if (strncmp(errstr, "warning: ", strlen("warning: ")) != 0) {
gctl_free(req);
exit(EXIT_FAILURE);
@@ -486,8 +490,7 @@ load_library(void)
errx(EXIT_FAILURE, "Cannot open library: %s.", dlerror());
lib_version = dlsym(dlh, "lib_version");
if (lib_version == NULL) {
- fprintf(stderr, "Cannot find symbol %s: %s.\n", "lib_version",
- dlerror());
+ warnx("Cannot find symbol %s: %s.", "lib_version", dlerror());
dlclose(dlh);
exit(EXIT_FAILURE);
}
@@ -498,15 +501,14 @@ load_library(void)
}
version = dlsym(dlh, "version");
if (version == NULL) {
- fprintf(stderr, "Cannot find symbol %s: %s.\n", "version",
- dlerror());
+ warnx("Cannot find symbol %s: %s.", "version", dlerror());
dlclose(dlh);
exit(EXIT_FAILURE);
}
class_commands = dlsym(dlh, "class_commands");
if (class_commands == NULL) {
- fprintf(stderr, "Cannot find symbol %s: %s.\n",
- "class_commands", dlerror());
+ warnx("Cannot find symbol %s: %s.", "class_commands",
+ dlerror());
dlclose(dlh);
exit(EXIT_FAILURE);
}
@@ -688,10 +690,8 @@ std_list_available(void)
int error;
error = geom_gettree(&mesh);
- if (error != 0) {
- fprintf(stderr, "Cannot get GEOM tree: %s.\n", strerror(error));
- exit(EXIT_FAILURE);
- }
+ if (error != 0)
+ errc(EXIT_FAILURE, error, "Cannot get GEOM tree");
classp = find_class(&mesh, gclass_name);
geom_deletetree(&mesh);
if (classp != NULL)
@@ -709,14 +709,12 @@ std_list(struct gctl_req *req, unsigned flags __unused)
int error, i, nargs;
error = geom_gettree(&mesh);
- if (error != 0) {
- fprintf(stderr, "Cannot get GEOM tree: %s.\n", strerror(error));
- exit(EXIT_FAILURE);
- }
+ if (error != 0)
+ errc(EXIT_FAILURE, error, "Cannot get GEOM tree");
classp = find_class(&mesh, gclass_name);
if (classp == NULL) {
geom_deletetree(&mesh);
- fprintf(stderr, "Class %s not found.\n", gclass_name);
+ warnx("Class %s not found.", gclass_name);
return;
}
nargs = gctl_get_int(req, "nargs");
@@ -727,7 +725,7 @@ std_list(struct gctl_req *req, unsigned flags __unused)
if (gp != NULL)
list_one_geom(gp);
else
- fprintf(stderr, "No such geom: %s.\n", name);
+ warnx("No such geom: %s.", name);
}
} else {
LIST_FOREACH(gp, &classp->lg_geom, lg_geom) {
@@ -847,13 +845,11 @@ std_status(struct gctl_req *req, unsigned flags __unused)
int error, i, n, nargs, script;
error = geom_gettree(&mesh);
- if (error != 0) {
- fprintf(stderr, "Cannot get GEOM tree: %s.\n", strerror(error));
- exit(EXIT_FAILURE);
- }
+ if (error != 0)
+ errc(EXIT_FAILURE, error, "Cannot get GEOM tree");
classp = find_class(&mesh, gclass_name);
if (classp == NULL) {
- fprintf(stderr, "Class %s not found.\n", gclass_name);
+ warnx("Class %s not found.", gclass_name);
goto end;
}
nargs = gctl_get_int(req, "nargs");
@@ -865,7 +861,7 @@ std_status(struct gctl_req *req, unsigned flags __unused)
name = gctl_get_ascii(req, "arg%d", i);
gp = find_geom(classp, name);
if (gp == NULL)
- fprintf(stderr, "No such geom: %s.\n", name);
+ warnx("No such geom: %s.", name);
else {
status_update_len(gp, &name_len, &status_len);
n++;
diff --git a/sbin/geom/core/geom.h b/sbin/geom/core/geom.h
index 3762146..5368b56 100644
--- a/sbin/geom/core/geom.h
+++ b/sbin/geom/core/geom.h
@@ -28,19 +28,23 @@
#ifndef _GEOM_H_
#define _GEOM_H_
-#define G_LIB_VERSION 1
+#define G_LIB_VERSION 2
#define G_FLAG_NONE 0x0000
#define G_FLAG_VERBOSE 0x0001
#define G_FLAG_LOADKLD 0x0002
-#define G_TYPE_NONE 0
-#define G_TYPE_STRING 1
-#define G_TYPE_NUMBER 2
+#define G_TYPE_NONE 0x00
+#define G_TYPE_BOOL 0x01
+#define G_TYPE_STRING 0x02
+#define G_TYPE_NUMBER 0x03
+#define G_TYPE_MASK 0x03
+#define G_TYPE_DONE 0x10
#define G_OPT_MAX 16
-#define G_OPT_DONE(opt) (opt)->go_char = '\0'
-#define G_OPT_ISDONE(opt) ((opt)->go_char == '\0')
+#define G_OPT_DONE(opt) do { (opt)->go_type |= G_TYPE_DONE; } while (0)
+#define G_OPT_ISDONE(opt) ((opt)->go_type & G_TYPE_DONE)
+#define G_OPT_TYPE(opt) ((opt)->go_type & G_TYPE_MASK)
#define G_OPT_SENTINEL { '\0', NULL, NULL, G_TYPE_NONE }
#define G_NULL_OPTS { G_OPT_SENTINEL }
OpenPOWER on IntegriCloud