#include <pakfire/parser.h>
#include <pakfire/path.h>
#include <pakfire/problem.h>
+#include <pakfire/pty.h>
#include <pakfire/repo.h>
#include <pakfire/scriptlet.h>
#include <pakfire/solution.h>
return pakfire_timespec_delta(&now, &build->time_start);
}
-static int pakfire_build_output_callback(
- struct pakfire_ctx* ctx, void* data, const char* buffer, size_t length) {
+static int pakfire_build_output_callback(struct pakfire_ctx* ctx, void* data,
+ const enum pakfire_jail_output_stream stream, const char* line, size_t length) {
struct pakfire_build* build = data;
// Get the runtime of the build
const unsigned int s = (unsigned int)t % 60;
const unsigned int ms = (unsigned int)(t * 1000.0) % 1000;
- if (h)
- INFO(ctx, "[%02u:%02u:%02u.%04u] %.*s", h, m, s, ms, (int)length, buffer);
+ switch (stream) {
+ case PAKFIRE_STDOUT:
+ if (h)
+ INFO(ctx, "[%02u:%02u:%02u.%04u] %.*s", h, m, s, ms, (int)length, line);
- else if (m)
- INFO(ctx, "[ %02u:%02u.%04u] %.*s", m, s, ms, (int)length, buffer);
+ else if (m)
+ INFO(ctx, "[ %02u:%02u.%04u] %.*s", m, s, ms, (int)length, line);
- else
- INFO(ctx, "[ %02u.%04u] %.*s", s, ms, (int)length, buffer);
+ else
+ INFO(ctx, "[ %02u.%04u] %.*s", s, ms, (int)length, line);
+ break;
+
+ case PAKFIRE_STDERR:
+ if (h)
+ ERROR(ctx, "[%02u:%02u:%02u.%04u] %.*s", h, m, s, ms, (int)length, line);
+
+ else if (m)
+ ERROR(ctx, "[ %02u:%02u.%04u] %.*s", m, s, ms, (int)length, line);
+
+ else
+ ERROR(ctx, "[ %02u.%04u] %.*s", s, ms, (int)length, line);
+ break;
+ }
return 0;
}
const char* filename,
const char* args[],
pakfire_jail_input_callback input_callback, void* input_data,
- pakfire_pty_stdout_callback stdout_callback, void* stdout_data) {
+ pakfire_jail_output_callback output_callback, void* output_data) {
char* script = NULL;
size_t length = 0;
int r;
// Execute the script
r = pakfire_jail_exec_script(build->jail, script, length, args, build->env,
- input_callback, input_data, stdout_callback, stdout_data);
+ input_callback, input_data, output_callback, output_data);
if (r)
ERROR(build->ctx, "Script '%s' failed with status %d\n", filename, r);
return 0;
}
-static int pakfire_build_process_pkgconfig_provides(
- struct pakfire_ctx* ctx, void* data, const char* line, const size_t length) {
+static int pakfire_build_process_pkgconfig_provides(struct pakfire_ctx* ctx, void* data,
+ const enum pakfire_jail_output_stream stream, const char* line, const size_t length) {
struct pakfire_find_deps_ctx* deps = data;
+ struct pakfire_build* self = deps->build;
+
+ switch (stream) {
+ // Process any output
+ case PAKFIRE_STDOUT:
+ return pakfire_build_process_pkgconfig_dep(deps->pkg, PAKFIRE_PKG_PROVIDES, line, length);
- return pakfire_build_process_pkgconfig_dep(deps->pkg, PAKFIRE_PKG_PROVIDES, line, length);
+ // Log any errors
+ case PAKFIRE_STDERR:
+ ERROR(self->ctx, "%.*s", (int)length, line);
+ break;
+ }
+
+ return 0;
}
-static int pakfire_build_process_pkgconfig_requires(
- struct pakfire_ctx* ctx, void* data, const char* line, const size_t length) {
+static int pakfire_build_process_pkgconfig_requires(struct pakfire_ctx* ctx, void* data,
+ const enum pakfire_jail_output_stream stream, const char* line, const size_t length) {
struct pakfire_find_deps_ctx* deps = data;
+ struct pakfire_build* self = deps->build;
+
+ switch (stream) {
+ // Process any output
+ case PAKFIRE_STDOUT:
+ return pakfire_build_process_pkgconfig_dep(deps->pkg, PAKFIRE_PKG_REQUIRES, line, length);
- return pakfire_build_process_pkgconfig_dep(deps->pkg, PAKFIRE_PKG_REQUIRES, line, length);
+ // Log any errors
+ case PAKFIRE_STDERR:
+ ERROR(self->ctx, "%.*s", (int)length, line);
+ break;
+ }
+
+ return 0;
}
static int pakfire_build_find_pkgconfig_provides(
return pakfire_package_add_dep(pkg, key, "%.*s", (int)length, line);
}
-static int pakfire_build_add_perl_provides(struct pakfire_ctx* ctx,
- void* data, const char* line, size_t length) {
+static int pakfire_build_add_perl_provides(struct pakfire_ctx* ctx, void* data,
+ const enum pakfire_jail_output_stream stream, const char* line, size_t length) {
struct pakfire_package* pkg = data;
- return pakfire_build_add_perl_dep(ctx, pkg, PAKFIRE_PKG_PROVIDES, line, length);
+ switch (stream) {
+ // Process output
+ case PAKFIRE_STDOUT:
+ return pakfire_build_add_perl_dep(ctx, pkg, PAKFIRE_PKG_PROVIDES, line, length);
+
+ // Log errors
+ case PAKFIRE_STDERR:
+ ERROR(ctx, "%.*s", (int)length, line);
+ break;
+ }
+
+ return 0;
}
-static int pakfire_build_add_perl_requires(struct pakfire_ctx* ctx,
- void* data, const char* line, size_t length) {
+static int pakfire_build_add_perl_requires(struct pakfire_ctx* ctx, void* data,
+ const enum pakfire_jail_output_stream stream, const char* line, size_t length) {
struct pakfire_package* pkg = data;
- return pakfire_build_add_perl_dep(ctx, pkg, PAKFIRE_PKG_REQUIRES, line, length);
+ switch (stream) {
+ // Process output
+ case PAKFIRE_STDOUT:
+ return pakfire_build_add_perl_dep(ctx, pkg, PAKFIRE_PKG_REQUIRES, line, length);
+
+ // Log errors
+ case PAKFIRE_STDERR:
+ ERROR(ctx, "%.*s", (int)length, line);
+ break;
+ }
+
+ return 0;
}
static int pakfire_build_find_perl_deps(struct pakfire_build* build,
return __pakfire_string_setn(command, lcommand, s, l);
}
-static int pakfire_build_process_scriptlet_dep(
- struct pakfire_ctx* ctx, void* data, const char* line, const size_t length) {
+static int pakfire_build_process_scriptlet_dep(struct pakfire_ctx* ctx, void* data,
+ const enum pakfire_jail_output_stream stream, const char* line, const size_t length) {
struct pakfire_find_deps_ctx* deps = data;
+ struct pakfire_build* self = deps->build;
char command[PATH_MAX];
char path[PATH_MAX];
int r;
- // Try to extract the command
- r = pakfire_build_extract_command(command, sizeof(command), line, length);
- if (r < 0) {
- switch (-r) {
- // Ignore if the string was presumed to be invalid (some other format)
- case EINVAL:
- DEBUG(ctx, "Ignoring invalid line %.*s\n", (int)length, line);
- return 0;
+ switch (stream) {
+ // Process output
+ case PAKFIRE_STDOUT:
+ // Try to extract the command
+ r = pakfire_build_extract_command(command, sizeof(command), line, length);
+ if (r < 0) {
+ switch (-r) {
+ // Ignore if the string was presumed to be invalid (some other format)
+ case EINVAL:
+ DEBUG(ctx, "Ignoring invalid line %.*s\n", (int)length, line);
+ return 0;
+
+ default:
+ return r;
+ }
+ }
- default:
- return r;
- }
- }
+ DEBUG(ctx, "Found '%s' as a dependency of the scriptlet\n", command);
- DEBUG(ctx, "Found '%s' as a dependency of the scriptlet\n", command);
+ // Add absolute paths just like that
+ if (pakfire_path_is_absolute(command)) {
+ r = pakfire_package_add_dep(deps->pkg, PAKFIRE_PKG_PREREQUIRES, "%s", command);
+ if (r < 0)
+ return r;
- // Add absolute paths just like that
- if (pakfire_path_is_absolute(command)) {
- r = pakfire_package_add_dep(deps->pkg, PAKFIRE_PKG_PREREQUIRES, "%s", command);
- if (r < 0)
- return r;
+ // Otherwise, we will have to resolve the command
+ } else {
+ r = pakfire_which(deps->build->pakfire, path, command);
+ if (r < 0)
+ return r;
- // Otherwise, we will have to resolve the command
- } else {
- r = pakfire_which(deps->build->pakfire, path, command);
- if (r < 0)
- return r;
+ // If we could resolve the command, we add the full path
+ if (*path) {
+ r = pakfire_package_add_dep(deps->pkg, PAKFIRE_PKG_PREREQUIRES, "%s", path);
+ if (r < 0)
+ return r;
+ }
+ }
+ break;
- // If we could resolve the command, we add the full path
- if (*path) {
- r = pakfire_package_add_dep(deps->pkg, PAKFIRE_PKG_PREREQUIRES, "%s", path);
- if (r < 0)
- return r;
- }
+ // Log errors
+ case PAKFIRE_STDERR:
+ ERROR(self->ctx, "%.*s", (int)length, line);
+ break;
}
return 0;
}
#endif /* ENABLE_DEBUG */
+static int pakfire_jail_output_stdout(struct pakfire_ctx* ctx, void* data, const char* line, size_t length) {
+ struct pakfire_jail_exec* exec = data;
+
+ // Do nothing if we don't have a callback
+ if (!exec->callbacks.output)
+ return 0;
+
+ return exec->callbacks.output(ctx, exec->callbacks.output_data, PAKFIRE_STDOUT, line, length);
+}
+
+static int pakfire_jail_output_stderr(struct pakfire_ctx* ctx, void* data, const char* line, size_t length) {
+ struct pakfire_jail_exec* exec = data;
+
+ // Do nothing if we don't have a callback
+ if (!exec->callbacks.output)
+ return 0;
+
+ return exec->callbacks.output(ctx, exec->callbacks.output_data, PAKFIRE_STDERR, line, length);
+}
+
// Capabilities
// Logs all capabilities of the current process
static int __pakfire_jail_exec(struct pakfire_jail* jail,
pakfire_jail_callback callback, void* data, int flags,
pakfire_jail_input_callback input_callback, void* input_data,
- pakfire_pty_stdout_callback stdout_callback, void* stdout_data,
+ pakfire_jail_output_callback output_callback, void* output_data,
char** output, size_t* output_length) {
struct pakfire_log_stream* stdout = NULL;
struct pakfire_log_stream* stderr = NULL;
int r;
// We cannot have both, an output callback and buffer
- if (stdout_callback && output)
+ if (output_callback && output)
return -EINVAL;
// Initialize context for this call
}
// Otherwise send the output to the log streamer
- } else {
+ } else if (output_callback) {
+ // Store the callback
+ ctx.callbacks.output = output_callback;
+ ctx.callbacks.output_data = output_data;
+
// Create a new stream
- r = pakfire_log_stream_create(&stdout, jail->ctx, stdout_callback, stdout_data);
+ r = pakfire_log_stream_create(&stdout, jail->ctx, pakfire_jail_output_stdout, &ctx);
if (r < 0) {
ERROR(jail->ctx, "Failed to create standard output stream: %s\n", strerror(-r));
goto ERROR;
r = -errno;
goto ERROR;
}
- }
- // Send the standard error output to a log streamer, too
- r = pakfire_log_stream_create(&stderr, jail->ctx, stdout_callback, stdout_data);
- if (r < 0) {
- ERROR(jail->ctx, "Failed to create standard error stream: %s\n", strerror(-r));
- goto ERROR;
- }
+ // Send the standard error output to a log streamer, too
+ r = pakfire_log_stream_create(&stderr, jail->ctx, pakfire_jail_output_stderr, &ctx);
+ if (r < 0) {
+ ERROR(jail->ctx, "Failed to create standard error stream: %s\n", strerror(-r));
+ goto ERROR;
+ }
- // Ask to stream our output into this
- ctx.streams.stderr = pakfire_log_stream_as_file(stderr);
- if (!ctx.streams.stderr) {
- ERROR(jail->ctx, "Failed to open file stream for standard output: %m\n");
- r = -errno;
- goto ERROR;
+ // Ask to stream our output into this
+ ctx.streams.stderr = pakfire_log_stream_as_file(stderr);
+ if (!ctx.streams.stderr) {
+ ERROR(jail->ctx, "Failed to open file stream for standard output: %m\n");
+ r = -errno;
+ goto ERROR;
+ }
}
}
int pakfire_jail_communicate(
struct pakfire_jail* jail, const char* argv[], struct pakfire_env* env, int flags,
pakfire_jail_input_callback input_callback, void* input_data,
- pakfire_pty_stdout_callback stdout_callback, void* stdout_data) {
+ pakfire_jail_output_callback output_callback, void* output_data) {
struct pakfire_jail_command command = {
.jail = jail,
.argv = argv,
};
return __pakfire_jail_exec(jail, pakfire_jail_launch_command, &command, flags,
- input_callback, input_data, stdout_callback, stdout_data, NULL, NULL);
+ input_callback, input_data, output_callback, output_data, NULL, NULL);
}
int pakfire_jail_exec_script(struct pakfire_jail* jail,
const char* script, const size_t size, const char* args[], struct pakfire_env* env,
pakfire_jail_input_callback input_callback, void* input_data,
- pakfire_pty_stdout_callback stdout_callback, void* stdout_data) {
+ pakfire_jail_output_callback output_callback, void* output_data) {
char path[PATH_MAX];
const char** argv = NULL;
FILE* f = NULL;
// Run the script
r = pakfire_jail_communicate(jail, argv, env, 0,
- input_callback, input_data, stdout_callback, stdout_data);
+ input_callback, input_data, output_callback, output_data);
ERROR:
if (argv)