未验证 提交 7ad72565 编写于 作者: 羽飞's avatar 羽飞 提交者: GitHub

Merge pull request #28 from hnwyllmm/feature/readline

use readline in obclient
PROJECT(obclient)
MESSAGE("Begin to build " ${PROJECT_NAME})
MESSAGE(STATUS "This is PROJECT_BINARY_DIR dir " ${PROJECT_BINARY_DIR})
MESSAGE(STATUS "This is PROJECT_SOURCE_DIR dir " ${PROJECT_SOURCE_DIR})
ADD_EXECUTABLE(obclient)
MESSAGE("Begin to build " obclient)
INCLUDE(CheckIncludeFiles)
#INCLUDE_DIRECTORIES([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)
INCLUDE_DIRECTORIES(. ${PROJECT_SOURCE_DIR}/../../deps /usr/local/include SYSTEM)
TARGET_INCLUDE_DIRECTORIES(obclient PRIVATE . ${PROJECT_SOURCE_DIR}/../deps /usr/local/include /usr/include)
# 父cmake 设置的include_directories 和link_directories并不传导到子cmake里面
#INCLUDE_DIRECTORIES(BEFORE ${CMAKE_INSTALL_PREFIX}/include)
LINK_DIRECTORIES(/usr/local/lib ${PROJECT_BINARY_DIR}/../../lib)
TARGET_LINK_DIRECTORIES(obclient PRIVATE /usr/local/lib ${PROJECT_BINARY_DIR}/../../lib)
# stdio.h 必须放在readline/readline.h 前面,因为readline头文件不能直接单独编译
CHECK_INCLUDE_FILES("stdio.h;readline/readline.h" HAVE_READLINE_HEADER)
FIND_LIBRARY(READLINE_LIBRARY readline)
IF (HAVE_READLINE_HEADER AND READLINE_LIBRARY)
TARGET_LINK_LIBRARIES(obclient ${READLINE_LIBRARY})
ADD_DEFINITIONS(-DUSE_READLINE)
ELSE ()
MESSAGE ("readline is not found")
ENDIF()
FILE(GLOB_RECURSE ALL_SRC *.cpp)
FOREACH (F ${ALL_SRC})
......@@ -19,15 +29,14 @@ FOREACH (F ${ALL_SRC})
ENDFOREACH (F)
# 指定目标文件位置
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/../../bin)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/../bin)
MESSAGE("Binary directory:" ${EXECUTABLE_OUTPUT_PATH})
ADD_EXECUTABLE(${PROJECT_NAME} ${PRJ_SRC})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} common pthread dl)
TARGET_SOURCES(obclient PRIVATE ${PRJ_SRC})
TARGET_LINK_LIBRARIES(obclient common pthread dl)
# Target 必须在定义 ADD_EXECUTABLE 之后, programs 不受这个限制
# TARGETS和PROGRAMS 的默认权限是OWNER_EXECUTE, GROUP_EXECUTE, 和WORLD_EXECUTE,即755权限, programs 都是处理脚步类
# 类型分为RUNTIME/LIBRARY/ARCHIVE, prog
INSTALL(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)
\ No newline at end of file
INSTALL(TARGETS obclient RUNTIME DESTINATION bin)
......@@ -29,14 +29,41 @@ See the Mulan PSL v2 for more details. */
#include "common/defs.h"
#include "common/lang/string.h"
#ifdef USE_READLINE
#include "readline/readline.h"
#endif
#define MAX_MEM_BUFFER_SIZE 8192
#define PORT_DEFAULT 6789
using namespace common;
bool is_exit_command(const char *cmd)
#ifdef USE_READLINE
char *my_readline(const char *prompt)
{
return readline(prompt);
}
#else // USE_READLINE
char *my_readline(const char *prompt)
{
return 0 == strncasecmp("exit", cmd, 4) || 0 == strncasecmp("bye", cmd, 3);
char *buffer = (char *)malloc(MAX_MEM_BUFFER_SIZE);
if (nullptr == buffer) {
fprintf(stderr, "failed to alloc line buffer");
return nullptr;
}
char *s = fgets(buffer, MAX_MEM_BUFFER_SIZE, stdin);
if (nullptr == s) {
fprintf(stderr, "failed to read message from console");
free(buffer);
return nullptr;
}
return buffer;
}
#endif // USE_READLINE
bool is_exit_command(const char *cmd) {
return 0 == strncasecmp("exit", cmd, 4) ||
0 == strncasecmp("bye", cmd, 3);
}
int init_unix_sock(const char *unix_sock_path)
......@@ -89,38 +116,8 @@ int init_tcp_sock(const char *server_host, int server_port)
return sockfd;
}
// 这里的代码本来是为了处理控制台不能接收超长字符串的问题
// 但是设置控制台模式为非 ICANON 后,不能再正常的处理 backspace
// 所以暂时不调用这个函数
// 需要测试超长字符串场景的同学,可以通过文本重定向的方式测试
int set_terminal_noncanonical()
{
int fd = STDIN_FILENO;
struct termios old_termios;
int ret = tcgetattr(fd, &old_termios);
if (ret < 0) {
printf("Failed to get tc attr. error=%s\n", strerror(errno));
return -1;
}
struct termios new_attr = old_termios;
new_attr.c_lflag &= ~ICANON;
new_attr.c_cc[VERASE] = '\b';
ret = tcsetattr(fd, TCSANOW, &new_attr);
if (ret < 0) {
printf("Failed to set tc attr. error=%s\n", strerror(errno));
return -1;
}
return 0;
}
int main(int argc, char *argv[])
{
int ret = 0; // set_terminal_noncanonical();
if (ret < 0) {
printf("Warning: failed to set terminal non canonical. Long command may be handled incorrect\n");
}
const char *unix_socket_path = nullptr;
const char *server_host = "127.0.0.1";
int server_port = PORT_DEFAULT;
......@@ -143,7 +140,6 @@ int main(int argc, char *argv[])
const char *prompt_str = "miniob > ";
int sockfd, send_bytes;
// char send[MAXLINE];
if (unix_socket_path != nullptr) {
sockfd = init_unix_sock(unix_socket_path);
......@@ -155,23 +151,24 @@ int main(int argc, char *argv[])
}
char send_buf[MAX_MEM_BUFFER_SIZE];
// char buf[MAXDATASIZE];
fputs(prompt_str, stdout);
while (fgets(send_buf, MAX_MEM_BUFFER_SIZE, stdin) != NULL) {
if (common::is_blank(send_buf)) {
fputs(prompt_str, stdout);
char *input_command = nullptr;
while ((input_command = my_readline(prompt_str)) != nullptr) {
if (common::is_blank(input_command)) {
free(input_command);
continue;
}
if (is_exit_command(send_buf)) {
if (is_exit_command(input_command)) {
free(input_command);
break;
}
if ((send_bytes = write(sockfd, send_buf, strlen(send_buf) + 1)) == -1) {
if ((send_bytes = write(sockfd, input_command, strlen(input_command) + 1)) == -1) { // TODO writen
fprintf(stderr, "send error: %d:%s \n", errno, strerror(errno));
exit(1);
}
free(input_command);
memset(send_buf, 0, sizeof(send_buf));
int len = 0;
......@@ -198,7 +195,6 @@ int main(int argc, char *argv[])
printf("Connection has been closed\n");
break;
}
fputs(prompt_str, stdout);
}
close(sockfd);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册