Skip to content

Latest commit

 

History

History
1668 lines (1265 loc) · 52.4 KB

unsorted.asc

File metadata and controls

1668 lines (1265 loc) · 52.4 KB

unsorted

ALIGN

__

macros for alignment.
 They take a number or pointer, and align upwards to 2,4,8,..256
 There are the macros ALIGN_2 ALIGN_4 ALIGN_8 ...,
 and ALIGN_P, which aligns to the size of a pointer. (8 for amd64)
OPTFENCE

#ifndef clang

prevent gcc to optimize away registers and variables
 the macro OPTFENCE(...) can be invoked with any parameter.
 The parameters will get calculated, even if gcc doesn't recognize
 the use of the parameters, e.g. cause they are needed for an inlined asm syscall.

 The macro translates to an asm jmp and a function call to the function
 opt_fence, which is defined with the attribute "noipa" -
 (the compiler "forgets" the function body, so gcc is forced
 to generate all arguments for the function)
 The generated asm jump hops over the call to the function,
 but this gcc doesn't recognize.

 This generates some overhead,
 (a few (never reached) bytes for setting up the function call, and the jmp)
 but I didn't find any other solution,
 which gcc wouldn't cut for optimizations from time to time.
 (volatile, volatile asm, optimize attributes,
 andsoon have all shown up to be unreliable - sometimes(!)).

 Had some fun debugging these bugs, which naturally showed up only sometimes.
 (Many syscalls also work with scrambled arguments..)
 And, I believe it IS a compiler bug.
 Volatile should be volatile for sure, not only sometimes.
 I mean, why the heck do I write volatile??
OPTIMIZATIONS

__

enable some optimizations,
 with a slitghtly bigger memory footprint.
 defaults to off
 (yet only calloc is optimized. todo)
_die

void _die()

internal implementation of die
_match

int _match(char *text, const char *re, text_match *st_match)
../src/match/match.c l.96

_match_ext2

char* _match_ext2(char *text, char *re, void(*p_matched_cb)(int number, char *pos,int len), int(*p_wildcard_cb)(int number, char *match_char), text_match *st_match)

internal implementation of match_ext
accept

int accept( int fd, struct sockaddr *upeersockaddr, int *upeeraddrlen)
../include/syscall_stubs.h l.247 manpage: accept

assert

__
Defines: kill getpid memcpy write rt_sigaction
../macros/assert.h l.4

bind

int bind( int fd, struct sockaddr *umyaddr, int addrlen)
../include/syscall_stubs.h l.241 manpage: bind

bsd_cksum

unsigned int bsd_cksum( const char* p, unsigned int len )

bsd checksum
bsd_cksumblock

unsigned int bsd_cksumblock( unsigned int hash, const char* p, unsigned int len )

bsd checksum, called by bsd_cksum,
 with initial hash value
bsd_definitions

__

definitions, found at BSD
 enable with mini_bsd_definitions
bsd_timespec

__

timespec functions, copied from freebsd
bsearch

void* bsearch(const void *key, const void *base0, size_t nmemb, size_t size, int (*compar)(const void *, const void *))

search for an element
 code is copied from netbsd
calloc

void* calloc(int nmemb, int size)
../src/memory/calloc.c l.2 manpage: calloc

cfmakeraw

void cfmakeraw(struct termios tp)
*Defines:
termio
../src/termios/cfmakeraw.c l.3 manpage: cfmakeraw

config

__

configuration settings, to be compiled statically.
 System specific paths, maximums, etc go here.
 Other values are within globaldefs.h;
 architecture specific values are within the folder headers.
ctype_functions

#ifdef mini_ctype_functions

create functions instead of macros for isalpha, .., isprint
 the ctype macros are defined also without being explicitely enabled.
def

#define SETOPT_short( opts, option ) (

Set a option flag(s) (bit(s))  manually.
		param options: e.g. just a, or ( a+h+l) to check for several flags at once
die

#define die(errnum,msg) {ewritesl(msg);exit_errno(errnum);}
Defines: execve errno_str exit write

write msg to stderr and exit with failure
 if errno is defined and set, /bin/errno is executed to give a verbose error
 message
 if errno is either not defined or not set,
 exit with -1
die_if

#define die_if( when, errnum, msg ) if( when ) die( errnum, msg )
Defines: write execve errno_str exit

when arg1 is true, write msg to stderr and exit with failure
 if errno is defined and set, /bin/errno is executed to give a verbose error
 message
 if errno is either not defined or not set,
 exit with -1
dief

#define dief(errnum,fmt,…​) {fprintf(stderr,fmt,VA_ARGS);exit_errno(errnum);}
Defines: getpid fileno write kill errno_str exit execve strlen globals

write fmt andargs via fprintf to stderr and exit with failure
 if errno is defined and set, /bin/errno is executed to give a verbose error
 message
 if errno is either not defined or not set,
 exit with -1
dief_if

#define dief_if( when, errnum, fmt,…​ ) if( when ) dief( errnum, fmt, VA_ARGS )
Defines: write exit errno_str execve

