Commit 0898ca10 authored by Juanma Barranquero's avatar Juanma Barranquero

Implement dynamic loading of GnuTLS on Windows.

* lisp/term/w32-win.el (dynamic-library-alist): Add `gnutls'.

* nt/INSTALL: Clarify GnuTLS support.

* src/callproc.c, src/emacs.c: Include lisp.h before src/w32.h, not after.

* src/gnutls.c (Qgnutls_dll): Define.
  (DEF_GNUTLS_FN, LOAD_GNUTLS_FN): New macros.
  (gnutls_*): Declare function pointers.
  (init_gnutls_functions): New function to initialize function pointers.
  (emacs_gnutls_handshake, Fgnutls_error_string, Fgnutls_deinit)
  (emacs_gnutls_global_init, Fgnutls_bye): Use function pointers.
  (emacs_gnutls_record_check_pending, emacs_gnutls_transport_set_errno):
  Wrappers for gnutls_record_check_pending and gnutls_transport_set_errno.
  (emacs_gnutls_write, emacs_gnutls_read)
  (emacs_gnutls_handle_error, Fgnutls_error_fatalp)
  (Fgnutls_available_p): New function.
  (Fgnutls_boot): Call Fgnutls_available_p.  Use function pointers.
  (syms_of_gnutls) <Qgnutls_dll>: Initialize and staticpro it.
  (syms_of_gnutls) <Sgnutls_available_p>: defsubr it.

* src/gnutls.h (GNUTLS_EMACS_ERROR_NOT_LOADED): New macro.
  (emacs_gnutls_write, emacs_gnutls_read): Mark as extern.
  (emacs_gnutls_record_check_pending, emacs_gnutls_transport_set_errno):
  Declare.

* src/w32.c (QCloaded_from, Vlibrary_cache): Define.
  (w32_delayed_load): Move from image.c.  When loading a library, record
  its filename in the :loaded-from property of the library id.
  (globals_of_w32) <QCloaded_from, Vlibrary_cache>:
  Initialize and staticpro them.
  (emacs_gnutls_pull, emacs_gnutls_push): Call emacs_gnutls_* functions.

* src/image.c: Include w32.h.
  (Vimage_type_cache): Delete.
  (syms_of_image) <Vimage_type_cache>: Don't initialize and staticpro it.
  (CACHE_IMAGE_TYPE, Finit_image_library): Use Vlibrary_cache instead.
  (w32_delayed_load): Move to w32.c.

* src/process.c: Include lisp.h before src/w32.h, not after.
  (wait_reading_process_output): Call emacs_gnutls_record_check_pending
  instead of gnutls_record_check_pending.

* src/w32.h (VlibraryCache, QCloaded_from, w32_delayed_load): Declare.
parent 67a2aecd
2011-05-04 Juanma Barranquero <lekktu@gmail.com>
* term/w32-win.el (dynamic-library-alist): Add `gnutls'.
2011-05-04 Glenn Morris <rgm@gnu.org>
* calendar/diary-lib.el (diary-fancy-date-pattern): Turn it into a
......
......@@ -202,13 +202,14 @@ See the documentation of `create-fontset-from-fontset-spec' for the format.")
'(png "libpng12d.dll" "libpng12.dll" "libpng3.dll" "libpng.dll"
;; these are libpng 1.2.8 from GTK+
"libpng13d.dll" "libpng13.dll"))
'(jpeg "jpeg62.dll" "libjpeg.dll" "jpeg-62.dll" "jpeg.dll")
'(tiff "libtiff3.dll" "libtiff.dll")
'(gif "giflib4.dll" "libungif4.dll" "libungif.dll")
'(svg "librsvg-2-2.dll")
'(gdk-pixbuf "libgdk_pixbuf-2.0-0.dll")
'(glib "libglib-2.0-0.dll")
'(gobject "libgobject-2.0-0.dll")))
'(jpeg "jpeg62.dll" "libjpeg.dll" "jpeg-62.dll" "jpeg.dll")
'(tiff "libtiff3.dll" "libtiff.dll")
'(gif "giflib4.dll" "libungif4.dll" "libungif.dll")
'(svg "librsvg-2-2.dll")
'(gdk-pixbuf "libgdk_pixbuf-2.0-0.dll")
'(glib "libglib-2.0-0.dll")
'(gobject "libgobject-2.0-0.dll")
'(gnutls "libgnutls-26.dll")))
;;; multi-tty support
(defvar w32-initialized nil
......
2011-05-04 Juanma Barranquero <lekktu@gmail.com>
* INSTALL: Clarify GnuTLS support.
2011-04-30 Eli Zaretskii <eliz@gnu.org>
* config.nt (HAVE_LONG_LONG_INT, HAVE_UNSIGNED_LONG_LONG_INT):
......
......@@ -325,12 +325,17 @@
* Optional GnuTLS support
You can build Emacs with GnuTLS support. Put the gnutls/gnutls.h header in
the include path and link to the appropriate libraries (gnutls.dll and
gcrypt.dll) with the --lib option.
If configure.bat finds the gnutls/gnutls.h file in the include path,
Emacs is built with GnuTLS support by default; to avoid that you can
pass the argument --without-gnutls.
You can get pre-built binaries and an installer at
http://josefsson.org/gnutls4win/.
In order to support GnuTLS at runtime, a GnuTLS-enabled Emacs must
be able to find the relevant DLLs during startup; failure to do so
is not an error, but GnuTLS won't be available to the running
session.
You can get pre-built binaries (including any required DLL and the
gnutls.h file) and an installer at http://josefsson.org/gnutls4win/.
* Experimental SVG support
......
2011-05-04 Juanma Barranquero <lekktu@gmail.com>
Implement dynamic loading of GnuTLS on Windows.
* gnutls.h (GNUTLS_EMACS_ERROR_NOT_LOADED): New macro.
(emacs_gnutls_write, emacs_gnutls_read): Mark as extern.
(emacs_gnutls_record_check_pending, emacs_gnutls_transport_set_errno):
Declare.
* gnutls.c (Qgnutls_dll): Define.
(DEF_GNUTLS_FN, LOAD_GNUTLS_FN): New macros.
(gnutls_*): Declare function pointers.
(init_gnutls_functions): New function to initialize function pointers.
(emacs_gnutls_handshake, Fgnutls_error_string, Fgnutls_deinit)
(emacs_gnutls_global_init, Fgnutls_bye): Use function pointers.
(emacs_gnutls_record_check_pending, emacs_gnutls_transport_set_errno):
Wrappers for gnutls_record_check_pending and gnutls_transport_set_errno.
(emacs_gnutls_write, emacs_gnutls_read)
(emacs_gnutls_handle_error, Fgnutls_error_fatalp)
(Fgnutls_available_p): New function.
(Fgnutls_boot): Call Fgnutls_available_p. Use function pointers.
(syms_of_gnutls) <Qgnutls_dll>: Initialize and staticpro it.
(syms_of_gnutls) <Sgnutls_available_p>: defsubr it.
* image.c: Include w32.h.
(Vimage_type_cache): Delete.
(syms_of_image) <Vimage_type_cache>: Don't initialize and staticpro it.
(CACHE_IMAGE_TYPE, Finit_image_library): Use Vlibrary_cache instead.
(w32_delayed_load): Move to w32.c.
* w32.h (VlibraryCache, QCloaded_from, w32_delayed_load): Declare.
* w32.c (QCloaded_from, Vlibrary_cache): Define.
(w32_delayed_load): Move from image.c. When loading a library, record
its filename in the :loaded-from property of the library id.
(globals_of_w32) <QCloaded_from, Vlibrary_cache>:
Initialize and staticpro them.
(emacs_gnutls_pull, emacs_gnutls_push): Call emacs_gnutls_* functions.
* process.c: Include lisp.h before w32.h, not after.
(wait_reading_process_output): Call emacs_gnutls_record_check_pending
instead of gnutls_record_check_pending.
* callproc.c, emacs.c: Include lisp.h before w32.h, not after.
2011-05-04 Teodor Zlatanov <tzz@lifelogs.com>
* gnutls.c (Fgnutls_boot): Support :keylist and :crlfiles options
......
......@@ -29,6 +29,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <sys/file.h>
#include <fcntl.h>
#include "lisp.h"
#ifdef WINDOWSNT
#define NOMINMAX
#include <windows.h>
......@@ -41,7 +43,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <sys/param.h>
#endif /* MSDOS */
#include "lisp.h"
#include "commands.h"
#include "buffer.h"
#include "character.h"
......
......@@ -29,6 +29,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <setjmp.h>
#include <unistd.h>
#include "lisp.h"
#ifdef WINDOWSNT
#include <fcntl.h>
#include <windows.h> /* just for w32.h */
......@@ -41,7 +43,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <GNUstepBase/GSConfig.h>
#endif
#include "lisp.h"
#include "commands.h"
#include "intervals.h"
#include "buffer.h"
......
This diff is collapsed.
......@@ -42,6 +42,7 @@ typedef enum
GNUTLS_STAGE_READY,
} gnutls_initstage_t;
#define GNUTLS_EMACS_ERROR_NOT_LOADED GNUTLS_E_APPLICATION_ERROR_MIN + 1
#define GNUTLS_EMACS_ERROR_INVALID_TYPE GNUTLS_E_APPLICATION_ERROR_MIN
#define GNUTLS_INITSTAGE(proc) (XPROCESS (proc)->gnutls_initstage)
......@@ -52,13 +53,16 @@ typedef enum
#define GNUTLS_LOG2(level, max, string, extra) if (level <= max) { gnutls_log_function2 (level, "(Emacs) " string, extra); }
EMACS_INT
extern EMACS_INT
emacs_gnutls_write (int fildes, struct Lisp_Process *proc, const char *buf,
EMACS_INT nbyte);
EMACS_INT
extern EMACS_INT
emacs_gnutls_read (int fildes, struct Lisp_Process *proc, char *buf,
EMACS_INT nbyte);
extern int emacs_gnutls_record_check_pending (gnutls_session_t state);
extern void emacs_gnutls_transport_set_errno (gnutls_session_t state, int err);
extern void syms_of_gnutls (void);
#endif
......
......@@ -67,6 +67,7 @@ typedef struct x_bitmap_record Bitmap_Record;
#ifdef HAVE_NTGUI
#include "w32.h"
#include "w32term.h"
/* W32_TODO : Color tables on W32. */
......@@ -556,10 +557,6 @@ x_create_bitmap_mask (struct frame *f, int id)
static struct image_type *image_types;
/* Cache for delayed-loading image types. */
static Lisp_Object Vimage_type_cache;
/* The symbol `xbm' which is used as the type symbol for XBM images. */
static Lisp_Object Qxbm;
......@@ -589,7 +586,7 @@ static int x_build_heuristic_mask (struct frame *, struct image *,
Lisp_Object);
#define CACHE_IMAGE_TYPE(type, status) \
do { Vimage_type_cache = Fcons (Fcons (type, status), Vimage_type_cache); } while (0)
do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0)
#define ADD_IMAGE_TYPE(type) \
do { Vimage_types = Fcons (type, Vimage_types); } while (0)
......@@ -1900,34 +1897,6 @@ mark_image_cache (struct image_cache *c)
if (!fn_##func) return 0; \
}
/* Load a DLL implementing an image type.
The argument LIBRARIES is usually the variable
`dynamic-library-alist', which associates a symbol, identifying
an external DLL library, to a list of possible filenames.
The function returns NULL if no library could be loaded for
the given symbol, or if the library was previously loaded;
else the handle of the DLL. */
static HMODULE
w32_delayed_load (Lisp_Object libraries, Lisp_Object type)
{
HMODULE library = NULL;
if (CONSP (libraries) && NILP (Fassq (type, Vimage_type_cache)))
{
Lisp_Object dlls = Fassq (type, libraries);
if (CONSP (dlls))
for (dlls = XCDR (dlls); CONSP (dlls); dlls = XCDR (dlls))
{
CHECK_STRING_CAR (dlls);
if (library = LoadLibrary (SDATA (XCAR (dlls))))
break;
}
}
return library;
}
#endif /* HAVE_NTGUI */
static int x_create_x_image_and_pixmap (struct frame *, int, int, int,
......@@ -5452,7 +5421,6 @@ init_png_functions (Lisp_Object libraries)
{
HMODULE library;
/* Try loading libpng under probable names. */
if (!(library = w32_delayed_load (libraries, Qpng)))
return 0;
......@@ -8634,7 +8602,7 @@ of `dynamic-library-alist', which see). */)
Lisp_Object tested;
/* Don't try to reload the library. */
tested = Fassq (type, Vimage_type_cache);
tested = Fassq (type, Vlibrary_cache);
if (CONSP (tested))
return XCDR (tested);
......@@ -8714,9 +8682,6 @@ as a ratio to the frame height and width. If the value is
non-numeric, there is no explicit limit on the size of images. */);
Vmax_image_size = make_float (MAX_IMAGE_SIZE);
Vimage_type_cache = Qnil;
staticpro (&Vimage_type_cache);
Qpbm = intern_c_string ("pbm");
staticpro (&Qpbm);
ADD_IMAGE_TYPE (Qpbm);
......
......@@ -33,6 +33,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <unistd.h>
#include <fcntl.h>
#include "lisp.h"
/* Only MS-DOS does not define `subprocesses'. */
#ifdef subprocesses
......@@ -77,7 +79,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#endif /* subprocesses */
#include "lisp.h"
#include "systime.h"
#include "systty.h"
......@@ -4537,10 +4538,10 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
some data in the TCP buffers so that select works, but
with custom pull/push functions we need to check if some
data is available in the buffers manually. */
if (nfds == 0 &&
if (nfds == 0 &&
wait_proc && wait_proc->gnutls_p /* Check for valid process. */
/* Do we have pending data? */
&& gnutls_record_check_pending (wait_proc->gnutls_state) > 0)
&& emacs_gnutls_record_check_pending (wait_proc->gnutls_state) > 0)
{
nfds = 1;
/* Set to Available. */
......
......@@ -150,6 +150,8 @@ typedef struct _PROCESS_MEMORY_COUNTERS_EX {
typedef HRESULT (WINAPI * ShGetFolderPath_fn)
(IN HWND, IN int, IN HANDLE, IN DWORD, OUT char *);
Lisp_Object QCloaded_from;
void globals_of_w32 (void);
static DWORD get_rid (PSID);
......@@ -5712,6 +5714,54 @@ sys_localtime (const time_t *t)
return localtime (t);
}
/* Delayed loading of libraries. */
Lisp_Object Vlibrary_cache;
/* The argument LIBRARIES is an alist that associates a symbol
LIBRARY_ID, identifying an external DLL library known to Emacs, to
a list of filenames under which the library is usually found. In
most cases, the argument passed as LIBRARIES is the variable
`dynamic-library-alist', which is initialized to a list of common
library names. If the function loads the library successfully, it
returns the handle of the DLL, and records the filename in the
property :loaded-from of LIBRARY_ID; it returns NULL if the library
could not be found, or when it was already loaded (because the
handle is not recorded anywhere, and so is lost after use). It
would be trivial to save the handle too in :loaded-from, but
currently there's no use case for it. */
HMODULE
w32_delayed_load (Lisp_Object libraries, Lisp_Object library_id)
{
HMODULE library_dll = NULL;
CHECK_SYMBOL (library_id);
if (CONSP (libraries) && NILP (Fassq (library_id, Vlibrary_cache)))
{
Lisp_Object found = Qnil;
Lisp_Object dlls = Fassq (library_id, libraries);
if (CONSP (dlls))
for (dlls = XCDR (dlls); CONSP (dlls); dlls = XCDR (dlls))
{
CHECK_STRING_CAR (dlls);
if (library_dll = LoadLibrary (SDATA (XCAR (dlls))))
{
found = XCAR (dlls);
break;
}
}
Fput (library_id, QCloaded_from, found);
}
return library_dll;
}
static void
check_windows_init_file (void)
{
......@@ -5910,6 +5960,12 @@ globals_of_w32 (void)
get_process_times_fn = (GetProcessTimes_Proc)
GetProcAddress (kernel32, "GetProcessTimes");
QCloaded_from = intern_c_string (":loaded-from");
staticpro (&QCloaded_from);
Vlibrary_cache = Qnil;
staticpro (&Vlibrary_cache);
g_b_init_is_windows_9x = 0;
g_b_init_open_process_token = 0;
g_b_init_get_token_information = 0;
......@@ -6178,7 +6234,7 @@ emacs_gnutls_pull (gnutls_transport_ptr_t p, void* buf, size_t sz)
err = errno; /* Other errors are just passed on. */
}
gnutls_transport_set_errno (process->gnutls_state, err);
emacs_gnutls_transport_set_errno (process->gnutls_state, err);
return -1;
}
......@@ -6197,8 +6253,8 @@ emacs_gnutls_push (gnutls_transport_ptr_t p, const void* buf, size_t sz)
/* Negative bytes written means we got an error in errno.
Translate the WSAEWOULDBLOCK alias EWOULDBLOCK to EAGAIN. */
gnutls_transport_set_errno (process->gnutls_state,
errno == EWOULDBLOCK ? EAGAIN : errno);
emacs_gnutls_transport_set_errno (process->gnutls_state,
errno == EWOULDBLOCK ? EAGAIN : errno);
return -1;
}
......
......@@ -143,6 +143,9 @@ extern void syms_of_fontset (void);
extern int _sys_read_ahead (int fd);
extern int _sys_wait_accept (int fd);
extern Lisp_Object Vlibrary_cache, QCloaded_from;
extern HMODULE w32_delayed_load (Lisp_Object, Lisp_Object);
#ifdef HAVE_GNUTLS
#include <gnutls/gnutls.h>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment