aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorXiang Xiao <xiaoxiang@xiaomi.com>2021-05-05 22:44:36 -0700
committerJakub Jelen <jjelen@redhat.com>2021-05-31 12:21:42 +0200
commita8a74a70faa54dc9fa58db52bedfd41278a249f4 (patch)
tree1de13d13441b4c2cbb7ae062fddbd09d3519a1dd /examples
parent3b29e2ad4ca1e70726ca74cefee03d6024b9b3bb (diff)
downloadlibssh-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.txt8
-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));
}