From e8c66fa769d036a99510d6093c2cabda7186b955 Mon Sep 17 00:00:00 2001 From: Olivier Ligot Date: Fri, 19 Jul 2013 18:51:31 +0200 Subject: [PATCH] Fix C compilation when using libfcgi connector on OS X (#65) --- library/server/libfcgi/Clib/README.md | 13 +- library/server/libfcgi/README.md | 13 +- .../libfcgi/implementation/mac/fcgi_c_api.e | 144 ++++++++++++++ .../libfcgi/implementation/mac/fcgi_imp.e | 179 ++++++++++++++++++ library/server/libfcgi/libfcgi-safe.ecf | 19 +- library/server/libfcgi/libfcgi.ecf | 19 +- 6 files changed, 374 insertions(+), 13 deletions(-) create mode 100644 library/server/libfcgi/implementation/mac/fcgi_c_api.e create mode 100644 library/server/libfcgi/implementation/mac/fcgi_imp.e diff --git a/library/server/libfcgi/Clib/README.md b/library/server/libfcgi/Clib/README.md index 6348592c..224d63c3 100644 --- a/library/server/libfcgi/Clib/README.md +++ b/library/server/libfcgi/Clib/README.md @@ -1,6 +1,6 @@ -== libFCGI for Eiffel libFCGI wrapper library == +# libFCGI for Eiffel libFCGI wrapper library -=== On Windows === +## On Windows The Eiffel libFCGI wrapper needs a modified version of libFCGI (provided by http://www.fastcgi.com/devkit/libfcgi/) @@ -12,10 +12,15 @@ And then to build the needed .dll and .lib file, use either: build_win32.bat or build_win64.bat -=== On other platorms === +## On other platorms You can use the original version of libfcgi -For instance, on Ubuntu (or any debian): +### Debian based system (Ubuntu, ...) +On Ubuntu (or any Debian based system): > sudo apt-get install libfcgi-dev + +### Mac OS X +On Mac OS X: +> sudo port install fcgi diff --git a/library/server/libfcgi/README.md b/library/server/libfcgi/README.md index 09f769b8..c0d26f43 100644 --- a/library/server/libfcgi/README.md +++ b/library/server/libfcgi/README.md @@ -1,13 +1,16 @@ -== Eiffel libFCGI wrapper library == +# Eiffel libFCGI wrapper library This Eiffel library wraps the libFCGI devkit from http://www.fastcgi.com/devkit/libfcgi/ -=== Windows === +## Windows To compile your own binaries .lib and .dll on __Windows__: [read more](Clib/README.md) -=== Others === +## Others -==== Debian based system (ubuntu, ...) ==== -To install the fcgi lib on debian, you can use +### Debian based system (ubuntu, ...) +To install the fcgi lib on Ubuntu (or any Debian based system), you can use > sudo apt-get install libfcgi-dev +### Mac OS X +To install the fcgi lib on Mac OS X, you can use [MacPorts](http://www.macports.org/) +> sudo port install fcgi diff --git a/library/server/libfcgi/implementation/mac/fcgi_c_api.e b/library/server/libfcgi/implementation/mac/fcgi_c_api.e new file mode 100644 index 00000000..144abb9e --- /dev/null +++ b/library/server/libfcgi/implementation/mac/fcgi_c_api.e @@ -0,0 +1,144 @@ +note + description: "Wrappers around FastCGI C API." + legal: "See notice at end of class." + status: "See notice at end of class." + date: "$Date$" + revision: "$Revision$" + +class + FCGI_C_API + +feature -- Connection + + accept: INTEGER + -- Accept a Fast CGI connection. + -- Return 0 for successful calls, -1 otherwise. + external + "C inline use %"fcgi_stdio.h%"" + alias + "return FCGI_Accept();" + end + + environ: POINTER + -- Get the (char**) environ variable from the DLL. + external + "C inline use %"crt_externs.h%"" + alias + "return (char*) _NSGetEnviron();" + end + + finish + -- Finished current request from HTTP server started from + -- the most recent call to `fcgi_accept'. + external + "C inline use %"fcgi_stdio.h%"" + alias + "FCGI_Finish();" + end + + set_exit_status (v: INTEGER) + -- Set the exit status for the most recent request + external + "C inline use %"fcgi_stdio.h%"" + alias + "FCGI_SetExitStatus($v);" + end + +feature -- Input + + read_content_into (a_buffer: POINTER; a_length: INTEGER): INTEGER + -- Read content stream into `a_buffer' but no more than `a_length' character. + external + "C inline use %"fcgi_stdio.h%"" + alias + "[ + { + size_t n; + if (! FCGI_feof(FCGI_stdin)) { + n = FCGI_fread($a_buffer, 1, $a_length, FCGI_stdin); + } else { + n = 0; + } + return n; + } + ]" + end + +feature {FCGI_IMP} -- Internal + + feof (v: POINTER): INTEGER + -- FCGI_feof() + external + "C inline use %"fcgi_stdio.h%"" + alias + "FCGI_feof" + end + +feature {NONE} -- Input + + gets (s: POINTER): POINTER + -- gets() reads a line from stdin into the buffer pointed to + -- by s until either a terminating newline or EOF, which it + -- replaces with '\0' + -- No check for buffer overrun is performed + external + "C inline use %"fcgi_stdio.h%"" + alias + "return FCGI_gets($s);" + end + +feature -- Output + + put_string (v: POINTER; n: INTEGER) + external + "C inline use %"fcgi_stdio.h%"" + alias + "FCGI_fwrite($v, 1, $n, FCGI_stdout);" + end + +feature -- Error + + put_error (v: POINTER; n: INTEGER) + external + "C inline use %"fcgi_stdio.h%"" + alias + "FCGI_fwrite($v, 1, $n, FCGI_stderr);" + end + +feature -- Access + + stdout: POINTER + -- FCGI_stdout() return pointer on output FCGI_FILE + external + "C inline use %"fcgi_stdio.h%"" + alias + "FCGI_stdout" + end + + stdin: POINTER + -- FCGI_stdin() return pointer on input FCGI_FILE + external + "C inline use %"fcgi_stdio.h%"" + alias + "FCGI_stdin" + end + + stderr: POINTER + -- FCGI_stderr() return pointer on error FCGI_FILE + external + "C inline use %"fcgi_stdio.h%"" + alias + "FCGI_stderr" + end + +note + copyright: "Copyright (c) 1984-2011, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 5949 Hollister Ave., Goleta, CA 93117 USA + Telephone 805-685-1006, Fax 805-685-6869 + Website http://www.eiffel.com + Customer support http://support.eiffel.com + ]" +end diff --git a/library/server/libfcgi/implementation/mac/fcgi_imp.e b/library/server/libfcgi/implementation/mac/fcgi_imp.e new file mode 100644 index 00000000..7f41b318 --- /dev/null +++ b/library/server/libfcgi/implementation/mac/fcgi_imp.e @@ -0,0 +1,179 @@ +note + description: "Implementation for the FCGI_I interface" + legal: "See notice at end of class." + status: "See notice at end of class." + date: "$Date$" + revision: "$Revision$" + +deferred class FCGI_IMP + +inherit + FCGI_I + STRING_HANDLER + +feature {NONE} -- Initialization + + make + -- Initialize FCGI interface + do + create fcgi + end + + fcgi: FCGI_C_API + -- FastCGI C API primitives + + +feature -- Access + + fcgi_environ: POINTER + do + Result := fcgi.environ + end + + fcgi_end_of_input: BOOLEAN + do + Result := fcgi.feof (fcgi.stdin) = 0 + end + +feature -- FCGI Connection + + fcgi_listen: INTEGER + -- Listen to the FCGI input stream + -- Return 0 for successful calls, -1 otherwise. + do + Result := {FCGI_C_API}.accept + end + + fcgi_finish + -- Finish current request from HTTP server started from + -- the most recent call to `fcgi_accept'. + do + {FCGI_C_API}.finish + end + + set_fcgi_exit_status (v: INTEGER) + do + {FCGI_C_API}.set_exit_status (-2) + end + +feature -- FCGI output + + put_string (a_str: READABLE_STRING_8) + -- Put `a_str' on the FastCGI stdout. + local + l_c_str: C_STRING + do + l_c_str := c_buffer + l_c_str.set_string (a_str) + {FCGI_C_API}.put_string (l_c_str.item, l_c_str.count) + end + +feature -- Error + + put_error (a_message: READABLE_STRING_8) + -- Put error message `a_message' on the FastCGI stderr + local + l_c_str: C_STRING + do + l_c_str := c_buffer + l_c_str.set_string (a_message) + fcgi.put_error (l_c_str.item, l_c_str.count) + end + +feature -- FCGI Input + + copy_from_stdin (n: INTEGER; tf: FILE) + -- Read up to n bytes from stdin and write to given file + local + l_c_str: C_STRING + num, readsize, writecount: INTEGER + done: BOOLEAN + do + readsize := n.min (K_input_bufsize) + l_c_str := c_buffer + from + until done or writecount >= n + loop + num := {FCGI_C_API}.read_content_into (l_c_str.item, readsize) + if num = 0 then + -- EOF + done := True + else + tf.put_managed_pointer (c_buffer.managed_data, 0, num) + writecount := writecount + num + end + end + end + +feature {NONE} -- Implementation: FCGI Input + + fill_pointer_from_stdin (p: POINTER; n: INTEGER): INTEGER + -- Read up to `n' bytes from stdin and store in pointer `p' + -- and return number of bytes read. + do + Result := {FCGI_C_API}.read_content_into (p, n) + end + +feature -- I/O Routines + +--RFO read_stdin_into (a_str: STRING) +--RFO -- Read a string from the `stdin' into `a_str'. +--RFO require +--RFO a_str_not_void: a_str /= Void +--RFO local +--RFO l_c_str: C_STRING +--RFO n: INTEGER +--RFO do +--RFO l_c_str := c_buffer +--RFO n := {FCGI_C_API}.read_content_into (l_c_str.item, l_c_str.capacity) +--RFO a_str.set_count (n) +--RFO l_c_str.read_substring_into (a_str, 1, n) +--RFO end + +--RFO read_string_into (a_str: STRING) +--RFO require +--RFO exists: a_str /= Void +--RFO local +--RFO l_c_str: C_STRING +--RFO p: POINTER +--RFO do +--RFO create l_c_str.make_empty (1024) +--RFO p := {FCGI_C_API}.gets (l_c_str.item) +--RFO-- if p /= default_pointer and p = l_c_str.item then +--RFO a_str.resize (l_c_str.count) +--RFO l_c_str.read_string_into (a_str) +--RFO-- else +--RFO-- put_error_line ("Bad pointer from gets") +--RFO-- end +--RFO end + +--RFO read_line +--RFO -- Read up to the next end of line, or end of input +--RFO -- Leave result in last_string +--RFO -- Newline character is absent from result +--RFO do +--RFO if last_string = Void then +--RFO create Result.make (K_input_bufsize) +--RFO else +--RFO last_string.wipe_out +--RFO end +--RFO-- if input_filename /= Void then +--RFO-- io.read_line +--RFO-- last_string.append (io.last_string) +--RFO-- else +--RFO read_string_into (last_string) +--RFO-- end +--RFO end + +note + copyright: "Copyright (c) 1984-2011, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 5949 Hollister Ave., Goleta, CA 93117 USA + Telephone 805-685-1006, Fax 805-685-6869 + Website http://www.eiffel.com + Customer support http://support.eiffel.com + ]" + +end diff --git a/library/server/libfcgi/libfcgi-safe.ecf b/library/server/libfcgi/libfcgi-safe.ecf index fe797bfe..525ce69e 100644 --- a/library/server/libfcgi/libfcgi-safe.ecf +++ b/library/server/libfcgi/libfcgi-safe.ecf @@ -26,7 +26,12 @@ - + + + + + + @@ -34,6 +39,7 @@ /linux$ /fake$ + /mac$ @@ -41,8 +47,17 @@ /fake$ /windows$ + /mac$ - + + + + + /fake$ + /windows$ + /linux$ + + diff --git a/library/server/libfcgi/libfcgi.ecf b/library/server/libfcgi/libfcgi.ecf index f03336d3..1b0dbdc3 100644 --- a/library/server/libfcgi/libfcgi.ecf +++ b/library/server/libfcgi/libfcgi.ecf @@ -27,7 +27,12 @@ - + + + + + + @@ -36,6 +41,7 @@ /linux$ /fake$ + /mac$ @@ -43,8 +49,17 @@ /windows$ /fake$ + /mac$ - + + + + + /fake$ + /windows$ + /linux$ + +