Begin working on Util man page

This commit is contained in:
Jordan Bancino 2022-11-25 21:54:57 +00:00
parent f07ea912b2
commit 6900d0649e
5 changed files with 100 additions and 79 deletions

83
man/man3/Util.3 Normal file
View file

@ -0,0 +1,83 @@
.Dd $Mdocdate: November 25 2022 $
.Dt UTIL 3
.Os Telodendria Project
.Sh NAME
.Nm Util
.Nd Some misc. helper functions that don't need their own headers.
.Sh SYNOPSIS
.In Util.h
.Ft unsigned long
.Fn UtilServerTs "void"
.Ft unsigned long
.Fn UtilLastModified "char *"
.Ft int
.Fn UtilMkdir "const char *" "const mode_t"
.Ft char *
.Fn UtilUtf8Encode "unsigned long"
.Ft char *
.Fn UtilStringDuplicate "char *"
.Ft char *
.Fn UtilStringConcat "char *" "char *"
.Ft int
.Fn UtilSleepMillis "long"
.Ft size_t
.Fn UtilParseBytes "char *"
.Ft ssize_t
.Fn UtilGetDelim "char **" "size_t *" "int" "FILE *"
.Ft ssize_t
.Fn UtilGetLine "char **" "size_t *" "FILE *"
.Sh DESCRIPTION
.Pp
This header holds a number of random functions related to strings,
time, and other tasks that don't require a full API, just one or
two functions. For the most part, the functions here are entirely
standalone, depending only on POSIX functions, however there are a
few that specifically utilize Telodendria APIs. Those are noted.
.Pp
.Fn UtilServerTs
gets the current time in milliseconds since the Unix epoch. This
uses
.Xr gettimeofday 2
and time_t, and converts it to a single number, which is then
returned to the caller. A note on the 2038 problem: as long as
sizeof(long) >= 8, that is, as long as the long datatype is 64 bits
or more, which it is on all modern 64-bit Unix-like operating
systems, then everything should be fine. Expect Telodendria on 32 bit
machines to break in 2038. I didn't want to try to hack together
some system to store larger numbers than the architecture supports.
We can always re-evaluate things over the next decade.
.Pp
.Fn UtilUtf8Encode
takes a UTF-8 codepoint and encodes it into a string buffer
containing between 1 and 4 bytes. The string buffer is allocated
on the heap, so it should be freed when it is no longer needed.
.Pp
.Fn UtilStringDuplicate
duplicates a NULL-terminated string, and returns a new string on the
heap. This is useful when a function takes in a string that it needs
to store for for long amounts of time, even perhaps after the
original string is long gone.
.Pp
.Fn UtilSleepMillis
sleeps the calling thread for the given number of milliseconds. It
occurred to me that POSIX does not specify a super friendly way to
sleep, so this is a wrapper around the POSIX
.Xr nanosleep 2
designed to make its usage much, much simpler.
.Pp
.Fn UtilLastModified
uses
.Xr stat 2
to get the last modified time of the given file. This is used
primarily for caching file data.
.Pp
.Fn UtilStringConcat
takes in two NULL-terminated strings and returns their concatenation.
It works a lot like
.Xr strcat 3 ,
but it takes care of allocating memory big enough to hold both
strings. One or both strings may be NULL. If a string is NULL, it
is treated like an empty string.
.Sh RETURN VALUES
.Pp
TODO

View file

