GETCAP(3)
π 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 keepbufalive through all your later calls tocgetmatch(),cgetcap(),cgetnum(),cgetstr(), andcgetustr(). after that you canfree(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 unresolvedtcexpansion-1β the requested record could not be found π-2β a system error happened (couldn't open/read a file, etc.) and it also setserrno-3β a potential reference loop was detected (see thetc=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 thecgetent()call. - if you're doing sequential access (see below), it must be called before the first sequential access call (
cgetfirst()orcgetnext()), or be directly preceded by acgetclose()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 previouscgetfirst()orcgetnext()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 database1β successful return of a record with possibly more remaining (we have not reached the end of the database yet π)2β the record contains an unresolvedtcexpansion-1β a system error occurred-2β a potential reference loop is detected (seetc=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] capabilitynameis present [true]nameTvalueβ capability (name,T) has valuevaluename@β no capabilitynameexistsnameT@β 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 typeTforname - the capability
:name@:will prevent any following values ofnamefrom 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=baroverrides the definition offript=foointerpolated from the capability recordoldinfile2πwho-cares@prevents the definition of anywho-caresdefinitions inoldfrom being seenglork#200is inherited fromold- and
blahplus anything defined by the recordextensionsis added to those definitions inold
πΈ note that the position of thefript=barandwho-cares@definitions beforetc=oldis important here. if they were after, the definitions inoldwould 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=nameloops incgetent(). - 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
- Copyright (c) 1992, 1993 The Regents of the University of California. All rights reserved
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms