diff --git a/man/man3/Util.3 b/man/man3/Util.3 new file mode 100644 index 0000000..e487535 --- /dev/null +++ b/man/man3/Util.3 @@ -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 diff --git a/src/HttpServer.c b/src/HttpServer.c index 9141828..c819fe1 100644 --- a/src/HttpServer.c +++ b/src/HttpServer.c @@ -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; diff --git a/src/TelodendriaConfig.c b/src/TelodendriaConfig.c index 2a4a443..96746af 100644 --- a/src/TelodendriaConfig.c +++ b/src/TelodendriaConfig.c @@ -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"); diff --git a/src/Util.c b/src/Util.c index 000eb8c..dcb75af 100644 --- a/src/Util.c +++ b/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); } diff --git a/src/include/Util.h b/src/include/Util.h index 7ec97eb..4484991 100644 --- a/src/include/Util.h +++ b/src/include/Util.h @@ -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 #include -/* - * 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 */