when arg1 is true, vall dief(errnum,fmt)
 if errno is defined and set, /bin/errno is executed to give a verbose error
 message
 if errno is either not defined or not set,
 exit with -1
dies

#define dies(errnum,…​) {eprintsl(VA_ARGS);exit_errno(errnum);}
Defines: execve errno_str exit write

write variable string list to stderr and exit with failure
 if errno is defined and set, /bin/errno is executed to give a verbose error
 message
 if errno is either not defined or not set,
 exit with -1
dies_if

#define dies_if( when, errnum, …​ ) if( when ) dies( errnum, VA_ARGS )
Defines: exit errno_str execve write

when arg1 is true, vall dies(errnum, ... )
 if errno is defined and set, /bin/errno is executed to give a verbose error
 message
 if errno is either not defined or not set,
 exit with -1
dirbuf_malloc

#ifndef mini_dirbuf_malloc

which malloc to use for allocating the dir handles
 malloc : use malloc, therefore the minibuf
 malloc_brk : use malloc_brk
 defaults to malloc
eprintf

#define eprintf(fmt,…​) fprintf(stderr, fmt, VA_ARGS)
Defines: strlen write fileno

write fmt and arguments to stderr.
err

#define err( status, fmt …​ ) { fprintf(stderr,fmt ); fprints(stderr,":",strerror(errno)); exit(status); }
Defines: kill exit strlen globals getpid strerror errno write fileno

print an error message to stderr,
 print an error message dependend on errno ( strerror(errno) ),
 exit with status

../src/process/error.h l.20 manpage: err

error

#define error( status, errnum, fmt …​ ) { fprintf(stderr,fmt ); if (errnum) fprints(stderr,":",strerror(errnum)); if ( status ) exit(status); }
Defines: exit kill strlen globals getpid strerror fileno write

print an error message to stderr
 when errnum is not 0, print either the number,
  or a verbose error message (with strerror),
  when mini_verbose_errstr is defined.
  (verbose error messages add aboyut 4kB)

 when status is non null, terminate with status
errx

#define errx( status, fmt …​ ) { fprintf(stderr,fmt); exit(status); }
Defines: kill exit strlen globals getpid write fileno

print an error message to stderr,
 exit with status
ether_ntoa

char* ether_ntoa( const struct ether_addr e )
*Defines:
network
../src/network/ether_ntoa.c l.3 manpage: ether_ntoa

ewritesl

#define ewritesl(str) write(STDERR_FILENO,str"\n",sizeof(str)+1)
Defines: write

write the constant str to stderr, followed by a newline.
 Computes length with sizeof(str) at compile time.
fgetsn

int fgetsn(char buf, int size, FILE F)
Defines: read fileno

get a line like fgets, but return the len of the read string.
fgetsp

char* fgetsp(char buf, int size, FILE F)
Defines: read fileno

read a line from F into buf with max chars size.
 Return a pointer to the terminating '0' byte.
 A terminating linebreak is not written to buf.
fgetud

unsigned int fgetud(FILE* F)
Defines: read fileno

read an unsigned integer from the stream F
 reads all digits until a nondigit is read.
fgetul

unsigned long int fgetul(FILE* F)
Defines: fileno read

read an unsigned long integer from the stream F
 reads all digits until a nondigit is read.
flock

int flock( unsigned int fd, unsigned int cmd)
../include/syscall_stubs.h l.130 manpage: flock

fwritesl

#define fwritesl(fd,str) write(fd,str"\n",sizeof(str)+1)
Defines: write

write the constant str to fd,followed by a newline.
 Computes length with sizeof(str) at compile time.
getegid

int DEF_syscall(getegid,0)
../include/syscall_stubs.h l.215 manpage: getegid

geteuid

int DEF_syscall(geteuid,0)
../include/syscall_stubs.h l.213 manpage: geteuid

getgrouplist

int getgrouplist(const char* user, gid_t group, gid_t groups, int *ngroups)
*Defines:
grent token_i userdb passwdfile_open setpwent pwent setgrent token_s write open mmap

needs rewrite.
 now nonstandard.
getgroups

int getgroups(int maxgroups, int list)
*Defines:
token_s write open mmap getuid grent token_i userdb passwdfile_open setpwent pwent setgrent

get the groups of the calling process
 does not necessarily contain the primary group,
 which is given in the passwd entry.
 This function calls internally setgrent() and getgrent();
 therefore any iteration with getgrent will be resetted.
gethostname

int gethostname(char name,int len)
*Defines:
network uname

gethostname
getresuid

int getresuid( uid_t *ruid, uid_t *euid, uid_t *suid)
../include/syscall_stubs.h l.210 manpage: getresuid

getrlimit

int getrlimit( unsigned int resource, struct rlimit *rlim)
../include/syscall_stubs.h l.231 manpage: getrlimit

getrusage

int getrusage( int who, struct rusage *ru)
../include/syscall_stubs.h l.142 manpage: getrusage

getsid

int getsid( pid_t pid)
../include/syscall_stubs.h l.164 manpage: getsid

getsockopt

int getsockopt( int fd, int level, int optname, char *optval, int *optlen)
../include/syscall_stubs.h l.245 manpage: getsockopt

getusergroups

int getusergroups(const char* user, int maxgroups, int list)
*Defines:
userdb passwdfile_open pwent setpwent setgrent grent token_i mmap token_s write open

get the supplementary groups for the user uid.
 does not necessarily contain the primary group,
 which is given in the passwd entry.
 This function calls internally setgrent() and getgrent();
 therefore any iteration with getgrent will be resetted.
group_printf

//
Defines: getpid fileno write itooct uitohex atoi globals uitodec uitoHEX ultodec kill strlen

printf, eprintf, fprintf, itodec, ltodec, itohex, anprintf, sprintf (conversions %d %l %x %ud %ul %ux ),
htonl

uint32_t htonl(uint32_t i)
Defines: network
../src/network/htonl.c l.5 manpage: htonl

htons

uint16_t htons(uint16_t i)
Defines: network
../src/network/htons.c l.3 manpage: htons

inet_aton

int inet_aton(const char* s, struct in_addr addr)
*Defines:
network
../src/network/inet_aton.c l.3 manpage: inet_aton

inet_ntoa

char* inet_ntoa( struct in_addr in)
Defines: network

convert a address
 This returns a pointer to a string in the globals,
 therefore the routine isn't reentrant.
 (whoever thought this might be a good idea..)
initgroups

int initgroups(const char* user, gid_t group)
../src/userdb/initgroups.c l.2 manpage: initgroups

killpg

int killpg( int pid, int signal )
../src/process/killpg.c l.2 manpage: killpg

listen

int listen( int fd, int backlog)
../include/syscall_stubs.h l.248 manpage: listen

locale_dummies

__

several dummy definitions,
 mostly locale related.
 (locales are not the target of minilib,
 so define mini_dummies to have code relying on locales
 running)
 Quite often some code does only checking for locales,
 but doesn't rely on them.
lstat

int lstat(const char* filename,struct stat* statbuf)
../include/syscall_stubs.h l.113 manpage: lstat

match_ext

int match_ext(char *text, const char *re, void(*p_match)(int number, char *pos,int len, void *userdata), int(*p_match_char)(int number, char *match_char, void *userdata), tmatch_ext *st_match, void *userdata)

