summaryrefslogtreecommitdiff
path: root/src/w32.c
diff options
context:
space:
mode:
authorJuanma Barranquero <lekktu@gmail.com>2011-05-04 16:03:16 +0200
committerJuanma Barranquero <lekktu@gmail.com>2011-05-04 16:03:16 +0200
commit0898ca10c0109274d24f91453036c065f9f5c056 (patch)
tree32c087173edd460b860b5c3ec8298777a39b52ca /src/w32.c
parent67a2aecd40f802838d97f2aeb81f0a3698c68f62 (diff)
downloademacs-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.c62
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;
}