diff options
author | Xiang Xiao <xiaoxiang@xiaomi.com> | 2021-05-05 22:44:36 -0700 |
---|---|---|
committer | Jakub Jelen <jjelen@redhat.com> | 2021-05-31 12:21:42 +0200 |
commit | a8a74a70faa54dc9fa58db52bedfd41278a249f4 (patch) | |
tree | 1de13d13441b4c2cbb7ae062fddbd09d3519a1dd /examples | |
parent | 3b29e2ad4ca1e70726ca74cefee03d6024b9b3bb (diff) | |
download | libssh-a8a74a70faa54dc9fa58db52bedfd41278a249f4.tar.gz libssh-a8a74a70faa54dc9fa58db52bedfd41278a249f4.tar.xz libssh-a8a74a70faa54dc9fa58db52bedfd41278a249f4.zip |
examples/ssh_server_fork: Support the multi-client through pthread
so the same code base demo both multi-process and multi-thread model
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Change-Id: I98554a99b7a31586be37abde7c357f81a05c3d6e
Diffstat (limited to 'examples')
-rw-r--r-- | examples/CMakeLists.txt | 8 | ||||
-rw-r--r-- | examples/ssh_server.c (renamed from examples/ssh_server_fork.c) | 39 |
2 files changed, 43 insertions, 4 deletions
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 4e09083a..49c19183 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -37,9 +37,13 @@ if (UNIX AND NOT WIN32) if (WITH_SERVER AND (ARGP_LIBRARY OR HAVE_ARGP_H)) if (HAVE_LIBUTIL) - add_executable(ssh_server_fork ssh_server_fork.c) - target_compile_options(ssh_server_fork PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) + add_executable(ssh_server_fork ssh_server.c) + target_compile_options(ssh_server_fork PRIVATE ${DEFAULT_C_COMPILE_FLAGS} -DWITH_FORK) target_link_libraries(ssh_server_fork ssh::ssh ${ARGP_LIBRARY} util) + + add_executable(ssh_server_pthread ssh_server.c) + target_compile_options(ssh_server_pthread PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) + target_link_libraries(ssh_server_pthread ssh::ssh ${ARGP_LIBRARY} pthread util) endif (HAVE_LIBUTIL) if (WITH_GSSAPI AND GSSAPI_FOUND) diff --git a/examples/ssh_server_fork.c b/examples/ssh_server.c index 7f939d21..24c494e7 100644 --- a/examples/ssh_server_fork.c +++ b/examples/ssh_server.c @@ -24,6 +24,7 @@ The goal is to show the API in action. #ifdef HAVE_LIBUTIL_H #include <libutil.h> #endif +#include <pthread.h> #ifdef HAVE_PTY_H #include <pty.h> #endif @@ -783,18 +784,38 @@ static void handle_session(ssh_event event, ssh_session session) { } } +#ifdef WITH_FORK /* SIGCHLD handler for cleaning up dead children. */ static void sigchld_handler(int signo) { (void) signo; while (waitpid(-1, NULL, WNOHANG) > 0); } +#else +static void *session_thread(void *arg) { + ssh_session session = arg; + ssh_event event; + + event = ssh_event_new(); + if (event != NULL) { + /* Blocks until the SSH session ends by either + * child thread exiting, or client disconnecting. */ + handle_session(event, session); + ssh_event_free(event); + } else { + fprintf(stderr, "Could not create polling context\n"); + } + ssh_disconnect(session); + ssh_free(session); + return NULL; +} +#endif int main(int argc, char **argv) { ssh_bind sshbind; ssh_session session; - ssh_event event; - struct sigaction sa; int rc; +#ifdef WITH_FORK + struct sigaction sa; /* Set up SIGCHLD handler. */ sa.sa_handler = sigchld_handler; @@ -804,6 +825,7 @@ int main(int argc, char **argv) { fprintf(stderr, "Failed to register SIGCHLD handler\n"); return 1; } +#endif rc = ssh_init(); if (rc < 0) { @@ -844,6 +866,9 @@ int main(int argc, char **argv) { /* Blocks until there is a new incoming connection. */ if(ssh_bind_accept(sshbind, session) != SSH_ERROR) { +#ifdef WITH_FORK + ssh_event event; + switch(fork()) { case 0: /* Remove the SIGCHLD handler inherited from parent. */ @@ -869,6 +894,16 @@ int main(int argc, char **argv) { case -1: fprintf(stderr, "Failed to fork\n"); } +#else + pthread_t tid; + + rc = pthread_create(&tid, NULL, session_thread, session); + if (rc == 0) { + pthread_detach(tid); + continue; + } + fprintf(stderr, "Failed to pthread_create\n"); +#endif } else { fprintf(stderr, "%s\n", ssh_get_error(sshbind)); } |