Skip to content

Commit

Permalink
feat(buffer): ability to read from stdin
Browse files Browse the repository at this point in the history
  • Loading branch information
jtheoof committed Dec 29, 2019
1 parent 5f06804 commit 02bc464
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 16 deletions.
24 changes: 24 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
]
}
]
}
1 change: 1 addition & 0 deletions include/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@

bool folder_exists(const char *path);
bool file_exists(const char *path);
char *file_dump_stdin_into_a_temp_file();
22 changes: 7 additions & 15 deletions src/application.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand All @@ -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)) {
Expand Down
7 changes: 6 additions & 1 deletion src/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
49 changes: 49 additions & 0 deletions src/file.c
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
}

0 comments on commit 02bc464

Please sign in to comment.