struct pakfire_cgroup* cgroup;
struct pakfire_cgroup_stats cgroup_stats;
+
+ // The function to be called once the jail has been set up
+ int (*callback)(struct pakfire_jail* jail, void* data);
+ void* data;
};
static int pivot_root(const char* new_root, const char* old_root) {
return sd_event_exit(sd_event_source_get_event(source), 0);
}
+static int pakfire_jail_launch_command(struct pakfire_jail* jail, void* data) {
+ char** argv = data;
+ int r;
+
+ // Check if argv is valid
+ if (!argv || !argv[0])
+ return -EINVAL;
+
+ DEBUG(jail->ctx, "Launching command:\n");
+
+ // Log argv
+ for (unsigned int i = 0; argv[i]; i++)
+ DEBUG(jail->ctx, " argv[%u] = %s\n", i, argv[i]);
+
+ // exec() command
+ r = execvpe(argv[0], argv, jail->env);
+ if (r < 0) {
+ // Translate errno into regular exit code
+ switch (errno) {
+ case ENOENT:
+#if 0
+ // Ignore if the command doesn't exist
+ if (ctx->flags & PAKFIRE_JAIL_NOENT_OK)
+ r = 0;
+ else
+ r = 127;
+
+ break;
+#endif
+
+ default:
+ r = 1;
+ }
+
+ ERROR(jail->ctx, "Could not execve(%s): %m\n", argv[0]);
+ }
+
+ // We should not get here
+ return r;
+}
+
/*
Performs the initialisation that needs to happen in the parent part
*/
return 0;
}
-static int pakfire_jail_child(struct pakfire_jail* jail, struct pakfire_jail_exec* ctx,
- const char* argv[]) {
+static int pakfire_jail_child(struct pakfire_jail* jail, struct pakfire_jail_exec* ctx) {
int r;
- // Check if we have received a command
- if (!argv || !*argv)
- return -EINVAL;
-
// Redirect any logging to our log pipe
pakfire_ctx_set_log_callback(jail->ctx, pakfire_jail_log_redirect, ctx);
return r;
DEBUG(jail->ctx, "Child process initialization done\n");
- DEBUG(jail->ctx, "Launching command:\n");
-
- // Log argv
- for (unsigned int i = 0; argv[i]; i++)
- DEBUG(jail->ctx, " argv[%u] = %s\n", i, argv[i]);
- // exec() command
- r = execvpe(argv[0], (char**)argv, jail->env);
- if (r < 0) {
- // Translate errno into regular exit code
- switch (errno) {
- case ENOENT:
- // Ignore if the command doesn't exist
- if (ctx->flags & PAKFIRE_JAIL_NOENT_OK)
- r = 0;
- else
- r = 127;
-
- break;
-
- default:
- r = 1;
- }
-
- ERROR(jail->ctx, "Could not execve(%s): %m\n", argv[0]);
+ // Check if we have a callback
+ if (!ctx->callback) {
+ ERROR(jail->ctx, "No callback set\n");
+ return 126;
}
- // We should not get here
- return r;
+ // Call the callback
+ return ctx->callback(jail, ctx->data);
}
// Run a command in the jail
static int __pakfire_jail_exec(struct pakfire_jail* jail,
- const char* argv[], int flags,
+ pakfire_jail_callback callback, void* data, int flags,
pakfire_pty_stdin_callback stdin_callback, void* stdin_data,
pakfire_pty_stdout_callback stdout_callback, void* stdout_data,
char** output, size_t* output_length) {
int pty_flags = 0;
int r;
- // Check if argv is valid
- if (!argv || !argv[0])
- return -EINVAL;
-
// We cannot have both, an output callback and buffer
if (stdout_callback && output)
return -EINVAL;
.flags = flags,
.pidfd = -1,
+ // Callback & Data
+ .callback = callback,
+ .data = data,
+
// Exit Code
.exit = -1,
};
// Child process
} else if (ctx.pid == 0) {
- r = pakfire_jail_child(jail, &ctx, argv);
+ r = pakfire_jail_child(jail, &ctx);
_exit(r);
}
}
int pakfire_jail_exec(struct pakfire_jail* jail, const char* argv[], int flags) {
- return __pakfire_jail_exec(jail, argv, flags, NULL, NULL, NULL, NULL, NULL, NULL);
+ return __pakfire_jail_exec(jail, pakfire_jail_launch_command, argv, flags,
+ NULL, NULL, NULL, NULL, NULL, NULL);
}
int pakfire_jail_exec_capture_output(struct pakfire_jail* jail,
const char* argv[], int flags, char** output, size_t* length) {
- return __pakfire_jail_exec(jail, argv, flags, NULL, NULL, NULL, NULL, output, length);
+ return __pakfire_jail_exec(jail, pakfire_jail_launch_command, argv, flags,
+ NULL, NULL, NULL, NULL, output, length);
}
int pakfire_jail_communicate(
struct pakfire_jail* jail, const char* argv[], int flags,
pakfire_pty_stdin_callback stdin_callback, void* stdin_data,
pakfire_pty_stdout_callback stdout_callback, void* stdout_data) {
- return __pakfire_jail_exec(jail, argv, flags,
+ return __pakfire_jail_exec(jail, pakfire_jail_launch_command, argv, flags,
stdin_callback, stdin_data, stdout_callback, stdout_data, NULL, NULL);
}