Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F152935045
D37338.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D37338.diff
View Options
diff --git a/stand/libsa/dev.c b/stand/libsa/dev.c
--- a/stand/libsa/dev.c
+++ b/stand/libsa/dev.c
@@ -67,3 +67,85 @@
snprintf(name, sizeof(name), "%s%d:", d->d_dev->dv_name, d->d_unit);
return (name);
}
+
+/* NB: devspec points to the remainder of the device name after dv_name */
+static int
+default_parsedev(struct devdesc **dev, const char *devspec,
+ const char **path)
+{
+ struct devdesc *idev;
+ int unit, err;
+ char *cp;
+
+ idev = malloc(sizeof(struct devdesc));
+ if (idev == NULL)
+ return (ENOMEM);
+
+ unit = 0;
+ cp = (char *)devspec; /* strtol interface, alas */
+
+ if (*devspec != '\0' && *devspec != ':') {
+ errno = 0;
+ unit = strtol(devspec, &cp, 0);
+ if (errno != 0 || cp == devspec) {
+ err = EUNIT;
+ goto fail;
+ }
+ }
+ if (*cp != '\0' && *cp != ':') {
+ err = EINVAL;
+ goto fail;
+ }
+
+ idev->d_unit = unit;
+ if (path != NULL)
+ *path = (*cp == 0) ? cp : cp + 1;
+ if (dev != NULL) /* maybe this can be required? */
+ *dev = idev;
+ else
+ free(idev);
+ return (0);
+fail:
+ free(idev);
+ return (err);
+}
+
+/* NB: devspec points to the whole device spec, and possible trailing path */
+int
+devparse(struct devdesc **dev, const char *devspec, const char **path)
+{
+ struct devdesc *idev;
+ struct devsw *dv;
+ int i, err;
+ const char *np;
+
+ /* minimum length check */
+ if (strlen(devspec) < 2)
+ return (EINVAL);
+
+ /* look for a device that matches */
+ for (i = 0; devsw[i] != NULL; i++) {
+ dv = devsw[i];
+ if (!strncmp(devspec, dv->dv_name, strlen(dv->dv_name)))
+ break;
+ }
+ if (devsw[i] == NULL)
+ return (ENOENT);
+ idev = NULL;
+ err = 0;
+ if (dv->dv_parsedev) {
+ err = dv->dv_parsedev(&idev, np, path);
+ } else {
+ np = devspec + strlen(dv->dv_name);
+ err = default_parsedev(&idev, np, path);
+ }
+ if (err != 0)
+ return (err);
+
+ idev->d_dev = dv;
+ if (dev != NULL)
+ *dev = idev;
+ else
+ free(idev);
+ return (0);
+}
diff --git a/stand/libsa/libsa.3 b/stand/libsa/libsa.3
--- a/stand/libsa/libsa.3
+++ b/stand/libsa/libsa.3
@@ -508,6 +508,35 @@
.Pp
Format the specified device as a string.
.It Xo
+.Ft int
+.Fn devparse "struct devdesc **dev" "const char *devdesc" "const char **path"
+.Xc
+.Pp
+Parse the
+.Dv devdesc
+string of the form
+.Sq device:[/path/to/file] .
+The
+.Dv devsw
+table is used to match the start of the
+.Sq device
+string with
+.Fa dv_name .
+If
+.Fa dv_parsedev
+is non-NULL, then it will be called to parse the rest of the string and allocate
+the
+.Dv struct devdesc
+for this path.
+If NULL, then a default routine will be called that will allocate a simple
+.Dv struct devdesc ,
+parse a unit number and ensure there's no trailing characters.
+If
+.Dv path
+is non-NULL, then a pointer to the remainder of the
+.Dv devdesc
+string after the device specification is written.
+.It Xo
.Ft void
.Fn twiddle void
.Xc
@@ -765,8 +794,10 @@
is, by convention, the part of the device specification that follows the
.Fa dv_name
part of the string.
-So when parsing the string
-.Dq disk3p5:/xxx
+So when
+.Fa devparse
+is parsing the string
+.Dq disk3p5:/xxx ,
.Dv devpart
will point to the
.Sq 3
@@ -781,6 +812,9 @@
to point to the portion of the string after device specification, or
.Dq /xxx
in the earlier example.
+Generally, code needing to parse a path will use
+.Fa devparse
+instead of calling this routine directly.
.El
.Sh HISTORY
The
diff --git a/stand/libsa/stand.h b/stand/libsa/stand.h
--- a/stand/libsa/stand.h
+++ b/stand/libsa/stand.h
@@ -187,6 +187,7 @@
};
char *devformat(struct devdesc *d);
+int devparse(struct devdesc **, const char *, const char **);
struct open_file {
int f_flags; /* see F_* below */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Apr 19, 4:27 AM (20 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31746006
Default Alt Text
D37338.diff (3 KB)
Attached To
Mode
D37338: stand: Introduce devparse to parse device / path strings
Attached
Detach File
Event Timeline
Log In to Comment