aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBaptiste Daroussin <bapt@FreeBSD.org>2022-11-24 08:16:05 +0000
committerBaptiste Daroussin <bapt@FreeBSD.org>2023-01-25 08:51:23 +0000
commitc69a31795b0ec00525d37ef0f0a9828a56ecf991 (patch)
tree8a16242734c1534268e2051dd81bdc29ec384824
parent026b0ff652e327ff850e643a7ab8d78fa9e56412 (diff)
downloadsrc-c69a31795b0ec00525d37ef0f0a9828a56ecf991.tar.gz
src-c69a31795b0ec00525d37ef0f0a9828a56ecf991.zip
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 (cherry picked from commit a1ab15abe2e2a1ed92cbad056df71afff7e8794e)
-rw-r--r--libexec/flua/modules/lposix.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/libexec/flua/modules/lposix.c b/libexec/flua/modules/lposix.c
index adf3a7bb9a1f..88687be2788c 100644
--- a/libexec/flua/modules/lposix.c
+++ b/libexec/flua/modules/lposix.c
@@ -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>
@@ -64,6 +66,62 @@ lua_chmod(lua_State *L)
}
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)
{
int n;
@@ -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