Convert to CMake, fix terminal resize behaviour
Fucking terminals, always broken in one way or another. For future reference, libedit acts even worse than readline.
This commit is contained in:
		
							
								
								
									
										56
									
								
								CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
				
			|||||||
 | 
					project (json-rpc-shell C)
 | 
				
			||||||
 | 
					cmake_minimum_required (VERSION 2.8.5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Moar warnings
 | 
				
			||||||
 | 
					if ("${CMAKE_C_COMPILER_ID}" MATCHES "GNU" OR CMAKE_COMPILER_IS_GNUC)
 | 
				
			||||||
 | 
						set (CMAKE_C_FLAGS "-std=c99")
 | 
				
			||||||
 | 
						set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wall -Wextra")
 | 
				
			||||||
 | 
					endif ("${CMAKE_C_COMPILER_ID}" MATCHES "GNU" OR CMAKE_COMPILER_IS_GNUC)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Version
 | 
				
			||||||
 | 
					set (project_VERSION_MAJOR "0")
 | 
				
			||||||
 | 
					set (project_VERSION_MINOR "1")
 | 
				
			||||||
 | 
					set (project_VERSION_PATCH "0")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set (project_VERSION "${project_VERSION_MAJOR}")
 | 
				
			||||||
 | 
					set (project_VERSION "${project_VERSION}.${project_VERSION_MINOR}")
 | 
				
			||||||
 | 
					set (project_VERSION "${project_VERSION}.${project_VERSION_PATCH}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# For custom modules
 | 
				
			||||||
 | 
					set (CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Dependencies
 | 
				
			||||||
 | 
					find_package (PkgConfig REQUIRED)
 | 
				
			||||||
 | 
					pkg_check_modules (dependencies REQUIRED libcurl jansson)
 | 
				
			||||||
 | 
					find_package (LibEV REQUIRED)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include_directories (${dependencies_INCLUDE_DIRS} ${LIBEV_INCLUDE_DIRS})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Build the main executable and link it
 | 
				
			||||||
 | 
					add_executable (${PROJECT_NAME} ${PROJECT_NAME}.c)
 | 
				
			||||||
 | 
					target_link_libraries (${PROJECT_NAME}
 | 
				
			||||||
 | 
						${dependencies_LIBRARIES} ${LIBEV_LIBRARIES} readline)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# The files to be installed
 | 
				
			||||||
 | 
					include (GNUInstallDirs)
 | 
				
			||||||
 | 
					install (TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR})
 | 
				
			||||||
 | 
					install (FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# CPack
 | 
				
			||||||
 | 
					set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "Shell for JSON-RPC 2.0 HTTP queries")
 | 
				
			||||||
 | 
					set (CPACK_PACKAGE_VENDOR "Premysl Janouch")
 | 
				
			||||||
 | 
					set (CPACK_PACKAGE_CONTACT "Přemysl Janouch <p.janouch@gmail.com>")
 | 
				
			||||||
 | 
					set (CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
 | 
				
			||||||
 | 
					set (CPACK_PACKAGE_VERSION_MAJOR ${project_VERSION_MAJOR})
 | 
				
			||||||
 | 
					set (CPACK_PACKAGE_VERSION_MINOR ${project_VERSION_MINOR})
 | 
				
			||||||
 | 
					set (CPACK_PACKAGE_VERSION_PATCH ${project_VERSION_PATCH})
 | 
				
			||||||
 | 
					set (CPACK_GENERATOR "TGZ;ZIP")
 | 
				
			||||||
 | 
					set (CPACK_PACKAGE_FILE_NAME
 | 
				
			||||||
 | 
						"${PROJECT_NAME}-${project_VERSION}-${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}")
 | 
				
			||||||
 | 
					set (CPACK_PACKAGE_INSTALL_DIRECTORY "${PROJECT_NAME}-${project_VERSION}")
 | 
				
			||||||
 | 
					set (CPACK_SOURCE_GENERATOR "TGZ;ZIP")
 | 
				
			||||||
 | 
					set (CPACK_SOURCE_IGNORE_FILES "/\\\\.git;/build;/CMakeLists.txt.user")
 | 
				
			||||||
 | 
					set (CPACK_SOURCE_PACKAGE_FILE_NAME "${PROJECT_NAME}-${project_VERSION}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include (CPack)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										19
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								Makefile
									
									
									
									
									
								
							@@ -1,19 +0,0 @@
 | 
				
			|||||||
SHELL = /bin/sh
 | 
					 | 
				
			||||||
CC = clang
 | 
					 | 
				
			||||||
# -Wunused-function is pretty annoying here, as everything is static
 | 
					 | 
				
			||||||
CFLAGS = -std=c99 -Wall -Wextra -Wno-unused-function -ggdb
 | 
					 | 
				
			||||||
# -lpthread is only there for debugging (gdb & errno)
 | 
					 | 
				
			||||||
LDFLAGS = `pkg-config --libs libcurl jansson` -lpthread -lreadline
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.PHONY: all clean
 | 
					 | 
				
			||||||
.SUFFIXES:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
targets = json-rpc-shell
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
all: $(targets)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
clean:
 | 
					 | 
				
			||||||
	rm -f $(targets)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
json-rpc-shell: json-rpc-shell.c
 | 
					 | 
				
			||||||
	$(CC) $< -o $@ $(CFLAGS) $(LDFLAGS)
 | 
					 | 
				
			||||||
							
								
								
									
										11
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								README
									
									
									
									
									
								
							@@ -10,15 +10,16 @@ Fuck Java.  With a sharp, pointy object.  In the ass.  Hard.  json-c as well.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Building and Running
 | 
					Building and Running
 | 
				
			||||||
--------------------
 | 
					--------------------
 | 
				
			||||||
Build dependencies: clang, pkg-config, GNU make, Jansson, cURL, readline
 | 
					Build dependencies: CMake, pkg-config, libev, Jansson, cURL, readline
 | 
				
			||||||
 | 
					 | 
				
			||||||
If you don't have Clang, you can edit the Makefile to use GCC or TCC, they work
 | 
					 | 
				
			||||||
just as good.  But there's no CMake support yet, so I force it in the Makefile.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 $ git clone https://github.com/pjanouch/json-rpc-shell.git
 | 
					 $ git clone https://github.com/pjanouch/json-rpc-shell.git
 | 
				
			||||||
 | 
					 $ mkdir build
 | 
				
			||||||
 | 
					 $ cd build
 | 
				
			||||||
 | 
					 $ cmake .. -DCMAKE_BUILD_TYPE=Debug
 | 
				
			||||||
 $ make
 | 
					 $ make
 | 
				
			||||||
 | 
					
 | 
				
			||||||
That is all, no installation is required, or supported for that matter.
 | 
					Now you can run the following command to get some help about the exact usage:
 | 
				
			||||||
 | 
					 $ ./json-rpc-shell --help
 | 
				
			||||||
 | 
					
 | 
				
			||||||
License
 | 
					License
 | 
				
			||||||
-------
 | 
					-------
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										18
									
								
								cmake/FindLibEV.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								cmake/FindLibEV.cmake
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					# Public Domain
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# The author of libev is a dick and doesn't want to add support for pkg-config,
 | 
				
			||||||
 | 
					# forcing us to include this pointless file in the distribution.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Some distributions do add it, though
 | 
				
			||||||
 | 
					find_package (PkgConfig REQUIRED)
 | 
				
			||||||
 | 
					pkg_check_modules (LIBEV QUIET libev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (NOT LIBEV_FOUND)
 | 
				
			||||||
 | 
						find_path (LIBEV_INCLUDE_DIRS ev.h)
 | 
				
			||||||
 | 
						find_library (LIBEV_LIBRARIES NAMES ev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (LIBEV_INCLUDE_DIRS AND LIBEV_LIBRARIES)
 | 
				
			||||||
 | 
							set (LIBEV_FOUND TRUE)
 | 
				
			||||||
 | 
						endif (LIBEV_INCLUDE_DIRS AND LIBEV_LIBRARIES)
 | 
				
			||||||
 | 
					endif (NOT LIBEV_FOUND)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										119
									
								
								json-rpc-shell.c
									
									
									
									
									
								
							
							
						
						
									
										119
									
								
								json-rpc-shell.c
									
									
									
									
									
								
							@@ -40,7 +40,10 @@
 | 
				
			|||||||
#include <iconv.h>
 | 
					#include <iconv.h>
 | 
				
			||||||
#include <langinfo.h>
 | 
					#include <langinfo.h>
 | 
				
			||||||
#include <sys/stat.h>
 | 
					#include <sys/stat.h>
 | 
				
			||||||
 | 
					#include <signal.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <ev.h>
 | 
				
			||||||
#include <getopt.h>
 | 
					#include <getopt.h>
 | 
				
			||||||
#include <readline/readline.h>
 | 
					#include <readline/readline.h>
 | 
				
			||||||
#include <readline/history.h>
 | 
					#include <readline/history.h>
 | 
				
			||||||
@@ -144,18 +147,6 @@ str_append_data (struct str *self, const char *data, size_t n)
 | 
				
			|||||||
	self->str[self->len] = '\0';
 | 
						self->str[self->len] = '\0';
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
str_append_c (struct str *self, char c)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	str_append_data (self, &c, 1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
str_append (struct str *self, const char *s)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	str_append_data (self, s, strlen (s));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// --- Utilities ---------------------------------------------------------------
 | 
					// --- Utilities ---------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char *strdup_printf (const char *format, ...) ATTRIBUTE_PRINTF (1, 2);
 | 
					static char *strdup_printf (const char *format, ...) ATTRIBUTE_PRINTF (1, 2);
 | 
				
			||||||
@@ -242,7 +233,7 @@ mkdir_with_parents (char *path)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// --- Main program ------------------------------------------------------------
 | 
					// --- Main program ------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct app_context
 | 
					static struct app_context
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	CURL *curl;                         ///< cURL handle
 | 
						CURL *curl;                         ///< cURL handle
 | 
				
			||||||
	char curl_error[CURL_ERROR_SIZE];   ///< cURL error info buffer
 | 
						char curl_error[CURL_ERROR_SIZE];   ///< cURL error info buffer
 | 
				
			||||||
@@ -256,7 +247,8 @@ struct app_context
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	iconv_t term_to_utf8;               ///< Terminal encoding to UTF-8
 | 
						iconv_t term_to_utf8;               ///< Terminal encoding to UTF-8
 | 
				
			||||||
	iconv_t term_from_utf8;             ///< UTF-8 to terminal encoding
 | 
						iconv_t term_from_utf8;             ///< UTF-8 to terminal encoding
 | 
				
			||||||
};
 | 
					}
 | 
				
			||||||
 | 
					g_ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PARSE_FAIL(...)                                                        \
 | 
					#define PARSE_FAIL(...)                                                        \
 | 
				
			||||||
	BLOCK_START                                                                \
 | 
						BLOCK_START                                                                \
 | 
				
			||||||
@@ -569,6 +561,47 @@ fail:
 | 
				
			|||||||
	free (input);
 | 
						free (input);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					on_winch (EV_P_ ev_signal *handle, int revents)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						(void) loop;
 | 
				
			||||||
 | 
						(void) handle;
 | 
				
			||||||
 | 
						(void) revents;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// This fucks up big time on terminals with automatic wrapping such as
 | 
				
			||||||
 | 
						// rxvt-unicode or newer VTE when the current line overflows, however we
 | 
				
			||||||
 | 
						// can't do much about that
 | 
				
			||||||
 | 
						rl_resize_terminal ();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					on_readline_input (char *line)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!line)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							rl_callback_handler_remove ();
 | 
				
			||||||
 | 
							ev_break (EV_DEFAULT_ EVBREAK_ONE);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (*line)
 | 
				
			||||||
 | 
							add_history (line);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Stupid readline forces us to use a global variable
 | 
				
			||||||
 | 
						process_input (&g_ctx, line);
 | 
				
			||||||
 | 
						free (line);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					on_tty_readable (EV_P_ ev_io *handle, int revents)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						(void) loop;
 | 
				
			||||||
 | 
						(void) handle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (revents & EV_READ)
 | 
				
			||||||
 | 
							rl_callback_read_char ();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
print_usage (const char *program_name)
 | 
					print_usage (const char *program_name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -591,9 +624,6 @@ main (int argc, char *argv[])
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	const char *invocation_name = argv[0];
 | 
						const char *invocation_name = argv[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct app_context ctx;
 | 
					 | 
				
			||||||
	memset (&ctx, 0, sizeof ctx);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	static struct option opts[] =
 | 
						static struct option opts[] =
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		{ "help",      no_argument,       NULL, 'h' },
 | 
							{ "help",      no_argument,       NULL, 'h' },
 | 
				
			||||||
@@ -624,11 +654,11 @@ main (int argc, char *argv[])
 | 
				
			|||||||
			printf (PROGRAM_NAME " " PROGRAM_VERSION "\n");
 | 
								printf (PROGRAM_NAME " " PROGRAM_VERSION "\n");
 | 
				
			||||||
			exit (EXIT_SUCCESS);
 | 
								exit (EXIT_SUCCESS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		case 'a':  ctx.auto_id      = true;  break;
 | 
							case 'a':  g_ctx.auto_id      = true;  break;
 | 
				
			||||||
		case 'o':  origin = optarg;            break;
 | 
							case 'o':  origin = optarg;            break;
 | 
				
			||||||
		case 'p':  ctx.pretty_print = true;  break;
 | 
							case 'p':  g_ctx.pretty_print = true;  break;
 | 
				
			||||||
		case 't':  ctx.trust_all    = true;  break;
 | 
							case 't':  g_ctx.trust_all    = true;  break;
 | 
				
			||||||
		case 'v':  ctx.verbose      = true;  break;
 | 
							case 'v':  g_ctx.verbose      = true;  break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			print_error ("wrong options");
 | 
								print_error ("wrong options");
 | 
				
			||||||
@@ -652,7 +682,7 @@ main (int argc, char *argv[])
 | 
				
			|||||||
			" either `http://' or `https://'");
 | 
								" either `http://' or `https://'");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	CURL *curl;
 | 
						CURL *curl;
 | 
				
			||||||
	if (!(ctx.curl = curl = curl_easy_init ()))
 | 
						if (!(g_ctx.curl = curl = curl_easy_init ()))
 | 
				
			||||||
		exit_fatal ("cURL initialization failed");
 | 
							exit_fatal ("cURL initialization failed");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct curl_slist *headers = NULL;
 | 
						struct curl_slist *headers = NULL;
 | 
				
			||||||
@@ -666,10 +696,12 @@ main (int argc, char *argv[])
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if (curl_easy_setopt (curl, CURLOPT_POST,           1L)
 | 
						if (curl_easy_setopt (curl, CURLOPT_POST,           1L)
 | 
				
			||||||
	 || curl_easy_setopt (curl, CURLOPT_NOPROGRESS,     1L)
 | 
						 || curl_easy_setopt (curl, CURLOPT_NOPROGRESS,     1L)
 | 
				
			||||||
	 || curl_easy_setopt (curl, CURLOPT_ERRORBUFFER,    ctx.curl_error)
 | 
						 || curl_easy_setopt (curl, CURLOPT_ERRORBUFFER,    g_ctx.curl_error)
 | 
				
			||||||
	 || curl_easy_setopt (curl, CURLOPT_HTTPHEADER,     headers)
 | 
						 || curl_easy_setopt (curl, CURLOPT_HTTPHEADER,     headers)
 | 
				
			||||||
	 || curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, ctx.trust_all ? 0L : 1L)
 | 
						 || curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER,
 | 
				
			||||||
	 || curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, ctx.trust_all ? 0L : 2L)
 | 
								g_ctx.trust_all ? 0L : 1L)
 | 
				
			||||||
 | 
						 || curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST,
 | 
				
			||||||
 | 
								g_ctx.trust_all ? 0L : 2L)
 | 
				
			||||||
	 || curl_easy_setopt (curl, CURLOPT_URL,            endpoint))
 | 
						 || curl_easy_setopt (curl, CURLOPT_URL,            endpoint))
 | 
				
			||||||
		exit_fatal ("cURL setup failed");
 | 
							exit_fatal ("cURL setup failed");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -683,9 +715,9 @@ main (int argc, char *argv[])
 | 
				
			|||||||
	encoding = strdup_printf ("%s//TRANSLIT", encoding);
 | 
						encoding = strdup_printf ("%s//TRANSLIT", encoding);
 | 
				
			||||||
#endif // __linux__
 | 
					#endif // __linux__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((ctx.term_from_utf8 = iconv_open (encoding, "utf-8"))
 | 
						if ((g_ctx.term_from_utf8 = iconv_open (encoding, "utf-8"))
 | 
				
			||||||
		== (iconv_t) -1
 | 
							== (iconv_t) -1
 | 
				
			||||||
	 || (ctx.term_to_utf8 = iconv_open ("utf-8", nl_langinfo (CODESET)))
 | 
						 || (g_ctx.term_to_utf8 = iconv_open ("utf-8", nl_langinfo (CODESET)))
 | 
				
			||||||
		== (iconv_t) -1)
 | 
							== (iconv_t) -1)
 | 
				
			||||||
		exit_fatal ("creating the UTF-8 conversion object failed: %s",
 | 
							exit_fatal ("creating the UTF-8 conversion object failed: %s",
 | 
				
			||||||
			strerror (errno));
 | 
								strerror (errno));
 | 
				
			||||||
