Skip to content

Commit

Permalink
Fix php-cgi process hanging after PHP script was served (#221).
Browse files Browse the repository at this point in the history
Copy license and readme files to the bin/ directory during build.

Implement waitpid() on Windows. Better handling of php-cgi processes
hanging should also be used on Windows. Use the latest mongoose.c
from the Linux branch in the next Windows release.
  • Loading branch information
cztomczak committed Dec 2, 2018
1 parent 2f73d49 commit 3a56b93
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 12 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ TARGET=build/bin/phpdesktop

INCLUDES = -Isrc -Lbuild/lib -Lbuild/bin

CCFLAGS = -g -Wall -Werror -std=gnu++11 $(INCLUDES)
CCFLAGS = -g -Wall -Werror -std=gnu++11 -pthread $(INCLUDES)
CCFLAGS += $(shell pkg-config --cflags glib-2.0 gtk+-3.0)

CFLAGS_OPTIMIZE = -O3 -fvisibility=hidden

LDFLAGS = -Wl,-rpath,. -Wl,-rpath,"\$$ORIGIN" -lX11 -lcef -lcef_dll_wrapper -Wl,--as-needed -ldl
LDFLAGS = -Wl,-rpath,. -Wl,-rpath,"\$$ORIGIN" -lX11 -lcef -lcef_dll_wrapper -Wl,--as-needed -ldl -lpthread
LDFLAGS += $(shell pkg-config --libs glib-2.0 gtk+-3.0)

OBJS=\
Expand Down
1 change: 1 addition & 0 deletions build-php.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ set -e
root_dir=$(dirname $0)
cd ${root_dir}/build/php*/
php_dir=$(pwd)
echo "Found PHP: ${php_dir}"
echo "Configure PHP..."
./configure \
--prefix=${php_dir}/dist-install \
Expand Down
3 changes: 3 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ rc=$?;
if [[ ${rc} = 0 ]]; then
echo "OK phpdesktop was built";
cp src/php.ini build/bin/
cp CEF.License.txt build/bin/
cp CEF.Readme.txt build/bin/
cp License.txt build/bin/
if [[ -d build/bin/www ]]; then
rm -r build/bin/www
fi
Expand Down
37 changes: 34 additions & 3 deletions src/mongoose.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Forked from Mongoose MIT licensed revision 04fc209.
// Bug fixes and minor changes were made for PHP Desktop.
// This is a custom edition of Mongoose web server for PHP Desktop.
// Copyright (c) 2012 PHP Desktop.
// Copyright (c) 2004 Sergey Lyubka.
//
Expand Down Expand Up @@ -1294,6 +1294,19 @@ static int kill(pid_t pid, int sig_num) {
return 0;
}

#define WNOHANG 1 /* do not wait for child to exit */
static pid_t waitpid(pid_t pid, int *status, int flags) {
(void)status;
DWORD waitres = WaitForSingleObject((HANDLE)pid, 0);
if (waitres == WAIT_OBJECT_0) {
return pid;
}
if (waitres == WAIT_TIMEOUT) {
return 0;
}
return (pid_t)-1;
}

static void trim_trailing_whitespaces(char *s) {
char *e = s + strlen(s) - 1;
while (e > s && isspace(* (unsigned char *) e)) {
Expand Down Expand Up @@ -1466,14 +1479,25 @@ static pid_t spawn_process(struct mg_connection *conn, const char *prog,
// if it was set to be ignored. Restore it to default action.
signal(SIGCHLD, SIG_DFL);

// It is recommended to use sigaction() instead of signal()
// as it is more reliable. However this does not fix issue
// with php-cgi zombie processes hanging after PHP script
// was served. (Linux issue).
// struct sigaction sa;
// memset(&sa, 0, sizeof(sa));
// sa.sa_handler = SIG_DFL;
// sigaction(SIGCHLD, &sa, NULL);

interp = conn->ctx->config[CGI_INTERPRETER];
if (interp == NULL) {
(void) execle(prog, prog, NULL, envp);
cry(conn, "%s: execle(%s): %s", __func__, prog, strerror(ERRNO));
} else {
// char prog_abspath[PATH_MAX];
// strcpy(prog_abspath, dir);
// strcat(prog_abspath, "/");
// strcat(prog_abspath, prog);
// conn->ctx->callbacks.log_message(conn, interp);
(void) execle(interp, interp, prog, NULL, envp);
cry(conn, "%s: execle(%s %s): %s", __func__, interp, prog,
strerror(ERRNO));
Expand Down Expand Up @@ -3666,7 +3690,14 @@ static void handle_cgi_request(struct mg_connection *conn, const char *prog) {

done:
if (pid != (pid_t) -1) {
kill(pid, SIGKILL);
// Use SIGABRT so that CGI process has an opportunity to
// handle event and exit gracefully.
kill(pid, SIGABRT);
// Wait until process is terminated, otherwise CGI process will be
// hanging forever on Linux. This code should also be used on Windows.
// Do not use the "status" param that can be returned by waitpid().
// These statuses are buggy and CGI process will still be hanging.
while (waitpid(pid, NULL, 0) != (pid_t) -1);
}
if (fdin[0] != -1) {
close(fdin[0]);
Expand Down Expand Up @@ -5616,7 +5647,7 @@ struct mg_context *mg_start(const struct mg_callbacks *callbacks,
// won't kill the whole process.
(void) signal(SIGPIPE, SIG_IGN);
// Also ignoring SIGCHLD to let the OS to reap zombies properly.
(void) signal(SIGCHLD, SIG_IGN);
// (void) signal(SIGCHLD, SIG_IGN);
#endif // !_WIN32

(void) pthread_mutex_init(&ctx->mutex, NULL);
Expand Down
11 changes: 6 additions & 5 deletions src/mongoose_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ std::string g_mongoose_url = "";
struct mg_context* g_mongoose_context = 0;
extern std::string g_cgi_env_from_argv;

static int mongoose_log_message(const struct mg_connection* conn,
static int mongoose_error_message(const struct mg_connection* conn,
const char *message) {
// Called when mongoose is about to log a message. If callback returns
// non-zero, mongoose does not log anything.
LOG(WARNING) << message;
// Called when mongoose is about to log an error message.
// If callback returns non-zero, mongoose does not log anything
// to a file ("error_log_file" option).
LOG(ERROR) << message;
return 0;
}

Expand Down Expand Up @@ -109,7 +110,7 @@ bool MongooseStart() {

// Start mongoose
mg_callbacks callbacks = {0};
callbacks.log_message = &mongoose_log_message;
callbacks.log_message = &mongoose_error_message;
callbacks.end_request = &mongoose_end_request;
g_mongoose_context = mg_start(&callbacks, NULL, options);
if (g_mongoose_context == NULL) {
Expand Down
4 changes: 2 additions & 2 deletions src/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
// Project website: https://github.com/cztomczak/phpdesktop

#include "utils.h"
#include <limits.h>
#include <unistd.h>


std::string executable_dir() {
// Directory in which executable resides.
char app_path[1024] = {};
char app_path[PATH_MAX] = {};
ssize_t pplen = readlink("/proc/self/exe", app_path, sizeof(app_path)-1);
if (pplen != -1) {
app_path[pplen] = '\0';
Expand Down

0 comments on commit 3a56b93

Please sign in to comment.