1 #include "first.h" 2 3 #include "mod_magnet_cache.h" 4 #include "stat_cache.h" 5 6 #include <errno.h> 7 #include <stdlib.h> 8 #include <string.h> /* strstr() */ 9 #include <unistd.h> /* lseek() read() */ 10 11 #include <lualib.h> 12 #include <lauxlib.h> 13 14 __attribute_cold__ 15 static script *script_init(void) 16 { 17 script *const sc = calloc(1, sizeof(*sc)); 18 force_assert(sc); 19 return sc; 20 } 21 22 __attribute_cold__ 23 static void script_free(script *sc) 24 { 25 if (!sc) return; 26 lua_close(sc->L); 27 free(sc->name.ptr); 28 free(sc->etag.ptr); 29 free(sc); 30 } 31 32 #if 0 33 script_cache *script_cache_init(void) 34 { 35 script_cache *p = calloc(1, sizeof(script_cache)); 36 force_assert(p); 37 return p; 38 } 39 #endif 40 41 void script_cache_free_data(script_cache *p) 42 { 43 if (!p) return; 44 for (uint32_t i = 0; i < p->used; ++i) 45 script_free(p->ptr[i]); 46 free(p->ptr); 47 } 48 49 __attribute_cold__ 50 __attribute_noinline__ 51 static lua_State *script_cache_load_script(script * const sc, int etag_flags) 52 { 53 /* read file and use luaL_loadbuffer() 54 * eliminate TOC-TOU race w/ independent stat() in stat_cache_get_entry() */ 55 56 stat_cache_entry * const sce = stat_cache_get_entry_open(&sc->name, 1); 57 buffer_clear(&sc->etag); 58 if (NULL == sce || sce->fd < 0 || -1 == lseek(sce->fd, 0, SEEK_SET)) { 59 /*(sce->fd < 0 might indicate empty file, which is not a valid script)*/ 60 if (NULL != sce) errno = EBADF; 61 return NULL; 62 } 63 const buffer * const etag = stat_cache_etag_get(sce, etag_flags); 64 if (etag) 65 buffer_copy_buffer(&sc->etag, etag); 66 67 const off_t sz = sce->st.st_size; 68 char * const buf = malloc(sz+1); 69 force_assert(buf); 70 71 ssize_t rd = 0; 72 off_t off = 0; 73 do { 74 rd = read(sce->fd, buf+off, (size_t)(sz-off)); 75 } while (rd > 0 ? (off += rd) != sz : rd < 0 && errno == EINTR); 76 if (off != sz) { /*(file truncated?)*/ 77 if (rd >= 0) errno = EIO; 78 free(buf); 79 return NULL; 80 } 81 82 /*(coarse heuristic to detect if script needs req_env initialized)*/ 83 buf[sz] = '\0'; /* for strstr() */ 84 sc->req_env_init = (NULL != strstr(buf, "req_env")); 85 86 int rc = luaL_loadbuffer(sc->L, buf, (size_t)sz, sc->name.ptr); 87 free(buf); 88 89 if (0 != rc) { 90 /* oops, an error, return it */ 91 return sc->L; 92 } 93 94 force_assert(lua_isfunction(sc->L, -1)); 95 return sc->L; 96 } 97 98 __attribute_cold__ 99 __attribute_nonnull__() 100 __attribute_returns_nonnull__ 101 static script *script_cache_new_script(script_cache * const cache, const buffer * const name) 102 { 103 script * const sc = script_init(); 104 105 if (cache->used == cache->size) { 106 cache->size += 16; 107 cache->ptr = realloc(cache->ptr, cache->size * sizeof(*(cache->ptr))); 108 force_assert(cache->ptr); 109 } 110 cache->ptr[cache->used++] = sc; 111 112 buffer_copy_buffer(&sc->name, name); 113 sc->L = luaL_newstate(); 114 luaL_openlibs(sc->L); 115 return sc; 116 } 117 118 script *script_cache_get_script(script_cache *cache, const buffer *name) 119 { 120 for (uint32_t i = 0; i < cache->used; ++i) { 121 script * const sc = cache->ptr[i]; 122 if (buffer_is_equal(&sc->name, name)) 123 return sc; 124 } 125 return script_cache_new_script(cache, name); 126 } 127 128 lua_State *script_cache_check_script(script * const sc, int etag_flags) 129 { 130 if (lua_gettop(sc->L) == 0) 131 return script_cache_load_script(sc, etag_flags); 132 133 /*force_assert(lua_gettop(sc->L) == 2);*/ 134 /*force_assert(lua_isfunction(sc->L, -2));*/ 135 136 stat_cache_entry * const sce = stat_cache_get_entry(&sc->name); 137 if (NULL == sce) { 138 lua_pop(sc->L, 2); /* pop the old function and lighty table */ 139 return script_cache_load_script(sc, etag_flags); 140 } 141 142 const buffer * const etag = stat_cache_etag_get(sce, etag_flags); 143 if (NULL == etag || !buffer_is_equal(&sc->etag, etag)) { 144 if (0 == etag_flags) 145 return sc->L; 146 /* the etag is outdated, reload the function */ 147 lua_pop(sc->L, 2); /* pop the old function and lighty table */ 148 return script_cache_load_script(sc, etag_flags); 149 } 150 151 return sc->L; 152 } 153