@@ -711,17 +743,30 @@ main (int argc, char *argv[])
 | 
				
			|||||||
		RL_PROMPT_START_IGNORE, RL_PROMPT_END_IGNORE,
 | 
							RL_PROMPT_START_IGNORE, RL_PROMPT_END_IGNORE,
 | 
				
			||||||
		RL_PROMPT_START_IGNORE, RL_PROMPT_END_IGNORE);
 | 
							RL_PROMPT_START_IGNORE, RL_PROMPT_END_IGNORE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	char *line;
 | 
						// readline 6.3 doesn't immediately redraw the terminal upon reception
 | 
				
			||||||
	while ((line = readline (prompt)))
 | 
						// of SIGWINCH, so we must run it in an event loop to remediate that
 | 
				
			||||||
	{
 | 
						struct ev_loop *loop = EV_DEFAULT;
 | 
				
			||||||
		if (*line)
 | 
						if (!loop)
 | 
				
			||||||
			add_history (line);
 | 
							exit_fatal ("libev initialization failed");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		process_input (&ctx, line);
 | 
						ev_signal winch_watcher;
 | 
				
			||||||
		free (line);
 | 
						ev_io tty_watcher;
 | 
				
			||||||
	}
 | 
					
 | 
				
			||||||
 | 
						ev_signal_init (&winch_watcher, on_winch, SIGWINCH);
 | 
				
			||||||
 | 
						ev_signal_start (EV_DEFAULT_ &winch_watcher);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ev_io_init (&tty_watcher, on_tty_readable, STDIN_FILENO, EV_READ);
 | 
				
			||||||
 | 
						ev_io_start (EV_DEFAULT_ &tty_watcher);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rl_catch_sigwinch = false;
 | 
				
			||||||
 | 
						rl_callback_handler_install (prompt, on_readline_input);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ev_run (loop, 0);
 | 
				
			||||||
	putchar ('\n');
 | 
						putchar ('\n');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ev_loop_destroy (loop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// User has terminated the program, let's save the history and clean up
 | 
				
			||||||
	char *dir = strdup (history_path);
 | 
						char *dir = strdup (history_path);
 | 
				
			||||||
	(void) mkdir_with_parents (dirname (dir));
 | 
						(void) mkdir_with_parents (dirname (dir));
 | 
				
			||||||
	free (dir);
 | 
						free (dir);
 | 
				
			||||||
@@ -731,8 +776,8 @@ main (int argc, char *argv[])
 | 
				
			|||||||
			history_path, strerror (errno));
 | 
								history_path, strerror (errno));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	free (history_path);
 | 
						free (history_path);
 | 
				
			||||||
	iconv_close (ctx.term_from_utf8);
 | 
						iconv_close (g_ctx.term_from_utf8);
 | 
				
			||||||
	iconv_close (ctx.term_to_utf8);
 | 
						iconv_close (g_ctx.term_to_utf8);
 | 
				
			||||||
	curl_slist_free_all (headers);
 | 
						curl_slist_free_all (headers);
 | 
				
			||||||
	free (origin);
 | 
						free (origin);
 | 
				
			||||||
	curl_easy_cleanup (curl);
 | 
						curl_easy_cleanup (curl);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user