Software /
code /
prosody
Comparison
util-src/crand.c @ 7824:56552733742e
util.crand: Let Lua handle allocation, freeing and error handling for buffer
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Fri, 20 Jan 2017 11:52:46 +0100 |
parent | 7823:9b66ada1487c |
child | 7825:1dfa5847d49e |
comparison
equal
deleted
inserted
replaced
7823:9b66ada1487c | 7824:56552733742e |
---|---|
17 #include "lauxlib.h" | 17 #include "lauxlib.h" |
18 | 18 |
19 #include <string.h> | 19 #include <string.h> |
20 #include <errno.h> | 20 #include <errno.h> |
21 | 21 |
22 /* | |
23 * TODO: Decide on fixed size or dynamically allocated buffer | |
24 */ | |
25 #if 1 | |
26 #include <stdlib.h> | |
27 #else | |
28 #define BUFLEN 256 | |
29 #endif | |
30 | |
31 #if defined(WITH_GETRANDOM) | 22 #if defined(WITH_GETRANDOM) |
32 #include <unistd.h> | 23 #include <unistd.h> |
33 #include <sys/syscall.h> | 24 #include <sys/syscall.h> |
34 #include <linux/random.h> | 25 #include <linux/random.h> |
35 | 26 |
36 #ifndef SYS_getrandom | 27 #ifndef SYS_getrandom |
37 #error getrandom() requires Linux 3.17 or later | 28 #error getrandom() requires Linux 3.17 or later |
38 #endif | 29 #endif |
39 | 30 |
40 /* Was this not supposed to be a function? */ | 31 /* Was this not supposed to be a function? */ |
41 int getrandom(char *buf, size_t len, int flags) { | 32 int getrandom(void *buf, size_t len, int flags) { |
42 return syscall(SYS_getrandom, buf, len, flags); | 33 return syscall(SYS_getrandom, buf, len, flags); |
43 } | 34 } |
44 | 35 |
45 #elif defined(WITH_ARC4RANDOM) | 36 #elif defined(WITH_ARC4RANDOM) |
46 #include <stdlib.h> | 37 #include <stdlib.h> |
49 #else | 40 #else |
50 #error util.crand compiled without a random source | 41 #error util.crand compiled without a random source |
51 #endif | 42 #endif |
52 | 43 |
53 int Lrandom(lua_State *L) { | 44 int Lrandom(lua_State *L) { |
54 #ifdef BUFLEN | |
55 unsigned char buf[BUFLEN]; | |
56 #else | |
57 unsigned char *buf; | |
58 #endif | |
59 int ret = 0; | 45 int ret = 0; |
60 size_t len = (size_t)luaL_checkinteger(L, 1); | 46 size_t len = (size_t)luaL_checkinteger(L, 1); |
61 #ifdef BUFLEN | 47 void *buf = lua_newuserdata(L, len); |
62 len = len > BUFLEN ? BUFLEN : len; | |
63 #else | |
64 buf = malloc(len); | |
65 | |
66 if(buf == NULL) { | |
67 lua_pushnil(L); | |
68 lua_pushstring(L, "out of memory"); | |
69 /* or it migth be better to | |
70 * return lua_error(L); | |
71 */ | |
72 return 2; | |
73 } | |
74 | |
75 #endif | |
76 | 48 |
77 #if defined(WITH_GETRANDOM) | 49 #if defined(WITH_GETRANDOM) |
78 ret = getrandom(buf, len, 0); | 50 ret = getrandom(buf, len, 0); |
79 | 51 |
80 if(ret < 0) { | 52 if(ret < 0) { |
81 #ifndef BUFLEN | |
82 free(buf); | |
83 #endif | |
84 lua_pushnil(L); | 53 lua_pushnil(L); |
85 lua_pushstring(L, strerror(errno)); | 54 lua_pushstring(L, strerror(errno)); |
86 lua_pushinteger(L, errno); | 55 lua_pushinteger(L, errno); |
87 return 3; | 56 return 3; |
88 } | 57 } |
94 ret = RAND_bytes(buf, len); | 63 ret = RAND_bytes(buf, len); |
95 | 64 |
96 if(ret == 1) { | 65 if(ret == 1) { |
97 ret = len; | 66 ret = len; |
98 } else { | 67 } else { |
99 #ifndef BUFLEN | |
100 free(buf); | |
101 #endif | |
102 lua_pushnil(L); | 68 lua_pushnil(L); |
103 lua_pushstring(L, "failed"); | 69 lua_pushstring(L, "failed"); |
104 /* lua_pushinteger(L, ERR_get_error()); */ | 70 /* lua_pushinteger(L, ERR_get_error()); */ |
105 return 2; | 71 return 2; |
106 } | 72 } |
107 | 73 |
108 #endif | 74 #endif |
109 | 75 |
110 lua_pushlstring(L, (const char *)buf, ret); | 76 lua_pushlstring(L, buf, ret); |
111 #ifndef BUFLEN | |
112 free(buf); | |
113 #endif | |
114 return 1; | 77 return 1; |
115 } | 78 } |
116 | 79 |
117 #ifdef ENABLE_SEEDING | 80 #ifdef ENABLE_SEEDING |
118 int Lseed(lua_State *L) { | 81 int Lseed(lua_State *L) { |