diff options
author | Juanma Barranquero <lekktu@gmail.com> | 2011-05-04 16:03:16 +0200 |
---|---|---|
committer | Juanma Barranquero <lekktu@gmail.com> | 2011-05-04 16:03:16 +0200 |
commit | 0898ca10c0109274d24f91453036c065f9f5c056 (patch) | |
tree | 32c087173edd460b860b5c3ec8298777a39b52ca /src/w32.c | |
parent | 67a2aecd40f802838d97f2aeb81f0a3698c68f62 (diff) | |
download | emacs-0898ca10c0109274d24f91453036c065f9f5c056.tar.gz |
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.
Diffstat (limited to 'src/w32.c')
-rw-r--r-- | src/w32.c | 62 |
1 files changed, 59 insertions, 3 deletions
diff --git a/src/w32.c b/src/w32.c index 230ccc8de10..d81fdf3305d 100644 --- a/src/w32.c +++ b/src/w32.c @@ -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; } |