feat(buffer): ability to read from stdin

This commit is contained in:
Jeremy Attali 2019-12-29 16:48:13 -05:00
parent 5f06804eea
commit 02bc464564
5 changed files with 87 additions and 16 deletions

24
.vscode/launch.json vendored
View File

@ -51,6 +51,30 @@
"ignoreFailures": true
}
]
},
{
"name": "swappy - stdin",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/meson-out/swappy",
"args": ["-f", "-"],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [
{
"name": "G_MESSAGES_DEBUG",
"value": "all"
}
],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}

View File

@ -2,3 +2,4 @@
bool folder_exists(const char *path);
bool file_exists(const char *path);
char *file_dump_stdin_into_a_temp_file();

View File

@ -157,6 +157,7 @@ void application_finish(struct swappy_state *state) {
cairo_surface_destroy(state->cairo_surface);
cairo_surface_destroy(state->image_surface);
g_free(state->storage_path);
g_free(state->file_str);
g_free(state->geometry_str);
g_free(state->geometry);
g_free(state->ui);
@ -531,19 +532,8 @@ static gboolean has_option_file(struct swappy_state *state) {
return (state->file_str != NULL);
}
static gboolean is_file_valid(const char *file) {
cairo_surface_t *surface = cairo_image_surface_create_from_png(file);
cairo_status_t status = cairo_surface_status(surface);
if (status) {
g_warning("error while loading: %s - cairo status: %s", file,
cairo_status_to_string(status));
return false;
}
cairo_surface_destroy(surface);
return true;
static gboolean is_file_from_stdin(const char *file) {
return (strcmp(file, "-") == 0);
}
static gint command_line_handler(GtkApplication *app,
@ -560,8 +550,10 @@ static gint command_line_handler(GtkApplication *app,
}
if (has_option_file(state)) {
if (!is_file_valid(state->file_str)) {
return EXIT_FAILURE;
if (is_file_from_stdin(state->file_str)) {
char *new_file_str = file_dump_stdin_into_a_temp_file();
g_free(state->file_str);
state->file_str = new_file_str;
}
if (!buffer_init_from_file(state)) {

View File

@ -178,8 +178,13 @@ bool buffer_init_from_file(struct swappy_state *state) {
char *file = state->file_str;
cairo_surface_t *surface = cairo_image_surface_create_from_png(file);
cairo_status_t status = cairo_surface_status(surface);
g_assert(surface);
if (status) {
g_warning("error while loading png file: %s - cairo status: %s", file,
cairo_status_to_string(status));
return false;
}
int width = cairo_image_surface_get_width(surface);
int height = cairo_image_surface_get_height(surface);

View File

@ -1,7 +1,15 @@
#define _POSIX_C_SOURCE 200112L
#include <errno.h>
#include <fcntl.h>
#include <glib.h>
#include <glib/gstdio.h>
#include <stdbool.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#define BLOCK_SIZE 1024
bool folder_exists(const char *path) {
struct stat sb;
@ -18,3 +26,44 @@ bool file_exists(const char *path) {
return (stat(path, &sb) == 0 && S_ISREG(sb.st_mode));
}
char *file_dump_stdin_into_a_temp_file() {
char buf[BLOCK_SIZE];
GError *error = NULL;
if (isatty(STDIN_FILENO)) {
g_warning("stdin is a tty");
return NULL;
}
// Reopen stdin as binary mode
g_freopen(NULL, "rb", stdin);
const gchar *tempdir = g_get_tmp_dir();
gchar filename[] = "swappy-stdin-XXXXXX.png";
gchar *ret = g_build_filename(tempdir, filename, NULL);
gint fd = g_mkstemp(ret);
if (fd == -1) {
g_warning("unable to dump stdin into temporary file");
return NULL;
}
g_info("writing stdin content into filepath: %s", ret);
size_t count = 1;
while (count > 0) {
count = fread(buf, 1, sizeof(buf), stdin);
write(fd, &buf, count);
}
g_close(fd, &error);
if (error) {
g_warning("unable to close temporary file: %s", error->message);
g_error_free(error);
return NULL;
}
return ret;
}