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) {