@ -464,8 +464,6 @@ HttpServerWorkerThread(void *args)
HashMap *requestParams; HashMap *requestParams;
ssize_t requestPathLen; ssize_t requestPathLen;
int lineError = -1;
ssize_t i = 0; ssize_t i = 0;
HttpRequestMethod requestMethod; HttpRequestMethod requestMethod;
@ -484,13 +482,13 @@ HttpServerWorkerThread(void *args)
/* Get the first line of the request. /* Get the first line of the request.
* *
* Every once in a while, we're too fast for the client. When this * Every once in a while, we're too fast for the client. When this
* happens, UtilGetLine() sets lineError to EAGAIN. If we get * happens, UtilGetLine() sets errno to EAGAIN. If we get
* EAGAIN, then clear the error on the stream and try again * EAGAIN, then clear the error on the stream and try again
* after 1ms. This is typically more than enough time for the * after 1ms. This is typically more than enough time for the
* client to send data. */ * client to send data. */
firstRead = UtilServerTs(); firstRead = UtilServerTs();
while ((lineLen = UtilGetLine(&line, &lineSize, fp, &lineError)) == -1 while ((lineLen = UtilGetLine(&line, &lineSize, fp)) == -1
&& lineError == EAGAIN) && errno == EAGAIN)
{ {
clearerr(fp); clearerr(fp);
@ -571,7 +569,7 @@ HttpServerWorkerThread(void *args)
goto internal_error; goto internal_error;
} }
while ((lineLen = UtilGetLine(&line, &lineSize, fp, &lineError)) != -1) while ((lineLen = UtilGetLine(&line, &lineSize, fp)) != -1)
{ {
char *headerKey; char *headerKey;
char *headerValue; char *headerValue;

View file

@ -245,7 +245,7 @@ TelodendriaConfigParse(HashMap * config, LogConfig * lc)
GET_DIRECTIVE("max-cache"); GET_DIRECTIVE("max-cache");
ASSERT_NO_CHILDREN("max-cache"); ASSERT_NO_CHILDREN("max-cache");
ASSERT_VALUES("max-cache", 1); ASSERT_VALUES("max-cache", 1);
tConfig->maxCache = UtilStringToBytes(ArrayGet(value, 0)); tConfig->maxCache = UtilParseBytes(ArrayGet(value, 0));
GET_DIRECTIVE("federation"); GET_DIRECTIVE("federation");
ASSERT_NO_CHILDREN("federation"); ASSERT_NO_CHILDREN("federation");

View file

@ -263,7 +263,7 @@ UtilSleepMillis(long ms)
} }
size_t size_t
UtilStringToBytes(char *str) UtilParseBytes(char *str)
{ {
size_t bytes = 0; size_t bytes = 0;
@ -313,7 +313,7 @@ UtilStringToBytes(char *str)
} }
ssize_t ssize_t
UtilGetDelim(char **linePtr, size_t * n, int delim, FILE * stream, int *err) UtilGetDelim(char **linePtr, size_t * n, int delim, FILE * stream)
{ {
char *curPos, *newLinePtr; char *curPos, *newLinePtr;
size_t newLinePtrLen; size_t newLinePtrLen;
@ -321,7 +321,7 @@ UtilGetDelim(char **linePtr, size_t * n, int delim, FILE * stream, int *err)
if (!linePtr || !n || !stream) if (!linePtr || !n || !stream)
{ {
*err = EINVAL; errno = EINVAL;
return -1; return -1;
} }
@ -331,7 +331,7 @@ UtilGetDelim(char **linePtr, size_t * n, int delim, FILE * stream, int *err)
if (!(*linePtr = Malloc(*n))) if (!(*linePtr = Malloc(*n)))
{ {
*err = ENOMEM; errno = ENOMEM;
return -1; return -1;
} }
} }
@ -344,7 +344,6 @@ UtilGetDelim(char **linePtr, size_t * n, int delim, FILE * stream, int *err)
if (ferror(stream) || (c == EOF && curPos == *linePtr)) if (ferror(stream) || (c == EOF && curPos == *linePtr))
{ {
*err = errno;
return -1; return -1;
} }
@ -358,9 +357,9 @@ UtilGetDelim(char **linePtr, size_t * n, int delim, FILE * stream, int *err)
if (SSIZE_MAX / 2 < *n) if (SSIZE_MAX / 2 < *n)
{ {
#ifdef EOVERFLOW #ifdef EOVERFLOW
*err = EOVERFLOW; errno = EOVERFLOW;
#else #else
*err = ERANGE; errno = ERANGE;
#endif #endif
return -1; return -1;
} }
@ -369,7 +368,7 @@ UtilGetDelim(char **linePtr, size_t * n, int delim, FILE * stream, int *err)
if (!(newLinePtr = Realloc(*linePtr, newLinePtrLen))) if (!(newLinePtr = Realloc(*linePtr, newLinePtrLen)))
{ {
*err = ENOMEM; errno = ENOMEM;
return -1; return -1;
} }
@ -391,7 +390,7 @@ UtilGetDelim(char **linePtr, size_t * n, int delim, FILE * stream, int *err)
} }
ssize_t ssize_t
UtilGetLine(char **linePtr, size_t * n, FILE * stream, int *err) UtilGetLine(char **linePtr, size_t * n, FILE * stream)
{ {
return UtilGetDelim(linePtr, n, '\n', stream, err); return UtilGetDelim(linePtr, n, '\n', stream);
} }

View file

@ -22,12 +22,6 @@
* SOFTWARE. * SOFTWARE.
*/ */
/*
* Util.h: Some misc. helper functions that provide functionality that
* doesn't need its own full API. The functions here are entirely
* stand-alone, and generally don't depend on any of the other APIs
* defined by Telodendria.
*/
#ifndef TELODENDRIA_UTIL_H #ifndef TELODENDRIA_UTIL_H
#define TELODENDRIA_UTIL_H #define TELODENDRIA_UTIL_H
@ -35,25 +29,6 @@
#include <stddef.h> #include <stddef.h>
#include <sys/types.h> #include <sys/types.h>
/*
* Get the current type in milliseconds since the Unix epoch. This uses
* POSIX gettimeofday(2) and time_t, and converts it to a single number,
* which is returned.
*
* A note on the 2038 problem: that's a long ways away, screw future
* me!
*
* Kidding. As long as (sizeof(long) == 8), that is, as long as the
* long datatype is 64 bits, which is is on all modern 64-bit Unix-like
* operating systems, then everything should be fine. Expect
* Telodendria on 32-bit machines to break in 2038. I didn't want to
* try to hack together some system to store larger numbers than the
* architecture supports. We can always re-evaluate things over the
* next decade.
*
* Return: A long representing the current time in milliseconds since
* the beginning of the Unix epoch, just as the Matrix spec requires.
*/
extern unsigned long extern unsigned long
UtilServerTs(void); UtilServerTs(void);
@ -63,59 +38,25 @@ extern unsigned long
extern int extern int
UtilMkdir(const char *, const mode_t); UtilMkdir(const char *, const mode_t);
/*
* Encode a single UTF-8 codepoint as a string buffer containing
* between 1 and 4 bytes. The string buffer is allocated on the heap,
* so it should be freed when it is no longer needed.
*
* Params:
*
* (unsigned long) The UTF-8 codepoint to encode as a byte buffer.
*
* Return: a null-terminated byte buffer representing the UTF-8
* codepoint.
*/
extern char * extern char *
UtilUtf8Encode(unsigned long); UtilUtf8Encode(unsigned long);
/*
* Duplicate a null-terminated string, and return a new string on the
* heap.
*
* Params:
* (char *) The string to duplicate. It can be located anywhere on
* the heap or the stack.
*
* Return: A pointer to a null-terminated string on the heap. You must
* free() it when you're done with it. This may also return NULL if the
* call to malloc() fails.
*/
extern char * extern char *
UtilStringDuplicate(char *); UtilStringDuplicate(char *);
extern char * extern char *
UtilStringConcat(char *, char *); UtilStringConcat(char *, char *);
/*
* Sleep for the given number of milliseconds. This is a simple wrapper
* for nanosleep() that makes its usage much easier.
*
* Params:
* (long) The number of milliseconds to sleep for.
*
* Return: The result of nanosleep().
*/
extern int extern int
UtilSleepMillis(long); UtilSleepMillis(long);
extern size_t extern size_t
UtilStringToBytes(char *); UtilParseBytes(char *);
extern ssize_t extern ssize_t
UtilGetDelim(char **, size_t *, int, FILE *, int *); UtilGetDelim(char **, size_t *, int, FILE *);
extern ssize_t extern ssize_t
UtilGetLine(char **, size_t *, FILE *, int *); UtilGetLine(char **, size_t *, FILE *);
#endif /* TELODENDRIA_UTIL_H */ #endif /* TELODENDRIA_UTIL_H */