That way, we can have the length as an extra argument.
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
// Run the command (if given)
if (argv)
- return pakfire_jail_exec(build->jail, argv, 0, NULL);
+ return pakfire_jail_exec(build->jail, argv, 0);
// Otherwise run the shell
return pakfire_jail_shell(build->jail);
PAKFIRE_JAIL_HAS_LOOP_DEVICES = (1 << 3),
};
-int pakfire_jail_exec(struct pakfire_jail* jail, const char* argv[], int flags, char** output);
+int pakfire_jail_exec(struct pakfire_jail* jail, const char* argv[], int flags);
+
+int pakfire_jail_exec_capture_output(struct pakfire_jail* jail,
+ const char* argv[], int flags, char** output, size_t* length);
// Resource limits
int pakfire_jail_set_cgroup(struct pakfire_jail* jail, struct pakfire_cgroup* cgroup);
pakfire_pty_stdout_callback stdout_callback, void* stdout_data);
// Convenience functions
-int pakfire_jail_run(struct pakfire* pakfire, const char* argv[], int flags, char** output);
+int pakfire_jail_run(struct pakfire* pakfire,
+ const char* argv[], int flags, char** output, size_t* output_length);
int pakfire_jail_run_script(struct pakfire* pakfire,
const char* script, const size_t length, const char* argv[], int flags);
const char* argv[], int flags,
pakfire_pty_stdin_callback stdin_callback, void* stdin_data,
pakfire_pty_stdout_callback stdout_callback, void* stdout_data,
- char** output) {
+ char** output, size_t* output_length) {
int pty_flags = 0;
int r;
}
// Return the output
- if (output) {
- *output = pakfire_pty_output(ctx.pty, NULL);
- }
+ if (output)
+ *output = pakfire_pty_output(ctx.pty, output_length);
ERROR:
// Destroy the temporary cgroup (if any)
return ctx.exit;
}
-int pakfire_jail_exec(struct pakfire_jail* jail,
- const char* argv[], int flags, char** output) {
- return __pakfire_jail_exec(jail, argv, flags, NULL, NULL, NULL, NULL, output);
+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);
+}
+
+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);
}
int pakfire_jail_communicate(
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,
- stdin_callback, stdin_data, stdout_callback, stdout_data, NULL);
+ stdin_callback, stdin_data, stdout_callback, stdout_data, NULL, NULL);
}
int pakfire_jail_exec_script(struct pakfire_jail* jail,
A convenience function that creates a new jail, runs the given command and destroys
the jail again.
*/
-int pakfire_jail_run(struct pakfire* pakfire, const char* argv[], int flags, char** output) {
+int pakfire_jail_run(struct pakfire* pakfire,
+ const char* argv[], int flags, char** output, size_t* output_length) {
struct pakfire_jail* jail = NULL;
int r;
goto ERROR;
// Execute the command
- r = pakfire_jail_exec(jail, argv, flags, output);
+ r = pakfire_jail_exec_capture_output(jail, argv, flags, output, output_length);
ERROR:
if (jail)
}
// Execute /bin/bash
- r = pakfire_jail_exec(jail, argv, PAKFIRE_JAIL_INTERACTIVE, NULL);
+ r = pakfire_jail_exec(jail, argv, PAKFIRE_JAIL_INTERACTIVE);
// Raise any errors
if (r < 0)
goto ERROR;
}
- r = pakfire_jail_run(pakfire, argv, 0, NULL);
+ r = pakfire_jail_run(pakfire, argv, 0, NULL, NULL);
ERROR:
if (ctx)
// The output of the command
char* output = NULL;
+ size_t length = 0;
// Execute the command inside the Pakfire environment
- r = pakfire_jail_run(parser->pakfire, argv, 0, &output);
+ r = pakfire_jail_run(parser->pakfire, argv, 0, &output, &length);
if (r) {
// Just log this and continue
DEBUG(parser->pakfire, "Command '%s' failed with return code %d\n", command, r);
// Run a few things
for (unsigned int i = 0; i < 3; i++) {
- ASSERT_SUCCESS(pakfire_jail_exec(jail, argv, 0, NULL));
+ ASSERT_SUCCESS(pakfire_jail_exec(jail, argv, 0));
}
// Try reading the stats into some invalid space
ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire));
// Check if we receive the correct exit code
- ASSERT(pakfire_jail_exec(jail, argv, 0, NULL) == 123);
+ ASSERT(pakfire_jail_exec(jail, argv, 0) == 123);
// Success
r = EXIT_SUCCESS;
ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire));
// Check if we receive the correct exit code
- ASSERT(pakfire_jail_exec(jail, argv, 0, NULL) == 139);
+ ASSERT(pakfire_jail_exec(jail, argv, 0) == 139);
// Success
r = EXIT_SUCCESS;
static int test_exec(const struct test* t) {
struct pakfire_jail* jail = NULL;
char* output = NULL;
+ size_t length = 0;
// Create a new jail
ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire));
// Try to execute something
- ASSERT_SUCCESS(pakfire_jail_exec(jail, cmd_hello_world, 0, &output));
+ ASSERT_SUCCESS(pakfire_jail_exec_capture_output(jail, cmd_hello_world, 0, &output, &length));
// We should have some output
ASSERT_STRING_EQUALS(output, "Hello World!\n");
+ ASSERT_EQUALS(length, strlen("Hello World!\n"));
// Destroy it
ASSERT_NULL(pakfire_jail_unref(jail));
ASSERT_SUCCESS(pakfire_jail_set_cgroup(jail, cgroup));
// Run command
- ASSERT(pakfire_jail_exec(jail, cmd_hello_world, 0, NULL) == 0);
+ ASSERT(pakfire_jail_exec(jail, cmd_hello_world, 0) == 0);
r = EXIT_SUCCESS;
ASSERT_SUCCESS(pakfire_jail_nice(jail, 5));
// Check if the nice level has been set
- ASSERT_SUCCESS(pakfire_jail_exec(jail, argv, 0, &output));
+ ASSERT_SUCCESS(pakfire_jail_exec_capture_output(jail, argv, 0, &output, NULL));
ASSERT_STRING_EQUALS(output, "5\n");
// Success
ASSERT_SUCCESS(pakfire_cgroup_set_memory_limit(cgroup, 100 * 1024 * 1024));
// Try to exhaust all memory
- ASSERT_FAILURE(pakfire_jail_exec(jail, cmd_exhaust_memory, 0, NULL));
+ ASSERT_FAILURE(pakfire_jail_exec(jail, cmd_exhaust_memory, 0));
// A fork bomb should also exhaust all memory
- ASSERT_FAILURE(pakfire_jail_exec(jail, cmd_fork_bomb, 0, NULL));
+ ASSERT_FAILURE(pakfire_jail_exec(jail, cmd_fork_bomb, 0));
// Success
r = EXIT_SUCCESS;
ASSERT_SUCCESS(pakfire_cgroup_set_pid_limit(cgroup, 100));
// Try to fork as many processes as possible
- ASSERT_FAILURE(pakfire_jail_exec(jail, cmd_fork_bomb, 0, NULL));
+ ASSERT_FAILURE(pakfire_jail_exec(jail, cmd_fork_bomb, 0));
// Success
r = EXIT_SUCCESS;
char* output = NULL;
// Execute a simple command
- ASSERT_SUCCESS(pakfire_jail_run(t->pakfire, cmd_stat_ownership, 0, &output));
+ ASSERT_SUCCESS(pakfire_jail_run(t->pakfire, cmd_stat_ownership, 0, &output, NULL));
// Check if the file has been mapped to root/root
ASSERT_STRING_EQUALS(output, "uid=0 gid=0\n");
ASSERT_SUCCESS(pakfire_jail_bind(jail, source, target, MS_RDONLY));
// Check if the mount actually works
- ASSERT_SUCCESS(pakfire_jail_exec(jail, argv, 0, NULL));
+ ASSERT_SUCCESS(pakfire_jail_exec(jail, argv, 0));
// Success
r = EXIT_SUCCESS;
};
// Perform the command
- return pakfire_jail_exec(jail, argv, 0, NULL);
+ return pakfire_jail_exec(jail, argv, 0);
}
static int test_send_signal(const struct test* t) {
ASSERT_SUCCESS(pakfire_jail_set_timeout(jail, 1));
// Check if we receive the correct exit code
- ASSERT(pakfire_jail_exec(jail, argv, 0, NULL) == 139);
+ ASSERT(pakfire_jail_exec(jail, argv, 0) == 139);
// Success
r = EXIT_SUCCESS;