GETCAP(3)

πŸ“¦
version 15.1 Β· 2 versions
, in freebsd 15.1

πŸ’– GETCAP(3) β€” capability database access routines πŸ’–

ok bestie, buckle up, this is the GETCAP(3) page from the Library Functions Manual and it's honestly giving "the whole squad shows up to the group chat at once" energy. it's long, but every single function here is a little icon and you're gonna love them. πŸ’…

✨ NAME ✨

cgetent, cgetset, cgetmatch, cgetcap, cgetnum, cgetstr, cgetustr, cgetfirst, cgetnext, cgetclose β€” capability database access routines. that's the whole crew, no cap. 🫢

πŸ“š LIBRARY πŸ“š

Standard C Library (libc, -lc) β€” the classic, the blueprint, the main character. πŸ‘‘


🌸 SYNOPSIS 🌸

#include <stdlib.h>

int
cgetent(char **buf, char **db_array, const char *name);

int
cgetset(const char *ent);

int
cgetmatch(const char *buf, const char *name);

char *
cgetcap(char *buf, const char *cap, int type);

int
cgetnum(char *buf, const char *cap, long *num);

int
cgetstr(char *buf, const char *cap, char **str);

int
cgetustr(char *buf, const char *cap, char **str);

int
cgetfirst(char **buf, char **db_array);

int
cgetnext(char **buf, char **db_array);

int
cgetclose(void);

like look at them. all lined up. so organized. πŸŽ€


πŸ¦‹ DESCRIPTION πŸ¦‹

🌈 the entry point: cgetent()

okay so cgetent() pulls the capability name out of the database you point at with db_array β€” and heads up, db_array is a NULL terminated array of file names, don't forget the NULL bestie 😭 β€” and it hands you back a pointer to a malloc(3)'d copy of that record in buf.

and like, sneaky detail: cgetent() will first look for files ending in .db (peep cap_mkdb(1)) before it even touches the ASCII file. it's doing a vibe check on the compiled version first, respect.

🚨 you must keep buf alive through all your later calls to cgetmatch(), cgetcap(), cgetnum(), cgetstr(), and cgetustr(). after that you can free(3) it. don't free it early, that's the drama nobody wants.

