webmcp
annotate libraries/extos/extos.c @ 27:1da1078a87b1
fix crash on eglibc
compiling without _GNU_SOURCE causes extos to crash on crypt as the return pointer is invalid.
compiling without _GNU_SOURCE causes extos to crash on crypt as the return pointer is invalid.
author | Daniel Poelzleithner <poelzi@poelzi.org> |
---|---|
date | Wed Sep 15 02:43:06 2010 +0200 (2010-09-15) |
parents | 9fdfb27f8e67 |
children | 3d43a5cf17c1 |
rev | line source |
---|---|
jbe/bsw@0 | 1 #include <lua.h> |
jbe/bsw@0 | 2 #include <lauxlib.h> |
jbe/bsw@0 | 3 #include <dirent.h> |
jbe/bsw@0 | 4 #include <time.h> |
jbe/bsw@0 | 5 #include <unistd.h> |
jbe/bsw@0 | 6 #include <sys/types.h> |
jbe/bsw@0 | 7 #include <sys/wait.h> |
jbe/bsw@0 | 8 #include <signal.h> |
jbe/bsw@0 | 9 #include <errno.h> |
jbe/bsw@0 | 10 #include <stdio.h> |
jbe/bsw@0 | 11 #include <string.h> |
jbe/bsw@0 | 12 #include <fcntl.h> |
jbe/bsw@0 | 13 #include <poll.h> |
jbe/bsw@0 | 14 #include <stdlib.h> |
jbe/bsw@0 | 15 |
jbe/bsw@0 | 16 #define EXTOS_MAX_ERRLEN 80 |
jbe/bsw@0 | 17 #define EXTOS_EXEC_MAX_ARGS 64 |
jbe/bsw@0 | 18 |
jbe/bsw@0 | 19 static lua_Number extos_monotonic_start_time; |
jbe/bsw@0 | 20 |
jbe/bsw@0 | 21 static int extos_pfilter(lua_State *L) { |
jbe/bsw@0 | 22 int i, result, exit_status, status_pipe_len; |
jbe/bsw@0 | 23 const char *in_buf; |
jbe/bsw@0 | 24 size_t in_len; |
jbe/bsw@0 | 25 size_t in_pos = 0; |
jbe/bsw@0 | 26 const char *filename; |
jbe/bsw@0 | 27 const char *args[EXTOS_EXEC_MAX_ARGS+2]; |
jbe/bsw@0 | 28 int pipe_status[2]; |
jbe/bsw@0 | 29 int pipe_in[2]; |
jbe/bsw@0 | 30 int pipe_out[2]; |
jbe/bsw@0 | 31 int pipe_err[2]; |
jbe/bsw@0 | 32 pid_t child; |
jbe/bsw@0 | 33 char status_buf[1]; |
jbe/bsw@0 | 34 char *out_buf = NULL; |
jbe/bsw@0 | 35 size_t out_len = 1024; |
jbe/bsw@0 | 36 size_t out_pos = 0; |
jbe/bsw@0 | 37 char *err_buf = NULL; |
jbe/bsw@0 | 38 size_t err_len = 1024; |
jbe/bsw@0 | 39 size_t err_pos = 0; |
jbe/bsw@0 | 40 void *old_sigpipe_action; |
jbe/bsw@0 | 41 struct pollfd fds[3]; |
jbe/bsw@0 | 42 int in_closed = 0; |
jbe/bsw@0 | 43 int out_closed = 0; |
jbe/bsw@0 | 44 int err_closed = 0; |
jbe/bsw@0 | 45 void *newptr; |
jbe/bsw@0 | 46 char errmsg[EXTOS_MAX_ERRLEN+1]; |
jbe/bsw@0 | 47 in_buf = luaL_optlstring(L, 1, "", &in_len); |
jbe/bsw@0 | 48 filename = luaL_checkstring(L, 2); |
jbe/bsw@0 | 49 args[0] = filename; |
jbe/bsw@0 | 50 for (i = 0; i < EXTOS_EXEC_MAX_ARGS; i++) { |
jbe/bsw@0 | 51 if (lua_isnoneornil(L, 3+i)) break; |
jbe/bsw@0 | 52 else args[i+1] = luaL_checkstring(L, 3+i); |
jbe/bsw@0 | 53 } |
jbe/bsw@0 | 54 if (!lua_isnoneornil(L, 3+i)) { |
jbe/bsw@0 | 55 return luaL_error(L, "Too many arguments for pfilter call."); |
jbe/bsw@0 | 56 } |
jbe/bsw@0 | 57 args[i+1] = 0; |
jbe/bsw@0 | 58 // status pipe for internal communication |
jbe/bsw@0 | 59 if (pipe(pipe_status) < 0) { |
jbe/bsw@0 | 60 strerror_r(errno, errmsg, EXTOS_MAX_ERRLEN+1); |
jbe/bsw@0 | 61 goto extos_pfilter_error_A0; |
jbe/bsw@0 | 62 } |
jbe/bsw@0 | 63 // stdin |
jbe/bsw@0 | 64 if (pipe(pipe_in) < 0) { |
jbe/bsw@0 | 65 strerror_r(errno, errmsg, EXTOS_MAX_ERRLEN+1); |
jbe/bsw@0 | 66 goto extos_pfilter_error_A1; |
jbe/bsw@0 | 67 } |
jbe/bsw@0 | 68 if (in_len) { |
jbe/bsw@0 | 69 do result = fcntl(pipe_in[1], F_SETFL, O_NONBLOCK); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 70 } else { |
jbe/bsw@0 | 71 do result = close(pipe_in[1]); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 72 in_closed = 1; |
jbe/bsw@0 | 73 } |
jbe/bsw@0 | 74 if (result < 0) { |
jbe/bsw@0 | 75 strerror_r(errno, errmsg, EXTOS_MAX_ERRLEN+1); |
jbe/bsw@0 | 76 goto extos_pfilter_error_A2; |
jbe/bsw@0 | 77 } |
jbe/bsw@0 | 78 // stdout |
jbe/bsw@0 | 79 if (pipe(pipe_out) < 0) { |
jbe/bsw@0 | 80 strerror_r(errno, errmsg, EXTOS_MAX_ERRLEN+1); |
jbe/bsw@0 | 81 goto extos_pfilter_error_A2; |
jbe/bsw@0 | 82 } |
jbe/bsw@0 | 83 do result = fcntl(pipe_out[0], F_SETFL, O_NONBLOCK); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 84 if (result < 0) { |
jbe/bsw@0 | 85 strerror_r(errno, errmsg, EXTOS_MAX_ERRLEN+1); |
jbe/bsw@0 | 86 goto extos_pfilter_error_A3; |
jbe/bsw@0 | 87 } |
jbe/bsw@0 | 88 // stderr |
jbe/bsw@0 | 89 if (pipe(pipe_err) < 0) { |
jbe/bsw@0 | 90 strerror_r(errno, errmsg, EXTOS_MAX_ERRLEN+1); |
jbe/bsw@0 | 91 goto extos_pfilter_error_A3; |
jbe/bsw@0 | 92 } |
jbe/bsw@0 | 93 do result = fcntl(pipe_err[0], F_SETFL, O_NONBLOCK); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 94 if (result < 0) { |
jbe/bsw@0 | 95 strerror_r(errno, errmsg, EXTOS_MAX_ERRLEN+1); |
jbe/bsw@0 | 96 goto extos_pfilter_error_A4; |
jbe/bsw@0 | 97 } |
jbe/bsw@0 | 98 // fork |
jbe/bsw@0 | 99 child = fork(); |
jbe/bsw@0 | 100 if (child < 0) { |
jbe/bsw@0 | 101 strerror_r(errno, errmsg, EXTOS_MAX_ERRLEN+1); |
jbe/bsw@0 | 102 goto extos_pfilter_error_A4; |
jbe/bsw@0 | 103 } |
jbe/bsw@0 | 104 // skip error handling |
jbe/bsw@0 | 105 goto extos_pfilter_success_A; |
jbe/bsw@0 | 106 // error handling |
jbe/bsw@0 | 107 extos_pfilter_error_A4: |
jbe/bsw@0 | 108 do result = close(pipe_err[0]); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 109 do result = close(pipe_err[1]); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 110 extos_pfilter_error_A3: |
jbe/bsw@0 | 111 do result = close(pipe_out[0]); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 112 do result = close(pipe_out[1]); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 113 extos_pfilter_error_A2: |
jbe/bsw@0 | 114 do result = close(pipe_in[0]); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 115 do result = close(pipe_in[1]); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 116 extos_pfilter_error_A1: |
jbe/bsw@0 | 117 do result = close(pipe_status[0]); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 118 do result = close(pipe_status[1]); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 119 extos_pfilter_error_A0: |
jbe/bsw@0 | 120 return luaL_error(L, "Unexpected error in pfilter: %s", errmsg); |
jbe/bsw@0 | 121 // end of error handling |
jbe/bsw@0 | 122 extos_pfilter_success_A: |
jbe/bsw@0 | 123 if (child) { // parent |
jbe/bsw@0 | 124 old_sigpipe_action = signal(SIGPIPE, SIG_IGN); |
jbe/bsw@0 | 125 do result = close(pipe_status[1]); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 126 if (result < 0) goto extos_pfilter_error_B; |
jbe/bsw@0 | 127 do result = close(pipe_in[0]); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 128 if (result < 0) goto extos_pfilter_error_B; |
jbe/bsw@0 | 129 do result = close(pipe_out[1]); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 130 if (result < 0) goto extos_pfilter_error_B; |
jbe/bsw@0 | 131 do result = close(pipe_err[1]); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 132 if (result < 0) goto extos_pfilter_error_B; |
jbe/bsw@0 | 133 out_buf = malloc(out_len * sizeof(char)); |
jbe/bsw@0 | 134 if (!out_buf) goto extos_pfilter_error_B; |
jbe/bsw@0 | 135 err_buf = malloc(err_len * sizeof(char)); |
jbe/bsw@0 | 136 if (!err_buf) goto extos_pfilter_error_B; |
jbe/bsw@0 | 137 while (!in_closed || !out_closed || !err_closed) { |
jbe/bsw@0 | 138 i = 0; |
jbe/bsw@0 | 139 if (!in_closed) { |
jbe/bsw@0 | 140 fds[i].fd = pipe_in[1]; |
jbe/bsw@0 | 141 fds[i].events = POLLOUT; |
jbe/bsw@0 | 142 i++; |
jbe/bsw@0 | 143 } |
jbe/bsw@0 | 144 if (!out_closed) { |
jbe/bsw@0 | 145 fds[i].fd = pipe_out[0]; |
jbe/bsw@0 | 146 fds[i].events = POLLIN; |
jbe/bsw@0 | 147 i++; |
jbe/bsw@0 | 148 } |
jbe/bsw@0 | 149 if (!err_closed) { |
jbe/bsw@0 | 150 fds[i].fd = pipe_err[0]; |
jbe/bsw@0 | 151 fds[i].events = POLLIN; |
jbe/bsw@0 | 152 i++; |
jbe/bsw@0 | 153 } |
jbe/bsw@0 | 154 do result = poll(fds, i, -1); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 155 if (result < 0) goto extos_pfilter_error_B; |
jbe/bsw@0 | 156 if (!in_closed) { |
jbe/bsw@0 | 157 do result = write(pipe_in[1], in_buf+in_pos, in_len-in_pos); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 158 if (result < 0) { |
jbe/bsw@0 | 159 if (errno == EPIPE) { |
jbe/bsw@0 | 160 do result = close(pipe_in[1]); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 161 in_closed = 1; |
jbe/bsw@0 | 162 } else if (errno != EAGAIN) { |
jbe/bsw@0 | 163 goto extos_pfilter_error_B; |
jbe/bsw@0 | 164 } |
jbe/bsw@0 | 165 } else { |
jbe/bsw@0 | 166 in_pos += result; |
jbe/bsw@0 | 167 if (in_pos == in_len) { |
jbe/bsw@0 | 168 do result = close(pipe_in[1]); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 169 in_closed = 1; |
jbe/bsw@0 | 170 } |
jbe/bsw@0 | 171 } |
jbe/bsw@0 | 172 } |
jbe/bsw@0 | 173 if (!out_closed) { |
jbe/bsw@0 | 174 do result = read(pipe_out[0], out_buf+out_pos, out_len-out_pos); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 175 if (result < 0) { |
jbe/bsw@0 | 176 if (errno != EAGAIN) goto extos_pfilter_error_B; |
jbe/bsw@0 | 177 } else if (result == 0) { |
jbe/bsw@0 | 178 do result = close(pipe_out[0]); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 179 out_closed = 1; |
jbe/bsw@0 | 180 } else { |
jbe/bsw@0 | 181 out_pos += result; |
jbe/bsw@0 | 182 if (out_pos == out_len) { |
jbe/bsw@0 | 183 out_len *= 2; |
jbe/bsw@0 | 184 newptr = realloc(out_buf, out_len * sizeof(char)); |
jbe/bsw@0 | 185 if (!newptr) goto extos_pfilter_error_B; |
jbe/bsw@0 | 186 out_buf = newptr; |
jbe/bsw@0 | 187 } |
jbe/bsw@0 | 188 } |
jbe/bsw@0 | 189 } |
jbe/bsw@0 | 190 if (!err_closed) { |
jbe/bsw@0 | 191 do result = read(pipe_err[0], err_buf+err_pos, err_len-err_pos); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 192 if (result < 0) { |
jbe/bsw@0 | 193 if (errno != EAGAIN) goto extos_pfilter_error_B; |
jbe/bsw@0 | 194 } else if (result == 0) { |
jbe/bsw@0 | 195 do result = close(pipe_err[0]); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 196 err_closed = 1; |
jbe/bsw@0 | 197 } else { |
jbe/bsw@0 | 198 err_pos += result; |
jbe/bsw@0 | 199 if (err_pos == err_len) { |
jbe/bsw@0 | 200 err_len *= 2; |
jbe/bsw@0 | 201 newptr = realloc(err_buf, err_len * sizeof(char)); |
jbe/bsw@0 | 202 if (!newptr) goto extos_pfilter_error_B; |
jbe/bsw@0 | 203 err_buf = newptr; |
jbe/bsw@0 | 204 } |
jbe/bsw@0 | 205 } |
jbe/bsw@0 | 206 } |
jbe/bsw@0 | 207 } |
jbe/bsw@0 | 208 lua_pushlstring(L, out_buf, out_pos); |
jbe/bsw@0 | 209 free(out_buf); |
jbe/bsw@0 | 210 out_buf = NULL; |
jbe/bsw@0 | 211 lua_pushlstring(L, err_buf, err_pos); |
jbe/bsw@0 | 212 free(err_buf); |
jbe/bsw@0 | 213 err_buf = NULL; |
jbe/bsw@0 | 214 do result = waitpid(child, &exit_status, 0); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 215 child = 0; |
jbe/bsw@0 | 216 if (result < 0) goto extos_pfilter_error_B; |
jbe/bsw@0 | 217 do status_pipe_len = read(pipe_status[0], status_buf, 1); while (status_pipe_len < 0 && errno == EINTR); |
jbe/bsw@0 | 218 if (status_pipe_len < 0) goto extos_pfilter_error_B; |
jbe/bsw@0 | 219 do result = close(pipe_status[0]); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 220 signal(SIGPIPE, old_sigpipe_action); |
jbe/bsw@0 | 221 if (status_pipe_len == 0) { |
jbe/bsw@0 | 222 if (WIFEXITED(exit_status)) lua_pushinteger(L, WEXITSTATUS(exit_status)); |
jbe/bsw@0 | 223 else lua_pushinteger(L, -WTERMSIG(exit_status)); |
jbe/bsw@0 | 224 return 3; |
jbe/bsw@0 | 225 } else if (status_buf[0] == 0) { |
jbe/bsw@0 | 226 return luaL_error(L, "Error in pfilter while reopening standard file descriptors in child process."); |
jbe/bsw@0 | 227 } else { |
jbe/bsw@0 | 228 strerror_r(status_buf[0], errmsg, EXTOS_MAX_ERRLEN+1); |
jbe/bsw@0 | 229 lua_pushnil(L); |
jbe/bsw@0 | 230 lua_pushfstring(L, "Could not execute \"%s\": %s", filename, errmsg); |
jbe/bsw@0 | 231 return 2; |
jbe/bsw@0 | 232 } |
jbe/bsw@0 | 233 extos_pfilter_error_B: |
jbe/bsw@0 | 234 signal(SIGPIPE, old_sigpipe_action); |
jbe/bsw@0 | 235 strerror_r(errno, errmsg, EXTOS_MAX_ERRLEN+1); |
jbe/bsw@0 | 236 if (out_buf) free(out_buf); |
jbe/bsw@0 | 237 if (err_buf) free(err_buf); |
jbe/bsw@0 | 238 if (!in_closed) { |
jbe/bsw@0 | 239 do result = close(pipe_in[1]); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 240 } |
jbe/bsw@0 | 241 if (!out_closed) { |
jbe/bsw@0 | 242 do result = close(pipe_out[0]); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 243 } |
jbe/bsw@0 | 244 if (!err_closed) { |
jbe/bsw@0 | 245 do result = close(pipe_err[0]); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 246 } |
jbe/bsw@0 | 247 if (child) do result = waitpid(child, &exit_status, 0); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 248 return luaL_error(L, "Unexpected error in pfilter: %s", errmsg); |
jbe/bsw@0 | 249 } else { // child |
jbe/bsw@0 | 250 do result = close(pipe_status[0]); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 251 do result = close(pipe_in[1]); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 252 do result = close(pipe_out[0]); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 253 do result = close(0); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 254 do result = close(1); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 255 do result = close(2); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 256 do result = dup(pipe_in[0]); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 257 if (result != 0) goto extos_pfilter_error_fd_remapping; |
jbe/bsw@0 | 258 do result = dup(pipe_out[1]); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 259 if (result != 1) goto extos_pfilter_error_fd_remapping; |
jbe/bsw@0 | 260 do result = dup(pipe_err[1]); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 261 if (result != 2) goto extos_pfilter_error_fd_remapping; |
jbe/bsw@0 | 262 execvp(filename, args); |
jbe/bsw@0 | 263 status_buf[0] = errno; |
jbe/bsw@0 | 264 do result = write(pipe_status[1], status_buf, 1); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 265 _exit(0); |
jbe/bsw@0 | 266 extos_pfilter_error_fd_remapping: |
jbe/bsw@0 | 267 status_buf[0] = 0; |
jbe/bsw@0 | 268 do result = write(pipe_status[1], status_buf, 1); while (result < 0 && errno == EINTR); |
jbe/bsw@0 | 269 _exit(0); |
jbe/bsw@0 | 270 } |
jbe/bsw@0 | 271 } |
jbe/bsw@0 | 272 |
jbe/bsw@0 | 273 static int extos_listdir(lua_State *L) { |
jbe/bsw@0 | 274 DIR *dir; |
jbe/bsw@0 | 275 int i = 1; |
jbe/bsw@0 | 276 struct dirent entry_buffer; |
jbe/bsw@0 | 277 struct dirent *entry; |
jbe/bsw@0 | 278 dir = opendir(luaL_checkstring(L, 1)); |
jbe/bsw@0 | 279 if (!dir) { |
jbe/bsw@0 | 280 lua_pushnil(L); |
jbe/bsw@0 | 281 lua_pushliteral(L, "Could not list directory."); |
jbe/bsw@0 | 282 return 2; |
jbe/bsw@0 | 283 } |
jbe/bsw@0 | 284 lua_settop(L, 0); |
jbe/bsw@0 | 285 lua_newtable(L); // 1 |
jbe/bsw@0 | 286 while (1) { |
jbe/bsw@0 | 287 readdir_r(dir, &entry_buffer, &entry); |
jbe/bsw@0 | 288 if (!entry) break; |
jbe/bsw@0 | 289 // Linux doesn't have d_namlen |
jbe/bsw@0 | 290 //lua_pushlstring(L, entry->d_name, entry->d_namlen); |
jbe/bsw@0 | 291 lua_pushstring(L, entry->d_name); |
jbe/bsw@0 | 292 lua_rawseti(L, 1, i++); |
jbe/bsw@0 | 293 } |
jbe/bsw@0 | 294 closedir(dir); |
jbe/bsw@0 | 295 return 1; |
jbe/bsw@0 | 296 } |
jbe/bsw@0 | 297 |
jbe/bsw@0 | 298 static int extos_crypt(lua_State *L) { |
jbe/bsw@0 | 299 char *key; |
jbe/bsw@0 | 300 char *salt; |
jbe/bsw@0 | 301 char *result; |
jbe/bsw@0 | 302 key = luaL_checkstring(L, 1); |
jbe/bsw@0 | 303 salt = luaL_checkstring(L, 2); |
jbe/bsw@0 | 304 result = crypt(key, salt); // TODO: Call not thread safe |
jbe/bsw@0 | 305 if (result) lua_pushstring(L, result); |
jbe/bsw@0 | 306 else lua_pushnil(L); |
jbe/bsw@0 | 307 return 1; |
jbe/bsw@0 | 308 } |
jbe/bsw@0 | 309 |
jbe/bsw@0 | 310 static int extos_hires_time(lua_State *L) { |
jbe/bsw@0 | 311 struct timespec tp; |
jbe/bsw@0 | 312 if (clock_gettime(CLOCK_REALTIME, &tp)) { |
jbe/bsw@0 | 313 return luaL_error(L, "Could not access CLOCK_REALTIME."); |
jbe/bsw@0 | 314 } |
jbe/bsw@0 | 315 lua_pushnumber(L, tp.tv_sec + 0.000000001 * tp.tv_nsec); |
jbe/bsw@0 | 316 return 1; |
jbe/bsw@0 | 317 } |
jbe/bsw@0 | 318 |
jbe/bsw@0 | 319 // returns time in seconds since loading the library |
jbe/bsw@0 | 320 static int extos_monotonic_hires_time(lua_State *L) { |
jbe/bsw@0 | 321 struct timespec tp; |
jbe/bsw@0 | 322 if (clock_gettime(CLOCK_MONOTONIC, &tp)) { |
jbe/bsw@0 | 323 return luaL_error(L, "Could not access CLOCK_MONOTONIC."); |
jbe/bsw@0 | 324 } |
jbe/bsw@0 | 325 lua_pushnumber(L, |
jbe/bsw@0 | 326 tp.tv_sec + 0.000000001 * tp.tv_nsec - extos_monotonic_start_time |
jbe/bsw@0 | 327 ); |
jbe/bsw@0 | 328 return 1; |
jbe/bsw@0 | 329 } |
jbe/bsw@0 | 330 |
jbe/bsw@0 | 331 int luaopen_extos(lua_State *L) { |
jbe/bsw@0 | 332 { |
jbe/bsw@0 | 333 struct timespec tp; |
jbe/bsw@0 | 334 if (clock_gettime(CLOCK_MONOTONIC, &tp)) { |
jbe/bsw@0 | 335 return luaL_error(L, "Could not access monotonic hires time."); |
jbe/bsw@0 | 336 } |
jbe/bsw@0 | 337 extos_monotonic_start_time = tp.tv_sec + 0.000000001 * tp.tv_nsec; |
jbe/bsw@0 | 338 } |
jbe/bsw@0 | 339 lua_getglobal(L, "os"); |
jbe/bsw@0 | 340 lua_pushcfunction(L, extos_pfilter); |
jbe/bsw@0 | 341 lua_setfield(L, -2, "pfilter"); |
jbe/bsw@0 | 342 lua_pushcfunction(L, extos_listdir); |
jbe/bsw@0 | 343 lua_setfield(L, -2, "listdir"); |
jbe/bsw@0 | 344 lua_pushcfunction(L, extos_crypt); |
jbe/bsw@0 | 345 lua_setfield(L, -2, "crypt"); |
jbe/bsw@0 | 346 lua_pushcfunction(L, extos_hires_time); |
jbe/bsw@0 | 347 lua_setfield(L, -2, "hires_time"); |
jbe/bsw@0 | 348 lua_pushcfunction(L, extos_monotonic_hires_time); |
jbe/bsw@0 | 349 lua_setfield(L, -2, "monotonic_hires_time"); |
jbe/bsw@0 | 350 return 0; |
jbe/bsw@0 | 351 } |