FastCGI with Ada

I found http://support.zeus.com/zws/examples/2005/12/16/hello_world_in_perl_and_c and these two examples work.

Now I tried this for Ada, and I can not do this from 2 days.

fcgi_stdio.ads

with Interfaces.C; with Interfaces.C.Strings; package fcgi_stdio is function FCGI_Accept return Interfaces.C.int; pragma Import (C, FCGI_Accept, "FCGI_Accept"); procedure FCGI_printf (str : Interfaces.C.Strings.chars_ptr); pragma Import (C, FCGI_printf, "FCGI_printf"); end fcgi_stdio; 

test.adb

 with fcgi_stdio; with Interfaces.C; with Interfaces.C.Strings; procedure Test is begin while Integer (fcgi_stdio.FCGI_Accept) >= 0 loop fcgi_stdio.FCGI_printf (Interfaces.C.Strings.New_String ("Content-Type: text/plain" & ASCII.LF & ASCII.LF)); fcgi_stdio.FCGI_printf (Interfaces.C.Strings.New_String ("Hello World from Ada!" & ASCII.LF)); end loop; end Test; 

When I run it in the console, I get the following error:

 $ ./test raised STORAGE_ERROR : Qaru or erroneous memory access 

Apache error_log shows:

 Premature end of script headers: test 

Does anyone have an idea how I can make it work?

+4
source share
1 answer

While experimenting on Mac OS X, it seems that the problem is that FCGI_printf() is a varargs function. It calls FCGI_fprintf() , also varargs:

 int FCGI_fprintf(FCGI_FILE *fp, const char *format, ...) { va_list ap; int n = 0; va_start(ap, format); <------ crash here 

Ada does not have a standard way of specifying varargs functions, and GNAT also does not have an implementation.

The GNAT documentation says the solution is to provide a C wrapper for the varargs function:

 #include <fcgi_stdio.h> int FCGI_printf_wrapper(const char *msg) { return FCGI_printf(msg); } 

and import the wrapper:

 procedure FCGI_printf (str : Interfaces.C.Strings.chars_ptr); pragma Import (C, FCGI_printf, "FCGI_printf_wrapper"); 

Another problem with the program is that in Ada, unlike C and many other languages, "\n" not a way to insert a newline character into a string. Try

 fcgi_stdio.FCGI_printf (Interfaces.C.Strings.New_String ("Content-Type: text/plain" & ASCII.LF & ASCII.LF)); 

[edited 13.1.13]

+7
source

All Articles