aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2011-05-04 22:31:24 -0700
committerPaul Eggert2011-05-04 22:31:24 -0700
commit852a74a59b12d505eba86a0aed46bfe8af7b9acf (patch)
treec18226075e72f2892a3e2f90e36c4e60f25c6b69 /src
parentaab2b9b5abaa4862b2814929c31035e7920f5e21 (diff)
parentf7ff1b0f0792f1f870778404531e68e77832c4a1 (diff)
downloademacs-852a74a59b12d505eba86a0aed46bfe8af7b9acf.tar.gz
emacs-852a74a59b12d505eba86a0aed46bfe8af7b9acf.zip
Merge from mainline.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog79
-rw-r--r--src/callproc.c3
-rw-r--r--src/emacs.c3
-rw-r--r--src/gnutls.c329
-rw-r--r--src/gnutls.h14
-rw-r--r--src/image.c48
-rw-r--r--src/makefile.w32-in3
-rw-r--r--src/nsfns.m9
-rw-r--r--src/process.c12
-rw-r--r--src/w32.c62
-rw-r--r--src/w32.h3
-rw-r--r--src/w32heap.c25
12 files changed, 472 insertions, 118 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index c0d81fc1248..ee2db310562 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,4 +1,4 @@
12011-05-04 Paul Eggert <eggert@cs.ucla.edu> 12011-05-05 Paul Eggert <eggert@cs.ucla.edu>
2 2
3 * term.c (vfatal): Remove stray call to va_end. 3 * term.c (vfatal): Remove stray call to va_end.
4 It's not needed and the C Standard doesn't allow it here anyway. 4 It's not needed and the C Standard doesn't allow it here anyway.
@@ -119,6 +119,83 @@
119 119
120 * fns.c (Frandom): Let EMACS_UINT be wider than unsigned long. 120 * fns.c (Frandom): Let EMACS_UINT be wider than unsigned long.
121 121
1222011-05-05 Eli Zaretskii <eliz@gnu.org>
123
124 * w32heap.c (allocate_heap) [USE_LISP_UNION_TYPE || USE_LSB_TAG]:
125 New version that can reserve upto 2GB of heap space.
126
1272011-05-05 Chong Yidong <cyd@stupidchicken.com>
128
129 * nsfns.m (Fns_read_file_name): Doc fix (Bug#8534).
130
1312011-05-05 Teodor Zlatanov <tzz@lifelogs.com>
132
133 * gnutls.c (fn_gnutls_certificate_set_x509_key_file): Add alias to
134 `gnutls_certificate_set_x509_key_file'.
135
1362011-05-05 Juanma Barranquero <lekktu@gmail.com>
137
138 * makefile.w32-in ($(BLD)/image.$(O), $(BLD)/process.$(O)):
139 Update dependencies.
140
1412011-05-04 Juanma Barranquero <lekktu@gmail.com>
142
143 * gnutls.h (emacs_gnutls_write, emacs_gnutls_read):
144 * gnutls.c (emacs_gnutls_write, emacs_gnutls_read):
145 Remove unused parameter `fildes'.
146 * process.c (read_process_output, send_process): Don't pass it.
147
1482011-05-04 Juanma Barranquero <lekktu@gmail.com>
149
150 Fix previous change: the library cache is defined in w32.c.
151 * image.c (CACHE_IMAGE_TYPE) [!HAVE_NTGUI]: Define to noop.
152 (Finit_image_library): Wrap Vlibrary_cache on "#ifdef HAVE_NTGUI".
153
1542011-05-04 Juanma Barranquero <lekktu@gmail.com>
155
156 Implement dynamic loading of GnuTLS on Windows.
157
158 * gnutls.h (GNUTLS_EMACS_ERROR_NOT_LOADED): New macro.
159 (emacs_gnutls_write, emacs_gnutls_read): Mark as extern.
160 (emacs_gnutls_record_check_pending, emacs_gnutls_transport_set_errno):
161 Declare.
162
163 * gnutls.c (Qgnutls_dll): Define.
164 (DEF_GNUTLS_FN, LOAD_GNUTLS_FN): New macros.
165 (gnutls_*): Declare function pointers.
166 (init_gnutls_functions): New function to initialize function pointers.
167 (emacs_gnutls_handshake, Fgnutls_error_string, Fgnutls_deinit)
168 (emacs_gnutls_global_init, Fgnutls_bye): Use function pointers.
169 (emacs_gnutls_record_check_pending, emacs_gnutls_transport_set_errno):
170 Wrappers for gnutls_record_check_pending and gnutls_transport_set_errno.
171 (emacs_gnutls_write, emacs_gnutls_read)
172 (emacs_gnutls_handle_error, Fgnutls_error_fatalp)
173 (Fgnutls_available_p): New function.
174 (Fgnutls_boot): Call Fgnutls_available_p. Use function pointers.
175 (syms_of_gnutls) <Qgnutls_dll>: Initialize and staticpro it.
176 (syms_of_gnutls) <Sgnutls_available_p>: defsubr it.
177
178 * image.c: Include w32.h.
179 (Vimage_type_cache): Delete.
180 (syms_of_image) <Vimage_type_cache>: Don't initialize and staticpro it.
181 (CACHE_IMAGE_TYPE, Finit_image_library): Use Vlibrary_cache instead.
182 (w32_delayed_load): Move to w32.c.
183
184 * w32.h (VlibraryCache, QCloaded_from, w32_delayed_load): Declare.
185
186 * w32.c (QCloaded_from, Vlibrary_cache): Define.
187 (w32_delayed_load): Move from image.c. When loading a library, record
188 its filename in the :loaded-from property of the library id.
189 (globals_of_w32) <QCloaded_from, Vlibrary_cache>:
190 Initialize and staticpro them.
191 (emacs_gnutls_pull, emacs_gnutls_push): Call emacs_gnutls_* functions.
192
193 * process.c: Include lisp.h before w32.h, not after.
194 (wait_reading_process_output): Call emacs_gnutls_record_check_pending
195 instead of gnutls_record_check_pending.
196
197 * callproc.c, emacs.c: Include lisp.h before w32.h, not after.
198
1222011-05-04 Teodor Zlatanov <tzz@lifelogs.com> 1992011-05-04 Teodor Zlatanov <tzz@lifelogs.com>
123 200
124 * gnutls.c (Fgnutls_boot): Support :keylist and :crlfiles options 201 * gnutls.c (Fgnutls_boot): Support :keylist and :crlfiles options
diff --git a/src/callproc.c b/src/callproc.c
index c2c301eb4a5..2763331bde2 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -29,6 +29,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
29#include <sys/file.h> 29#include <sys/file.h>
30#include <fcntl.h> 30#include <fcntl.h>
31 31
32#include "lisp.h"
33
32#ifdef WINDOWSNT 34#ifdef WINDOWSNT
33#define NOMINMAX 35#define NOMINMAX
34#include <windows.h> 36#include <windows.h>
@@ -41,7 +43,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
41#include <sys/param.h> 43#include <sys/param.h>
42#endif /* MSDOS */ 44#endif /* MSDOS */
43 45
44#include "lisp.h"
45#include "commands.h" 46#include "commands.h"
46#include "buffer.h" 47#include "buffer.h"
47#include "character.h" 48#include "character.h"
diff --git a/src/emacs.c b/src/emacs.c
index 0a132e156a0..8c4490b0a52 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -29,6 +29,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
29#include <setjmp.h> 29#include <setjmp.h>
30#include <unistd.h> 30#include <unistd.h>
31 31
32#include "lisp.h"
33
32#ifdef WINDOWSNT 34#ifdef WINDOWSNT
33#include <fcntl.h> 35#include <fcntl.h>
34#include <windows.h> /* just for w32.h */ 36#include <windows.h> /* just for w32.h */
@@ -41,7 +43,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
41#include <GNUstepBase/GSConfig.h> 43#include <GNUstepBase/GSConfig.h>
42#endif 44#endif
43 45
44#include "lisp.h"
45#include "commands.h" 46#include "commands.h"
46#include "intervals.h" 47#include "intervals.h"
47#include "buffer.h" 48#include "buffer.h"
diff --git a/src/gnutls.c b/src/gnutls.c
index fd970910d24..e25ae25f64c 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -34,6 +34,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
34static int 34static int
35emacs_gnutls_handle_error (gnutls_session_t, int err); 35emacs_gnutls_handle_error (gnutls_session_t, int err);
36 36
37static Lisp_Object Qgnutls_dll;
37static Lisp_Object Qgnutls_log_level; 38static Lisp_Object Qgnutls_log_level;
38static Lisp_Object Qgnutls_code; 39static Lisp_Object Qgnutls_code;
39static Lisp_Object Qgnutls_anon, Qgnutls_x509pki; 40static Lisp_Object Qgnutls_anon, Qgnutls_x509pki;
@@ -56,6 +57,182 @@ static Lisp_Object Qgnutls_bootprop_verify_hostname_error;
56/* Callback keys for `gnutls-boot'. Unused currently. */ 57/* Callback keys for `gnutls-boot'. Unused currently. */
57static Lisp_Object Qgnutls_bootprop_callbacks_verify; 58static Lisp_Object Qgnutls_bootprop_callbacks_verify;
58 59
60static void gnutls_log_function (int, const char *);
61static void gnutls_log_function2 (int, const char*, const char*);
62
63
64#ifdef WINDOWSNT
65
66/* Macro for defining functions that will be loaded from the GnuTLS DLL. */
67#define DEF_GNUTLS_FN(rettype,func,args) rettype (FAR CDECL *fn_##func)args
68
69/* Macro for loading GnuTLS functions from the library. */
70#define LOAD_GNUTLS_FN(lib,func) { \
71 fn_##func = (void *) GetProcAddress (lib, #func); \
72 if (!fn_##func) return 0; \
73 }
74
75DEF_GNUTLS_FN (gnutls_alert_description_t, gnutls_alert_get,
76 (gnutls_session_t));
77DEF_GNUTLS_FN (const char *, gnutls_alert_get_name,
78 (gnutls_alert_description_t));
79DEF_GNUTLS_FN (int, gnutls_alert_send_appropriate, (gnutls_session_t, int));
80DEF_GNUTLS_FN (int, gnutls_anon_allocate_client_credentials,
81 (gnutls_anon_client_credentials_t *));
82DEF_GNUTLS_FN (void, gnutls_anon_free_client_credentials,
83 (gnutls_anon_client_credentials_t));
84DEF_GNUTLS_FN (int, gnutls_bye, (gnutls_session_t, gnutls_close_request_t));
85DEF_GNUTLS_FN (int, gnutls_certificate_allocate_credentials,
86 (gnutls_certificate_credentials_t *));
87DEF_GNUTLS_FN (void, gnutls_certificate_free_credentials,
88 (gnutls_certificate_credentials_t));
89DEF_GNUTLS_FN (const gnutls_datum_t *, gnutls_certificate_get_peers,
90 (gnutls_session_t, unsigned int *));
91DEF_GNUTLS_FN (void, gnutls_certificate_set_verify_flags,
92 (gnutls_certificate_credentials_t, unsigned int));
93DEF_GNUTLS_FN (int, gnutls_certificate_set_x509_crl_file,
94 (gnutls_certificate_credentials_t, const char *,
95 gnutls_x509_crt_fmt_t));
96DEF_GNUTLS_FN (int, gnutls_certificate_set_x509_key_file,
97 (gnutls_certificate_credentials_t, const char *, const char *,
98 gnutls_x509_crt_fmt_t));
99DEF_GNUTLS_FN (int, gnutls_certificate_set_x509_trust_file,
100 (gnutls_certificate_credentials_t, const char *,
101 gnutls_x509_crt_fmt_t));
102DEF_GNUTLS_FN (gnutls_certificate_type_t, gnutls_certificate_type_get,
103 (gnutls_session_t));
104DEF_GNUTLS_FN (int, gnutls_certificate_verify_peers2,
105 (gnutls_session_t, unsigned int *));
106DEF_GNUTLS_FN (int, gnutls_credentials_set,
107 (gnutls_session_t, gnutls_credentials_type_t, void *));
108DEF_GNUTLS_FN (void, gnutls_deinit, (gnutls_session_t));
109DEF_GNUTLS_FN (int, gnutls_error_is_fatal, (int));
110DEF_GNUTLS_FN (int, gnutls_global_init, (void));
111DEF_GNUTLS_FN (void, gnutls_global_set_log_function, (gnutls_log_func));
112DEF_GNUTLS_FN (void, gnutls_global_set_log_level, (int));
113DEF_GNUTLS_FN (int, gnutls_handshake, (gnutls_session_t));
114DEF_GNUTLS_FN (int, gnutls_init, (gnutls_session_t *, gnutls_connection_end_t));
115DEF_GNUTLS_FN (int, gnutls_priority_set_direct,
116 (gnutls_session_t, const char *, const char **));
117DEF_GNUTLS_FN (size_t, gnutls_record_check_pending, (gnutls_session_t));
118DEF_GNUTLS_FN (ssize_t, gnutls_record_recv, (gnutls_session_t, void *, size_t));
119DEF_GNUTLS_FN (ssize_t, gnutls_record_send,
120 (gnutls_session_t, const void *, size_t));
121DEF_GNUTLS_FN (const char *, gnutls_strerror, (int));
122DEF_GNUTLS_FN (void, gnutls_transport_set_errno, (gnutls_session_t, int));
123DEF_GNUTLS_FN (void, gnutls_transport_set_lowat, (gnutls_session_t, int));
124DEF_GNUTLS_FN (void, gnutls_transport_set_ptr2,
125 (gnutls_session_t, gnutls_transport_ptr_t,
126 gnutls_transport_ptr_t));
127DEF_GNUTLS_FN (void, gnutls_transport_set_pull_function,
128 (gnutls_session_t, gnutls_pull_func));
129DEF_GNUTLS_FN (void, gnutls_transport_set_push_function,
130 (gnutls_session_t, gnutls_push_func));
131DEF_GNUTLS_FN (int, gnutls_x509_crt_check_hostname,
132 (gnutls_x509_crt_t, const char *));
133DEF_GNUTLS_FN (void, gnutls_x509_crt_deinit, (gnutls_x509_crt_t));
134DEF_GNUTLS_FN (int, gnutls_x509_crt_import,
135 (gnutls_x509_crt_t, const gnutls_datum_t *,
136 gnutls_x509_crt_fmt_t));
137DEF_GNUTLS_FN (int, gnutls_x509_crt_init, (gnutls_x509_crt_t *));
138
139static int
140init_gnutls_functions (Lisp_Object libraries)
141{
142 HMODULE library;
143
144 if (!(library = w32_delayed_load (libraries, Qgnutls_dll)))
145 {
146 GNUTLS_LOG (1, 1, "GnuTLS library not found");
147 return 0;
148 }
149
150 LOAD_GNUTLS_FN (library, gnutls_alert_get);
151 LOAD_GNUTLS_FN (library, gnutls_alert_get_name);
152 LOAD_GNUTLS_FN (library, gnutls_alert_send_appropriate);
153 LOAD_GNUTLS_FN (library, gnutls_anon_allocate_client_credentials);
154 LOAD_GNUTLS_FN (library, gnutls_anon_free_client_credentials);
155 LOAD_GNUTLS_FN (library, gnutls_bye);
156 LOAD_GNUTLS_FN (library, gnutls_certificate_allocate_credentials);
157 LOAD_GNUTLS_FN (library, gnutls_certificate_free_credentials);
158 LOAD_GNUTLS_FN (library, gnutls_certificate_get_peers);
159 LOAD_GNUTLS_FN (library, gnutls_certificate_set_verify_flags);
160 LOAD_GNUTLS_FN (library, gnutls_certificate_set_x509_crl_file);
161 LOAD_GNUTLS_FN (library, gnutls_certificate_set_x509_key_file);
162 LOAD_GNUTLS_FN (library, gnutls_certificate_set_x509_trust_file);
163 LOAD_GNUTLS_FN (library, gnutls_certificate_type_get);
164 LOAD_GNUTLS_FN (library, gnutls_certificate_verify_peers2);
165 LOAD_GNUTLS_FN (library, gnutls_credentials_set);
166 LOAD_GNUTLS_FN (library, gnutls_deinit);
167 LOAD_GNUTLS_FN (library, gnutls_error_is_fatal);
168 LOAD_GNUTLS_FN (library, gnutls_global_init);
169 LOAD_GNUTLS_FN (library, gnutls_global_set_log_function);
170 LOAD_GNUTLS_FN (library, gnutls_global_set_log_level);
171 LOAD_GNUTLS_FN (library, gnutls_handshake);
172 LOAD_GNUTLS_FN (library, gnutls_init);
173 LOAD_GNUTLS_FN (library, gnutls_priority_set_direct);
174 LOAD_GNUTLS_FN (library, gnutls_record_check_pending);
175 LOAD_GNUTLS_FN (library, gnutls_record_recv);
176 LOAD_GNUTLS_FN (library, gnutls_record_send);
177 LOAD_GNUTLS_FN (library, gnutls_strerror);
178 LOAD_GNUTLS_FN (library, gnutls_transport_set_errno);
179 LOAD_GNUTLS_FN (library, gnutls_transport_set_lowat);
180 LOAD_GNUTLS_FN (library, gnutls_transport_set_ptr2);
181 LOAD_GNUTLS_FN (library, gnutls_transport_set_pull_function);
182 LOAD_GNUTLS_FN (library, gnutls_transport_set_push_function);
183 LOAD_GNUTLS_FN (library, gnutls_x509_crt_check_hostname);
184 LOAD_GNUTLS_FN (library, gnutls_x509_crt_deinit);
185 LOAD_GNUTLS_FN (library, gnutls_x509_crt_import);
186 LOAD_GNUTLS_FN (library, gnutls_x509_crt_init);
187
188 GNUTLS_LOG2 (1, 1, "GnuTLS library loaded:",
189 SDATA (Fget (Qgnutls_dll, QCloaded_from)));
190 return 1;
191}
192
193#else /* !WINDOWSNT */
194
195#define fn_gnutls_alert_get gnutls_alert_get
196#define fn_gnutls_alert_get_name gnutls_alert_get_name
197#define fn_gnutls_alert_send_appropriate gnutls_alert_send_appropriate
198#define fn_gnutls_anon_allocate_client_credentials gnutls_anon_allocate_client_credentials
199#define fn_gnutls_anon_free_client_credentials gnutls_anon_free_client_credentials
200#define fn_gnutls_bye gnutls_bye
201#define fn_gnutls_certificate_allocate_credentials gnutls_certificate_allocate_credentials
202#define fn_gnutls_certificate_free_credentials gnutls_certificate_free_credentials
203#define fn_gnutls_certificate_get_peers gnutls_certificate_get_peers
204#define fn_gnutls_certificate_set_verify_flags gnutls_certificate_set_verify_flags
205#define fn_gnutls_certificate_set_x509_crl_file gnutls_certificate_set_x509_crl_file
206#define fn_gnutls_certificate_set_x509_key_file gnutls_certificate_set_x509_key_file
207#define fn_gnutls_certificate_set_x509_trust_file gnutls_certificate_set_x509_trust_file
208#define fn_gnutls_certificate_type_get gnutls_certificate_type_get
209#define fn_gnutls_certificate_verify_peers2 gnutls_certificate_verify_peers2
210#define fn_gnutls_credentials_set gnutls_credentials_set
211#define fn_gnutls_deinit gnutls_deinit
212#define fn_gnutls_error_is_fatal gnutls_error_is_fatal
213#define fn_gnutls_global_init gnutls_global_init
214#define fn_gnutls_global_set_log_function gnutls_global_set_log_function
215#define fn_gnutls_global_set_log_level gnutls_global_set_log_level
216#define fn_gnutls_handshake gnutls_handshake
217#define fn_gnutls_init gnutls_init
218#define fn_gnutls_priority_set_direct gnutls_priority_set_direct
219#define fn_gnutls_record_check_pending gnutls_record_check_pending
220#define fn_gnutls_record_recv gnutls_record_recv
221#define fn_gnutls_record_send gnutls_record_send
222#define fn_gnutls_strerror gnutls_strerror
223#define fn_gnutls_transport_set_errno gnutls_transport_set_errno
224#define fn_gnutls_transport_set_lowat gnutls_transport_set_lowat
225#define fn_gnutls_transport_set_ptr2 gnutls_transport_set_ptr2
226#define fn_gnutls_transport_set_pull_function gnutls_transport_set_pull_function
227#define fn_gnutls_transport_set_push_function gnutls_transport_set_push_function
228#define fn_gnutls_x509_crt_check_hostname gnutls_x509_crt_check_hostname
229#define fn_gnutls_x509_crt_deinit gnutls_x509_crt_deinit
230#define fn_gnutls_x509_crt_import gnutls_x509_crt_import
231#define fn_gnutls_x509_crt_init gnutls_x509_crt_init
232
233#endif /* !WINDOWSNT */
234
235
59static void 236static void
60gnutls_log_function (int level, const char* string) 237gnutls_log_function (int level, const char* string)
61{ 238{
@@ -83,11 +260,11 @@ emacs_gnutls_handshake (struct Lisp_Process *proc)
83 /* On W32 we cannot transfer socket handles between different runtime 260 /* On W32 we cannot transfer socket handles between different runtime
84 libraries, so we tell GnuTLS to use our special push/pull 261 libraries, so we tell GnuTLS to use our special push/pull
85 functions. */ 262 functions. */
86 gnutls_transport_set_ptr2 (state, 263 fn_gnutls_transport_set_ptr2 (state,
87 (gnutls_transport_ptr_t) proc, 264 (gnutls_transport_ptr_t) proc,
88 (gnutls_transport_ptr_t) proc); 265 (gnutls_transport_ptr_t) proc);
89 gnutls_transport_set_push_function (state, &emacs_gnutls_push); 266 fn_gnutls_transport_set_push_function (state, &emacs_gnutls_push);
90 gnutls_transport_set_pull_function (state, &emacs_gnutls_pull); 267 fn_gnutls_transport_set_pull_function (state, &emacs_gnutls_pull);
91 268
92 /* For non blocking sockets or other custom made pull/push 269 /* For non blocking sockets or other custom made pull/push
93 functions the gnutls_transport_set_lowat must be called, with 270 functions the gnutls_transport_set_lowat must be called, with
@@ -96,14 +273,14 @@ emacs_gnutls_handshake (struct Lisp_Process *proc)
96 (Note: this is probably not strictly necessary as the lowat 273 (Note: this is probably not strictly necessary as the lowat
97 value is only used when no custom pull/push functions are 274 value is only used when no custom pull/push functions are
98 set.) */ 275 set.) */
99 gnutls_transport_set_lowat (state, 0); 276 fn_gnutls_transport_set_lowat (state, 0);
100#else 277#else
101 /* This is how GnuTLS takes sockets: as file descriptors passed 278 /* This is how GnuTLS takes sockets: as file descriptors passed
102 in. For an Emacs process socket, infd and outfd are the 279 in. For an Emacs process socket, infd and outfd are the
103 same but we use this two-argument version for clarity. */ 280 same but we use this two-argument version for clarity. */
104 gnutls_transport_set_ptr2 (state, 281 fn_gnutls_transport_set_ptr2 (state,
105 (gnutls_transport_ptr_t) (long) proc->infd, 282 (gnutls_transport_ptr_t) (long) proc->infd,
106 (gnutls_transport_ptr_t) (long) proc->outfd); 283 (gnutls_transport_ptr_t) (long) proc->outfd);
107#endif 284#endif
108 285
109 proc->gnutls_initstage = GNUTLS_STAGE_TRANSPORT_POINTERS_SET; 286 proc->gnutls_initstage = GNUTLS_STAGE_TRANSPORT_POINTERS_SET;
@@ -111,10 +288,10 @@ emacs_gnutls_handshake (struct Lisp_Process *proc)
111 288
112 do 289 do
113 { 290 {
114 ret = gnutls_handshake (state); 291 ret = fn_gnutls_handshake (state);
115 emacs_gnutls_handle_error (state, ret); 292 emacs_gnutls_handle_error (state, ret);
116 } 293 }
117 while (ret < 0 && gnutls_error_is_fatal (ret) == 0); 294 while (ret < 0 && fn_gnutls_error_is_fatal (ret) == 0);
118 295
119 proc->gnutls_initstage = GNUTLS_STAGE_HANDSHAKE_TRIED; 296 proc->gnutls_initstage = GNUTLS_STAGE_HANDSHAKE_TRIED;
120 297
@@ -125,14 +302,25 @@ emacs_gnutls_handshake (struct Lisp_Process *proc)
125 } 302 }
126 else 303 else
127 { 304 {
128 gnutls_alert_send_appropriate (state, ret); 305 fn_gnutls_alert_send_appropriate (state, ret);
129 } 306 }
130 return ret; 307 return ret;
131} 308}
132 309
310int
311emacs_gnutls_record_check_pending (gnutls_session_t state)
312{
313 return fn_gnutls_record_check_pending (state);
314}
315
316void
317emacs_gnutls_transport_set_errno (gnutls_session_t state, int err)
318{
319 fn_gnutls_transport_set_errno (state, err);
320}
321
133EMACS_INT 322EMACS_INT
134emacs_gnutls_write (int fildes, struct Lisp_Process *proc, const char *buf, 323emacs_gnutls_write (struct Lisp_Process *proc, const char *buf, EMACS_INT nbyte)
135 EMACS_INT nbyte)
136{ 324{
137 ssize_t rtnval = 0; 325 ssize_t rtnval = 0;
138 EMACS_INT bytes_written; 326 EMACS_INT bytes_written;
@@ -152,7 +340,7 @@ emacs_gnutls_write (int fildes, struct Lisp_Process *proc, const char *buf,
152 340
153 while (nbyte > 0) 341 while (nbyte > 0)
154 { 342 {
155 rtnval = gnutls_write (state, buf, nbyte); 343 rtnval = fn_gnutls_record_send (state, buf, nbyte);
156 344
157 if (rtnval < 0) 345 if (rtnval < 0)
158 { 346 {
@@ -172,8 +360,7 @@ emacs_gnutls_write (int fildes, struct Lisp_Process *proc, const char *buf,
172} 360}
173 361
174EMACS_INT 362EMACS_INT
175emacs_gnutls_read (int fildes, struct Lisp_Process *proc, char *buf, 363emacs_gnutls_read (struct Lisp_Process *proc, char *buf, EMACS_INT nbyte)
176 EMACS_INT nbyte)
177{ 364{
178 ssize_t rtnval; 365 ssize_t rtnval;
179 gnutls_session_t state = proc->gnutls_state; 366 gnutls_session_t state = proc->gnutls_state;
@@ -183,7 +370,7 @@ emacs_gnutls_read (int fildes, struct Lisp_Process *proc, char *buf,
183 emacs_gnutls_handshake (proc); 370 emacs_gnutls_handshake (proc);
184 return -1; 371 return -1;
185 } 372 }
186 rtnval = gnutls_read (state, buf, nbyte); 373 rtnval = fn_gnutls_record_recv (state, buf, nbyte);
187 if (rtnval >= 0) 374 if (rtnval >= 0)
188 return rtnval; 375 return rtnval;
189 else if (emacs_gnutls_handle_error (state, rtnval) == 0) 376 else if (emacs_gnutls_handle_error (state, rtnval) == 0)
@@ -215,11 +402,11 @@ emacs_gnutls_handle_error (gnutls_session_t session, int err)
215 402
216 /* TODO: use gnutls-error-fatalp and gnutls-error-string. */ 403 /* TODO: use gnutls-error-fatalp and gnutls-error-string. */
217 404
218 str = gnutls_strerror (err); 405 str = fn_gnutls_strerror (err);
219 if (!str) 406 if (!str)
220 str = "unknown"; 407 str = "unknown";
221 408
222 if (gnutls_error_is_fatal (err)) 409 if (fn_gnutls_error_is_fatal (err))
223 { 410 {
224 ret = err; 411 ret = err;
225 GNUTLS_LOG2 (0, max_log_level, "fatal error:", str); 412 GNUTLS_LOG2 (0, max_log_level, "fatal error:", str);
@@ -234,9 +421,9 @@ emacs_gnutls_handle_error (gnutls_session_t session, int err)
234 if (err == GNUTLS_E_WARNING_ALERT_RECEIVED 421 if (err == GNUTLS_E_WARNING_ALERT_RECEIVED
235 || err == GNUTLS_E_FATAL_ALERT_RECEIVED) 422 || err == GNUTLS_E_FATAL_ALERT_RECEIVED)
236 { 423 {
237 int alert = gnutls_alert_get (session); 424 int alert = fn_gnutls_alert_get (session);
238 int level = (err == GNUTLS_E_FATAL_ALERT_RECEIVED) ? 0 : 1; 425 int level = (err == GNUTLS_E_FATAL_ALERT_RECEIVED) ? 0 : 1;
239 str = gnutls_alert_get_name (alert); 426 str = fn_gnutls_alert_get_name (alert);
240 if (!str) 427 if (!str)
241 str = "unknown"; 428 str = "unknown";
242 429
@@ -314,7 +501,7 @@ usage: (gnutls-error-fatalp ERROR) */)
314 if (!NUMBERP (err)) 501 if (!NUMBERP (err))
315 error ("Not an error symbol or code"); 502 error ("Not an error symbol or code");
316 503
317 if (0 == gnutls_error_is_fatal (XINT (err))) 504 if (0 == fn_gnutls_error_is_fatal (XINT (err)))
318 return Qnil; 505 return Qnil;
319 506
320 return Qt; 507 return Qt;
@@ -346,7 +533,7 @@ usage: (gnutls-error-string ERROR) */)
346 if (!NUMBERP (err)) 533 if (!NUMBERP (err))
347 return build_string ("Not an error symbol or code"); 534 return build_string ("Not an error symbol or code");
348 535
349 return build_string (gnutls_strerror (XINT (err))); 536 return build_string (fn_gnutls_strerror (XINT (err)));
350} 537}
351 538
352DEFUN ("gnutls-deinit", Fgnutls_deinit, Sgnutls_deinit, 1, 1, 0, 539DEFUN ("gnutls-deinit", Fgnutls_deinit, Sgnutls_deinit, 1, 1, 0,
@@ -361,13 +548,34 @@ See also `gnutls-init'. */)
361 548
362 if (GNUTLS_INITSTAGE (proc) >= GNUTLS_STAGE_INIT) 549 if (GNUTLS_INITSTAGE (proc) >= GNUTLS_STAGE_INIT)
363 { 550 {
364 gnutls_deinit (state); 551 fn_gnutls_deinit (state);
365 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT - 1; 552 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT - 1;
366 } 553 }
367 554
368 return Qt; 555 return Qt;
369} 556}
370 557
558DEFUN ("gnutls-available-p", Fgnutls_available_p, Sgnutls_available_p, 0, 0, 0,
559 doc: /* Return t if GnuTLS is available in this instance of Emacs. */)
560 (void)
561{
562#ifdef WINDOWSNT
563 Lisp_Object found = Fassq (Qgnutls_dll, Vlibrary_cache);
564 if (CONSP (found))
565 return XCDR (found);
566 else
567 {
568 Lisp_Object status;
569 status = init_gnutls_functions (Vdynamic_library_alist) ? Qt : Qnil;
570 Vlibrary_cache = Fcons (Fcons (Qgnutls_dll, status), Vlibrary_cache);
571 return status;
572 }
573#else
574 return Qt;
575#endif
576}
577
578
371/* Initializes global GnuTLS state to defaults. 579/* Initializes global GnuTLS state to defaults.
372Call `gnutls-global-deinit' when GnuTLS usage is no longer needed. 580Call `gnutls-global-deinit' when GnuTLS usage is no longer needed.
373Returns zero on success. */ 581Returns zero on success. */
@@ -377,8 +585,7 @@ emacs_gnutls_global_init (void)
377 int ret = GNUTLS_E_SUCCESS; 585 int ret = GNUTLS_E_SUCCESS;
378 586
379 if (!gnutls_global_initialized) 587 if (!gnutls_global_initialized)
380 ret = gnutls_global_init (); 588 ret = fn_gnutls_global_init ();
381
382 gnutls_global_initialized = 1; 589 gnutls_global_initialized = 1;
383 590
384 return gnutls_make_error (ret); 591 return gnutls_make_error (ret);
@@ -488,6 +695,12 @@ one trustfile (usually a CA bundle). */)
488 CHECK_SYMBOL (type); 695 CHECK_SYMBOL (type);
489 CHECK_LIST (proplist); 696 CHECK_LIST (proplist);
490 697
698 if (NILP (Fgnutls_available_p ()))
699 {
700 error ("GnuTLS not available");
701 return gnutls_make_error (GNUTLS_EMACS_ERROR_NOT_LOADED);
702 }
703
491 hostname = Fplist_get (proplist, Qgnutls_bootprop_hostname); 704 hostname = Fplist_get (proplist, Qgnutls_bootprop_hostname);
492 priority_string = Fplist_get (proplist, Qgnutls_bootprop_priority); 705 priority_string = Fplist_get (proplist, Qgnutls_bootprop_priority);
493 trustfiles = Fplist_get (proplist, Qgnutls_bootprop_trustfiles); 706 trustfiles = Fplist_get (proplist, Qgnutls_bootprop_trustfiles);
@@ -509,8 +722,8 @@ one trustfile (usually a CA bundle). */)
509 722
510 if (NUMBERP (loglevel)) 723 if (NUMBERP (loglevel))
511 { 724 {
512 gnutls_global_set_log_function (gnutls_log_function); 725 fn_gnutls_global_set_log_function (gnutls_log_function);
513 gnutls_global_set_log_level (XINT (loglevel)); 726 fn_gnutls_global_set_log_level (XINT (loglevel));
514 max_log_level = XINT (loglevel); 727 max_log_level = XINT (loglevel);
515 XPROCESS (proc)->gnutls_log_level = max_log_level; 728 XPROCESS (proc)->gnutls_log_level = max_log_level;
516 } 729 }
@@ -529,13 +742,13 @@ one trustfile (usually a CA bundle). */)
529 { 742 {
530 GNUTLS_LOG (2, max_log_level, "deallocating x509 credentials"); 743 GNUTLS_LOG (2, max_log_level, "deallocating x509 credentials");
531 x509_cred = XPROCESS (proc)->gnutls_x509_cred; 744 x509_cred = XPROCESS (proc)->gnutls_x509_cred;
532 gnutls_certificate_free_credentials (x509_cred); 745 fn_gnutls_certificate_free_credentials (x509_cred);
533 } 746 }
534 else if (EQ (type, Qgnutls_anon)) 747 else if (EQ (type, Qgnutls_anon))
535 { 748 {
536 GNUTLS_LOG (2, max_log_level, "deallocating anon credentials"); 749 GNUTLS_LOG (2, max_log_level, "deallocating anon credentials");
537 anon_cred = XPROCESS (proc)->gnutls_anon_cred; 750 anon_cred = XPROCESS (proc)->gnutls_anon_cred;
538 gnutls_anon_free_client_credentials (anon_cred); 751 fn_gnutls_anon_free_client_credentials (anon_cred);
539 } 752 }
540 else 753 else
541 { 754 {
@@ -558,7 +771,7 @@ one trustfile (usually a CA bundle). */)
558 { 771 {
559 GNUTLS_LOG (2, max_log_level, "allocating x509 credentials"); 772 GNUTLS_LOG (2, max_log_level, "allocating x509 credentials");
560 x509_cred = XPROCESS (proc)->gnutls_x509_cred; 773 x509_cred = XPROCESS (proc)->gnutls_x509_cred;
561 if (gnutls_certificate_allocate_credentials (&x509_cred) < 0) 774 if (fn_gnutls_certificate_allocate_credentials (&x509_cred) < 0)
562 memory_full (); 775 memory_full ();
563 776
564 if (NUMBERP (verify_flags)) 777 if (NUMBERP (verify_flags))
@@ -576,13 +789,13 @@ one trustfile (usually a CA bundle). */)
576 /* The default is already GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT. */ 789 /* The default is already GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT. */
577 GNUTLS_LOG (2, max_log_level, "ignoring invalid verify-flags"); 790 GNUTLS_LOG (2, max_log_level, "ignoring invalid verify-flags");
578 } 791 }
579 gnutls_certificate_set_verify_flags (x509_cred, gnutls_verify_flags); 792 fn_gnutls_certificate_set_verify_flags (x509_cred, gnutls_verify_flags);
580 } 793 }
581 else if (EQ (type, Qgnutls_anon)) 794 else if (EQ (type, Qgnutls_anon))
582 { 795 {
583 GNUTLS_LOG (2, max_log_level, "allocating anon credentials"); 796 GNUTLS_LOG (2, max_log_level, "allocating anon credentials");
584 anon_cred = XPROCESS (proc)->gnutls_anon_cred; 797 anon_cred = XPROCESS (proc)->gnutls_anon_cred;
585 if (gnutls_anon_allocate_client_credentials (&anon_cred) < 0) 798 if (fn_gnutls_anon_allocate_client_credentials (&anon_cred) < 0)
586 memory_full (); 799 memory_full ();
587 } 800 }
588 else 801 else
@@ -605,7 +818,7 @@ one trustfile (usually a CA bundle). */)
605 { 818 {
606 GNUTLS_LOG2 (1, max_log_level, "setting the trustfile: ", 819 GNUTLS_LOG2 (1, max_log_level, "setting the trustfile: ",
607 SSDATA (trustfile)); 820 SSDATA (trustfile));
608 ret = gnutls_certificate_set_x509_trust_file 821 ret = fn_gnutls_certificate_set_x509_trust_file
609 (x509_cred, 822 (x509_cred,
610 SSDATA (trustfile), 823 SSDATA (trustfile),
611 file_format); 824 file_format);
@@ -627,7 +840,7 @@ one trustfile (usually a CA bundle). */)
627 { 840 {
628 GNUTLS_LOG2 (1, max_log_level, "setting the CRL file: ", 841 GNUTLS_LOG2 (1, max_log_level, "setting the CRL file: ",
629 SSDATA (crlfile)); 842 SSDATA (crlfile));
630 ret = gnutls_certificate_set_x509_crl_file 843 ret = fn_gnutls_certificate_set_x509_crl_file
631 (x509_cred, 844 (x509_cred,
632 SSDATA (crlfile), 845 SSDATA (crlfile),
633 file_format); 846 file_format);
@@ -652,7 +865,7 @@ one trustfile (usually a CA bundle). */)
652 SSDATA (keyfile)); 865 SSDATA (keyfile));
653 GNUTLS_LOG2 (1, max_log_level, "setting the client cert file: ", 866 GNUTLS_LOG2 (1, max_log_level, "setting the client cert file: ",
654 SSDATA (certfile)); 867 SSDATA (certfile));
655 ret = gnutls_certificate_set_x509_key_file 868 ret = fn_gnutls_certificate_set_x509_key_file
656 (x509_cred, 869 (x509_cred,
657 SSDATA (certfile), 870 SSDATA (certfile),
658 SSDATA (keyfile), 871 SSDATA (keyfile),
@@ -685,7 +898,7 @@ one trustfile (usually a CA bundle). */)
685 898
686 GNUTLS_LOG (1, max_log_level, "gnutls_init"); 899 GNUTLS_LOG (1, max_log_level, "gnutls_init");
687 900
688 ret = gnutls_init (&state, GNUTLS_CLIENT); 901 ret = fn_gnutls_init (&state, GNUTLS_CLIENT);
689 902
690 if (ret < GNUTLS_E_SUCCESS) 903 if (ret < GNUTLS_E_SUCCESS)
691 return gnutls_make_error (ret); 904 return gnutls_make_error (ret);
@@ -708,9 +921,9 @@ one trustfile (usually a CA bundle). */)
708 921
709 GNUTLS_LOG (1, max_log_level, "setting the priority string"); 922 GNUTLS_LOG (1, max_log_level, "setting the priority string");
710 923
711 ret = gnutls_priority_set_direct (state, 924 ret = fn_gnutls_priority_set_direct (state,
712 priority_string_ptr, 925 priority_string_ptr,
713 NULL); 926 NULL);
714 927
715 if (ret < GNUTLS_E_SUCCESS) 928 if (ret < GNUTLS_E_SUCCESS)
716 return gnutls_make_error (ret); 929 return gnutls_make_error (ret);
@@ -719,11 +932,11 @@ one trustfile (usually a CA bundle). */)
719 932
720 if (EQ (type, Qgnutls_x509pki)) 933 if (EQ (type, Qgnutls_x509pki))
721 { 934 {
722 ret = gnutls_cred_set (state, GNUTLS_CRD_CERTIFICATE, x509_cred); 935 ret = fn_gnutls_credentials_set (state, GNUTLS_CRD_CERTIFICATE, x509_cred);
723 } 936 }
724 else if (EQ (type, Qgnutls_anon)) 937 else if (EQ (type, Qgnutls_anon))
725 { 938 {
726 ret = gnutls_cred_set (state, GNUTLS_CRD_ANON, anon_cred); 939 ret = fn_gnutls_credentials_set (state, GNUTLS_CRD_ANON, anon_cred);
727 } 940 }
728 else 941 else
729 { 942 {
@@ -751,7 +964,7 @@ one trustfile (usually a CA bundle). */)
751 check of the certificate's hostname with 964 check of the certificate's hostname with
752 gnutls_x509_crt_check_hostname() against :hostname. */ 965 gnutls_x509_crt_check_hostname() against :hostname. */
753 966
754 ret = gnutls_certificate_verify_peers2 (state, &peer_verification); 967 ret = fn_gnutls_certificate_verify_peers2 (state, &peer_verification);
755 968
756 if (ret < GNUTLS_E_SUCCESS) 969 if (ret < GNUTLS_E_SUCCESS)
757 return gnutls_make_error (ret); 970 return gnutls_make_error (ret);
@@ -802,15 +1015,15 @@ one trustfile (usually a CA bundle). */)
802 /* Up to here the process is the same for X.509 certificates and 1015 /* Up to here the process is the same for X.509 certificates and
803 OpenPGP keys. From now on X.509 certificates are assumed. This 1016 OpenPGP keys. From now on X.509 certificates are assumed. This
804 can be easily extended to work with openpgp keys as well. */ 1017 can be easily extended to work with openpgp keys as well. */
805 if (gnutls_certificate_type_get (state) == GNUTLS_CRT_X509) 1018 if (fn_gnutls_certificate_type_get (state) == GNUTLS_CRT_X509)
806 { 1019 {
807 ret = gnutls_x509_crt_init (&gnutls_verify_cert); 1020 ret = fn_gnutls_x509_crt_init (&gnutls_verify_cert);
808 1021
809 if (ret < GNUTLS_E_SUCCESS) 1022 if (ret < GNUTLS_E_SUCCESS)
810 return gnutls_make_error (ret); 1023 return gnutls_make_error (ret);
811 1024
812 gnutls_verify_cert_list = 1025 gnutls_verify_cert_list =
813 gnutls_certificate_get_peers (state, &gnutls_verify_cert_list_size); 1026 fn_gnutls_certificate_get_peers (state, &gnutls_verify_cert_list_size);
814 1027
815 if (NULL == gnutls_verify_cert_list) 1028 if (NULL == gnutls_verify_cert_list)
816 { 1029 {
@@ -818,17 +1031,17 @@ one trustfile (usually a CA bundle). */)
818 } 1031 }
819 1032
820 /* We only check the first certificate in the given chain. */ 1033 /* We only check the first certificate in the given chain. */
821 ret = gnutls_x509_crt_import (gnutls_verify_cert, 1034 ret = fn_gnutls_x509_crt_import (gnutls_verify_cert,
822 &gnutls_verify_cert_list[0], 1035 &gnutls_verify_cert_list[0],
823 GNUTLS_X509_FMT_DER); 1036 GNUTLS_X509_FMT_DER);
824 1037
825 if (ret < GNUTLS_E_SUCCESS) 1038 if (ret < GNUTLS_E_SUCCESS)
826 { 1039 {
827 gnutls_x509_crt_deinit (gnutls_verify_cert); 1040 fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
828 return gnutls_make_error (ret); 1041 return gnutls_make_error (ret);
829 } 1042 }
830 1043
831 if (!gnutls_x509_crt_check_hostname (gnutls_verify_cert, c_hostname)) 1044 if (!fn_gnutls_x509_crt_check_hostname (gnutls_verify_cert, c_hostname))
832 { 1045 {
833 if (NILP (verify_hostname_error)) 1046 if (NILP (verify_hostname_error))
834 { 1047 {
@@ -837,13 +1050,13 @@ one trustfile (usually a CA bundle). */)
837 } 1050 }
838 else 1051 else
839 { 1052 {
840 gnutls_x509_crt_deinit (gnutls_verify_cert); 1053 fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
841 error ("The x509 certificate does not match \"%s\"", 1054 error ("The x509 certificate does not match \"%s\"",
842 c_hostname); 1055 c_hostname);
843 } 1056 }
844 } 1057 }
845 1058
846 gnutls_x509_crt_deinit (gnutls_verify_cert); 1059 fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
847 } 1060 }
848 1061
849 return gnutls_make_error (ret); 1062 return gnutls_make_error (ret);
@@ -872,8 +1085,8 @@ This function may also return `gnutls-e-again', or
872 1085
873 state = XPROCESS (proc)->gnutls_state; 1086 state = XPROCESS (proc)->gnutls_state;
874 1087
875 ret = gnutls_bye (state, 1088 ret = fn_gnutls_bye (state,
876 NILP (cont) ? GNUTLS_SHUT_RDWR : GNUTLS_SHUT_WR); 1089 NILP (cont) ? GNUTLS_SHUT_RDWR : GNUTLS_SHUT_WR);
877 1090
878 return gnutls_make_error (ret); 1091 return gnutls_make_error (ret);
879} 1092}
@@ -883,6 +1096,9 @@ syms_of_gnutls (void)
883{ 1096{
884 gnutls_global_initialized = 0; 1097 gnutls_global_initialized = 0;
885 1098
1099 Qgnutls_dll = intern_c_string ("gnutls");
1100 staticpro (&Qgnutls_dll);
1101
886 Qgnutls_log_level = intern_c_string ("gnutls-log-level"); 1102 Qgnutls_log_level = intern_c_string ("gnutls-log-level");
887 staticpro (&Qgnutls_log_level); 1103 staticpro (&Qgnutls_log_level);
888 1104
@@ -956,6 +1172,7 @@ syms_of_gnutls (void)
956 defsubr (&Sgnutls_boot); 1172 defsubr (&Sgnutls_boot);
957 defsubr (&Sgnutls_deinit); 1173 defsubr (&Sgnutls_deinit);
958 defsubr (&Sgnutls_bye); 1174 defsubr (&Sgnutls_bye);
1175 defsubr (&Sgnutls_available_p);
959} 1176}
960 1177
961#endif /* HAVE_GNUTLS */ 1178#endif /* HAVE_GNUTLS */
diff --git a/src/gnutls.h b/src/gnutls.h
index 6c2e4c69523..e2a9bc9eaea 100644
--- a/src/gnutls.h
+++ b/src/gnutls.h
@@ -42,6 +42,7 @@ typedef enum
42 GNUTLS_STAGE_READY, 42 GNUTLS_STAGE_READY,
43} gnutls_initstage_t; 43} gnutls_initstage_t;
44 44
45#define GNUTLS_EMACS_ERROR_NOT_LOADED GNUTLS_E_APPLICATION_ERROR_MIN + 1
45#define GNUTLS_EMACS_ERROR_INVALID_TYPE GNUTLS_E_APPLICATION_ERROR_MIN 46#define GNUTLS_EMACS_ERROR_INVALID_TYPE GNUTLS_E_APPLICATION_ERROR_MIN
46 47
47#define GNUTLS_INITSTAGE(proc) (XPROCESS (proc)->gnutls_initstage) 48#define GNUTLS_INITSTAGE(proc) (XPROCESS (proc)->gnutls_initstage)
@@ -52,12 +53,13 @@ typedef enum
52 53
53#define GNUTLS_LOG2(level, max, string, extra) if (level <= max) { gnutls_log_function2 (level, "(Emacs) " string, extra); } 54#define GNUTLS_LOG2(level, max, string, extra) if (level <= max) { gnutls_log_function2 (level, "(Emacs) " string, extra); }
54 55
55EMACS_INT 56extern EMACS_INT
56emacs_gnutls_write (int fildes, struct Lisp_Process *proc, const char *buf, 57emacs_gnutls_write (struct Lisp_Process *proc, const char *buf, EMACS_INT nbyte);
57 EMACS_INT nbyte); 58extern EMACS_INT
58EMACS_INT 59emacs_gnutls_read (struct Lisp_Process *proc, char *buf, EMACS_INT nbyte);
59emacs_gnutls_read (int fildes, struct Lisp_Process *proc, char *buf, 60
60 EMACS_INT nbyte); 61extern int emacs_gnutls_record_check_pending (gnutls_session_t state);
62extern void emacs_gnutls_transport_set_errno (gnutls_session_t state, int err);
61 63
62extern void syms_of_gnutls (void); 64extern void syms_of_gnutls (void);
63 65
diff --git a/src/image.c b/src/image.c
index 6feeb75afd6..d78b556d8c9 100644
--- a/src/image.c
+++ b/src/image.c
@@ -67,6 +67,7 @@ typedef struct x_bitmap_record Bitmap_Record;
67 67
68 68
69#ifdef HAVE_NTGUI 69#ifdef HAVE_NTGUI
70#include "w32.h"
70#include "w32term.h" 71#include "w32term.h"
71 72
72/* W32_TODO : Color tables on W32. */ 73/* W32_TODO : Color tables on W32. */
@@ -556,10 +557,6 @@ x_create_bitmap_mask (struct frame *f, int id)
556 557
557static struct image_type *image_types; 558static struct image_type *image_types;
558 559
559/* Cache for delayed-loading image types. */
560
561static Lisp_Object Vimage_type_cache;
562
563/* The symbol `xbm' which is used as the type symbol for XBM images. */ 560/* The symbol `xbm' which is used as the type symbol for XBM images. */
564 561
565static Lisp_Object Qxbm; 562static Lisp_Object Qxbm;
@@ -587,9 +584,12 @@ static void x_laplace (struct frame *, struct image *);
587static void x_emboss (struct frame *, struct image *); 584static void x_emboss (struct frame *, struct image *);
588static int x_build_heuristic_mask (struct frame *, struct image *, 585static int x_build_heuristic_mask (struct frame *, struct image *,
589 Lisp_Object); 586 Lisp_Object);
590 587#ifdef HAVE_NTGUI
591#define CACHE_IMAGE_TYPE(type, status) \ 588#define CACHE_IMAGE_TYPE(type, status) \
592 do { Vimage_type_cache = Fcons (Fcons (type, status), Vimage_type_cache); } while (0) 589 do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0)
590#else
591#define CACHE_IMAGE_TYPE(type, status)
592#endif
593 593
594#define ADD_IMAGE_TYPE(type) \ 594#define ADD_IMAGE_TYPE(type) \
595 do { Vimage_types = Fcons (type, Vimage_types); } while (0) 595 do { Vimage_types = Fcons (type, Vimage_types); } while (0)
@@ -1900,34 +1900,6 @@ mark_image_cache (struct image_cache *c)
1900 if (!fn_##func) return 0; \ 1900 if (!fn_##func) return 0; \
1901 } 1901 }
1902 1902
1903/* Load a DLL implementing an image type.
1904 The argument LIBRARIES is usually the variable
1905 `dynamic-library-alist', which associates a symbol, identifying
1906 an external DLL library, to a list of possible filenames.
1907 The function returns NULL if no library could be loaded for
1908 the given symbol, or if the library was previously loaded;
1909 else the handle of the DLL. */
1910static HMODULE
1911w32_delayed_load (Lisp_Object libraries, Lisp_Object type)
1912{
1913 HMODULE library = NULL;
1914
1915 if (CONSP (libraries) && NILP (Fassq (type, Vimage_type_cache)))
1916 {
1917 Lisp_Object dlls = Fassq (type, libraries);
1918
1919 if (CONSP (dlls))
1920 for (dlls = XCDR (dlls); CONSP (dlls); dlls = XCDR (dlls))
1921 {
1922 CHECK_STRING_CAR (dlls);
1923 if (library = LoadLibrary (SDATA (XCAR (dlls))))
1924 break;
1925 }
1926 }
1927
1928 return library;
1929}
1930
1931#endif /* HAVE_NTGUI */ 1903#endif /* HAVE_NTGUI */
1932 1904
1933static int x_create_x_image_and_pixmap (struct frame *, int, int, int, 1905static int x_create_x_image_and_pixmap (struct frame *, int, int, int,
@@ -5452,7 +5424,6 @@ init_png_functions (Lisp_Object libraries)
5452{ 5424{
5453 HMODULE library; 5425 HMODULE library;
5454 5426
5455 /* Try loading libpng under probable names. */
5456 if (!(library = w32_delayed_load (libraries, Qpng))) 5427 if (!(library = w32_delayed_load (libraries, Qpng)))
5457 return 0; 5428 return 0;
5458 5429
@@ -8633,10 +8604,12 @@ of `dynamic-library-alist', which see). */)
8633{ 8604{
8634 Lisp_Object tested; 8605 Lisp_Object tested;
8635 8606
8607#ifdef HAVE_NTGUI
8636 /* Don't try to reload the library. */ 8608 /* Don't try to reload the library. */
8637 tested = Fassq (type, Vimage_type_cache); 8609 tested = Fassq (type, Vlibrary_cache);
8638 if (CONSP (tested)) 8610 if (CONSP (tested))
8639 return XCDR (tested); 8611 return XCDR (tested);
8612#endif
8640 8613
8641#if defined (HAVE_XPM) || defined (HAVE_NS) 8614#if defined (HAVE_XPM) || defined (HAVE_NS)
8642 if (EQ (type, Qxpm)) 8615 if (EQ (type, Qxpm))
@@ -8714,9 +8687,6 @@ as a ratio to the frame height and width. If the value is
8714non-numeric, there is no explicit limit on the size of images. */); 8687non-numeric, there is no explicit limit on the size of images. */);
8715 Vmax_image_size = make_float (MAX_IMAGE_SIZE); 8688 Vmax_image_size = make_float (MAX_IMAGE_SIZE);
8716 8689
8717 Vimage_type_cache = Qnil;
8718 staticpro (&Vimage_type_cache);
8719
8720 Qpbm = intern_c_string ("pbm"); 8690 Qpbm = intern_c_string ("pbm");
8721 staticpro (&Qpbm); 8691 staticpro (&Qpbm);
8722 ADD_IMAGE_TYPE (Qpbm); 8692 ADD_IMAGE_TYPE (Qpbm);
diff --git a/src/makefile.w32-in b/src/makefile.w32-in
index 0de687c01a1..4296cd64c6f 100644
--- a/src/makefile.w32-in
+++ b/src/makefile.w32-in
@@ -978,6 +978,7 @@ $(BLD)/image.$(O) : \
978 $(SRC)/frame.h \ 978 $(SRC)/frame.h \
979 $(SRC)/systime.h \ 979 $(SRC)/systime.h \
980 $(SRC)/termhooks.h \ 980 $(SRC)/termhooks.h \
981 $(SRC)/w32.h \
981 $(SRC)/w32gui.h \ 982 $(SRC)/w32gui.h \
982 $(SRC)/w32term.h \ 983 $(SRC)/w32term.h \
983 $(SRC)/window.h 984 $(SRC)/window.h
@@ -1304,7 +1305,9 @@ $(BLD)/print.$(O) : \
1304$(BLD)/process.$(O) : \ 1305$(BLD)/process.$(O) : \
1305 $(SRC)/process.c \ 1306 $(SRC)/process.c \
1306 $(CONFIG_H) \ 1307 $(CONFIG_H) \
1308 $(EMACS_ROOT)/nt/inc/inttypes.h \
1307 $(EMACS_ROOT)/nt/inc/netdb.h \ 1309 $(EMACS_ROOT)/nt/inc/netdb.h \
1310 $(EMACS_ROOT)/nt/inc/stdint.h \
1308 $(EMACS_ROOT)/nt/inc/unistd.h \ 1311 $(EMACS_ROOT)/nt/inc/unistd.h \
1309 $(EMACS_ROOT)/nt/inc/arpa/inet.h \ 1312 $(EMACS_ROOT)/nt/inc/arpa/inet.h \
1310 $(EMACS_ROOT)/nt/inc/netinet/in.h \ 1313 $(EMACS_ROOT)/nt/inc/netinet/in.h \
diff --git a/src/nsfns.m b/src/nsfns.m
index d4445d1d627..cdf350066be 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -1416,9 +1416,10 @@ DEFUN ("ns-popup-color-panel", Fns_popup_color_panel, Sns_popup_color_panel,
1416DEFUN ("ns-read-file-name", Fns_read_file_name, Sns_read_file_name, 1, 4, 0, 1416DEFUN ("ns-read-file-name", Fns_read_file_name, Sns_read_file_name, 1, 4, 0,
1417 doc: /* Use a graphical panel to read a file name, using prompt PROMPT. 1417 doc: /* Use a graphical panel to read a file name, using prompt PROMPT.
1418Optional arg DIR, if non-nil, supplies a default directory. 1418Optional arg DIR, if non-nil, supplies a default directory.
1419Optional arg ISLOAD, if non-nil, means read a file name for saving. 1419Optional arg MUSTMATCH, if non-nil, means the returned file or
1420directory must exist.
1420Optional arg INIT, if non-nil, provides a default file name to use. */) 1421Optional arg INIT, if non-nil, provides a default file name to use. */)
1421 (Lisp_Object prompt, Lisp_Object dir, Lisp_Object isLoad, Lisp_Object init) 1422 (Lisp_Object prompt, Lisp_Object dir, Lisp_Object mustmatch, Lisp_Object init)
1422{ 1423{
1423 static id fileDelegate = nil; 1424 static id fileDelegate = nil;
1424 int ret; 1425 int ret;
@@ -1443,7 +1444,7 @@ Optional arg INIT, if non-nil, provides a default file name to use. */)
1443 if ([dirS characterAtIndex: 0] == '~') 1444 if ([dirS characterAtIndex: 0] == '~')
1444 dirS = [dirS stringByExpandingTildeInPath]; 1445 dirS = [dirS stringByExpandingTildeInPath];
1445 1446
1446 panel = NILP (isLoad) ? 1447 panel = NILP (mustmatch) ?
1447 (id)[EmacsSavePanel savePanel] : (id)[EmacsOpenPanel openPanel]; 1448 (id)[EmacsSavePanel savePanel] : (id)[EmacsOpenPanel openPanel];
1448 1449
1449 [panel setTitle: promptS]; 1450 [panel setTitle: promptS];
@@ -1457,7 +1458,7 @@ Optional arg INIT, if non-nil, provides a default file name to use. */)
1457 1458
1458 panelOK = 0; 1459 panelOK = 0;
1459 BLOCK_INPUT; 1460 BLOCK_INPUT;
1460 if (NILP (isLoad)) 1461 if (NILP (mustmatch))
1461 { 1462 {
1462 ret = [panel runModalForDirectory: dirS file: initS]; 1463 ret = [panel runModalForDirectory: dirS file: initS];
1463 } 1464 }
diff --git a/src/process.c b/src/process.c
index 3dc096e7d60..8a94b3e6047 100644
--- a/src/process.c
+++ b/src/process.c
@@ -32,6 +32,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
32#include <unistd.h> 32#include <unistd.h>
33#include <fcntl.h> 33#include <fcntl.h>
34 34
35#include "lisp.h"
36
35/* Only MS-DOS does not define `subprocesses'. */ 37/* Only MS-DOS does not define `subprocesses'. */
36#ifdef subprocesses 38#ifdef subprocesses
37 39
@@ -76,7 +78,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
76 78
77#endif /* subprocesses */ 79#endif /* subprocesses */
78 80
79#include "lisp.h"
80#include "systime.h" 81#include "systime.h"
81#include "systty.h" 82#include "systty.h"
82 83
@@ -4539,7 +4540,7 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
4539 if (nfds == 0 && 4540 if (nfds == 0 &&
4540 wait_proc && wait_proc->gnutls_p /* Check for valid process. */ 4541 wait_proc && wait_proc->gnutls_p /* Check for valid process. */
4541 /* Do we have pending data? */ 4542 /* Do we have pending data? */
4542 && gnutls_record_check_pending (wait_proc->gnutls_state) > 0) 4543 && emacs_gnutls_record_check_pending (wait_proc->gnutls_state) > 0)
4543 { 4544 {
4544 nfds = 1; 4545 nfds = 1;
4545 /* Set to Available. */ 4546 /* Set to Available. */
@@ -4950,7 +4951,7 @@ read_process_output (Lisp_Object proc, register int channel)
4950 } 4951 }
4951#ifdef HAVE_GNUTLS 4952#ifdef HAVE_GNUTLS
4952 if (XPROCESS (proc)->gnutls_p) 4953 if (XPROCESS (proc)->gnutls_p)
4953 nbytes = emacs_gnutls_read (channel, XPROCESS (proc), 4954 nbytes = emacs_gnutls_read (XPROCESS (proc),
4954 chars + carryover + buffered, 4955 chars + carryover + buffered,
4955 readmax - buffered); 4956 readmax - buffered);
4956 else 4957 else
@@ -5413,9 +5414,8 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
5413 { 5414 {
5414#ifdef HAVE_GNUTLS 5415#ifdef HAVE_GNUTLS
5415 if (XPROCESS (proc)->gnutls_p) 5416 if (XPROCESS (proc)->gnutls_p)
5416 written = emacs_gnutls_write (outfd, 5417 written = emacs_gnutls_write (XPROCESS (proc),
5417 XPROCESS (proc), 5418 buf, this);
5418 buf, this);
5419 else 5419 else
5420#endif 5420#endif
5421 written = emacs_write (outfd, buf, this); 5421 written = emacs_write (outfd, buf, this);
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 {
150typedef HRESULT (WINAPI * ShGetFolderPath_fn) 150typedef HRESULT (WINAPI * ShGetFolderPath_fn)
151 (IN HWND, IN int, IN HANDLE, IN DWORD, OUT char *); 151 (IN HWND, IN int, IN HANDLE, IN DWORD, OUT char *);
152 152
153Lisp_Object QCloaded_from;
154
153void globals_of_w32 (void); 155void globals_of_w32 (void);
154static DWORD get_rid (PSID); 156static DWORD get_rid (PSID);
155 157
@@ -5712,6 +5714,54 @@ sys_localtime (const time_t *t)
5712 return localtime (t); 5714 return localtime (t);
5713} 5715}
5714 5716
5717
5718
5719/* Delayed loading of libraries. */
5720
5721Lisp_Object Vlibrary_cache;
5722
5723/* The argument LIBRARIES is an alist that associates a symbol
5724 LIBRARY_ID, identifying an external DLL library known to Emacs, to
5725 a list of filenames under which the library is usually found. In
5726 most cases, the argument passed as LIBRARIES is the variable
5727 `dynamic-library-alist', which is initialized to a list of common
5728 library names. If the function loads the library successfully, it
5729 returns the handle of the DLL, and records the filename in the
5730 property :loaded-from of LIBRARY_ID; it returns NULL if the library
5731 could not be found, or when it was already loaded (because the
5732 handle is not recorded anywhere, and so is lost after use). It
5733 would be trivial to save the handle too in :loaded-from, but
5734 currently there's no use case for it. */
5735HMODULE
5736w32_delayed_load (Lisp_Object libraries, Lisp_Object library_id)
5737{
5738 HMODULE library_dll = NULL;
5739
5740 CHECK_SYMBOL (library_id);
5741
5742 if (CONSP (libraries) && NILP (Fassq (library_id, Vlibrary_cache)))
5743 {
5744 Lisp_Object found = Qnil;
5745 Lisp_Object dlls = Fassq (library_id, libraries);
5746
5747 if (CONSP (dlls))
5748 for (dlls = XCDR (dlls); CONSP (dlls); dlls = XCDR (dlls))
5749 {
5750 CHECK_STRING_CAR (dlls);
5751 if (library_dll = LoadLibrary (SDATA (XCAR (dlls))))
5752 {
5753 found = XCAR (dlls);
5754 break;
5755 }
5756 }
5757
5758 Fput (library_id, QCloaded_from, found);
5759 }
5760
5761 return library_dll;
5762}
5763
5764
5715static void 5765static void
5716check_windows_init_file (void) 5766check_windows_init_file (void)
5717{ 5767{
@@ -5910,6 +5960,12 @@ globals_of_w32 (void)
5910 get_process_times_fn = (GetProcessTimes_Proc) 5960 get_process_times_fn = (GetProcessTimes_Proc)
5911 GetProcAddress (kernel32, "GetProcessTimes"); 5961 GetProcAddress (kernel32, "GetProcessTimes");
5912 5962
5963 QCloaded_from = intern_c_string (":loaded-from");
5964 staticpro (&QCloaded_from);
5965
5966 Vlibrary_cache = Qnil;
5967 staticpro (&Vlibrary_cache);
5968
5913 g_b_init_is_windows_9x = 0; 5969 g_b_init_is_windows_9x = 0;
5914 g_b_init_open_process_token = 0; 5970 g_b_init_open_process_token = 0;
5915 g_b_init_get_token_information = 0; 5971 g_b_init_get_token_information = 0;
@@ -6178,7 +6234,7 @@ emacs_gnutls_pull (gnutls_transport_ptr_t p, void* buf, size_t sz)
6178 err = errno; /* Other errors are just passed on. */ 6234 err = errno; /* Other errors are just passed on. */
6179 } 6235 }
6180 6236
6181 gnutls_transport_set_errno (process->gnutls_state, err); 6237 emacs_gnutls_transport_set_errno (process->gnutls_state, err);
6182 6238
6183 return -1; 6239 return -1;
6184 } 6240 }
@@ -6197,8 +6253,8 @@ emacs_gnutls_push (gnutls_transport_ptr_t p, const void* buf, size_t sz)
6197 6253
6198 /* Negative bytes written means we got an error in errno. 6254 /* Negative bytes written means we got an error in errno.
6199 Translate the WSAEWOULDBLOCK alias EWOULDBLOCK to EAGAIN. */ 6255 Translate the WSAEWOULDBLOCK alias EWOULDBLOCK to EAGAIN. */
6200 gnutls_transport_set_errno (process->gnutls_state, 6256 emacs_gnutls_transport_set_errno (process->gnutls_state,
6201 errno == EWOULDBLOCK ? EAGAIN : errno); 6257 errno == EWOULDBLOCK ? EAGAIN : errno);
6202 6258
6203 return -1; 6259 return -1;
6204} 6260}
diff --git a/src/w32.h b/src/w32.h
index 4086c4190e1..f1915125c90 100644
--- a/src/w32.h
+++ b/src/w32.h
@@ -143,6 +143,9 @@ extern void syms_of_fontset (void);
143extern int _sys_read_ahead (int fd); 143extern int _sys_read_ahead (int fd);
144extern int _sys_wait_accept (int fd); 144extern int _sys_wait_accept (int fd);
145 145
146extern Lisp_Object Vlibrary_cache, QCloaded_from;
147extern HMODULE w32_delayed_load (Lisp_Object, Lisp_Object);
148
146#ifdef HAVE_GNUTLS 149#ifdef HAVE_GNUTLS
147#include <gnutls/gnutls.h> 150#include <gnutls/gnutls.h>
148 151
diff --git a/src/w32heap.c b/src/w32heap.c
index bbdabd23502..477c11a5160 100644
--- a/src/w32heap.c
+++ b/src/w32heap.c
@@ -114,6 +114,7 @@ get_data_end (void)
114 return data_region_end; 114 return data_region_end;
115} 115}
116 116
117#if !defined (USE_LISP_UNION_TYPE) && !defined (USE_LSB_TAG)
117static char * 118static char *
118allocate_heap (void) 119allocate_heap (void)
119{ 120{
@@ -140,9 +141,31 @@ allocate_heap (void)
140 141
141 return ptr; 142 return ptr;
142} 143}
144#else /* USE_LISP_UNION_TYPE || USE_LSB_TAG */
145static char *
146allocate_heap (void)
147{
148 unsigned long size = 0x80000000; /* start by asking for 2GB */
149 void *ptr = NULL;
150
151 while (!ptr && size > 0x00100000)
152 {
153 reserved_heap_size = size;
154 ptr = VirtualAlloc (NULL,
155 get_reserved_heap_size (),
156 MEM_RESERVE,
157 PAGE_NOACCESS);
158 size -= 0x00800000; /* if failed, decrease request by 8MB */
159 }
160
161 return ptr;
162}
163#endif /* USE_LISP_UNION_TYPE || USE_LSB_TAG */
143 164
144 165
145/* Emulate Unix sbrk. */ 166/* Emulate Unix sbrk. Note that ralloc.c expects the return value to
167 be the address of the _start_ (not end) of the new block in case of
168 success, and zero (not -1) in case of failure. */
146void * 169void *
147sbrk (unsigned long increment) 170sbrk (unsigned long increment)
148{ 171{