return values, aka the mood ring:

  • 0 β€” success, slay ✨
  • 1 β€” the record you got back contains an unresolved tc expansion
  • -1 β€” the requested record could not be found πŸ˜”
  • -2 β€” a system error happened (couldn't open/read a file, etc.) and it also sets errno
  • -3 β€” a potential reference loop was detected (see the tc= comments below πŸ‘€)

πŸŽ€ cgetset() β€” the sneak-a-record-in function

cgetset() lets you slide a character buffer containing a single capability record entry into the capability database. conceptually it's added as the first "file" in the database, so it gets searched first on the cgetent() call. the entry goes in ent.

if ent is NULL, the current entry gets removed from the database. bye bestie πŸ‘‹

timing matters, so listen up:

  • a call to cgetset() must precede the database traversal. it must be called before the cgetent() call.
  • if you're doing sequential access (see below), it must be called before the first sequential access call (cgetfirst() or cgetnext()), or be directly preceded by a cgetclose() call.

returns 0 on success, -1 on failure. πŸ’€

🌟 cgetmatch() β€” name check

cgetmatch() returns 0 if name is one of the names of the capability record buf, and -1 if not. that's it. short king. πŸ‘‘

πŸ’… cgetcap() β€” the value finder

cgetcap() searches the capability record buf for the capability cap with type type. a type is specified using any single character. if you use a colon (:) as the type, an untyped capability gets searched for (there's a whole explanation of types further down, keep reading 🫢).

on success it returns a pointer to the value of cap in buf. if the requested capability couldn't be found? NULL. sorry babe. 😭

the end of the capability value is signaled by a : or ASCII NUL (syntax section below has the deets).

πŸ”’ cgetnum() β€” numbers only

cgetnum() retrieves the value of the numeric capability cap from the capability record pointed to by buf. the numeric value lands in the long pointed to by num.

returns 0 on success, -1 if the requested numeric capability could not be found.

πŸ“ cgetstr() β€” strings, decoded

cgetstr() retrieves the value of the string capability cap from the capability record pointed to by buf. a pointer to a decoded, NUL terminated, malloc(3)'d copy of the string is returned in the char * pointed to by str.

returns:

  • the number of characters in the decoded string, not including the trailing NUL β€” success ✨
  • -1 β€” the requested string capability could not be found
  • -2 β€” a system error was encountered (storage allocation failure)

🧚 cgetustr() β€” same but raw

cgetustr() is literally identical to cgetstr() except it does not expand special characters β€” instead it returns each character of the capability string literally. no filter, no edits, just vibes. πŸ™ˆ

⭐ cgetfirst() and cgetnext() β€” the sequential access duo

these two are a function group (a package deal, iykyk) that gives you sequential access to the NULL pointer terminated array of file names, db_array.

  • cgetfirst() returns the first record in the database and resets the access to the first record. fresh start energy.
  • cgetnext() returns the next record in the database with respect to the record returned by the previous cgetfirst() or cgetnext() call. and if there was no such previous call? you just get the first record in the database. generous.

each record comes back in a malloc(3)'d copy pointed to by buf. Tc expansion is done (see the tc= comments below).

the return-value lore:

  • 0 β€” upon completion of the database
  • 1 β€” successful return of a record with possibly more remaining (we have not reached the end of the database yet πŸ‘€)
  • 2 β€” the record contains an unresolved tc expansion
  • -1 β€” a system error occurred
  • -2 β€” a potential reference loop is detected (see tc= comments below)

and upon completion of the database (the 0 return), the database is closed. she's done. 🎬

🐚 cgetclose() β€” cleanup era

cgetclose() closes the sequential access and frees any memory and file descriptors being used. so tidy.

⚠️ note that it does not erase the buffer pushed by a call to cgetset(). that buffer stays. she lives there now. πŸ’€

πŸ”₯ CAPABILITY DATABASE SYNTAX πŸ”₯

capability databases are normally ASCII and may be edited with standard text editors. yes, plain text, we love a low-maintenance queen. πŸ’–

  • blank lines and lines beginning with a # are comments and are ignored.
  • lines ending with a \ mean the next line is a continuation of the current line; the \ and the following newline are ignored.
  • long lines are usually continued onto several physical lines by ending each line except the last with a \.

capability databases consist of a series of records, one per logical line. each record contains a variable number of :-separated fields (capabilities). empty fields consisting entirely of white space characters (spaces and tabs) are ignored. not me being ignored by a parser 😭

the first capability of each record specifies its names, separated by | characters. these names are how you reference records in the database. by convention, the last name is usually a comment and is not intended as a lookup tag.

for example, the vt100 record from the termcap(5) database begins:

d0|vt100|vt100-am|vt100am|dec vt100:

giving four names that can be used to access the record. four whole names, she ate. πŸ‘‘

the remaining non-empty capabilities describe a set of (name, value) bindings, consisting of a name optionally followed by a typed value:

  • name β€” typeless [boolean] capability name is present [true]
  • nameTvalue β€” capability (name, T) has value value
  • name@ β€” no capability name exists
  • nameT@ β€” capability (name, T) does not exist

names consist of one or more characters. names may contain any character except :, but it's usually best to restrict them to the printable characters and avoid use of graphics like #, =, %, @, etc.

types are single characters used to separate capability names from their associated typed values. types may be any character except a :. typically, graphics like #, =, %, etc. are used.

values may be any number of characters and may contain any character except :.


πŸ’œ CAPABILITY DATABASE SEMANTICS πŸ’œ

capability records describe a set of (name, value) bindings. names may have multiple values bound to them, and different values for a name are distinguished by their types. the cgetcap() function will return a pointer to a value of a name given the capability name and the type of the value. she's a matchmaker, fr fr. 🫢

the types # and = are conventionally used to denote numeric and string typed values, but no restriction on those types is enforced. the functions cgetnum() and cgetstr() can be used to implement the traditional syntax and semantics of # and =.

typeless capabilities are typically used to denote boolean objects with presence or absence indicating truth and false values respectively. this interpretation is conveniently represented by:

(getcap(buf, name, ':') != NULL)

πŸŒ€ the tc= situation

a special capability, tc= name, is used to indicate that the record specified by name should be substituted for the tc capability.

Tc capabilities may interpolate records which also contain tc capabilities, and more than one tc capability may be used in a record. a tc expansion scope (i.e., where the argument is searched for) contains the file in which the tc is declared and all subsequent files in the file array. that's the scope, don't forget it.

πŸ‘€ matching rules (important, bestie)

when a database is searched for a capability record, the first matching record in the search is returned.

when a record is scanned for a capability, the first matching capability is returned. specifically:

  • the capability :nameT@: will hide any following definition of a value of type T for name
  • the capability :name@: will prevent any following values of name from being seen

these features combined with tc capabilities can be used to generate variations of other databases and records by either adding new capabilities, overriding definitions with new definitions, or hiding following definitions via @ capabilities. it's giving remix, it's giving custom build. πŸ”₯


🌈 EXAMPLES 🌈

example|an example of binding multiple values to names:\
     :foo%bar:foo^blah:foo@:\
     :abc%xyz:abc^frap:abc$@:\
     :tc=more:

the capability foo has two values bound to it (bar of type % and blah of type ^) and any other value bindings are hidden. the capability abc also has two values bound but only a value of type $ is prevented from being defined in the capability record more.


file1:
     new|new_record|a modification of "old":\
          :fript=bar:who-cares@:tc=old:blah:tc=extensions:
file2:
     old|old_record|an old database record:\
          :fript=foo:who-cares:glork#200:

the records are extracted by calling cgetent() with file1 preceding file2.

so in the capability record new in file1:

  • fript=bar overrides the definition of fript=foo interpolated from the capability record old in file2 πŸ’…
  • who-cares@ prevents the definition of any who-cares definitions in old from being seen
  • glork#200 is inherited from old
  • and blah plus anything defined by the record extensions is added to those definitions in old
🌸 note that the position of the fript=bar and who-cares@ definitions before tc=old is important here. if they were after, the definitions in old would take precedence. order is everything, bestie, it's literally the whole plot. 😭

ok that's the vibe so far β€” more of this page is coming, don't go anywhere πŸ’–βœ¨

πŸ’– CGETNUM AND CGETSTR SYNTAX AND SEMANTICS πŸ’–

Okay so cgetnum() and cgetstr() come with two predefined shapes, and the syntax is literally this:

name#number  numeric capability name has value number
name=string  string capability name has value string
name#@       the numeric capability name does not exist
name=@       the string capability name does not exist

Numeric capability values may be given in one of three numeric bases. If the number starts with either 0x or 0X, it’s interpreted as a hexadecimal number β€” and both upper and lower case a-f may be used to denote the extended hexadecimal digits. Otherwise, if the number starts with a 0, it’s interpreted as an octal number. Otherwise, the number is interpreted as a decimal number. Slay, bases are handled πŸ’…

String capability values may contain any character. Non-printable ASCII codes, new lines, and colons may be conveniently represented by the use of escape sequences:

  • ^X β€” ('X' & 037), control-X
  • \b, \B β€” (ASCII 010), backspace
  • \t, \T β€” (ASCII 011), tab
  • \n, \N β€” (ASCII 012), line feed (newline)
  • \f, \F β€” (ASCII 014), form feed
  • \r, \R β€” (ASCII 015), carriage return
  • \e, \E β€” (ASCII 027), escape
  • \c, \C β€” (:), colon
  • \\ β€” (\), back slash
  • \^ β€” (^), caret
  • \nnn β€” (ASCII octal nnn)

A \ may be followed by up to three octal digits, and that directly specifies the numeric code for a character. The use of ASCII NULs, while easily encoded, causes all sorts of problems and must be used with care, since NULs are typically used to denote the end of strings; many applications use \200 to represent a NUL. So yeah, be careful with that one 😭


🩺 DIAGNOSTICS 🩺

The cgetent(), cgetset(), cgetmatch(), cgetnum(), cgetstr(), cgetustr(), cgetfirst(), and cgetnext() functions return a value greater than or equal to 0 on success and a value less than 0 on failure. The cgetcap() function returns a character pointer on success and a NULL on failure.

The cgetent() and cgetset() functions may fail and set errno for any of the errors specified for the library functions: fopen(3), fclose(3), open(2), and close(2).

The cgetent(), cgetset(), cgetstr(), and cgetustr() functions may fail and set errno as follows:

  • [ENOMEM] β€” No memory to allocate.

πŸ‘€ SEE ALSO πŸ‘€


πŸ’€ BUGS πŸ’€

  • Colons (:) cannot be used in names, types, or values.
  • There are no checks for tc=name loops in cgetent().
  • The buffer added to the database by a call to cgetset() is not unique to the database but is rather prepended to any database used.

✨ And that’s the page, bestie: this one comes from Debian, dated March 22, 2002, and it’s the GETCAP(3) man page. Byeeee πŸ’…πŸ«Ά

πŸ“¦ where this page comes from
  • freebsd 15.1: base 15.1
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms