httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Pavel Novy <>
Subject [PATCH] Apache 2.0 and NetWare - compatibility issue
Date Wed, 14 Nov 2001 14:58:53 GMT
Hi all,
I want to open an old issue with the bitfields used in some struct which 
is shared between the core and the modules. It causes strange problems 
if using different compilers for NetWare target builds, e.g. when 
compiling some own or 3rd party modules designed for Apache. I still 
hope that other compilers than CodeWarrior from Metrowerks will be 
supported to build the Apache webserver for NetWare. I've succeeded with 
build of Apache 2.0 using the GNU utilities (binutils, gcc) already, and 
Watcom (now OpenWatcom) is also an alternative, I think.

    Problem: There is a significant difference in implementation of the 
bitfields - gcc uses the smallest amount of bytes to store whole 
bitfield (three bits used here, so one byte allocated - i386, Linux, 
NetWare, ...); size of the bitfield with CW and Watcom is dependent on 
base type (e.g. char bf:1, small bf:1, ...; gcc is ignoring the base type).

A structure affected is defined in srclib/apr-util/include/apr_uri.h:
  * A structure to encompass all of the fields in a uri

struct apr_uri_t {

     /** has the structure been initialized */
     unsigned is_initialized:1;

     /** has the DNS been looked up yet */
     unsigned dns_looked_up:1;
     /** has the dns been resolved yet */
     unsigned dns_resolved:1;

This struct is used within a request_rec struct defined in include/httpd.h:
/** A structure that represents the current request */
struct request_rec {
     apr_uri_t parsed_uri;

     /* Various other config info which may change with .htaccess files
      * These are config vectors, with one void* pointer for each module
      * (the thing pointed to being the module's business).

     /** Options set in config files, etc. */
     struct ap_conf_vector_t *per_dir_config;
     /** Notes on *this* request */
     struct ap_conf_vector_t *request_config;

  * a linked list of the configuration directives in the .htaccess files
  * accessed by this request.
  * N.B. always add to the head of the list, _never_ to the end.
  * that way, a sub request's list can (temporarily) point to a parent's 
     const struct htaccess_result *htaccess;

     /** A list of output filters to be used for this request */
     struct ap_filter_t *output_filters;
     /** A list of input filters to be used for this request */
     struct ap_filter_t *input_filters;
     /** A flag to determine if the eos bucket has been sent yet */
     int eos_sent;

/* Things placed at the end of the record to avoid breaking binary
  * compatibility.  It would be nice to remember to reorder the entire
  * record to improve 64bit alignment the next time we need to break
  * binary compatibility for some other reason.

So, any accesses below "parsed_uri" are affected by the issue, if 
running mixed core/modules compiled with gcc/Watcom/CW (CW is 
additionaly affected by some weird alignment issue, so also incompatible 
with Watcom and gcc, but it is another problem). There is no problem, if 
the core and all modules are compiled with only one compiler, of course.

I suggest to not use the bitfields in this struct anymore, but use some 
single element (char type) instead and use some constantants defined in 
apr_uri.h file (or elsewhere) to access individual bits. It is still 
extendable, but not sure for alignment on all platforms and targets (it 
must be tested here, of course). The second way is to change the base 
type for "bits" from "unsigned" to "unsigned char", but it was rejected 
for Apache 1.3 when I proposed this, so I don't expect that it will be 
commited in version 2.0...

I found that the bitfield used in affected structure is not practically 
used in the sources, so I think that it could be easily rearranged here 
- only one reference from srclib/apr-util/uri/apr_uri.c found:
APU_DECLARE(int) apr_uri_parse(apr_pool_t *p, const char *uri,
                                           apr_uri_t *uptr)
     memset (uptr, '\0', sizeof(*uptr));
     uptr->is_initialized = 1;

Pavel Novy

View raw message