text matching engine

 This is somewhere between a fully fledged expression machine,
 and a simplicistic solution.
 Consciusly named 'text matching', since the inherent logic
 is quite different to a regular expression machine.

 The engine matches from left to right,
 backtracking is done as less as possible.
 Since the matching is nongreedy in general,
 many tries can be spared. Opposed to another route,
 where most patterns are per default greedy, and therfore
 not the first matching next char is seeked for, but the first
 solution while matching the most chars.
 (I do not want to make this a hard statement, and it
 depends onto each pattern. But it is the way, the solution
 of the pattern is searched for, in most patterns.)
 This shows up in the logic of the patterns, which is more natural to me.

 It is a compromise between performance, size
 and capabilities.
 The logic is different of a "regular" regular expression
 machine, but has advantages (and disadvantages).
 I'd say, the main advantage is the easiness of adding callbacks,
 and defining your own matching/logic within these.
 Performance might be better as well overall,
 but this depends also on the expressions.

 A few nonextensive benchmarks show,
 this engine is a bit faster than perl's regular expression machine,
 slower than gnu grep (around factor2), and has the same speed as sed.
 This might however vary with each usecase.
 In favor of codesize I'm not going to optimize match_ext,
 but there would be several possibilities, if you'd need a faster engine.
 (Albite I'd like to emphasise, sed (and match_ext), also perl, are quite fast.
 About 10 times faster than most expression engines.)

 matches:

 * for every count of any char
 + for 1 or more chars
 ? for 1 char
 # for space or end of text (0)
 $ match end of text

 backslash: escape *,?,%,$,!,+,#,& and backslash itself.
 !: invert the matching of the next character or character class
 ,: separator. e.g. %,1 matches like ?*1.
   ( without the commata, the '1' would be part of the % match)


 predefined character classes:
 \d - digit
 \D - nondigit
 \s - space
 \S - nonspace
 \w - word character ( defined as ascii 32-126,160-255 )
 \W - nonword character ( defined as ascii 0-31,127-159 )


 [xyz]: character classes, here x,y or z
   the characters are matched literally, also \,*,?,+,..
   it is not possible to match the closing bracket (])
   within a character class

 {nX}: counted match
  Match n times X.
  For X, all expressions are allowed.
  If you need to match a number at the first char of 'X',
  separate X by a commata. E.g. {5,0} matches 5 times '0'.

 %[1]..%[9]: matches like a '+',
  and calls the callback supplied as 3rd argument (when not null).
  the number past the %, e.g. %1, is optional,
  p_match will be callen with this number
  as first parameter.
  When not supplied, p_matched will be callen with
  the parameter 'number' set to 0.

  The matching is 'nongreedy'.
  It is possible to rewrite the string to match
  from within the p_matched callback.
  This will not have an effect onto the current matching,
  even if text is e.g. deleted by writing 0's.
  The matched positions are called in reverse order.
  (The last matched % in the regex calls p_match first,
  the first % in the regex from the left will be callen last)

 supply 0 for p_matched, when you do not need to extract matches.
 This will treat % in the regex like a *,
 a following digit (0..9) in the regex is ignored.
 if the 5th argument, a pointer to a tmatch_ext struct,
 is supplied, it will be filled with the first match.
 (counting from left)


 &[1] .. &[9]
  "match" like a '?' and call p_match_char
  p_match_char has to return either RE_MATCH, RE_NOMATCH, RE_MATCHEND
  or a number of the count of chars, which have been matched.

  Therefore it is possible to e.g. rule your own
  character classes, defined at runtime,
  or do further tricks like changing the matched chars,
  match several chars, andsoon.
  When returning RE_NOMATCH,
  it is possible, the p_match and p_match_char callbacks are callen several times,
  but with different pos or len parameters.

  The matching works straight from left to right.
  So, a "*&*" will call the callback & for the first char.
  When returning RE_NOMATCH, the second char will be matched.
  Until either RE_MATCH is returned from the callback,
  or the last char has been matched.

  Matching several characters is also posssible from within the callback,
  the position within the text will be incremented by that number,
  you return from the callback.

  When returning RE_MATCHEND from the callback,
  the whole regular expression is aborted, and returns with matched;
  no matter, if there are chars left in the expression.


  The difference between % and & is the logic.
  % matches nongreedy, and has to check therefore the right side of the star
  for its matching.
  Possibly this has to be repeated, when following chars do not match.

  & is matched straight from left to right.
  Whatever number you return, the textpointer will be incremented by that value.
  However, a & isn't expanded on it's own. ( what a % is ).
  e.g. "x%x" will match 'aa' in xaax, x&x will match the whole expression
  only, when you return '2' from the callback.

  Performancewise, matching with & is faster,
  since the % has on its right side to be matched
  with recursing calls of match_ext.

 When using closures for the callbacks, you will possibly have to
 enable an executable stack for the trampoline code
 of gcc. Here, gcc complains about that.
 For setting this bit, have a look into the ldscripts in the folder
 with the same name.

 supply 0 for p_match_char, when you don't need it.
 This will treat & in the regex like ?,
 and match a following digit (0..9) in the text,
 a following digit (0..9) in the regex is ignored.

 -----
 In general, you have to somehow invert the logic of regular expressions
 when using match_ext.
 e.g. when matching the parameter 'runlevel=default' at the kernel's
 commandline, a working regular expression would be
 "runlevel=(\S*)". This could be written here as "*runlevel=%#".
 For matching e.g. numbers, you'd most possibly best of
 with writing your own & callback.

 returns: 1 on match, 0 on no match
 ( RE_MATCH / RE_NOMATCH )

 if the pointer (argument 5) st_match is nonnull,
 the supplied struct tmatch_ext will be set to the first matching '%' location;
 if there is no match, tmatch_ext.len will be set to 0.
 The struct is defined as:
 typedef struct _tmatch_ext { char* pos; int len; } tmatch_ext;


 (memo) When the regex ist defined within C/cpp source code,
 a backslash has to be defined as double backslash.

 (note) - be careful when negating a following *, or ?.
  somehow - it is logical, but seems to me I overshoot a bit,
  tragically hit my own foot, and stumbled into a logical paradox.

  Negating EVERYTHING translates to true.
  However, since truth is negated as well, there's a problem,
  cause it's now 'false', but 'false' is true. This is very close
  to proving 42 is the answer. What is the escape velocity
  in km/s out of the solar system, btw.

  (I'm not kidding here. Just don't do a regex with !* or !?..
  And, please, do not ask me what is going to happen when the impossible
  gets possibilized. I have to point at the according sentences of the BSD license;//  there is NO WARRANTY for CONSEQUENTIAL DAMAGE, LOSS OF PROFIT, etc pp.)

  A "!+" will translate into nongreedy matching of any char, however;
  "%!+" will match with % everything but the last char;
  while "%+" matches with % only the first char.
  !+ basically sets the greedyness of the left * or % higher.
match_ext2

int match_ext2(char *text, char *re, void(*p_matched_cb)(int number, char *pos,int len), int(*p_wildcard_cb)(int number, char *match_char),text_match *st_match)

text matching engine

 WORK IN PROGRESS, please use ext_match
 Atm, please nested brackets are featureful.
 nesting {} within () seems to work.
 Nesting round brackets within {} gives sometimes
 trouble, when wildcards are used within the brackets.
 I'm leaving this at it is for now.
 Possibly I'm going to hardcode an error message for nested brackets,
 or nested brackets with wildcards.

 This is somewhere between a fully fledged expression machine,
 and a simplicistic solution.
 Consciusly named 'text matching', since the inherent logic
 is quite different to a regular expression machine;
 "natural expressions" might fit better for the name.

 The engine matches from left to right,
 backtracking is done as less as possible.
 Since the matching is nongreedy in general,
 many tries can be spared. Opposed to another route,
 where most patterns are per default greedy, and therfore
 not the first matching next char is seeked for, but the first
 solution while matching the most chars.
 (I do not want to make this a hard statement, and it
 depends onto each pattern. But it is the way, the solution
 of the pattern is searched for, in most patterns.)
 This shows up in the logic of the patterns, which is more natural to me.
 Your mileage might vary.


 It is a compromise between performance, size
 and capabilities.
 The logic is different of a "regular" regular expression
 machine, but has advantages (and disadvantages).
 I'd say, the main advantage is the easiness of adding callbacks,
 and defining your own matching/logic within these.
 Performance might be better as well overall,
 but this depends on the expressions and usecases as well.

 Yet I for myself have to get a grip of the possibilities of this engine.
 However, I have the feeling, the logic is much more natural.
 With regular regexes you always have to think kind of 'backwards',
 e.g., match ".*" -> match "." (any char) x times.
 gets to a simple "*"
 or, to match all group and user id's of /etc/passwd,
 a regular expression would be: "(\d*):(\d*)"
 This is here: "*(\d*):(\d*)*"
 The content in the brackets looks the same,
 but it's matched quite different.
 The regular expression (the first) matches x times \d, for x>=0.
 In the second expressin, the ext_match expression,
 the first digit is matched, and then nongreedy any chars, until
 the first occurence of ':'.
 It is another logic. Whether it suits you, you have to decide.

 The callbacks have shown up to be a mighty tool, while
 at the same time having a good performance.


 A few nonextensive benchmarks show,
 this engine is a bit faster than perl's regular expression machine,
 slower than gnu grep (around factor2), and has the same speed as sed.
 This might vary with each usecase, but the callbacks for extracting matches
 have some advantage, as well as the strict left to right and nongreedy parsing.

 In favor of codesize I'm not going to optimize ext_match,
 but there would be several possibilities, if you'd need a faster engine.
 (Albite I'd like to emphasise, sed (and ext_match), also perl, are quite fast.
 About 5 to 10 times faster than most expression engines.)

 matches:

 * for every count of any char
 + for 1 or more chars
 ? for 1 char
 # for space, end of text (\0), linebreak, tab ( \t \n \f \r \v )
 @ matches the beginning of the text or endofline (\n)
 $ match end of text (\0) or linebreak

 backslash: escape *,?,%,@,$,!,+,#,& and backslash itself.
 !: invert the matching of the next character or character class
 ,: separator. e.g. %,1 matches like ?*1.
   ( without the commata, the '1' would be part of the % match)


 predefined character classes:
 \d - digit
 \D - nondigit
 \s - space
 \S - nonspace
 \w - word character ( defined as ascii 32-126,160-255 )
 \W - nonword character ( defined as ascii 0-31,127-159 )
 \x - hexadecimal digit (0-9,a-f,A-F)


 [xyz]: character classes, here x,y or z
   the characters are matched literally, also \,*,?,+,..
   it is not possible to match the closing bracket (])
   within a character class

 {nX}: counted match
  Match n times X.
  For X, all expressions are allowed.
  If you need to match a number at the first char of 'X',
  separate X by a commata. E.g. {5,0} matches 5 times '0'.
  n can be a number, * or +.
  ('*' matches 0 or more, '+' 1 or more times)

 (X): match the subexpression X. atm, no nesting of round () and {} brackets allowed

 %[1]..%[9]: matches like a '+',
  and calls the callback supplied as 3rd argument (when not null).
  the number past the %, e.g. %1, is optional,
  p_matched_cb will be callen with this number
  as first parameter.
  When not supplied, p_matched_cb will be callen with
  the parameter 'number' set to 0.

  The matching is 'nongreedy'.
  It is possible to rewrite the string to match
  from within the p_matched_cb callback.
  This will not have an effect onto the current matching,
  even if text is e.g. deleted by writing 0's.

  The matched positions are called in reverse order.

  (The last matched % in the regex calls p_matched_cb first,
  the first % in the regex from the left will be callen last)
  / The regex is first matched; when the regex has matched,
  the %'s are filled/ the callbacks executed.
  (x) bracketed patterns are matched the same way.

  (Not like &, which callbacks are invoked, while matching)

 supply 0 for p_matched_cb, when you do not need to extract matches.
 This will treat % in the regex like a *,
 a following digit (0..9) in the regex is ignored.
 if the 5th argument, a pointer to a text_match struct,
 is supplied, it will be filled with the first match.
 (counting from left)


 &[1] .. &[9]
  "match" like a '?' and call p_wildcard_cb
  p_wildcard_cb has to return either RE_MATCH, RE_NOMATCH, RE_MATCHEND
  or the number of the count of chars, which have been matched.

  Therefore it is possible to e.g. rule your own
  character classes, defined at runtime,
  or do further tricks like changing the matched chars,
  match several chars, andsoon.
  When returning RE_NOMATCH,
  it is possible, the p_wildcard_cb callback is callen several times,
  but with different pos or len parameters, since p_wildcard_cb is
  invoked while matching.

  The matching works straight from left to right.
  So, a "*&*" will call the callback & for the first char.
  When returning RE_NOMATCH, the second char will be tried to match.
  Until either RE_MATCH is returned from the callback,
  or the last char of the text has been tried to match.

  Matching several characters is also posssible from within the callback,
  the position within the text will be incremented by that number,
  you return from the callback.

  When returning RE_MATCHEND from the callback,
  the whole expression is aborted, and returns with matched;
  no matter, if there are chars left in the expression.


  The difference between % and & is the logic.
  % matches nongreedy, and has to check therefore the right side of the star
  for its matching.
  Possibly this has to be repeated, when following chars do not match.

  & is matched straight from left to right.
  Whatever number you return, the textpointer will be incremented by that value.
  However, a & isn't expanded on it's own. ( what a % is ).
  e.g. "x%x" will match 'aa' in xaax, x&x will match the whole expression
  only, when you return '2' from the callback.

  Performancewise, matching with & is faster,
  since the % has on its right side to be matched
  with recursing calls of ext_match.

 When using closures for the callbacks, you will possibly have to
 enable an executable stack for the trampoline code
 of gcc. Here, gcc complains about that.
 For setting this bit, please have a look into the ldscripts in the folder
 with the same name.

 supply 0 for p_wildcard_cb, when you don't need it.
 This will treat & in the regex like ?,
 and match a following digit (0..9) in the text,
 a following digit (0..9) in the regex is ignored.

 -----
 In general, you have to somehow invert the logic of regular expressions
 when using ext_match.
 Regular expressions could be regarded as "polish rpn notation",
 first the char to be matched, then the count.
 This expression machine could be described as "natural expression" machine.
 First you define the number, then the chars or expression to be matched.

 Furthermore, *,% and + match as less as possible.
 You have to think about what needs to follow the wildcards.

 e.g. when matching the parameter 'runlevel=default' at the kernel's
 commandline, a working regular expression would be
 "runlevel=(\S*)". This could be written here as "*runlevel=%#".
 For matching e.g. numbers, you'd most possibly best of
 with writing your own & callback.

 returns: 1 on match, 0 on no match
 ( RE_MATCH / RE_NOMATCH )

 if the pointer (argument 5) st_match is nonnull,
 the supplied struct text_match will be set to the first matching '%' location;
 if there is no match, text_match.len will be set to 0.
 The struct is defined as:
 typedef struct _text_match { char* pos; int len; } text_match;


 (memo) When the regex ist defined within C/cpp source code,
 a backslash has to be defined as double backslash.

 (note) - be careful when negating a following *, or ?.
  somehow - it is logical, but seems to me I overshoot a bit,
  tragically hit my own foot, and stumbled into a logical paradox.

  Negating EVERYTHING translates to true.
  However, since truth is negated as well, there's a problem,
  cause it's now 'false', but 'false' is true. This is very close
  to proving 42 is the answer. What is the escape velocity
  in km/s out of the solar system, btw.

  (I'm not kidding here. Just don't do a regex with !* or !?..
  And, please, do not ask me what is going to happen when the impossible
  gets possibilized. I have to point at the according sentences of the BSD license;
  there is NO WARRANTY for CONSEQUENTIAL DAMAGE, LOSS OF PROFIT, etc pp.)

  A "!+" will translate into nongreedy matching of any char, however;
  "%!+" will match with % everything but the last char;
  while "%+" matches with % only the first char.
  !+ basically sets the greedyness of the left * or % higher.

 (work in progress here) please use ext_match
 return 0 for nomatch, the current textpos ( >0 ) for a match
 With the exception of an empty text, matched by e.g. "*".
 This will return 0, albite the regex formally matches, with 0 chars.

 (todo)
 bracket matching () and {} needs debugging. (test/extmatch2 for testing)
 Add a callback for bracket matches, and add a matchlist
 (linked list, allocated with malloc_brk)
 Trouble: e.g. *:(*) doesn't match, albite it should
  .. better. Now: # matches the end, after a bracket. Like it should
   $ doesn't. But should as well.
 change '+' to greedy matching of any char
 for {n,X} let n be * or + as well.
  (this would be closer to regular regulars again.?.)


 note. About a tokenizer:
 matching quoted string is really easy with the callback structure:
  just match with &. When a quote is matched, look forward to the next quote,
  and return that many chars. Same time, the quoted string is matched.
  That's so easy, it is hard to believe.
  When using closures for that, it is same time easy to collect all tokens.

  It is even easier. just a "*("*")*" is enough.

  ->There is something needed for partial matching. Possibly spare the last *, and return,
  as soon the pattern is at it's end (and not the text?)
  Already works this way.

  Should start to define the language for the init scripts.
  Or better, start thinking abut that, but follow my other obligations the next time.

  Have to think thouroughly about what points would make such a language useful.
  The reason to think about that is clear - performance squeezing, faster startup time.
  And writing the startup scripts in C is. Well. little bit painful.
  However, together with minilib, there is nearly no difference between having a C program compiled
  and run, or working with scripts. To not have the overhead of linking the external libraries in,
  is of quite some advance.
  The only difference, the compiled binaries are "cached".
  have just to sort something sensible out for the systematic.
  Implement an own loader? possibly easy. Since the loading address is fixed.
  This could possibly also be the solution for the yet unclear question of the line between parsing
  arguments and calling the main function of the small core tools, andsoon.

 ..yet I've to fiddle out the possibilities (and quirks) of this machine.
 seems, this expression language did overpower it's creator.

 Bugs (features):
 matching e.g. *matches*@*doesn't match*
 potentiates the *@* to many possibilities.
 One for every linebreak following 'matches'.
memchr

void* memchr(const void *s, int c, unsigned int n)
../src/memory/memchr.c l.2 manpage: memchr

msync

int msync( void* addr, size_t len, int flags)
../include/syscall_stubs.h l.262 manpage: msync

network

__

network definitions
ntohl

#define ntohl(i) htonl(i)
../src/network/ntohl.h l.2 manpage: ntohl

ntohs

#define ntohs(i) htons(i)
Defines: network
../src/network/macros.h l.2 manpage: ntohs

optimization_fence

void optimization_fence(void*p)

prevent optimizations.
 cast a var to void*, and calling this,
 leaves the compiler unknown on what he can strip.
 The function attribute noipa means,
 the compiler doesn't know, what the function itself does.
 (the function does nothing, but don't tell that gcc, please..)
 therefore, everything used as parameter to this function,
 will be calculated, defined, and so on before.
 It's used for the globals,
 shich are pushed within _start onto the stack.
 since _start itself only provides a global pointer,
 and initialitzes some of the globals,
 but doesn't use them again,
 this construction is needed.
 more funnily, the function will never be called.
 It's past the asm inline syscall to exit.
 But again, luckily gcc doesn't know.
 All other options, like having the globals volatile,
 setting the optimization flag of _start to 0,
 having a volatile asm call with the globals as param, and so on,
 have been useless. All after all, seems to me, ai has it's restrictions.

 With less overhead the macro OPTFENCE(...) goes.
 There the call to the "ipa" function is jumped over,
 via asm inline instructions.
 Doesn't work with clang.
 But yet I also didn't it with clang.
poll

int poll(struct pollfd *fds, nfds_t cnt, int timeout)
../include/poll.h l.25 manpage: poll

prctl

int prctl( int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5)
../include/syscall_stubs.h l.274

pwent

__

define passwd and group structures
qsort

void qsort(void base, size_t nel, size_t width, int (*comp)(const void *, const void *))
*Defines:
swap

(quick) shell sort routine
 following the tradition, this isn't exactly a quicksort algorithm,
 albite named quicksort.
 It is a shell sort implementation, originally done by Ray Gardner, 5/90;
 which in turn I did find within musl.

../src/sort/qsort.c l.35 manpage: qsort

recv

int recv(int sockfd, void buf, size_t len, int flags)
*Defines:
recvfrom
../src/network/recv.c l.3 manpage: recv

recvfrom

int recvfrom( int fd, void *ubuf, size_t size, unsigned flags, struct sockaddr *addr, unsigned int *addr_len)
../include/syscall_stubs.h l.236 manpage: recvfrom

rt_sigsuspend

int rt_sigsuspend( const sigset_t *mask, size_t sigsetsize)
../include/syscall_stubs.h l.188

sendto

int sendto( int fd, void *buff, size_t len, unsigned flags, struct sockaddr *addr, int addr_len)
../include/syscall_stubs.h l.239 manpage: sendto

setbrk

int setbrk(long addr)
Defines: sys_brk

set the current brk
 wrapper for brk(), with type of brk changed to long
setenv

int setenv( const char name, const char *value, int overwrite )
*Defines:
stpcpy strcpy ret_errno strlen 0 environ

put a string into the environmental vars
 UNTESTED (!) TODO
 the supplied string's pointer is put into the environmental array of pointers.
 The supplied strings are copied into memory.
 If overwrite is zero, an existing environmental variable is not overritten.
 If overwrite is 1, the environmental variable is overwritten,
 but not(!) freed from memory.
 The supplied value is not checked for e.g. an '='

 Returns:
 - 0 on success
 - EINVAL on error
setresuid

int setresuid( uid_t *ruid, uid_t *euid, uid_t *suid)
../include/syscall_stubs.h l.211 manpage: setresuid

setreuid

int setreuid( uid_t ruid, uid_t euid)
../include/syscall_stubs.h l.163 manpage: setreuid

setrlimit

int setrlimit( unsigned int resource, struct rlimit *rlim)
../include/syscall_stubs.h l.232 manpage: setrlimit

setsockopt

int setsockopt( int fd, int level, int optname, const void *optval, int optlen)
../include/syscall_stubs.h l.243 manpage: setsockopt

short_errstr

const char* short_errstr(int num)

short error (errno) string.
 this adds about 2kB to the compiled binary(!)
sigsuspend

int sigsuspend( const sigset_t mask )
*Defines:
rt_sigsuspend
../src/process/sigaction.c l.53 manpage: sigsuspend

snprintfs

int snprintfs( char* buf, int size, char *fmt, …​)

prints formatted and unbuffered output into buf.
 only %s and %c are recognized.
 snprintfs instead of snprintf can save some bytes.
 untested
socket

int socket( int family, int type, int protocol)
../include/syscall_stubs.h l.229 manpage: socket

stpcpy

char *stpcpy(char *dest, const char *src)

copy src to dest, return a pointer to the last char +1 ( ending '0' )
stplcpy

char *stplcpy(char *dest, const char *src, int size)

copy src to dest, return a pointer to the last char +1 ( ending '0' )
 doesn't pad dest with 0, when size<src;
stpncpy

char *stpncpy(char *dest, const char *src, int size)

copy src to dest, return a pointer to the last char +1 ( ending '0' )
 Please note stplcpy (terminology borrowed from freebsd),
 which does the same,
 but doesn't pad dest with 0's.
strcspn

int strcspn(const char *s1, const char *s2)

look for the first place in s1,
 containing one of the chars of s2.
 Optimizes a bit (+16Bytes code),
 when OPTIMIZE is defined
strlcpy

char *strlcpy(char *dest, const char *src, int n)

copy max n chars from src to dest,
 when src is longer than dest,
 end dest[n-1] with '\0'.
strncat

char* strncat( char* dst, const char* src, unsigned int n)
../src/string/strncat.c l.2 manpage: strncat

strndup

char strndup(const char *source, int maxlen)
*Defines:
stplcpy strlen 0
../src/string/strndup.c l.5 manpage: strndup

strnlen

int strnlen(const char*str, int max)

return len of str.
 if str points to 0, return 0
 if no 0 is within max chars of str,
 return max
strpbrk

char* strpbrk(const char* s, const char* charset)
../src/string/strpbrk.c l.2 manpage: strpbrk

strspn

int strspn(const char *s1, const char *s2)
../src/string/strspn.c l.2 manpage: strspn

strtoimax

int strtoimax(const char *c, const char **endp, int base)

conversion
strtok

char* strtok(char s, const char *delim)
*Defines:
strtok_r
../src/string/strtok.c l.3 manpage: strtok

strtok_r

char* strtok_r(char *s, const char *delim, char **last)
../src/string/strtok_r.c l.2 manpage: strtok_r

strtoll

long long int strtoll(const char c, const char **endp, int base)
*Defines:
strtol

conversion
 doesn't check for overflow(!)
 For linux x64, long long and long both have 64 bit.
 Therefore, strtoll just calls strtol
sys_signame

_const char* sys_signame[] = _

abbreviated signal names, according to BSD > 4.2
tcgetpgrp

int tcgetpgrp(int fd)
../src/termios/tcgetpgrp.c l.2 manpage: tcgetpgrp

tcsetpgrp

int tcsetpgrp(int fd, int pgrp)
../src/termios/tcsetpgrp.c l.2 manpage: tcsetpgrp

term_width

int term_width()
Defines: environ termio

get the terminal width
 reads the environmental var COLS,
 if not present, returns 80.
 Doesn't check for the existence of a terminal.
termio

__

termios structures and definitions
timerfd_create

int timerfd_create( int clockid, int flags)
../include/syscall_stubs.h l.268

timerfd_gettime

int timerfd_gettime( int ufd, struct itimerspec *otmr)
../include/syscall_stubs.h l.272

timerfd_settime

int timerfd_settime( int ufd, int flags, const struct itimerspec *utmr, struct itimerspec *otmr)
../include/syscall_stubs.h l.270

times

int times( struct tms *info)
../include/syscall_stubs.h l.149 manpage: times

token_i

int token_i( userdb* udb, char **p )
../src/userdb/userdb.c l.33

token_s

char *token_s( userdb *udb, char **p )

tokenizer for the passwd/group files.
 used by the group/user pwentry access functions.
 performance of subsequent calls could be improved by replacing all ':' and '\n'
 by 0's when loading the db file.
 it would be possible as well, testing not only single bytes, but
 integers of longs at once. However, in most cases, e.g.
 for big directories with many small files, in most cases
 all files do have the same owner and group. Since the last result to calls
 of the access functions is cached,
 there wouldn't be an improvement by optimizing the tokenizing functions.
 So I'm leaving this for now, as it is.
 And most possibly it would be better to implement bsd's cached versions
 of the user db access functions instead.
unsetenv

int unsetenv( char name)
*Defines:
ret_errno environ

remove a string from the environmental vars
 The env var is not free'd. (It's not possible,
 since we don't know whether the string has been allocated
 with malloc or has been setup by the system )
 Returns:
 - 0 on success,
 - EINVAL: string was 0, did contain a '=', some other error
userdb_open

int userdb_open(userdb udb, const char file)
Defines: fstat close write globals
../src/userdb/userdb_open.c l.3

warn

#define warn( fmt …​ ) { fprintf(stderr,fmt ); }
Defines: write fileno strlen globals getpid kill

print an error message to stderr
where

int where(const char file,char *buf)
*Defines:
access environ

locate an executable in PATH
writesl

#define writesl(str) write(STDOUT_FILENO,str "\n",sizeof(str)+1)
Defines: write

write the constant str to stdout, followed by a newline.
 Computes length with sizeof(str) at compile time.