Apache command parser prototype

I am creating an Apache2 module and am experiencing a strange compilation problem. This is the prototype for my function used to parse the config command named "analytics_ip":

static const char *apr_cfg_set_analytics_ip(cmd_parms *cmd, void *config, const char *data);

      

This is an array of command_rec structures containing pointers to this function:

static const command_rec apr_cmds[] =
{
 AP_INIT_TAKE1("analytics_ip", apr_cfg_set_analytics_ip, NULL, OR_ALL, ""),
 { NULL }
};

      

The command_rec structure is declared in the header file http_config.h

typedef struct command_struct command_rec;
struct command_struct {
    /** Name of this command */
    const char *name;
    /** The function to be called when this directive is parsed */
    cmd_func func;
    /** Extra data, for functions which implement multiple commands... */
    void *cmd_data;
    /** What overrides need to be allowed to enable this command. */
    int req_override;
    /** What the command expects as arguments */
    enum cmd_how args_how;

    /** 'usage' message, in case of syntax errors */
    const char *errmsg;
};

      

When I follow cmd_func it gets the following declaration:

typedef const char *(*cmd_func) ();

      

If I am not mistaken it means "a function pointer returning a pointer to char and taking no arguments". How can this be possible? The command parsing function must accept at least one parameter containing the value of the module of the configuration variable corresponding to this function.

I am using g ++ to compile this module. Error message:

mod_xxx.h:65:2: error: invalid conversion from โ€˜const char* (*)(cmd_parms*, void*, const char*) {aka const char* (*)(cmd_parms_struct*, void*, const char*)}โ€™ to โ€˜cmd_func {aka const char* (*)()}โ€™ [-fpermissive]
  };

      

Thank you in advance

+3


source to share


2 answers


cmd_func

is a union, it is defined in http_config.h as follows:

typedef union {
    /** function to call for a no-args */
    const char *(*no_args) (cmd_parms *parms, void *mconfig);
    /** function to call for a raw-args */
    const char *(*raw_args) (cmd_parms *parms, void *mconfig,
                             const char *args);
    /** function to call for a argv/argc */
    const char *(*take_argv) (cmd_parms *parms, void *mconfig,
                             int argc, char *const argv[]);
    /** function to call for a take1 */
    const char *(*take1) (cmd_parms *parms, void *mconfig, const char *w);
    /** function to call for a take2 */
    const char *(*take2) (cmd_parms *parms, void *mconfig, const char *w,
                          const char *w2);
    /** function to call for a take3 */
    const char *(*take3) (cmd_parms *parms, void *mconfig, const char *w,
                          const char *w2, const char *w3);
    /** function to call for a flag */
    const char *(*flag) (cmd_parms *parms, void *mconfig, int on);
} cmd_func;

      

enum cmd_how args_how;

is responsible for choosing the correct version of the function.

The commander switch is located in server / config.c (in function invoke_cmd

).



You seem to be using the "take1" version that matches cmd->AP_TAKE1

or just cmd->take1

.

The problem might be that C and C ++ have differences in union initialization . ( AP_INIT_TAKE1

uses syntax { .take1=func }

that doesn't work in C ++).

You will need to initialize static const command_rec apr_cmds

in a C ++ compatible way, or move it into a separate object file compiled with C. Or if you are not using C ++ then just compile with gcc

.

+3


source


For a project I'm working on, we added a throw to complete the compilation and the code seems to work fine as it reads the values โ€‹โ€‹given in the config file correctly. Here's an excerpt from this practice: extern "C" { static const command_rec kiwix_settings[] = { AP_INIT_TAKE1("zimFile", (const char* (*)())kiwix_set_zimfilename, NULL, RSRC_CONF, "The ZIM filename in full including the extension"), AP_INIT_TAKE1("zimPath", (const char* (*)())kiwix_set_path, NULL, RSRC_CONF, "The path to the ZIM file, including the trailing //"), { NULL } }; }

The complete file (and indeed the project) opens. Here's a link to the complete file https://github.com/kiwix/kiwix-apache/blob/master/mod_kiwix.cpp



PS: thanks for your question and https://stackoverflow.com/users/257568/artemgr as they helped me and another volunteer to figure out how to solve the problem for our project.

0


source







All Articles