Reflect a minor improvement in cap_to_text() output in man page.
Also, improve the "cap" package documentation to give an overview
of its text representation support.
Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
diff --git a/cap/text.go b/cap/text.go
index df037c3..11dae90 100644
--- a/cap/text.go
+++ b/cap/text.go
@@ -74,8 +74,15 @@
return m
}
-// String converts a full capability Set into it canonical readable
-// string representation (which may contain spaces).
+// String converts a full capability Set into a single short readable
+// string representation (which may contain spaces). See the
+// cap.FromText() function for an explanation of its return values.
+//
+// Note (*cap.Set).String() may evolve to generate more compact
+// strings representing the a given Set over time, but it should
+// maintain compatibility with the libcap:cap_to_text() function for
+// any given release. Further, it will always be an inverse of
+// cap.FromText().
func (c *Set) String() string {
if c == nil || len(c.flat) == 0 {
return "<invalid>"
@@ -149,6 +156,43 @@
// FromText converts the canonical text representation for a Set into
// a freshly allocated Set.
+//
+// The format follows the following pattern: a set of space separated
+// sequences. Each sequence applies over the previous sequence to
+// build up a Set. The format of a sequence is:
+//
+// [comma list of cap_values][[ops][flags]]*
+//
+// Examples:
+//
+// "all=ep"
+// "cap_chown,cap_setuid=ip cap_setuid+e"
+// "=p cap_setpcap-p+i"
+//
+// Here "all" refers to all named capabilities known to the hosting
+// kernel, and "all" is assumed if no capabilities are listed before
+// an "=".
+//
+// The ops values, "=", "+" and "-" imply "reset and raise", "raise"
+// and "lower" respectively. The "e", "i" and "p" characters
+// correspond to the capabilities of the corresponding Flag: "e"
+// (Effective); "i" (Inheritable); "p" (Permitted).
+//
+// This syntax is overspecified and there are many ways of building
+// the same final Set state. Any sequence that includes a '=' resets
+// the accumulated state of all Flags ignoring earlier sequences. On
+// each of the following lines we give three or more examples of ways
+// to specify a common Set. The last entry on each line is the one
+// generated by (*cap.Set).String() from that Set.
+//
+// "=p all+ei" "all=pie" "=pi all+e" "=eip"
+//
+// "cap_chown=p cap_setuid=i" "cap_chown=ip-p" "cap_chown=i"
+//
+// "cap_chown=-p" "all=" "cap_setuid=pie-pie" "="
+//
+// Note: FromText() is tested at release time to completely match the
+// import ability of the libcap:cap_from_text() function.
func FromText(text string) (*Set, error) {
c := NewSet()
scanner := bufio.NewScanner(strings.NewReader(text))
@@ -179,7 +223,8 @@
}
} else if sep != '=' {
if vals == "" {
- return nil, ErrBadText // Only "=" supports ""=="all".
+ // Only "=" supports ""=="all".
+ return nil, ErrBadText
}
} else if j := i + 1; j+1 < len(t) {
switch t[j] {
diff --git a/doc/cap_from_text.3 b/doc/cap_from_text.3
index 9f4c50b..59724c7 100644
--- a/doc/cap_from_text.3
+++ b/doc/cap_from_text.3
@@ -183,7 +183,7 @@
.nf
$ ./a.out "cap_chown=p cap_chown+e"
-caps_to_text() returned "= cap_chown+ep"
+caps_to_text() returned "cap_chown=ep"
$ ./a.out "all=pe cap_chown\-e cap_kill\-pe"
caps_to_text() returned "=ep cap_chown\-e cap_kill\-ep"