aboutsummaryrefslogtreecommitdiffstats
path: root/util-src
diff options
context:
space:
mode:
Diffstat (limited to 'util-src')
-rw-r--r--util-src/GNUmakefile1
-rw-r--r--util-src/encodings.c169
-rw-r--r--util-src/hashes.c114
-rw-r--r--util-src/makefile2
-rw-r--r--util-src/net.c19
-rw-r--r--util-src/poll.c45
-rw-r--r--util-src/pposix.c107
-rw-r--r--util-src/ringbuffer.c141
-rw-r--r--util-src/signal.c49
-rw-r--r--util-src/time.c8
-rw-r--r--util-src/windows.c7
11 files changed, 420 insertions, 242 deletions
diff --git a/util-src/GNUmakefile b/util-src/GNUmakefile
index a8b3529f..0b96bf41 100644
--- a/util-src/GNUmakefile
+++ b/util-src/GNUmakefile
@@ -24,6 +24,7 @@ install: $(ALL)
clean:
rm -f $(ALL) $(patsubst %.so,%.o,$(ALL))
+encodings.o: CFLAGS+=$(IDNA_FLAGS)
encodings.so: LDLIBS+=$(IDNA_LIBS)
hashes.so: LDLIBS+=$(OPENSSL_LIBS)
diff --git a/util-src/encodings.c b/util-src/encodings.c
index e55a3f44..72264da8 100644
--- a/util-src/encodings.c
+++ b/util-src/encodings.c
@@ -24,6 +24,9 @@
#if (LUA_VERSION_NUM == 501)
#define luaL_setfuncs(L, R, N) luaL_register(L, NULL, R)
#endif
+#if (LUA_VERSION_NUM < 504)
+#define luaL_pushfail lua_pushnil
+#endif
/***************** BASE64 *****************/
@@ -216,7 +219,7 @@ static const char *utf8_decode(const char *o, int *val) {
* Check that a string is valid UTF-8
* Returns NULL if not
*/
-const char *check_utf8(lua_State *L, int idx, size_t *l) {
+static const char *check_utf8(lua_State *L, int idx, size_t *l) {
size_t pos, len;
const char *s = luaL_checklstring(L, idx, &len);
pos = 0;
@@ -247,7 +250,7 @@ static int Lutf8_length(lua_State *L) {
size_t len;
if(!check_utf8(L, 1, &len)) {
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushliteral(L, "invalid utf8");
return 2;
}
@@ -268,41 +271,47 @@ static const luaL_Reg Reg_utf8[] = {
#include <unicode/usprep.h>
#include <unicode/ustring.h>
#include <unicode/utrace.h>
+#include <unicode/uspoof.h>
+#include <unicode/uidna.h>
static int icu_stringprep_prep(lua_State *L, const UStringPrepProfile *profile) {
size_t input_len;
int32_t unprepped_len, prepped_len, output_len;
const char *input;
char output[1024];
+ int flags = USPREP_ALLOW_UNASSIGNED;
UChar unprepped[1024]; /* Temporary unicode buffer (1024 characters) */
UChar prepped[1024];
UErrorCode err = U_ZERO_ERROR;
- if(!lua_isstring(L, 1)) {
- lua_pushnil(L);
- return 1;
- }
-
- input = lua_tolstring(L, 1, &input_len);
+ input = luaL_checklstring(L, 1, &input_len);
if(input_len >= 1024) {
- lua_pushnil(L);
+ luaL_pushfail(L);
return 1;
}
+ /* strict */
+ if(!lua_isnoneornil(L, 2)) {
+ luaL_checktype(L, 2, LUA_TBOOLEAN);
+ if(lua_toboolean(L, 2)) {
+ flags = 0;
+ }
+ }
+
u_strFromUTF8(unprepped, 1024, &unprepped_len, input, input_len, &err);
if(U_FAILURE(err)) {
- lua_pushnil(L);
+ luaL_pushfail(L);
return 1;
}
- prepped_len = usprep_prepare(profile, unprepped, unprepped_len, prepped, 1024, USPREP_ALLOW_UNASSIGNED, NULL, &err);
+ prepped_len = usprep_prepare(profile, unprepped, unprepped_len, prepped, 1024, flags, NULL, &err);
if(U_FAILURE(err)) {
- lua_pushnil(L);
+ luaL_pushfail(L);
return 1;
} else {
u_strToUTF8(output, 1024, &output_len, prepped, prepped_len, &err);
@@ -310,29 +319,62 @@ static int icu_stringprep_prep(lua_State *L, const UStringPrepProfile *profile)
if(U_SUCCESS(err) && output_len < 1024) {
lua_pushlstring(L, output, output_len);
} else {
- lua_pushnil(L);
+ luaL_pushfail(L);
}
return 1;
}
}
-UStringPrepProfile *icu_nameprep;
-UStringPrepProfile *icu_nodeprep;
-UStringPrepProfile *icu_resourceprep;
-UStringPrepProfile *icu_saslprep;
+static UStringPrepProfile *icu_nameprep;
+static UStringPrepProfile *icu_nodeprep;
+static UStringPrepProfile *icu_resourceprep;
+static UStringPrepProfile *icu_saslprep;
+static USpoofChecker *icu_spoofcheck;
+static UIDNA *icu_idna2008;
+
+#if (U_ICU_VERSION_MAJOR_NUM < 58)
+/* COMPAT */
+#define USPOOF_CONFUSABLE (USPOOF_SINGLE_SCRIPT_CONFUSABLE | USPOOF_MIXED_SCRIPT_CONFUSABLE | USPOOF_WHOLE_SCRIPT_CONFUSABLE)
+#endif
/* initialize global ICU stringprep profiles */
-void init_icu() {
+static void init_icu(void) {
UErrorCode err = U_ZERO_ERROR;
utrace_setLevel(UTRACE_VERBOSE);
icu_nameprep = usprep_openByType(USPREP_RFC3491_NAMEPREP, &err);
icu_nodeprep = usprep_openByType(USPREP_RFC3920_NODEPREP, &err);
icu_resourceprep = usprep_openByType(USPREP_RFC3920_RESOURCEPREP, &err);
icu_saslprep = usprep_openByType(USPREP_RFC4013_SASLPREP, &err);
+ icu_spoofcheck = uspoof_open(&err);
+ uspoof_setChecks(icu_spoofcheck, USPOOF_CONFUSABLE, &err);
+ int options = UIDNA_DEFAULT;
+#if 0
+ /* COMPAT with future Unicode versions */
+ options |= UIDNA_ALLOW_UNASSIGNED;
+#endif
+#if 1
+ /* Forbid eg labels starting with _ */
+ options |= UIDNA_USE_STD3_RULES;
+#endif
+#if 0
+ /* TODO determine if we need this */
+ options |= UIDNA_CHECK_BIDI;
+#endif
+#if 0
+ /* UTS46 makes it sound like these are the responsibility of registrars */
+ options |= UIDNA_CHECK_CONTEXTJ;
+ options |= UIDNA_CHECK_CONTEXTO;
+#endif
+#if 0
+ /* This disables COMPAT with IDNA 2003 */
+ options |= UIDNA_NONTRANSITIONAL_TO_ASCII;
+ options |= UIDNA_NONTRANSITIONAL_TO_UNICODE;
+#endif
+ icu_idna2008 = uidna_openUTS46(options, &err);
if(U_FAILURE(err)) {
- fprintf(stderr, "[c] util.encodings: error: %s\n", u_errorName((UErrorCode)err));
+ fprintf(stderr, "[c] util.encodings: error: %s\n", u_errorName(err));
}
}
@@ -362,27 +404,31 @@ static int stringprep_prep(lua_State *L, const Stringprep_profile *profile) {
const char *s;
char string[1024];
int ret;
-
- if(!lua_isstring(L, 1)) {
- lua_pushnil(L);
- return 1;
- }
+ Stringprep_profile_flags flags = 0;
s = check_utf8(L, 1, &len);
+ /* strict */
+ if(!lua_isnoneornil(L, 2)) {
+ luaL_checktype(L, 2, LUA_TBOOLEAN);
+ if(lua_toboolean(L, 2)) {
+ flags = STRINGPREP_NO_UNASSIGNED;
+ }
+ }
+
if(s == NULL || len >= 1024 || len != strlen(s)) {
- lua_pushnil(L);
+ luaL_pushfail(L);
return 1; /* TODO return error message */
}
strcpy(string, s);
- ret = stringprep(string, 1024, (Stringprep_profile_flags)0, profile);
+ ret = stringprep(string, 1024, flags, profile);
if(ret == STRINGPREP_OK) {
lua_pushstring(L, string);
return 1;
} else {
- lua_pushnil(L);
+ luaL_pushfail(L);
return 1; /* TODO return error message */
}
}
@@ -421,14 +467,15 @@ static int Lidna_to_ascii(lua_State *L) { /** idna.to_ascii(s) */
u_strFromUTF8(ustr, 1024, &ulen, s, len, &err);
if(U_FAILURE(err)) {
- lua_pushnil(L);
+ luaL_pushfail(L);
return 1;
}
- dest_len = uidna_IDNToASCII(ustr, ulen, dest, 1024, UIDNA_USE_STD3_RULES, NULL, &err);
+ UIDNAInfo info = UIDNA_INFO_INITIALIZER;
+ dest_len = uidna_nameToASCII(icu_idna2008, ustr, ulen, dest, 256, &info, &err);
- if(U_FAILURE(err)) {
- lua_pushnil(L);
+ if(U_FAILURE(err) || info.errors) {
+ luaL_pushfail(L);
return 1;
} else {
u_strToUTF8(output, 1024, &output_len, dest, dest_len, &err);
@@ -436,7 +483,7 @@ static int Lidna_to_ascii(lua_State *L) { /** idna.to_ascii(s) */
if(U_SUCCESS(err) && output_len < 1024) {
lua_pushlstring(L, output, output_len);
} else {
- lua_pushnil(L);
+ luaL_pushfail(L);
}
return 1;
@@ -455,14 +502,15 @@ static int Lidna_to_unicode(lua_State *L) { /** idna.to_unicode(s) */
u_strFromUTF8(ustr, 1024, &ulen, s, len, &err);
if(U_FAILURE(err)) {
- lua_pushnil(L);
+ luaL_pushfail(L);
return 1;
}
- dest_len = uidna_IDNToUnicode(ustr, ulen, dest, 1024, UIDNA_USE_STD3_RULES, NULL, &err);
+ UIDNAInfo info = UIDNA_INFO_INITIALIZER;
+ dest_len = uidna_nameToUnicode(icu_idna2008, ustr, ulen, dest, 1024, &info, &err);
- if(U_FAILURE(err)) {
- lua_pushnil(L);
+ if(U_FAILURE(err) || info.errors) {
+ luaL_pushfail(L);
return 1;
} else {
u_strToUTF8(output, 1024, &output_len, dest, dest_len, &err);
@@ -470,13 +518,47 @@ static int Lidna_to_unicode(lua_State *L) { /** idna.to_unicode(s) */
if(U_SUCCESS(err) && output_len < 1024) {
lua_pushlstring(L, output, output_len);
} else {
- lua_pushnil(L);
+ luaL_pushfail(L);
}
return 1;
}
}
+static int Lskeleton(lua_State *L) {
+ size_t len;
+ int32_t ulen, dest_len, output_len;
+ const char *s = luaL_checklstring(L, 1, &len);
+ UErrorCode err = U_ZERO_ERROR;
+ UChar ustr[1024];
+ UChar dest[1024];
+ char output[1024];
+
+ u_strFromUTF8(ustr, 1024, &ulen, s, len, &err);
+
+ if(U_FAILURE(err)) {
+ luaL_pushfail(L);
+ return 1;
+ }
+
+ dest_len = uspoof_getSkeleton(icu_spoofcheck, 0, ustr, ulen, dest, 1024, &err);
+
+ if(U_FAILURE(err)) {
+ luaL_pushfail(L);
+ return 1;
+ }
+
+ u_strToUTF8(output, 1024, &output_len, dest, dest_len, &err);
+
+ if(U_SUCCESS(err)) {
+ lua_pushlstring(L, output, output_len);
+ return 1;
+ }
+
+ luaL_pushfail(L);
+ return 1;
+}
+
#else /* USE_STRINGPREP_ICU */
/****************** libidn ********************/
@@ -490,7 +572,7 @@ static int Lidna_to_ascii(lua_State *L) { /** idna.to_ascii(s) */
int ret;
if(s == NULL || len != strlen(s)) {
- lua_pushnil(L);
+ luaL_pushfail(L);
return 1; /* TODO return error message */
}
@@ -501,7 +583,7 @@ static int Lidna_to_ascii(lua_State *L) { /** idna.to_ascii(s) */
idn_free(output);
return 1;
} else {
- lua_pushnil(L);
+ luaL_pushfail(L);
idn_free(output);
return 1; /* TODO return error message */
}
@@ -518,7 +600,7 @@ static int Lidna_to_unicode(lua_State *L) { /** idna.to_unicode(s) */
idn_free(output);
return 1;
} else {
- lua_pushnil(L);
+ luaL_pushfail(L);
idn_free(output);
return 1; /* TODO return error message */
}
@@ -558,6 +640,13 @@ LUALIB_API int luaopen_util_encodings(lua_State *L) {
luaL_setfuncs(L, Reg_utf8, 0);
lua_setfield(L, -2, "utf8");
+#ifdef USE_STRINGPREP_ICU
+ lua_newtable(L);
+ lua_pushcfunction(L, Lskeleton);
+ lua_setfield(L, -2, "skeleton");
+ lua_setfield(L, -2, "confusable");
+#endif
+
lua_pushliteral(L, "-3.14");
lua_setfield(L, -2, "version");
return 1;
diff --git a/util-src/hashes.c b/util-src/hashes.c
index b16eb03f..8eefcd6b 100644
--- a/util-src/hashes.c
+++ b/util-src/hashes.c
@@ -27,6 +27,7 @@ typedef unsigned __int32 uint32_t;
#include <openssl/sha.h>
#include <openssl/md5.h>
#include <openssl/hmac.h>
+#include <openssl/evp.h>
#if (LUA_VERSION_NUM == 501)
#define luaL_setfuncs(L, R, N) luaL_register(L, NULL, R)
@@ -35,8 +36,8 @@ typedef unsigned __int32 uint32_t;
#define HMAC_IPAD 0x36363636
#define HMAC_OPAD 0x5c5c5c5c
-const char *hex_tab = "0123456789abcdef";
-void toHex(const unsigned char *in, int length, unsigned char *out) {
+static const char *hex_tab = "0123456789abcdef";
+static void toHex(const unsigned char *in, int length, unsigned char *out) {
int i;
for(i = 0; i < length; i++) {
@@ -76,44 +77,6 @@ struct hash_desc {
void *ctx, *ctxo;
};
-static void hmac(struct hash_desc *desc, const char *key, size_t key_len,
- const char *msg, size_t msg_len, unsigned char *result) {
- union xory {
- unsigned char bytes[64];
- uint32_t quadbytes[16];
- };
-
- int i;
- unsigned char hashedKey[64]; /* Maximum used digest length */
- union xory k_ipad, k_opad;
-
- if(key_len > 64) {
- desc->Init(desc->ctx);
- desc->Update(desc->ctx, key, key_len);
- desc->Final(hashedKey, desc->ctx);
- key = (const char *)hashedKey;
- key_len = desc->digestLength;
- }
-
- memcpy(k_ipad.bytes, key, key_len);
- memset(k_ipad.bytes + key_len, 0, 64 - key_len);
- memcpy(k_opad.bytes, k_ipad.bytes, 64);
-
- for(i = 0; i < 16; i++) {
- k_ipad.quadbytes[i] ^= HMAC_IPAD;
- k_opad.quadbytes[i] ^= HMAC_OPAD;
- }
-
- desc->Init(desc->ctx);
- desc->Update(desc->ctx, k_ipad.bytes, 64);
- desc->Init(desc->ctxo);
- desc->Update(desc->ctxo, k_opad.bytes, 64);
- desc->Update(desc->ctx, msg, msg_len);
- desc->Final(result, desc->ctx);
- desc->Update(desc->ctxo, result, desc->digestLength);
- desc->Final(result, desc->ctxo);
-}
-
#define MAKE_HMAC_FUNCTION(myFunc, evp, size, type) \
static int myFunc(lua_State *L) { \
unsigned char hash[size], result[2*size]; \
@@ -137,56 +100,37 @@ MAKE_HMAC_FUNCTION(Lhmac_sha256, EVP_sha256, SHA256_DIGEST_LENGTH, SHA256_CTX)
MAKE_HMAC_FUNCTION(Lhmac_sha512, EVP_sha512, SHA512_DIGEST_LENGTH, SHA512_CTX)
MAKE_HMAC_FUNCTION(Lhmac_md5, EVP_md5, MD5_DIGEST_LENGTH, MD5_CTX)
-static int LscramHi(lua_State *L) {
- union xory {
- unsigned char bytes[SHA_DIGEST_LENGTH];
- uint32_t quadbytes[SHA_DIGEST_LENGTH / 4];
- };
- int i;
- SHA_CTX ctx, ctxo;
- unsigned char Ust[SHA_DIGEST_LENGTH];
- union xory Und;
- union xory res;
- size_t str_len, salt_len;
- struct hash_desc desc;
- const char *str = luaL_checklstring(L, 1, &str_len);
- const char *salt = luaL_checklstring(L, 2, &salt_len);
- char *salt2;
- const int iter = luaL_checkinteger(L, 3);
-
- desc.Init = (int (*)(void *))SHA1_Init;
- desc.Update = (int (*)(void *, const void *, size_t))SHA1_Update;
- desc.Final = (int (*)(unsigned char *, void *))SHA1_Final;
- desc.digestLength = SHA_DIGEST_LENGTH;
- desc.ctx = &ctx;
- desc.ctxo = &ctxo;
+static int Lpbkdf2_sha1(lua_State *L) {
+ unsigned char out[SHA_DIGEST_LENGTH];
- salt2 = malloc(salt_len + 4);
+ size_t pass_len, salt_len;
+ const char *pass = luaL_checklstring(L, 1, &pass_len);
+ const unsigned char *salt = (unsigned char *)luaL_checklstring(L, 2, &salt_len);
+ const int iter = luaL_checkinteger(L, 3);
- if(salt2 == NULL) {
- return luaL_error(L, "Out of memory in scramHi");
+ if(PKCS5_PBKDF2_HMAC(pass, pass_len, salt, salt_len, iter, EVP_sha1(), SHA_DIGEST_LENGTH, out) == 0) {
+ return luaL_error(L, "PKCS5_PBKDF2_HMAC() failed");
}
- memcpy(salt2, salt, salt_len);
- memcpy(salt2 + salt_len, "\0\0\0\1", 4);
- hmac(&desc, str, str_len, salt2, salt_len + 4, Ust);
- free(salt2);
+ lua_pushlstring(L, (char *)out, SHA_DIGEST_LENGTH);
- memcpy(res.bytes, Ust, sizeof(res));
+ return 1;
+}
- for(i = 1; i < iter; i++) {
- int j;
- hmac(&desc, str, str_len, (char *)Ust, sizeof(Ust), Und.bytes);
- for(j = 0; j < SHA_DIGEST_LENGTH / 4; j++) {
- res.quadbytes[j] ^= Und.quadbytes[j];
- }
+static int Lpbkdf2_sha256(lua_State *L) {
+ unsigned char out[SHA256_DIGEST_LENGTH];
- memcpy(Ust, Und.bytes, sizeof(Ust));
- }
+ size_t pass_len, salt_len;
+ const char *pass = luaL_checklstring(L, 1, &pass_len);
+ const unsigned char *salt = (unsigned char *)luaL_checklstring(L, 2, &salt_len);
+ const int iter = luaL_checkinteger(L, 3);
- lua_pushlstring(L, (char *)res.bytes, SHA_DIGEST_LENGTH);
+ if(PKCS5_PBKDF2_HMAC(pass, pass_len, salt, salt_len, iter, EVP_sha256(), SHA256_DIGEST_LENGTH, out) == 0) {
+ return luaL_error(L, "PKCS5_PBKDF2_HMAC() failed");
+ }
+ lua_pushlstring(L, (char *)out, SHA256_DIGEST_LENGTH);
return 1;
}
@@ -213,7 +157,9 @@ static const luaL_Reg Reg[] = {
{ "hmac_sha256", Lhmac_sha256 },
{ "hmac_sha512", Lhmac_sha512 },
{ "hmac_md5", Lhmac_md5 },
- { "scram_Hi_sha1", LscramHi },
+ { "scram_Hi_sha1", Lpbkdf2_sha1 }, /* COMPAT */
+ { "pbkdf2_hmac_sha1", Lpbkdf2_sha1 },
+ { "pbkdf2_hmac_sha256", Lpbkdf2_sha256 },
{ "equals", Lhash_equals },
{ NULL, NULL }
};
@@ -223,8 +169,12 @@ LUALIB_API int luaopen_util_hashes(lua_State *L) {
luaL_checkversion(L);
#endif
lua_newtable(L);
- luaL_setfuncs(L, Reg, 0);;
+ luaL_setfuncs(L, Reg, 0);
lua_pushliteral(L, "-3.14");
lua_setfield(L, -2, "version");
+#ifdef OPENSSL_VERSION
+ lua_pushstring(L, OpenSSL_version(OPENSSL_VERSION));
+ lua_setfield(L, -2, "_LIBCRYPTO_VERSION");
+#endif
return 1;
}
diff --git a/util-src/makefile b/util-src/makefile
index 02bad40a..1560fca4 100644
--- a/util-src/makefile
+++ b/util-src/makefile
@@ -23,6 +23,8 @@ install: $(ALL)
clean:
rm -f $(ALL) $(patsubst %.so,%.o,$(ALL))
+encodings.o: encodings.c
+ $(CC) $(CFLAGS) $(IDNA_FLAGS) -c -o $@ $<
encodings.so: encodings.o
$(LD) $(LDFLAGS) -o $@ $< $(LDLIBS) $(IDNA_LIBS)
diff --git a/util-src/net.c b/util-src/net.c
index 5f706d81..d786e885 100644
--- a/util-src/net.c
+++ b/util-src/net.c
@@ -33,10 +33,13 @@
#if (LUA_VERSION_NUM == 501)
#define luaL_setfuncs(L, R, N) luaL_register(L, NULL, R)
#endif
+#if (LUA_VERSION_NUM < 504)
+#define luaL_pushfail lua_pushnil
+#endif
/* Enumerate all locally configured IP addresses */
-const char *const type_strings[] = {
+static const char *const type_strings[] = {
"both",
"ipv4",
"ipv6",
@@ -46,8 +49,8 @@ const char *const type_strings[] = {
static int lc_local_addresses(lua_State *L) {
#ifndef _WIN32
/* Link-local IPv4 addresses; see RFC 3927 and RFC 5735 */
- const long ip4_linklocal = htonl(0xa9fe0000); /* 169.254.0.0 */
- const long ip4_mask = htonl(0xffff0000);
+ const uint32_t ip4_linklocal = htonl(0xa9fe0000); /* 169.254.0.0 */
+ const uint32_t ip4_mask = htonl(0xffff0000);
struct ifaddrs *addr = NULL, *a;
#endif
int n = 1;
@@ -59,7 +62,7 @@ static int lc_local_addresses(lua_State *L) {
#ifndef _WIN32
if(getifaddrs(&addr) < 0) {
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushfstring(L, "getifaddrs failed (%d): %s", errno,
strerror(errno));
return 2;
@@ -141,14 +144,14 @@ static int lc_pton(lua_State *L) {
case -1:
errno_ = errno;
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushstring(L, strerror(errno_));
lua_pushinteger(L, errno_);
return 3;
default:
case 0:
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushstring(L, strerror(EINVAL));
lua_pushinteger(L, EINVAL);
return 3;
@@ -170,7 +173,7 @@ static int lc_ntop(lua_State *L) {
family = AF_INET;
}
else {
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushstring(L, strerror(EAFNOSUPPORT));
lua_pushinteger(L, EAFNOSUPPORT);
return 3;
@@ -179,7 +182,7 @@ static int lc_ntop(lua_State *L) {
if(!inet_ntop(family, ipaddr, buf, INET6_ADDRSTRLEN))
{
errno_ = errno;
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushstring(L, strerror(errno_));
lua_pushinteger(L, errno_);
return 3;
diff --git a/util-src/poll.c b/util-src/poll.c
index 0ca0cf28..6c6a4e63 100644
--- a/util-src/poll.c
+++ b/util-src/poll.c
@@ -37,6 +37,9 @@
#if (LUA_VERSION_NUM == 501)
#define luaL_setmetatable(L, tname) luaL_getmetatable(L, tname); lua_setmetatable(L, -2)
#endif
+#if (LUA_VERSION_NUM < 504)
+#define luaL_pushfail lua_pushnil
+#endif
/*
* Structure to keep state for each type of API
@@ -59,7 +62,7 @@ typedef struct Lpoll_state {
/*
* Add an FD to be watched
*/
-int Ladd(lua_State *L) {
+static int Ladd(lua_State *L) {
struct Lpoll_state *state = luaL_checkudata(L, 1, STATE_MT);
int fd = luaL_checkinteger(L, 2);
@@ -67,7 +70,7 @@ int Ladd(lua_State *L) {
int wantwrite = lua_toboolean(L, 4);
if(fd < 0) {
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushstring(L, strerror(EBADF));
lua_pushinteger(L, EBADF);
return 3;
@@ -84,7 +87,7 @@ int Ladd(lua_State *L) {
if(ret < 0) {
ret = errno;
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushstring(L, strerror(ret));
lua_pushinteger(L, ret);
return 3;
@@ -96,14 +99,14 @@ int Ladd(lua_State *L) {
#else
if(fd > FD_SETSIZE) {
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushstring(L, strerror(EBADF));
lua_pushinteger(L, EBADF);
return 3;
}
if(FD_ISSET(fd, &state->all)) {
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushstring(L, strerror(EEXIST));
lua_pushinteger(L, EEXIST);
return 3;
@@ -137,7 +140,7 @@ int Ladd(lua_State *L) {
/*
* Set events to watch for, readable and/or writable
*/
-int Lset(lua_State *L) {
+static int Lset(lua_State *L) {
struct Lpoll_state *state = luaL_checkudata(L, 1, STATE_MT);
int fd = luaL_checkinteger(L, 2);
@@ -160,7 +163,7 @@ int Lset(lua_State *L) {
}
else {
ret = errno;
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushstring(L, strerror(ret));
lua_pushinteger(L, ret);
return 3;
@@ -169,9 +172,10 @@ int Lset(lua_State *L) {
#else
if(!FD_ISSET(fd, &state->all)) {
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushstring(L, strerror(ENOENT));
lua_pushinteger(L, ENOENT);
+ return 3;
}
if(!lua_isnoneornil(L, 3)) {
@@ -200,7 +204,7 @@ int Lset(lua_State *L) {
/*
* Remove FDs
*/
-int Ldel(lua_State *L) {
+static int Ldel(lua_State *L) {
struct Lpoll_state *state = luaL_checkudata(L, 1, STATE_MT);
int fd = luaL_checkinteger(L, 2);
@@ -217,7 +221,7 @@ int Ldel(lua_State *L) {
}
else {
ret = errno;
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushstring(L, strerror(ret));
lua_pushinteger(L, ret);
return 3;
@@ -226,9 +230,10 @@ int Ldel(lua_State *L) {
#else
if(!FD_ISSET(fd, &state->all)) {
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushstring(L, strerror(ENOENT));
lua_pushinteger(L, ENOENT);
+ return 3;
}
FD_CLR(fd, &state->wantread);
@@ -247,7 +252,7 @@ int Ldel(lua_State *L) {
/*
* Check previously manipulated event state for FDs ready for reading or writing
*/
-int Lpushevent(lua_State *L, struct Lpoll_state *state) {
+static int Lpushevent(lua_State *L, struct Lpoll_state *state) {
#ifdef USE_EPOLL
if(state->processed > 0) {
@@ -281,7 +286,7 @@ int Lpushevent(lua_State *L, struct Lpoll_state *state) {
/*
* Wait for event
*/
-int Lwait(lua_State *L) {
+static int Lwait(lua_State *L) {
struct Lpoll_state *state = luaL_checkudata(L, 1, STATE_MT);
int ret = Lpushevent(L, state);
@@ -312,18 +317,20 @@ int Lwait(lua_State *L) {
#endif
if(ret == 0) {
+ /* Is this an error? */
lua_pushnil(L);
lua_pushstring(L, "timeout");
return 2;
}
else if(ret < 0 && errno == EINTR) {
+ /* Is this an error? */
lua_pushnil(L);
lua_pushstring(L, "signal");
return 2;
}
else if(ret < 0) {
ret = errno;
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushstring(L, strerror(ret));
lua_pushinteger(L, ret);
return 3;
@@ -344,7 +351,7 @@ int Lwait(lua_State *L) {
/*
* Return Epoll FD
*/
-int Lgetfd(lua_State *L) {
+static int Lgetfd(lua_State *L) {
struct Lpoll_state *state = luaL_checkudata(L, 1, STATE_MT);
lua_pushinteger(L, state->epoll_fd);
return 1;
@@ -353,7 +360,7 @@ int Lgetfd(lua_State *L) {
/*
* Close epoll FD
*/
-int Lgc(lua_State *L) {
+static int Lgc(lua_State *L) {
struct Lpoll_state *state = luaL_checkudata(L, 1, STATE_MT);
if(state->epoll_fd == -1) {
@@ -375,7 +382,7 @@ int Lgc(lua_State *L) {
/*
* String representation
*/
-int Ltos(lua_State *L) {
+static int Ltos(lua_State *L) {
struct Lpoll_state *state = luaL_checkudata(L, 1, STATE_MT);
lua_pushfstring(L, "%s: %p", STATE_MT, state);
return 1;
@@ -384,7 +391,7 @@ int Ltos(lua_State *L) {
/*
* Create a new context
*/
-int Lnew(lua_State *L) {
+static int Lnew(lua_State *L) {
/* Allocate state */
Lpoll_state *state = lua_newuserdata(L, sizeof(Lpoll_state));
luaL_setmetatable(L, STATE_MT);
@@ -397,7 +404,7 @@ int Lnew(lua_State *L) {
int epoll_fd = epoll_create1(EPOLL_CLOEXEC);
if(epoll_fd <= 0) {
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushstring(L, strerror(errno));
lua_pushinteger(L, errno);
return 3;
diff --git a/util-src/pposix.c b/util-src/pposix.c
index 004f61a6..87be7e9a 100644
--- a/util-src/pposix.c
+++ b/util-src/pposix.c
@@ -25,14 +25,18 @@
#define _DEFAULT_SOURCE
#endif
#endif
+
#if defined(__APPLE__)
#ifndef _DARWIN_C_SOURCE
#define _DARWIN_C_SOURCE
#endif
#endif
+
+#if ! defined(__FreeBSD__)
#ifndef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200809L
#endif
+#endif
#include <stdlib.h>
#include <math.h>
@@ -57,6 +61,12 @@
#if (LUA_VERSION_NUM == 501)
#define luaL_setfuncs(L, R, N) luaL_register(L, NULL, R)
#endif
+#if (LUA_VERSION_NUM < 503)
+#define lua_isinteger(L, n) lua_isnumber(L, n)
+#endif
+#if (LUA_VERSION_NUM < 504)
+#define luaL_pushfail lua_pushnil
+#endif
#include <fcntl.h>
#if defined(__linux__)
@@ -102,7 +112,7 @@ static int lc_daemonize(lua_State *L) {
} else if(pid != 0) {
/* We are the parent process */
lua_pushboolean(L, 1);
- lua_pushnumber(L, pid);
+ lua_pushinteger(L, pid);
return 2;
}
@@ -133,7 +143,7 @@ static int lc_daemonize(lua_State *L) {
/* Syslog support */
-const char *const facility_strings[] = {
+static const char *const facility_strings[] = {
"auth",
#if !(defined(sun) || defined(__sun))
"authpriv",
@@ -159,7 +169,7 @@ const char *const facility_strings[] = {
"uucp",
NULL
};
-int facility_constants[] = {
+static int facility_constants[] = {
LOG_AUTH,
#if !(defined(sun) || defined(__sun))
LOG_AUTHPRIV,
@@ -195,9 +205,9 @@ int facility_constants[] = {
constant.
" -- syslog manpage
*/
-char *syslog_ident = NULL;
+static char *syslog_ident = NULL;
-int lc_syslog_open(lua_State *L) {
+static int lc_syslog_open(lua_State *L) {
int facility = luaL_checkoption(L, 2, "daemon", facility_strings);
facility = facility_constants[facility];
@@ -213,7 +223,7 @@ int lc_syslog_open(lua_State *L) {
return 0;
}
-const char *const level_strings[] = {
+static const char *const level_strings[] = {
"debug",
"info",
"notice",
@@ -221,7 +231,7 @@ const char *const level_strings[] = {
"error",
NULL
};
-int level_constants[] = {
+static int level_constants[] = {
LOG_DEBUG,
LOG_INFO,
LOG_NOTICE,
@@ -229,7 +239,7 @@ int level_constants[] = {
LOG_CRIT,
-1
};
-int lc_syslog_log(lua_State *L) {
+static int lc_syslog_log(lua_State *L) {
int level = level_constants[luaL_checkoption(L, 1, "notice", level_strings)];
if(lua_gettop(L) == 3) {
@@ -241,7 +251,7 @@ int lc_syslog_log(lua_State *L) {
return 0;
}
-int lc_syslog_close(lua_State *L) {
+static int lc_syslog_close(lua_State *L) {
(void)L;
closelog();
@@ -253,7 +263,7 @@ int lc_syslog_close(lua_State *L) {
return 0;
}
-int lc_syslog_setmask(lua_State *L) {
+static int lc_syslog_setmask(lua_State *L) {
int level_idx = luaL_checkoption(L, 1, "notice", level_strings);
int mask = 0;
@@ -267,31 +277,31 @@ int lc_syslog_setmask(lua_State *L) {
/* getpid */
-int lc_getpid(lua_State *L) {
+static int lc_getpid(lua_State *L) {
lua_pushinteger(L, getpid());
return 1;
}
/* UID/GID functions */
-int lc_getuid(lua_State *L) {
+static int lc_getuid(lua_State *L) {
lua_pushinteger(L, getuid());
return 1;
}
-int lc_getgid(lua_State *L) {
+static int lc_getgid(lua_State *L) {
lua_pushinteger(L, getgid());
return 1;
}
-int lc_setuid(lua_State *L) {
+static int lc_setuid(lua_State *L) {
int uid = -1;
if(lua_gettop(L) < 1) {
return 0;
}
- if(!lua_isnumber(L, 1) && lua_tostring(L, 1)) {
+ if(!lua_isinteger(L, 1) && lua_tostring(L, 1)) {
/* Passed UID is actually a string, so look up the UID */
struct passwd *p;
p = getpwnam(lua_tostring(L, 1));
@@ -304,7 +314,7 @@ int lc_setuid(lua_State *L) {
uid = p->pw_uid;
} else {
- uid = lua_tonumber(L, 1);
+ uid = lua_tointeger(L, 1);
}
if(uid > -1) {
@@ -342,14 +352,14 @@ int lc_setuid(lua_State *L) {
return 2;
}
-int lc_setgid(lua_State *L) {
+static int lc_setgid(lua_State *L) {
int gid = -1;
if(lua_gettop(L) < 1) {
return 0;
}
- if(!lua_isnumber(L, 1) && lua_tostring(L, 1)) {
+ if(!lua_isinteger(L, 1) && lua_tostring(L, 1)) {
/* Passed GID is actually a string, so look up the GID */
struct group *g;
g = getgrnam(lua_tostring(L, 1));
@@ -362,7 +372,7 @@ int lc_setgid(lua_State *L) {
gid = g->gr_gid;
} else {
- gid = lua_tonumber(L, 1);
+ gid = lua_tointeger(L, 1);
}
if(gid > -1) {
@@ -400,13 +410,13 @@ int lc_setgid(lua_State *L) {
return 2;
}
-int lc_initgroups(lua_State *L) {
+static int lc_initgroups(lua_State *L) {
int ret;
gid_t gid;
struct passwd *p;
if(!lua_isstring(L, 1)) {
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushstring(L, "invalid-username");
return 2;
}
@@ -414,7 +424,7 @@ int lc_initgroups(lua_State *L) {
p = getpwnam(lua_tostring(L, 1));
if(!p) {
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushstring(L, "no-such-user");
return 2;
}
@@ -433,7 +443,7 @@ int lc_initgroups(lua_State *L) {
break;
default:
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushstring(L, "invalid-gid");
return 2;
}
@@ -443,17 +453,17 @@ int lc_initgroups(lua_State *L) {
if(ret) {
switch(errno) {
case ENOMEM:
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushstring(L, "no-memory");
break;
case EPERM:
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushstring(L, "permission-denied");
break;
default:
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushstring(L, "unknown-error");
}
} else {
@@ -464,7 +474,7 @@ int lc_initgroups(lua_State *L) {
return 2;
}
-int lc_umask(lua_State *L) {
+static int lc_umask(lua_State *L) {
char old_mode_string[7];
mode_t old_mode = umask(strtoul(luaL_checkstring(L, 1), NULL, 8));
@@ -475,7 +485,7 @@ int lc_umask(lua_State *L) {
return 1;
}
-int lc_mkdir(lua_State *L) {
+static int lc_mkdir(lua_State *L) {
int ret = mkdir(luaL_checkstring(L, 1), S_IRUSR | S_IWUSR | S_IXUSR
| S_IRGRP | S_IWGRP | S_IXGRP
| S_IROTH | S_IXOTH); /* mode 775 */
@@ -500,7 +510,7 @@ int lc_mkdir(lua_State *L) {
* Example usage:
* pposix.setrlimit("NOFILE", 1000, 2000)
*/
-int string2resource(const char *s) {
+static int string2resource(const char *s) {
if(!strcmp(s, "CORE")) {
return RLIMIT_CORE;
}
@@ -550,7 +560,7 @@ int string2resource(const char *s) {
return -1;
}
-rlim_t arg_to_rlimit(lua_State *L, int idx, rlim_t current) {
+static rlim_t arg_to_rlimit(lua_State *L, int idx, rlim_t current) {
switch(lua_type(L, idx)) {
case LUA_TSTRING:
@@ -571,7 +581,7 @@ rlim_t arg_to_rlimit(lua_State *L, int idx, rlim_t current) {
}
}
-int lc_setrlimit(lua_State *L) {
+static int lc_setrlimit(lua_State *L) {
struct rlimit lim;
int arguments = lua_gettop(L);
int rid = -1;
@@ -610,7 +620,7 @@ int lc_setrlimit(lua_State *L) {
return 1;
}
-int lc_getrlimit(lua_State *L) {
+static int lc_getrlimit(lua_State *L) {
int arguments = lua_gettop(L);
const char *resource = NULL;
int rid = -1;
@@ -643,29 +653,29 @@ int lc_getrlimit(lua_State *L) {
if(lim.rlim_cur == RLIM_INFINITY) {
lua_pushstring(L, "unlimited");
} else {
- lua_pushnumber(L, lim.rlim_cur);
+ lua_pushinteger(L, lim.rlim_cur);
}
if(lim.rlim_max == RLIM_INFINITY) {
lua_pushstring(L, "unlimited");
} else {
- lua_pushnumber(L, lim.rlim_max);
+ lua_pushinteger(L, lim.rlim_max);
}
return 3;
}
-int lc_abort(lua_State *L) {
+static int lc_abort(lua_State *L) {
(void)L;
abort();
return 0;
}
-int lc_uname(lua_State *L) {
+static int lc_uname(lua_State *L) {
struct utsname uname_info;
if(uname(&uname_info) != 0) {
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushstring(L, strerror(errno));
return 2;
}
@@ -688,14 +698,14 @@ int lc_uname(lua_State *L) {
return 1;
}
-int lc_setenv(lua_State *L) {
+static int lc_setenv(lua_State *L) {
const char *var = luaL_checkstring(L, 1);
const char *value;
/* If the second argument is nil or nothing, unset the var */
if(lua_isnoneornil(L, 2)) {
if(unsetenv(var) != 0) {
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushstring(L, strerror(errno));
return 2;
}
@@ -707,7 +717,7 @@ int lc_setenv(lua_State *L) {
value = luaL_checkstring(L, 2);
if(setenv(var, value, 1) != 0) {
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushstring(L, strerror(errno));
return 2;
}
@@ -717,7 +727,7 @@ int lc_setenv(lua_State *L) {
}
#ifdef WITH_MALLINFO
-int lc_meminfo(lua_State *L) {
+static int lc_meminfo(lua_State *L) {
struct mallinfo info = mallinfo();
lua_createtable(L, 0, 5);
/* This is the total size of memory allocated with sbrk by malloc, in bytes. */
@@ -745,7 +755,7 @@ int lc_meminfo(lua_State *L) {
* Attempt to allocate space first
* Truncate to original size on failure
*/
-int lc_atomic_append(lua_State *L) {
+static int lc_atomic_append(lua_State *L) {
int err;
size_t len;
@@ -769,7 +779,7 @@ int lc_atomic_append(lua_State *L) {
case ENOSPC: /* No space left */
default: /* Other issues */
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushstring(L, strerror(err));
lua_pushinteger(L, err);
return 3;
@@ -796,12 +806,19 @@ int lc_atomic_append(lua_State *L) {
return luaL_error(L, "atomic_append() failed in ftruncate(): %s", strerror(errno));
}
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushstring(L, strerror(err));
lua_pushinteger(L, err);
return 3;
}
+static int lc_isatty(lua_State *L) {
+ FILE *f = *(FILE **) luaL_checkudata(L, 1, LUA_FILEHANDLE);
+ const int fd = fileno(f);
+ lua_pushboolean(L, isatty(fd));
+ return 1;
+}
+
/* Register functions */
int luaopen_util_pposix(lua_State *L) {
@@ -843,6 +860,8 @@ int luaopen_util_pposix(lua_State *L) {
{ "atomic_append", lc_atomic_append },
+ { "isatty", lc_isatty },
+
{ NULL, NULL }
};
diff --git a/util-src/ringbuffer.c b/util-src/ringbuffer.c
index 8f9013f7..0f250c12 100644
--- a/util-src/ringbuffer.c
+++ b/util-src/ringbuffer.c
@@ -2,11 +2,14 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
-#include <stdio.h>
#include <lua.h>
#include <lauxlib.h>
+#if (LUA_VERSION_NUM < 504)
+#define luaL_pushfail lua_pushnil
+#endif
+
typedef struct {
size_t rpos; /* read position */
size_t wpos; /* write position */
@@ -15,23 +18,67 @@ typedef struct {
char buffer[];
} ringbuffer;
-char readchar(ringbuffer *b) {
- b->blen--;
- return b->buffer[(b->rpos++) % b->alen];
+/* Translate absolute idx to a wrapped index within the buffer,
+ based on current read position */
+static int wrap_pos(const ringbuffer *b, const long idx, long *pos) {
+ if(idx > (long)b->blen) {
+ return 0;
+ }
+ if(idx + (long)b->rpos > (long)b->alen) {
+ *pos = idx - (b->alen - b->rpos);
+ } else {
+ *pos = b->rpos + idx;
+ }
+ return 1;
+}
+
+static int calc_splice_positions(const ringbuffer *b, long start, long end, long *out_start, long *out_end) {
+ if(start < 0) {
+ start = 1 + start + b->blen;
+ }
+ if(start <= 0) {
+ start = 1;
+ }
+
+ if(end < 0) {
+ end = 1 + end + b->blen;
+ }
+
+ if(end > (long)b->blen) {
+ end = b->blen;
+ }
+ if(start < 1) {
+ start = 1;
+ }
+
+ if(start > end) {
+ return 0;
+ }
+
+ start = start - 1;
+
+ if(!wrap_pos(b, start, out_start)) {
+ return 0;
+ }
+ if(!wrap_pos(b, end, out_end)) {
+ return 0;
+ }
+
+ return 1;
}
-void writechar(ringbuffer *b, char c) {
+static void writechar(ringbuffer *b, char c) {
b->blen++;
b->buffer[(b->wpos++) % b->alen] = c;
}
/* make sure position counters stay within the allocation */
-void modpos(ringbuffer *b) {
+static void modpos(ringbuffer *b) {
b->rpos = b->rpos % b->alen;
b->wpos = b->wpos % b->alen;
}
-int find(ringbuffer *b, const char *s, size_t l) {
+static int find(ringbuffer *b, const char *s, size_t l) {
size_t i, j;
int m;
@@ -64,7 +111,7 @@ int find(ringbuffer *b, const char *s, size_t l) {
* Find first position of a substring in buffer
* (buffer, string) -> number
*/
-int rb_find(lua_State *L) {
+static int rb_find(lua_State *L) {
size_t l, m;
ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt");
const char *s = luaL_checklstring(L, 2, &l);
@@ -82,7 +129,7 @@ int rb_find(lua_State *L) {
* Move read position forward without returning the data
* (buffer, number) -> boolean
*/
-int rb_discard(lua_State *L) {
+static int rb_discard(lua_State *L) {
ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt");
size_t r = luaL_checkinteger(L, 2);
@@ -103,13 +150,13 @@ int rb_discard(lua_State *L) {
* Read bytes from buffer
* (buffer, number, boolean?) -> string
*/
-int rb_read(lua_State *L) {
+static int rb_read(lua_State *L) {
ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt");
size_t r = luaL_checkinteger(L, 2);
int peek = lua_toboolean(L, 3);
if(r > b->blen) {
- lua_pushnil(L);
+ luaL_pushfail(L);
return 1;
}
@@ -135,7 +182,7 @@ int rb_read(lua_State *L) {
* Read buffer until first occurrence of a substring
* (buffer, string) -> string
*/
-int rb_readuntil(lua_State *L) {
+static int rb_readuntil(lua_State *L) {
size_t l, m;
ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt");
const char *s = luaL_checklstring(L, 2, &l);
@@ -154,14 +201,14 @@ int rb_readuntil(lua_State *L) {
* Write bytes into the buffer
* (buffer, string) -> integer
*/
-int rb_write(lua_State *L) {
+static int rb_write(lua_State *L) {
size_t l, w = 0;
ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt");
const char *s = luaL_checklstring(L, 2, &l);
/* Does `l` bytes fit? */
if((l + b->blen) > b->alen) {
- lua_pushnil(L);
+ luaL_pushfail(L);
return 1;
}
@@ -177,32 +224,82 @@ int rb_write(lua_State *L) {
return 1;
}
-int rb_tostring(lua_State *L) {
+static int rb_tostring(lua_State *L) {
ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt");
lua_pushfstring(L, "ringbuffer: %p %d/%d", b, b->blen, b->alen);
return 1;
}
-int rb_length(lua_State *L) {
+static int rb_sub(lua_State *L) {
+ ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt");
+
+ long start = luaL_checkinteger(L, 2);
+ long end = luaL_optinteger(L, 3, -1);
+
+ long wrapped_start, wrapped_end;
+ if(!calc_splice_positions(b, start, end, &wrapped_start, &wrapped_end)) {
+ lua_pushstring(L, "");
+ } else if(wrapped_end <= wrapped_start) {
+ lua_pushlstring(L, &b->buffer[wrapped_start], b->alen - wrapped_start);
+ lua_pushlstring(L, b->buffer, wrapped_end);
+ lua_concat(L, 2);
+ } else {
+ lua_pushlstring(L, &b->buffer[wrapped_start], (wrapped_end - wrapped_start));
+ }
+
+ return 1;
+}
+
+static int rb_byte(lua_State *L) {
+ ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt");
+
+ long start = luaL_optinteger(L, 2, 1);
+ long end = luaL_optinteger(L, 3, start);
+
+ long i;
+
+ long wrapped_start, wrapped_end;
+ if(calc_splice_positions(b, start, end, &wrapped_start, &wrapped_end)) {
+ if(wrapped_end <= wrapped_start) {
+ for(i = wrapped_start; i < (long)b->alen; i++) {
+ lua_pushinteger(L, (unsigned char)b->buffer[i]);
+ }
+ for(i = 0; i < wrapped_end; i++) {
+ lua_pushinteger(L, (unsigned char)b->buffer[i]);
+ }
+ return wrapped_end + (b->alen - wrapped_start);
+ } else {
+ for(i = wrapped_start; i < wrapped_end; i++) {
+ lua_pushinteger(L, (unsigned char)b->buffer[i]);
+ }
+ return wrapped_end - wrapped_start;
+ }
+ }
+
+ return 0;
+}
+
+static int rb_length(lua_State *L) {
ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt");
lua_pushinteger(L, b->blen);
return 1;
}
-int rb_size(lua_State *L) {
+static int rb_size(lua_State *L) {
ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt");
lua_pushinteger(L, b->alen);
return 1;
}
-int rb_free(lua_State *L) {
+static int rb_free(lua_State *L) {
ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt");
lua_pushinteger(L, b->alen - b->blen);
return 1;
}
-int rb_new(lua_State *L) {
- size_t size = luaL_optinteger(L, 1, sysconf(_SC_PAGESIZE));
+static int rb_new(lua_State *L) {
+ lua_Integer size = luaL_optinteger(L, 1, sysconf(_SC_PAGESIZE));
+ luaL_argcheck(L, size > 0, 1, "positive integer expected");
ringbuffer *b = lua_newuserdata(L, sizeof(ringbuffer) + size);
b->rpos = 0;
@@ -243,6 +340,10 @@ int luaopen_util_ringbuffer(lua_State *L) {
lua_setfield(L, -2, "size");
lua_pushcfunction(L, rb_length);
lua_setfield(L, -2, "length");
+ lua_pushcfunction(L, rb_sub);
+ lua_setfield(L, -2, "sub");
+ lua_pushcfunction(L, rb_byte);
+ lua_setfield(L, -2, "byte");
lua_pushcfunction(L, rb_free);
lua_setfield(L, -2, "free");
}
diff --git a/util-src/signal.c b/util-src/signal.c
index c696a3a2..1a398fa0 100644
--- a/util-src/signal.c
+++ b/util-src/signal.c
@@ -39,6 +39,9 @@
#if (LUA_VERSION_NUM == 501)
#define luaL_setfuncs(L, R, N) luaL_register(L, NULL, R)
#endif
+#if (LUA_VERSION_NUM < 503)
+#define lua_isinteger(L, n) lua_isnumber(L, n)
+#endif
#ifndef lsig
@@ -164,8 +167,8 @@ static lua_Hook Hsig = NULL;
static int Hmask = 0;
static int Hcount = 0;
-int signals[MAX_PENDING_SIGNALS];
-int nsig = 0;
+static int signals[MAX_PENDING_SIGNALS];
+static int nsig = 0;
static void sighook(lua_State *L, lua_Debug *ar) {
(void)ar;
@@ -176,7 +179,7 @@ static void sighook(lua_State *L, lua_Debug *ar) {
lua_gettable(L, LUA_REGISTRYINDEX);
for(int i = 0; i < nsig; i++) {
- lua_pushnumber(L, signals[i]);
+ lua_pushinteger(L, signals[i]);
lua_gettable(L, -2);
lua_call(L, 0, 0);
};
@@ -223,18 +226,18 @@ static int l_signal(lua_State *L) {
t = lua_type(L, 1);
if(t == LUA_TNUMBER) {
- sig = (int) lua_tonumber(L, 1);
+ sig = (int) lua_tointeger(L, 1);
} else if(t == LUA_TSTRING) {
lua_pushstring(L, LUA_SIGNAL);
lua_gettable(L, LUA_REGISTRYINDEX);
lua_pushvalue(L, 1);
lua_gettable(L, -2);
- if(!lua_isnumber(L, -1)) {
+ if(!lua_isinteger(L, -1)) {
return luaL_error(L, "invalid signal string");
}
- sig = (int) lua_tonumber(L, -1);
+ sig = (int) lua_tointeger(L, -1);
lua_pop(L, 1); /* get rid of number we pushed */
} else {
luaL_checknumber(L, 1); /* will always error, with good error msg */
@@ -245,9 +248,9 @@ static int l_signal(lua_State *L) {
if(args == 1 || lua_isnil(L, 2)) { /* clear handler */
lua_pushstring(L, LUA_SIGNAL);
lua_gettable(L, LUA_REGISTRYINDEX);
- lua_pushnumber(L, sig);
+ lua_pushinteger(L, sig);
lua_gettable(L, -2); /* return old handler */
- lua_pushnumber(L, sig);
+ lua_pushinteger(L, sig);
lua_pushnil(L);
lua_settable(L, -4);
lua_remove(L, -2); /* remove LUA_SIGNAL table */
@@ -258,7 +261,7 @@ static int l_signal(lua_State *L) {
lua_pushstring(L, LUA_SIGNAL);
lua_gettable(L, LUA_REGISTRYINDEX);
- lua_pushnumber(L, sig);
+ lua_pushinteger(L, sig);
lua_pushvalue(L, 2);
lua_settable(L, -3);
@@ -292,15 +295,15 @@ static int l_signal(lua_State *L) {
static int l_raise(lua_State *L) {
/* int args = lua_gettop(L); */
int t = 0; /* type */
- lua_Number ret;
+ lua_Integer ret;
luaL_checkany(L, 1);
t = lua_type(L, 1);
if(t == LUA_TNUMBER) {
- ret = (lua_Number) raise((int) lua_tonumber(L, 1));
- lua_pushnumber(L, ret);
+ ret = (lua_Integer) raise((int) lua_tointeger(L, 1));
+ lua_pushinteger(L, ret);
} else if(t == LUA_TSTRING) {
lua_pushstring(L, LUA_SIGNAL);
lua_gettable(L, LUA_REGISTRYINDEX);
@@ -311,9 +314,9 @@ static int l_raise(lua_State *L) {
return luaL_error(L, "invalid signal string");
}
- ret = (lua_Number) raise((int) lua_tonumber(L, -1));
+ ret = (lua_Integer) raise((int) lua_tointeger(L, -1));
lua_pop(L, 1); /* get rid of number we pushed */
- lua_pushnumber(L, ret);
+ lua_pushinteger(L, ret);
} else {
luaL_checknumber(L, 1); /* will always error, with good error msg */
}
@@ -334,7 +337,7 @@ static int l_raise(lua_State *L) {
static int l_kill(lua_State *L) {
int t; /* type */
- lua_Number ret; /* return value */
+ lua_Integer ret; /* return value */
luaL_checknumber(L, 1); /* must be int for pid */
luaL_checkany(L, 2); /* check for a second arg */
@@ -342,9 +345,9 @@ static int l_kill(lua_State *L) {
t = lua_type(L, 2);
if(t == LUA_TNUMBER) {
- ret = (lua_Number) kill((int) lua_tonumber(L, 1),
- (int) lua_tonumber(L, 2));
- lua_pushnumber(L, ret);
+ ret = (lua_Integer) kill((int) lua_tointeger(L, 1),
+ (int) lua_tointeger(L, 2));
+ lua_pushinteger(L, ret);
} else if(t == LUA_TSTRING) {
lua_pushstring(L, LUA_SIGNAL);
lua_gettable(L, LUA_REGISTRYINDEX);
@@ -355,10 +358,10 @@ static int l_kill(lua_State *L) {
return luaL_error(L, "invalid signal string");
}
- ret = (lua_Number) kill((int) lua_tonumber(L, 1),
- (int) lua_tonumber(L, -1));
+ ret = (lua_Integer) kill((int) lua_tointeger(L, 1),
+ (int) lua_tointeger(L, -1));
lua_pop(L, 1); /* get rid of number we pushed */
- lua_pushnumber(L, ret);
+ lua_pushinteger(L, ret);
} else {
luaL_checknumber(L, 2); /* will always error, with good error msg */
}
@@ -396,11 +399,11 @@ int luaopen_util_signal(lua_State *L) {
while(lua_signals[i].name != NULL) {
/* registry table */
lua_pushstring(L, lua_signals[i].name);
- lua_pushnumber(L, lua_signals[i].sig);
+ lua_pushinteger(L, lua_signals[i].sig);
lua_settable(L, -3);
/* signal table */
lua_pushstring(L, lua_signals[i].name);
- lua_pushnumber(L, lua_signals[i].sig);
+ lua_pushinteger(L, lua_signals[i].sig);
lua_settable(L, -5);
i++;
}
diff --git a/util-src/time.c b/util-src/time.c
index bfad52ee..afef3df5 100644
--- a/util-src/time.c
+++ b/util-src/time.c
@@ -1,22 +1,22 @@
#ifndef _POSIX_C_SOURCE
-#define _POSIX_C_SOURCE 199309L
+#define _POSIX_C_SOURCE 200809L
#endif
#include <time.h>
#include <lua.h>
-lua_Number tv2number(struct timespec *tv) {
+static lua_Number tv2number(struct timespec *tv) {
return tv->tv_sec + tv->tv_nsec * 1e-9;
}
-int lc_time_realtime(lua_State *L) {
+static int lc_time_realtime(lua_State *L) {
struct timespec t;
clock_gettime(CLOCK_REALTIME, &t);
lua_pushnumber(L, tv2number(&t));
return 1;
}
-int lc_time_monotonic(lua_State *L) {
+static int lc_time_monotonic(lua_State *L) {
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
lua_pushnumber(L, tv2number(&t));
diff --git a/util-src/windows.c b/util-src/windows.c
index 89bec57b..57af79d5 100644
--- a/util-src/windows.c
+++ b/util-src/windows.c
@@ -22,6 +22,9 @@
#if (LUA_VERSION_NUM == 501)
#define luaL_setfuncs(L, R, N) luaL_register(L, NULL, R)
#endif
+#if (LUA_VERSION_NUM < 504)
+#define luaL_pushfail lua_pushnil
+#endif
static int Lget_nameservers(lua_State *L) {
char stack_buffer[1024]; // stack allocated buffer
@@ -45,14 +48,14 @@ static int Lget_nameservers(lua_State *L) {
return 1;
} else {
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushfstring(L, "DnsQueryConfig returned %d", status);
return 2;
}
}
static int lerror(lua_State *L, char *string) {
- lua_pushnil(L);
+ luaL_pushfail(L);
lua_pushfstring(L, "%s: %d", string, GetLastError());
return 2;
}