You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Paul Sutton <pa...@ukweb.com> on 1997/09/04 14:26:25 UTC
OS abstraction, inlining functions
Here is a patch which adds support for OS specific "inline" functions.
These lets use abstract "small" functionality such as
ap_is_path_absolute() without the overhead of a system call (at least with
GCC) and without side-effects.
This patch:
a. Adds an os-inline.c file in os/unix
b. Builds libos.a to include both os.c and os-inline.c (but on
GCC os-inline.c will translate to an empty file)
c. Makes os/unix/Makefile responsible for copying required headers
to main (os.h and os-inline.c in this case)
d. Adds a #include "os.h" to main/conf.h so all source modules see
the OS specific data/functions/inlines
e. re-orders the libs on the httpd link to put libos.a at the end so it
is accessable from libmain.a
and finally
f. Provides an ap_is_path_absolute() OS abstraction, implemented as
an inlineable function and updates mod_alias and http_request to
use this abstraction rather than #ifdef/#else/#endif sections
I would like someone familiar with inlining (e.g. Dean?) to check that the
including logic is OK. It seems to compile fine here (linux2) when _GNUC_
is set and when it isn't.
If this is ok and accepted, the next stage would be to
a. Make win32 compile by adding ap_is_path_absolute to os/win32/os.c
and building it into ApacheCore (or ApacheOS.lib)
b. Move os specific stuff from conf.h into os/*/os.h (e.g. the large
#ifdef WIN32 section to os/win32/os.h)
c. Add other #defines into the abstractions (e.g. #define HAVE_SYMLINKS
on Unix) and functions
One question: should we call the abstraction functions ap_XXX() or
os_XXX(). Previously ap_XXX() has been used throughout (ap_signal,
ap_select etc). Now os_canonical_filename has been added. Shouldn't that
be renamed ap_canonical_filname?
//pcs
Index: Configure
===================================================================
RCS file: /export/home/cvs/apachen/src/Configure,v
retrieving revision 1.145
diff -u -r1.145 Configure
--- Configure 1997/09/03 08:30:04 1.145
+++ Configure 1997/09/04 09:43:02
@@ -893,8 +893,6 @@
echo >> Makefile.config
echo "#### End of Configure created section ####">> Makefile.config
-cp $OSDIR/os.h main/os.h
-
####################################################################
# Use TestCompile to see if $(CC) is ANSI and as a "final" sanity
# check
Index: Makefile.tmpl
===================================================================
RCS file: /export/home/cvs/apachen/src/Makefile.tmpl,v
retrieving revision 1.61
diff -u -r1.61 Makefile.tmpl
--- Makefile.tmpl 1997/09/03 08:30:04 1.61
+++ Makefile.tmpl 1997/09/04 09:43:02
@@ -11,8 +11,8 @@
OBJS= \
modules.o \
$(MODULES) \
- $(OSDIR)/libos.a \
- main/libmain.a
+ main/libmain.a \
+ $(OSDIR)/libos.a
SUBDIRS=main $(OSDIR) modules
Index: main/conf.h
===================================================================
RCS file: /export/home/cvs/apachen/src/main/conf.h,v
retrieving revision 1.130
diff -u -r1.130 conf.h
--- conf.h 1997/08/28 01:36:59 1.130
+++ conf.h 1997/09/04 09:43:06
@@ -55,6 +55,8 @@
* See README for a listing of what they mean
*/
+#include "os.h"
+
#if !defined(QNX) && !defined(MPE) && !defined(WIN32)
#include <sys/param.h>
#endif
Index: main/http_request.c
===================================================================
RCS file: /export/home/cvs/apachen/src/main/http_request.c,v
retrieving revision 1.81
diff -u -r1.81 http_request.c
--- http_request.c 1997/08/31 21:28:53 1.81
+++ http_request.c 1997/09/04 09:43:11
@@ -281,12 +281,7 @@
* for the moment, that's not worth the trouble.
*/
-#if defined(__EMX__) || defined(WIN32)
- /* Add OS/2 drive name support */
- if ((test_filename[0] != '/') && (test_filename[1] != ':'))
-#else
- if (test_filename[0] != '/')
-#endif
+ if (!ap_is_path_absolute(test_filename))
{
/* fake filenames (i.e. proxy:) only match Directory sections */
void *this_conf, *entry_config;
Index: modules/standard/mod_alias.c
===================================================================
RCS file: /export/home/cvs/apachen/src/modules/standard/mod_alias.c,v
retrieving revision 1.23
diff -u -r1.23 mod_alias.c
--- mod_alias.c 1997/08/18 13:12:08 1.23
+++ mod_alias.c 1997/09/04 09:43:14
@@ -323,12 +323,7 @@
char *ret;
int status;
-#if defined(__EMX__) || defined(WIN32)
- /* Add support for OS/2 drive names */
- if ((r->uri[0] != '/' && r->uri[0] != '\0') && r->uri[1] != ':')
-#else
- if (r->uri[0] != '/' && r->uri[0] != '\0')
-#endif
+ if (r->uri[0] != '\0' && !ap_is_path_absolute(r->uri))
return DECLINED;
if ((ret = try_alias_list (r, serverconf->redirects, 1, &status)) != NULL) {
Index: os/unix/Makefile.tmpl
===================================================================
RCS file: /export/home/cvs/apachen/src/os/unix/Makefile.tmpl,v
retrieving revision 1.3
diff -u -r1.3 Makefile.tmpl
--- Makefile.tmpl 1997/09/03 08:30:07 1.3
+++ Makefile.tmpl 1997/09/04 09:43:14
@@ -4,14 +4,15 @@
LFLAGS=$(LFLAGS1) $(EXTRA_LFLAGS)
INCDIR=../../main
-OBJS= os.o
+OBJS= os.o os-inline.o
LIB= libos.a
-all: $(LIB)
+all: $(LIB)
+ cp os.h ../../main
+ cp os-inline.c ../../main
-$(LIB): $(OBJS)
- rm -f $@
+$(LIB): $(OBJS)
ar crv $@ $(OBJS)
$(RANLIB) $@
@@ -20,8 +21,6 @@
clean:
rm -f $(OBJS)
-
-$(OBJS): Makefile
# DO NOT REMOVE
os.o: os.c
Index: os/unix/os.c
===================================================================
RCS file: /export/home/cvs/apachen/src/os/unix/os.c,v
retrieving revision 1.1
diff -u -r1.1 os.c
--- os.c 1997/08/10 13:33:18 1.1
+++ os.c 1997/09/04 09:43:14
@@ -0,0 +1,6 @@
+/*
+ * This file will include OS specific functions which are not inlineable.
+ * Any inlineable functions should be defined in os-inline.c instead.
+ */
+
+#include "os.h"
Index: os/unix/os.h
===================================================================
RCS file: /export/home/cvs/apachen/src/os/unix/os.h,v
retrieving revision 1.1
diff -u -r1.1 os.h
--- os.h 1997/08/10 13:33:19 1.1
+++ os.h 1997/09/04 09:43:14
@@ -0,0 +1,20 @@
+/*
+ * This file in included in all Apache source code. It contains definitions
+ * of facilities available on _this_ operating system (HAVE_* macros),
+ * and prototypes of OS specific functions defined in os.c or os-inline.c
+ */
+
+#if defined(__GNUC__) && !defined(INLINE)
+/* Compiler supports inline, so include the inlineable functions as
+ * part of the header
+ */
+#define INLINE extern inline
+#include "os-inline.c"
+#endif
+
+#ifndef INLINE
+/* Compiler does not support inline, so prototype the inlineable functions
+ * as normal
+ */
+extern int ap_is_path_absolute(char *f);
+#endif
===================================
os/unix/os-inline.c:
/*
* This file contains functions which can be inlined if the compiler
* has an "inline" modifier. Because of this, this file is both a
* header file and a compilable module.
*
* Only inlineable functions should be defined in here. They must all
* include the INLINE modifier.
*
* If the compiler supports inline, this file will be #included as a
* header file from os.h to create all the inline function
* definitions. INLINE will be defined to whatever is required on
* function definitions to make them inline declarations.
*
* If the compiler does not support inline, this file will be compiled
* as a normal C file into libos.a (along with os.c). In this case
* INLINE will _not_ be set so we can use this to test if we are
* compiling this source file.
*/
#ifndef INLINE
#define INLINE
/* Anything required only when compiling */
#endif
INLINE int ap_is_path_absolute(char *file)
{
return (file && file[0] == '/' ? 1 : 0);
}
Re: OS abstraction, inlining functions
Posted by Ben Laurie <be...@algroup.co.uk>.
Paul Sutton wrote:
>
> On Thu, 4 Sep 1997, Ben Laurie wrote:
> > Paul Sutton wrote:
> > > Here is a patch which adds support for OS specific "inline" functions.
> > > These lets use abstract "small" functionality such as
> > > ap_is_path_absolute() without the overhead of a system call (at least with
> > > GCC) and without side-effects.
> >
> > I presume you mean "function call", not "system call". But this isn't a
> > very good example, as it can be done with a #define, and thus avoid the
> > overhead on non-inlining compilers.
>
> Umm, that was my original intention but Dean pointed out the problem of
> side effects. It is a good point: consider
>
> #define ap_is_path_absolute(f) /* nb: for illustration only */ \
> ((f[1]==':'&&f[2]=='\\') /* C:\ style */ \
> || (f[0]=='\\'&&f[1]=='\\')) /* \\SERVER\ style */
>
> when called with
>
> ap_is_path_absolute(somestring++); or
> ap_is_path_absolute(server_root_relative(p, fname));
>
> Macros should be used where side-effects are not possible but in this case
> a function (or inline) must be used, surely. Annoyingly VC++ 5.0 does not
> support inline functions in C code.
Good point, but toupper() and friends have existed as macros with side
effects since the year dot.
Cheers,
Ben.
--
Ben Laurie |Phone: +44 (181) 994 6435|Apache Group member
Freelance Consultant |Fax: +44 (181) 994 6472|http://www.apache.org
and Technical Director|Email: ben@algroup.co.uk |Apache-SSL author
A.L. Digital Ltd, |http://www.algroup.co.uk/Apache-SSL
London, England. |"Apache: TDG" http://www.ora.com/catalog/apache
Re: OS abstraction, inlining functions
Posted by Paul Sutton <pa...@ukweb.com>.
On Thu, 4 Sep 1997, Ben Laurie wrote:
> Paul Sutton wrote:
> > Here is a patch which adds support for OS specific "inline" functions.
> > These lets use abstract "small" functionality such as
> > ap_is_path_absolute() without the overhead of a system call (at least with
> > GCC) and without side-effects.
>
> I presume you mean "function call", not "system call". But this isn't a
> very good example, as it can be done with a #define, and thus avoid the
> overhead on non-inlining compilers.
Umm, that was my original intention but Dean pointed out the problem of
side effects. It is a good point: consider
#define ap_is_path_absolute(f) /* nb: for illustration only */ \
((f[1]==':'&&f[2]=='\\') /* C:\ style */ \
|| (f[0]=='\\'&&f[1]=='\\')) /* \\SERVER\ style */
when called with
ap_is_path_absolute(somestring++); or
ap_is_path_absolute(server_root_relative(p, fname));
Macros should be used where side-effects are not possible but in this case
a function (or inline) must be used, surely. Annoyingly VC++ 5.0 does not
support inline functions in C code.
> ap_ is for functions that replace standard ones, os_ is for OS specific
> functions (that may do different things on different platforms).
>
> So, ap_is_path_absolute should be os_is_path_absolute.
This does sound reasonable, so I'm happy with this os_/ap_ distinction.
//pcs
Re: OS abstraction, inlining functions
Posted by Ben Laurie <be...@algroup.co.uk>.
Paul Sutton wrote:
>
> Here is a patch which adds support for OS specific "inline" functions.
> These lets use abstract "small" functionality such as
> ap_is_path_absolute() without the overhead of a system call (at least with
> GCC) and without side-effects.
I presume you mean "function call", not "system call". But this isn't a
very good example, as it can be done with a #define, and thus avoid the
overhead on non-inlining compilers.
> One question: should we call the abstraction functions ap_XXX() or
> os_XXX(). Previously ap_XXX() has been used throughout (ap_signal,
> ap_select etc). Now os_canonical_filename has been added. Shouldn't that
> be renamed ap_canonical_filname?
Actually, the os_ notation predates the ap_ notation - it was introduced
way back for os_escape_path (or whatever it is called).
ap_ is for functions that replace standard ones, os_ is for OS specific
functions (that may do different things on different platforms).
So, ap_is_path_absolute should be os_is_path_absolute.
Cheers,
Ben.
--
Ben Laurie |Phone: +44 (181) 994 6435|Apache Group member
Freelance Consultant |Fax: +44 (181) 994 6472|http://www.apache.org
and Technical Director|Email: ben@algroup.co.uk |Apache-SSL author
A.L. Digital Ltd, |http://www.algroup.co.uk/Apache-SSL
London, England. |"Apache: TDG" http://www.ora.com/catalog/apache
Re: OS abstraction, inlining functions
Posted by Dean Gaudet <dg...@arctic.org>.
This looks fine ...
note that in conf.h I added code to "#define inline" on non-GCC compilers.
Feel free to change that to use INLINE or whatever ... but note that I've
actually used inline a few places -- where I'm using it for static
inlines.
Dean
On Thu, 4 Sep 1997, Paul Sutton wrote:
> Here is a patch which adds support for OS specific "inline" functions.
> These lets use abstract "small" functionality such as
> ap_is_path_absolute() without the overhead of a system call (at least with
> GCC) and without side-effects.
>
> This patch:
>
> a. Adds an os-inline.c file in os/unix
> b. Builds libos.a to include both os.c and os-inline.c (but on
> GCC os-inline.c will translate to an empty file)
> c. Makes os/unix/Makefile responsible for copying required headers
> to main (os.h and os-inline.c in this case)
> d. Adds a #include "os.h" to main/conf.h so all source modules see
> the OS specific data/functions/inlines
> e. re-orders the libs on the httpd link to put libos.a at the end so it
> is accessable from libmain.a
>
> and finally
>
> f. Provides an ap_is_path_absolute() OS abstraction, implemented as
> an inlineable function and updates mod_alias and http_request to
> use this abstraction rather than #ifdef/#else/#endif sections
>
> I would like someone familiar with inlining (e.g. Dean?) to check that the
> including logic is OK. It seems to compile fine here (linux2) when _GNUC_
> is set and when it isn't.
>
> If this is ok and accepted, the next stage would be to
>
> a. Make win32 compile by adding ap_is_path_absolute to os/win32/os.c
> and building it into ApacheCore (or ApacheOS.lib)
> b. Move os specific stuff from conf.h into os/*/os.h (e.g. the large
> #ifdef WIN32 section to os/win32/os.h)
> c. Add other #defines into the abstractions (e.g. #define HAVE_SYMLINKS
> on Unix) and functions
>
> One question: should we call the abstraction functions ap_XXX() or
> os_XXX(). Previously ap_XXX() has been used throughout (ap_signal,
> ap_select etc). Now os_canonical_filename has been added. Shouldn't that
> be renamed ap_canonical_filname?
>
> //pcs
>
> Index: Configure
> ===================================================================
> RCS file: /export/home/cvs/apachen/src/Configure,v
> retrieving revision 1.145
> diff -u -r1.145 Configure
> --- Configure 1997/09/03 08:30:04 1.145
> +++ Configure 1997/09/04 09:43:02
> @@ -893,8 +893,6 @@
> echo >> Makefile.config
> echo "#### End of Configure created section ####">> Makefile.config
>
> -cp $OSDIR/os.h main/os.h
> -
> ####################################################################
> # Use TestCompile to see if $(CC) is ANSI and as a "final" sanity
> # check
> Index: Makefile.tmpl
> ===================================================================
> RCS file: /export/home/cvs/apachen/src/Makefile.tmpl,v
> retrieving revision 1.61
> diff -u -r1.61 Makefile.tmpl
> --- Makefile.tmpl 1997/09/03 08:30:04 1.61
> +++ Makefile.tmpl 1997/09/04 09:43:02
> @@ -11,8 +11,8 @@
> OBJS= \
> modules.o \
> $(MODULES) \
> - $(OSDIR)/libos.a \
> - main/libmain.a
> + main/libmain.a \
> + $(OSDIR)/libos.a
>
> SUBDIRS=main $(OSDIR) modules
>
> Index: main/conf.h
> ===================================================================
> RCS file: /export/home/cvs/apachen/src/main/conf.h,v
> retrieving revision 1.130
> diff -u -r1.130 conf.h
> --- conf.h 1997/08/28 01:36:59 1.130
> +++ conf.h 1997/09/04 09:43:06
> @@ -55,6 +55,8 @@
> * See README for a listing of what they mean
> */
>
> +#include "os.h"
> +
> #if !defined(QNX) && !defined(MPE) && !defined(WIN32)
> #include <sys/param.h>
> #endif
> Index: main/http_request.c
> ===================================================================
> RCS file: /export/home/cvs/apachen/src/main/http_request.c,v
> retrieving revision 1.81
> diff -u -r1.81 http_request.c
> --- http_request.c 1997/08/31 21:28:53 1.81
> +++ http_request.c 1997/09/04 09:43:11
> @@ -281,12 +281,7 @@
> * for the moment, that's not worth the trouble.
> */
>
> -#if defined(__EMX__) || defined(WIN32)
> - /* Add OS/2 drive name support */
> - if ((test_filename[0] != '/') && (test_filename[1] != ':'))
> -#else
> - if (test_filename[0] != '/')
> -#endif
> + if (!ap_is_path_absolute(test_filename))
> {
> /* fake filenames (i.e. proxy:) only match Directory sections */
> void *this_conf, *entry_config;
> Index: modules/standard/mod_alias.c
> ===================================================================
> RCS file: /export/home/cvs/apachen/src/modules/standard/mod_alias.c,v
> retrieving revision 1.23
> diff -u -r1.23 mod_alias.c
> --- mod_alias.c 1997/08/18 13:12:08 1.23
> +++ mod_alias.c 1997/09/04 09:43:14
> @@ -323,12 +323,7 @@
> char *ret;
> int status;
>
> -#if defined(__EMX__) || defined(WIN32)
> - /* Add support for OS/2 drive names */
> - if ((r->uri[0] != '/' && r->uri[0] != '\0') && r->uri[1] != ':')
> -#else
> - if (r->uri[0] != '/' && r->uri[0] != '\0')
> -#endif
> + if (r->uri[0] != '\0' && !ap_is_path_absolute(r->uri))
> return DECLINED;
>
> if ((ret = try_alias_list (r, serverconf->redirects, 1, &status)) != NULL) {
> Index: os/unix/Makefile.tmpl
> ===================================================================
> RCS file: /export/home/cvs/apachen/src/os/unix/Makefile.tmpl,v
> retrieving revision 1.3
> diff -u -r1.3 Makefile.tmpl
> --- Makefile.tmpl 1997/09/03 08:30:07 1.3
> +++ Makefile.tmpl 1997/09/04 09:43:14
> @@ -4,14 +4,15 @@
> LFLAGS=$(LFLAGS1) $(EXTRA_LFLAGS)
> INCDIR=../../main
>
> -OBJS= os.o
> +OBJS= os.o os-inline.o
>
> LIB= libos.a
>
> -all: $(LIB)
> +all: $(LIB)
> + cp os.h ../../main
> + cp os-inline.c ../../main
>
> -$(LIB): $(OBJS)
> - rm -f $@
> +$(LIB): $(OBJS)
> ar crv $@ $(OBJS)
> $(RANLIB) $@
>
> @@ -20,8 +21,6 @@
>
> clean:
> rm -f $(OBJS)
> -
> -$(OBJS): Makefile
>
> # DO NOT REMOVE
> os.o: os.c
> Index: os/unix/os.c
> ===================================================================
> RCS file: /export/home/cvs/apachen/src/os/unix/os.c,v
> retrieving revision 1.1
> diff -u -r1.1 os.c
> --- os.c 1997/08/10 13:33:18 1.1
> +++ os.c 1997/09/04 09:43:14
> @@ -0,0 +1,6 @@
> +/*
> + * This file will include OS specific functions which are not inlineable.
> + * Any inlineable functions should be defined in os-inline.c instead.
> + */
> +
> +#include "os.h"
> Index: os/unix/os.h
> ===================================================================
> RCS file: /export/home/cvs/apachen/src/os/unix/os.h,v
> retrieving revision 1.1
> diff -u -r1.1 os.h
> --- os.h 1997/08/10 13:33:19 1.1
> +++ os.h 1997/09/04 09:43:14
> @@ -0,0 +1,20 @@
> +/*
> + * This file in included in all Apache source code. It contains definitions
> + * of facilities available on _this_ operating system (HAVE_* macros),
> + * and prototypes of OS specific functions defined in os.c or os-inline.c
> + */
> +
> +#if defined(__GNUC__) && !defined(INLINE)
> +/* Compiler supports inline, so include the inlineable functions as
> + * part of the header
> + */
> +#define INLINE extern inline
> +#include "os-inline.c"
> +#endif
> +
> +#ifndef INLINE
> +/* Compiler does not support inline, so prototype the inlineable functions
> + * as normal
> + */
> +extern int ap_is_path_absolute(char *f);
> +#endif
>
> ===================================
> os/unix/os-inline.c:
>
> /*
> * This file contains functions which can be inlined if the compiler
> * has an "inline" modifier. Because of this, this file is both a
> * header file and a compilable module.
> *
> * Only inlineable functions should be defined in here. They must all
> * include the INLINE modifier.
> *
> * If the compiler supports inline, this file will be #included as a
> * header file from os.h to create all the inline function
> * definitions. INLINE will be defined to whatever is required on
> * function definitions to make them inline declarations.
> *
> * If the compiler does not support inline, this file will be compiled
> * as a normal C file into libos.a (along with os.c). In this case
> * INLINE will _not_ be set so we can use this to test if we are
> * compiling this source file.
> */
>
> #ifndef INLINE
> #define INLINE
>
> /* Anything required only when compiling */
>
> #endif
>
> INLINE int ap_is_path_absolute(char *file)
> {
> return (file && file[0] == '/' ? 1 : 0);
> }
>
>
>
Re: OS abstraction, inlining functions
Posted by Alexei Kosut <ak...@organic.com>.
On Thu, 4 Sep 1997, Paul Sutton wrote:
> One question: should we call the abstraction functions ap_XXX() or
> os_XXX(). Previously ap_XXX() has been used throughout (ap_signal,
> ap_select etc). Now os_canonical_filename has been added. Shouldn't that
> be renamed ap_canonical_filname?
Well, os_canonical_filename was named after os_escape_path(), which has
been around for a long while. But maybe we should change them. I dunno.
-- Alexei Kosut <ak...@organic.com>