summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Green <andy@warmcat.com>2011-01-20 10:23:50 +0000
committerAndy Green <andy@warmcat.com>2011-01-20 10:23:50 +0000
commited11a02201b53a6f72d60efcaa5ef726e4ece9ec (patch)
tree5f4b5f54c7a41f70d603317bf3d9248c1e56fe00
parente92cd1764ee0d5110fa8a587810446631a9ea702 (diff)
add-enable-nofork-config-option.patch
Signed-off-by: Andy Green <andy@warmcat.com>
-rw-r--r--README-test-server26
-rwxr-xr-xconfigure175
-rw-r--r--configure.ac13
-rw-r--r--lib/libwebsockets.c53
-rw-r--r--lib/private-libwebsockets.h2
-rw-r--r--test-server/test-server.c57
6 files changed, 217 insertions, 109 deletions
diff --git a/README-test-server b/README-test-server
index 2f14e17..4b30fab 100644
--- a/README-test-server
+++ b/README-test-server
@@ -15,6 +15,9 @@ $ libwebsockets-test-server
should be enough to get a test server listening on port 7861.
+Testing
+-------
+
If you point your browser (eg, Chrome) to
http://127.0.0.1:7681
@@ -23,6 +26,9 @@ It will fetch a script in the form of test.html, and then run the
script in there on the browser to open a websocket connection.
Incrementing numbers should appear in the browser display.
+Using SSL
+---------
+
To test it using SSL/WSS, just run the test server with
$ libwebsockets-test-server --ssl
@@ -41,5 +47,23 @@ same.
test-server.c is all that is needed to use libwebsockets for
serving both the script html over http and websockets.
-2010-11-08 Andy Green <andy@warmcat.com>
+Forkless operation
+------------------
+
+If your target device does not offer fork(), you can use
+libwebsockets from your own main loop instead. Use the
+configure option --nofork and simply call libwebsocket_service()
+from your own main loop as shown in the test app sources.
+
+
+Websocket version supported
+---------------------------
+
+Right now this is tested and working on websockets protocol 76/00
+Untested code is in for 04 support, there is no browser support
+available yet to test it with. Libwebsockets should autoselect
+between the supported versions according to what the browser
+asks for.
+
+2011-01-20 Andy Green <andy@warmcat.com>
diff --git a/configure b/configure
index 03e9e84..123de5b 100755
--- a/configure
+++ b/configure
@@ -735,6 +735,7 @@ with_gnu_ld
with_sysroot
enable_libtool_lock
enable_openssl
+enable_nofork
'
ac_precious_vars='build_alias
host_alias
@@ -1378,6 +1379,7 @@ Optional Features:
--enable-dependency-tracking do not reject slow dependency extractors
--disable-libtool-lock avoid locking (might break parallel builds)
--enable-openssl Enables https support and needs openssl libs
+ --enable-nofork Disables fork-related options
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@@ -1739,6 +1741,60 @@ $as_echo "$ac_res" >&6; }
} # ac_fn_c_check_func
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_type
+
# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
# -------------------------------------------------------
# Tests whether HEADER exists, giving a warning if it cannot be compiled using
@@ -1829,60 +1885,6 @@ fi
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
} # ac_fn_c_check_header_mongrel
-
-# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
-# -------------------------------------------
-# Tests whether TYPE exists after having included INCLUDES, setting cache
-# variable VAR accordingly.
-ac_fn_c_check_type ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- eval "$3=no"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$4
-int
-main ()
-{
-if (sizeof ($2))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$4
-int
-main ()
-{
-if (sizeof (($2)))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-else
- eval "$3=yes"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_type
cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
@@ -12014,37 +12016,16 @@ fi
CFLAGS="$CFLAGS -DLWS_OPENSSL_SUPPORT"
fi
-
-
-# Checks for header files.
-for ac_header in fcntl.h netinet/in.h stdlib.h string.h sys/socket.h unistd.h
-do :
- as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
- cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
+# Check whether --enable-nofork was given.
+if test "${enable_nofork+set}" = set; then :
+ enableval=$enable_nofork; nofork=yes
fi
-done
-
-
-# Checks for typedefs, structures, and compiler characteristics.
-ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
-if test "x$ac_cv_type_size_t" = xyes; then :
+if test "x$nofork" = "xyes" ; then
+CFLAGS="$CFLAGS -DLWS_NO_FORK"
else
-
-cat >>confdefs.h <<_ACEOF
-#define size_t unsigned int
-_ACEOF
-
-fi
-
-
-# Checks for library functions.
ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
if test "x$ac_cv_type_pid_t" = xyes; then :
@@ -12269,6 +12250,40 @@ $as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h
fi
+fi
+
+
+
+# Checks for header files.
+for ac_header in fcntl.h netinet/in.h stdlib.h string.h sys/socket.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+# Checks for typedefs, structures, and compiler characteristics.
+ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+fi
+
+
+# Checks for library functions.
+
for ac_header in stdlib.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
diff --git a/configure.ac b/configure.ac
index d3a407b..2ccdd68 100644
--- a/configure.ac
+++ b/configure.ac
@@ -28,6 +28,17 @@ AC_CHECK_LIB([ssl], [SSL_library_init])
CFLAGS="$CFLAGS -DLWS_OPENSSL_SUPPORT"
fi
+AC_ARG_ENABLE(nofork,
+ [ --enable-nofork Disables fork-related options],
+ [ nofork=yes
+ ])
+
+if test "x$nofork" = "xyes" ; then
+CFLAGS="$CFLAGS -DLWS_NO_FORK"
+else
+AC_FUNC_FORK
+fi
+
# Checks for header files.
@@ -37,7 +48,7 @@ AC_CHECK_HEADERS([fcntl.h netinet/in.h stdlib.h string.h sys/socket.h unistd.h])
AC_TYPE_SIZE_T
# Checks for library functions.
-AC_FUNC_FORK
+
AC_FUNC_MALLOC
AC_FUNC_REALLOC
AC_CHECK_FUNCS([bzero memset socket strerror])
diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c
index 1ba4410..5aa7c26 100644
--- a/lib/libwebsockets.c
+++ b/lib/libwebsockets.c
@@ -617,6 +617,8 @@ libwebsocket_create_server(int port,
return this;
}
+#ifndef LWS_NO_FORK
+
/**
* libwebsockets_fork_service_loop() - Optional helper function forks off
* a process for the websocket server loop.
@@ -635,29 +637,38 @@ libwebsockets_fork_service_loop(struct libwebsocket_context *this)
struct sockaddr_in cli_addr;
int n;
- if (fork())
- return 0;
+ n = fork();
+ if (n < 0)
+ return n;
- for (client = 1; client < this->count_protocols + 1; client++) {
- fd = socket(AF_INET, SOCK_STREAM, 0);
- if (fd < 0) {
- fprintf(stderr, "Unable to create socket\n");
- return -1;
- }
- cli_addr.sin_family = AF_INET;
- cli_addr.sin_port = htons(
- this->protocols[client - 1].broadcast_socket_port);
- cli_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
- n = connect(fd, (struct sockaddr *)&cli_addr,
- sizeof cli_addr);
- if (n < 0) {
- fprintf(stderr, "Unable to connect to "
- "broadcast socket %d, %s\n",
- client, strerror(errno));
- return -1;
+ if (!n) {
+
+ /* main process context */
+
+ for (client = 1; client < this->count_protocols + 1; client++) {
+ fd = socket(AF_INET, SOCK_STREAM, 0);
+ if (fd < 0) {
+ fprintf(stderr, "Unable to create socket\n");
+ return -1;
+ }
+ cli_addr.sin_family = AF_INET;
+ cli_addr.sin_port = htons(
+ this->protocols[client - 1].broadcast_socket_port);
+ cli_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
+ n = connect(fd, (struct sockaddr *)&cli_addr,
+ sizeof cli_addr);
+ if (n < 0) {
+ fprintf(stderr, "Unable to connect to "
+ "broadcast socket %d, %s\n",
+ client, strerror(errno));
+ return -1;
+ }
+
+ this->protocols[client - 1].broadcast_socket_user_fd = fd;
}
- this->protocols[client - 1].broadcast_socket_user_fd = fd;
+
+ return 0;
}
/* we want a SIGHUP when our parent goes down */
@@ -672,6 +683,8 @@ libwebsockets_fork_service_loop(struct libwebsocket_context *this)
return 0;
}
+#endif
+
/**
* libwebsockets_get_protocol() - Returns a protocol pointer from a websocket
* connection.
diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h
index 327e09c..a63d902 100644
--- a/lib/private-libwebsockets.h
+++ b/lib/private-libwebsockets.h
@@ -32,7 +32,9 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
+#ifndef LWS_NO_FORK
#include <sys/prctl.h>
+#endif
#include <netinet/in.h>
#include <arpa/inet.h>
diff --git a/test-server/test-server.c b/test-server/test-server.c
index 3365c0f..36a1978 100644
--- a/test-server/test-server.c
+++ b/test-server/test-server.c
@@ -264,12 +264,15 @@ int main(int argc, char **argv)
return -1;
}
+ buf[LWS_SEND_BUFFER_PRE_PADDING] = 'x';
+
+#ifdef LWS_NO_FORK
+
/*
- * After initializing and creating the websocket server in its own fork
- * we return to the main process here
+ * This example shows how to work with no forked service loop
*/
- buf[LWS_SEND_BUFFER_PRE_PADDING] = 'x';
+ fprintf(stderr, " Using no-fork service loop\n");
while (1) {
@@ -297,14 +300,54 @@ int main(int argc, char **argv)
* we have to give the websockets an opportunity to service
* "manually".
*
- * There's an optional call libwebsockets_fork_service_loop()
- * we could have used before this while loop, then the
- * websockets would have been serviced in a forked process
- * and we would not have to do the call below inside our loop.
+ * If no socket is needing service, the call below returns
+ * immediately and quickly.
*/
libwebsocket_service(server, 0);
}
+#else
+
+ /*
+ * This example shows how to work with the forked websocket service loop
+ */
+
+ fprintf(stderr, " Using forked service loop\n");
+
+ /*
+ * This forks the websocket service action into a subprocess so we
+ * don't have to take care about it.
+ */
+
+ n = libwebsockets_fork_service_loop(server);
+ if (n < 0) {
+ fprintf(stderr, "Unable to fork service loop %d\n", n);
+ return 1;
+ }
+
+ while (1) {
+
+ usleep(50000);
+
+ /*
+ * This broadcasts to all dumb-increment-protocol connections
+ * at 20Hz.
+ *
+ * We're just sending a character 'x', in these examples the
+ * callbacks send their own per-connection content.
+ *
+ * You have to send something with nonzero length to get the
+ * callback actions delivered.
+ *
+ * We take care of pre-and-post padding allocation.
+ */
+
+ libwebsockets_broadcast(&protocols[PROTOCOL_DUMB_INCREMENT],
+ &buf[LWS_SEND_BUFFER_PRE_PADDING], 1);
+ }
+
+#endif
+
return 0;
}