flua: add a chown(2) binding

The main difference with the chown in luaposix, is that it checks
and reports if a user or a group do exist when a string is passed
as arguments

Reviewed by:	kevans
Differential Revision:	https://reviews.freebsd.org/D37479
This commit is contained in:
Baptiste Daroussin 2022-11-24 09:16:05 +01:00
parent 3026214ed6
commit a1ab15abe2

View file

@ -30,6 +30,8 @@ __FBSDID("$FreeBSD$");
#include <sys/stat.h>
#include <errno.h>
#include <grp.h>
#include <pwd.h>
#include <string.h>
#include <unistd.h>
@ -63,6 +65,62 @@ lua_chmod(lua_State *L)
return 1;
}
static int
lua_chown(lua_State *L)
{
int n;
const char *path;
uid_t owner = (uid_t) -1;
gid_t group = (gid_t) -1;
n = lua_gettop(L);
luaL_argcheck(L, n > 1, n,
"chown takes at least two arguments");
path = luaL_checkstring(L, 1);
if (lua_isinteger(L, 2))
owner = (uid_t) lua_tointeger(L, 2);
else if (lua_isstring(L, 2)) {
struct passwd *p = getpwnam(lua_tostring(L, 2));
if (p != NULL)
owner = p->pw_uid;
else
return (luaL_argerror(L, 2,
lua_pushfstring(L, "unknown user %s",
lua_tostring(L, 2))));
} else if (!lua_isnoneornil(L, 2)) {
const char *type = luaL_typename(L, 2);
return (luaL_argerror(L, 2,
lua_pushfstring(L, "integer or string expected, got %s",
type)));
}
if (lua_isinteger(L, 3))
group = (gid_t) lua_tointeger(L, 3);
else if (lua_isstring(L, 3)) {
struct group *g = getgrnam(lua_tostring(L, 3));
if (g != NULL)
group = g->gr_gid;
else
return (luaL_argerror(L, 3,
lua_pushfstring(L, "unknown user %s",
lua_tostring(L, 3))));
} else if (!lua_isnoneornil(L, 3)) {
const char *type = luaL_typename(L, 3);
return (luaL_argerror(L, 3,
lua_pushfstring(L, "integer or string expected, got %s",
type)));
}
if (chown(path, owner, group) == -1) {
lua_pushnil(L);
lua_pushstring(L, strerror(errno));
lua_pushinteger(L, errno);
return (3);
}
lua_pushinteger(L, 0);
return (1);
}
static int
lua_getpid(lua_State *L)
{
@ -82,6 +140,7 @@ static const struct luaL_Reg sys_statlib[] = {
static const struct luaL_Reg unistdlib[] = {
REG_SIMPLE(getpid),
REG_SIMPLE(chown),
{ NULL, NULL },
};
#undef REG_SIMPLE