[Help-gnutls] Re: Build gnutls on windows

Martin Lambers marlam at marlam.de
Thu Sep 22 23:15:02 CEST 2005


On Wed, 21. Sep 2005, 22:44:57 +0200, Simon Josefsson wrote:
> > The first patch removes 'char *program_name = "gnutls";' from
> > lib/gnutls_global.c. This apparently reverts a change from 2005-08-30.
> > I did not get the missing symbols error afterwards. When does it cause
> > problems for you?
> 
> I had problems with this on uClinux too...  The problem is that the
> error module from gnulib use program_name, but the core GnuTLS library
> does not use the error module.  On some systems, the core library will
> not link because program_name is not present.  The error module is
> only used by some code in src/.
> 
> There has been discussion on solving this on the gnulib list, i.e.,
> having two different gnulib directories, one for the library in lib/
> and one for the application in src/.  This would also make it possible
> to use GPL'd gnulib modules in src/, without causing license problems
> in lib/.  Currently the only solution is to create a configure.ac in
> lib/ and build it separately.  This is what I did in GNU SASL, but I
> don't want to do the same for GnuTLS.

I've been following that discussion loosely, but now I realize how
useful two different directories could be.

> > The second patch changes the example code in doc/examples:
> > 1. Replace bzero with memset.
> > 2. Don't use mmap (this is the same change that was done in src/cli.c).
> 
> Ok.

I attached a patch wich contains only these changes.

> > 3. Include a different header on WIN32.
> > 4. Use inet_ntoa instead of inet_ntop on WIN32.
> 
> No... There should be gnulib modules to handle this silliness.  There
> already is a inet_ntop gnulib module.  There could be a gnulib module
> that provided sys/socket.h, netinet/in.h and arpa/inet.h on platforms
> that doesn't have them.  For mingw32, those files could simply include
> winsock2.h if that is indeed the proper way to get access to POSIX
> functionality.

Unfortunately, every single socket function on Win32 is incompatible
with POSIX in some way (or so it seems). Sometimes it's obvious,
sometimes not.
Examples: 
- errno is never set
- The "network library" must be initialized and closed with special
  functions
- Sockets cannot just be closed with close(), they need closesocket()
- shutdown() uses non-standard constants
- You cannot use fcntl() on a socket. There's only a limited
  ioctlsocket() function.

> > But maybe it would be better to disable compilation of the examples on
> > Win32 instead of cluttering example code with #ifdefs.
> 
> Exactly.  We should stop cluttering code with #ifdef's.  We should
> write code that works best on the GNU platform, and use gnulib modules
> where the native system is failing.

You're right. I'll keep that in mind.

However, this could mean to drop support for MinGW: I doubt that gnulib
is the best way to achieve reasonable POSIX support on Win32.

An unlink() replacement that delays the actual unlink operation until
all file descriptors referring to the file are closed is one example:
such a function is not easy to write on Win32. The same holds for
using standard functions like fcntl() or even close() on sockets.

Programs that are expected to work on Win32 often avoid to rely on basic
standardized functionality like this. Such code does not qualify for
"works best on the GNU platform" anymore.

Reasonable POSIX support on Win32 is not just a collection of fixes for
minor misbehaviour; it is a major task. Perhaps it would be better to
leave that to an external project and only support "MinGW + plibc" (or
something similar) as a target platform.

BTW, the unlink() and fcntl() examples are not yet handled by plibc as
far as I can tell.

Martin
-------------- next part --------------
Index: ex-cert-select.c
===================================================================
RCS file: /cvs/gnutls/gnutls/doc/examples/ex-cert-select.c,v
retrieving revision 1.5
diff -u -r1.5 ex-cert-select.c
--- ex-cert-select.c	10 Aug 2005 09:09:04 -0000	1.5
+++ ex-cert-select.c	22 Sep 2005 20:05:19 -0000
@@ -7,7 +7,6 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <unistd.h>
-#include <sys/mman.h>
 #include <sys/stat.h>
 #include <gnutls/gnutls.h>
 #include <gnutls/x509.h>
@@ -37,38 +36,34 @@
 gnutls_x509_privkey_t key;
 
 /* Helper functions to load a certificate and key
- * files into memory. They use mmap for simplicity.
+ * files into memory.
  */
-static gnutls_datum_t
-mmap_file (const char *file)
+static gnutls_datum 
+load_file (const char *file)
 {
-  int fd;
-  gnutls_datum_t mmaped_file = { NULL, 0 };
-  struct stat stat_st;
+  FILE *f;
+  gnutls_datum loaded_file = { NULL, 0 };
+  long filelen;
   void *ptr;
 
-  fd = open (file, 0);
-  if (fd == -1)
-    return mmaped_file;
-
-  fstat (fd, &stat_st);
-
-  ptr = mmap (NULL, stat_st.st_size, PROT_READ, MAP_SHARED, fd, 0);
-  close (fd);
-
-  if (ptr == MAP_FAILED)
-    return mmaped_file;
-
-  mmaped_file.data = ptr;
-  mmaped_file.size = stat_st.st_size;
+  if (!(f = fopen(file, "r"))
+      || fseek(f, 0, SEEK_END) != 0
+      || (filelen = ftell(f)) < 0
+      || fseek(f, 0, SEEK_SET) != 0
+      || !(ptr = malloc((size_t)filelen))
+      || fread(ptr, 1, (size_t)filelen, f) < (size_t)filelen)
+    {
+      return loaded_file;
+    }
 
-  return mmaped_file;
+  loaded_file.data = ptr;
+  loaded_file.size = (unsigned int)filelen;
+  return loaded_file;
 }
 
