forked from Telodendria/Telodendria
Begin working on Util man page
This commit is contained in:
parent
f07ea912b2
commit
6900d0649e
5 changed files with 100 additions and 79 deletions
83
man/man3/Util.3
Normal file
83
man/man3/Util.3
Normal 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
|
|
@ -464,8 +464,6 @@ HttpServerWorkerThread(void *args)
|
|||
HashMap *requestParams;
|
||||
ssize_t requestPathLen;
|
||||
|
||||
int lineError = -1;
|
||||
|
||||
ssize_t i = 0;
|
||||
HttpRequestMethod requestMethod;
|
||||
|
||||
|
@ -484,13 +482,13 @@ HttpServerWorkerThread(void *args)
|
|||
/* Get the first line of the request.
|
||||
*
|
||||
* 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
|
||||
* after 1ms. This is typically more than enough time for the
|
||||
* client to send data. */
|
||||
firstRead = UtilServerTs();
|
||||
while ((lineLen = UtilGetLine(&line, &lineSize, fp, &lineError)) == -1
|
||||
&& lineError == EAGAIN)
|
||||
while ((lineLen = UtilGetLine(&line, &lineSize, fp)) == -1
|
||||
&& errno == EAGAIN)
|
||||
{
|
||||
clearerr(fp);
|
||||
|
||||
|
@ -571,7 +569,7 @@ HttpServerWorkerThread(void *args)
|
|||
goto internal_error;
|
||||
}
|
||||
|
||||
while ((lineLen = UtilGetLine(&line, &lineSize, fp, &lineError)) != -1)
|
||||
while ((lineLen = UtilGetLine(&line, &lineSize, fp)) != -1)
|
||||
{
|
||||
char *headerKey;
|
||||
char *headerValue;
|
||||
|
|
|
@ -245,7 +245,7 @@ TelodendriaConfigParse(HashMap * config, LogConfig * lc)
|
|||
GET_DIRECTIVE("max-cache");
|
||||
ASSERT_NO_CHILDREN("max-cache");
|
||||
ASSERT_VALUES("max-cache", 1);
|
||||
tConfig->maxCache = UtilStringToBytes(ArrayGet(value, 0));
|
||||
tConfig->maxCache = UtilParseBytes(ArrayGet(value, 0));
|
||||
|
||||
GET_DIRECTIVE("federation");
|
||||
ASSERT_NO_CHILDREN("federation");
|
||||
|
|
19
src/Util.c
19
src/Util.c
|
@ -263,7 +263,7 @@ UtilSleepMillis(long ms)
|
|||
}
|
||||
|
||||
size_t
|
||||
UtilStringToBytes(char *str)
|
||||
UtilParseBytes(char *str)
|
||||
{
|
||||
size_t bytes = 0;
|
||||
|
||||
|
@ -313,7 +313,7 @@ UtilStringToBytes(char *str)
|
|||
}
|
||||
|
||||
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;
|
||||
size_t newLinePtrLen;
|
||||
|
@ -321,7 +321,7 @@ UtilGetDelim(char **linePtr, size_t * n, int delim, FILE * stream, int *err)
|
|||
|
||||
if (!linePtr || !n || !stream)
|
||||
{
|
||||
*err = EINVAL;
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -331,7 +331,7 @@ UtilGetDelim(char **linePtr, size_t * n, int delim, FILE * stream, int *err)
|
|||
|
||||
if (!(*linePtr = Malloc(*n)))
|
||||
{
|
||||
*err = ENOMEM;
|
||||
errno = ENOMEM;
|
||||
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))
|
||||
{
|
||||
*err = errno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -358,9 +357,9 @@ UtilGetDelim(char **linePtr, size_t * n, int delim, FILE * stream, int *err)
|
|||
if (SSIZE_MAX / 2 < *n)
|
||||
{
|
||||
#ifdef EOVERFLOW
|
||||
*err = EOVERFLOW;
|
||||
errno = EOVERFLOW;
|
||||
#else
|
||||
*err = ERANGE;
|
||||
errno = ERANGE;
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
@ -369,7 +368,7 @@ UtilGetDelim(char **linePtr, size_t * n, int delim, FILE * stream, int *err)
|
|||
|
||||
if (!(newLinePtr = Realloc(*linePtr, newLinePtrLen)))
|
||||
{
|
||||
*err = ENOMEM;
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -391,7 +390,7 @@ UtilGetDelim(char **linePtr, size_t * n, int delim, FILE * stream, int *err)
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -22,12 +22,6 @@
|
|||
* 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
|
||||
#define TELODENDRIA_UTIL_H
|
||||
|
||||
|
@ -35,25 +29,6 @@
|
|||
#include <stddef.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
|
||||
UtilServerTs(void);
|
||||
|
||||
|
@ -63,59 +38,25 @@ extern unsigned long
|
|||
extern int
|
||||
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 *
|
||||
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 *
|
||||
UtilStringDuplicate(char *);
|
||||
|
||||
extern 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
|
||||
UtilSleepMillis(long);
|
||||
|
||||
extern size_t
|
||||
UtilStringToBytes(char *);
|
||||
UtilParseBytes(char *);
|
||||
|
||||
extern ssize_t
|
||||
UtilGetDelim(char **, size_t *, int, FILE *, int *);
|
||||
UtilGetDelim(char **, size_t *, int, FILE *);
|
||||
|
||||
extern ssize_t
|
||||
UtilGetLine(char **, size_t *, FILE *, int *);
|
||||
UtilGetLine(char **, size_t *, FILE *);
|
||||
|
||||
#endif /* TELODENDRIA_UTIL_H */
|
||||
|
|
Loading…
Reference in a new issue