/* diriter ... -- entry */ static int ex_dir(lua_State *L) { const char *pathname; DIR **pd; struct dirent *d; switch (lua_type(L, 1)) { default: return luaL_typerror(L, 1, "pathname"); case LUA_TSTRING: pathname = lua_tostring(L, 1); lua_pushcfunction(L, ex_dir); /* pathname ... iter */ pd = lua_newuserdata(L, sizeof *pd);/* pathname ... iter state */ *pd = opendir(pathname); if (!*pd) return push_error(L); luaL_getmetatable(L, DIR_HANDLE); /* pathname ... iter state M */ lua_setmetatable(L, -2); /* pathname ... iter state */ lua_pushvalue(L, 1); /* pathname ... iter state pathname */ diriter_setpathname(L, -2); /* pathname ... iter state */ return 2; case LUA_TUSERDATA: pd = luaL_checkudata(L, 1, DIR_HANDLE); do d = readdir(*pd); while (d && isdotfile(d->d_name)); if (!d) { diriter_close(L); return push_error(L); } new_dirent(L); /* diriter ... entry */ diriter_getpathname(L, 1); /* diriter ... entry dir */ lua_pushstring(L, d->d_name); /* diriter ... entry dir name */ lua_pushvalue(L, -1); /* diriter ... entry dir name name */ lua_setfield(L, -4, "name"); /* diriter ... entry dir name */ lua_concat(L, 2); /* diriter ... entry fullpath */ lua_replace(L, 1); /* fullpath ... entry */ lua_replace(L, 2); /* fullpath entry ... */ return ex_dirent(L); } /*NOTREACHED*/ }
/* diriter -- diriter */ static int diriter_close(lua_State *L) { DIR **pd = lua_touserdata(L, 1); if (*pd) { closedir(*pd); *pd = 0; } lua_pushnil(L); diriter_setpathname(L, 1); return 0; }