-static void
-munmap_file (gnutls_datum_t data)
+static void unload_file(gnutls_datum data)
 {
-  munmap (data.data, data.size);
+  free(data.data);
 }
 
 /* Load the certificate and the private key.
@@ -79,7 +74,7 @@
   int ret;
   gnutls_datum_t data;
 
-  data = mmap_file (CERT_FILE);
+  data = load_file (CERT_FILE);
   if (data.data == NULL)
     {
       fprintf (stderr, "*** Error loading cert file.\n");
@@ -95,9 +90,9 @@
       exit (1);
     }
 
-  munmap_file (data);
+  unload_file (data);
 
-  data = mmap_file (KEY_FILE);
+  data = load_file (KEY_FILE);
   if (data.data == NULL)
     {
       fprintf (stderr, "*** Error loading key file.\n");
@@ -114,7 +109,7 @@
       exit (1);
     }
 
-  munmap_file (data);
+  unload_file (data);
 
 }
 
Index: ex-serv-anon.c
===================================================================
RCS file: /cvs/gnutls/gnutls/doc/examples/ex-serv-anon.c,v
retrieving revision 1.3
diff -u -r1.3 ex-serv-anon.c
--- ex-serv-anon.c	10 Aug 2005 09:09:04 -0000	1.3
+++ ex-serv-anon.c	22 Sep 2005 20:05:19 -0000
@@ -132,7 +132,7 @@
       i = 0;
       for (;;)
 	{
-	  bzero (buffer, MAX_BUF + 1);
+	  memset (buffer, 0, MAX_BUF + 1);
 	  ret = gnutls_record_recv (session, buffer, MAX_BUF);
 
 	  if (ret == 0)
Index: ex-serv-export.c
===================================================================
RCS file: /cvs/gnutls/gnutls/doc/examples/ex-serv-export.c,v
retrieving revision 1.4
diff -u -r1.4 ex-serv-export.c
--- ex-serv-export.c	10 Aug 2005 09:09:04 -0000	1.4
+++ ex-serv-export.c	22 Sep 2005 20:05:20 -0000
@@ -191,7 +191,7 @@
       i = 0;
       for (;;)
 	{
-	  bzero (buffer, MAX_BUF + 1);
+	  memset (buffer, 0, MAX_BUF + 1);
 	  ret = gnutls_record_recv (session, buffer, MAX_BUF);
 
 	  if (ret == 0)
Index: ex-serv-pgp.c
===================================================================
RCS file: /cvs/gnutls/gnutls/doc/examples/ex-serv-pgp.c,v
retrieving revision 1.4
diff -u -r1.4 ex-serv-pgp.c
--- ex-serv-pgp.c	10 Aug 2005 09:09:04 -0000	1.4
+++ ex-serv-pgp.c	22 Sep 2005 20:05:20 -0000
@@ -151,7 +151,7 @@
       i = 0;
       for (;;)
 	{
-	  bzero (buffer, MAX_BUF + 1);
+	  memset (buffer, 0, MAX_BUF + 1);
 	  ret = gnutls_record_recv (session, buffer, MAX_BUF);
 
 	  if (ret == 0)
Index: ex-serv-srp.c
===================================================================
RCS file: /cvs/gnutls/gnutls/doc/examples/ex-serv-srp.c,v
retrieving revision 1.4
diff -u -r1.4 ex-serv-srp.c
--- ex-serv-srp.c	10 Aug 2005 09:09:04 -0000	1.4
+++ ex-serv-srp.c	22 Sep 2005 20:05:20 -0000
@@ -135,7 +135,7 @@
       i = 0;
       for (;;)
 	{
-	  bzero (buffer, MAX_BUF + 1);
+	  memset (buffer, 0, MAX_BUF + 1);
 	  ret = gnutls_record_recv (session, buffer, MAX_BUF);
 
 	  if (ret == 0)
Index: ex-serv1.c
===================================================================
RCS file: /cvs/gnutls/gnutls/doc/examples/ex-serv1.c,v
retrieving revision 1.5
diff -u -r1.5 ex-serv1.c
--- ex-serv1.c	10 Aug 2005 09:09:04 -0000	1.5
+++ ex-serv1.c	22 Sep 2005 20:05:21 -0000
@@ -147,7 +147,7 @@
       i = 0;
       for (;;)
 	{
-	  bzero (buffer, MAX_BUF + 1);
+	  memset (buffer, 0, MAX_BUF + 1);
 	  ret = gnutls_record_recv (session, buffer, MAX_BUF);
 
 	  if (ret == 0)


More information about the Gnutls-help mailing list