summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleg Pudeyev <oleg@bsdpower.com>2014-01-20 05:36:01 -0500
committerOleg Pudeyev <oleg@bsdpower.com>2014-01-20 07:55:55 -0500
commita39e3cc06d6c514eea72f17db17dba6a41db5382 (patch)
treee19c75e574597bd1f607aa544567acbd1e4cd20b
parent8cf045460a01ffe74654a4acd2a7534101976800 (diff)
downloadpycurl-a39e3cc06d6c514eea72f17db17dba6a41db5382.tar.gz
Add --avoid-stdio option to not pass FILE pointers from Python to libcurl on Windows (issue #117)
-rw-r--r--INSTALL.rst15
-rw-r--r--setup.py15
-rw-r--r--src/pycurl.c2
3 files changed, 27 insertions, 5 deletions
diff --git a/INSTALL.rst b/INSTALL.rst
index f96fa55..5ca73d6 100644
--- a/INSTALL.rst
+++ b/INSTALL.rst
@@ -92,12 +92,23 @@ and compiled libraries.
Additional Windows setup.py options:
-- ``--use-libcurl-dll`` - build against libcurl DLL, if not given PycURL will
+- ``--use-libcurl-dll``: build against libcurl DLL, if not given PycURL will
be built against libcurl statically.
-- ``--libcurl-lib-name=libcurl_imp.lib`` - specify a different name for libcurl
+- ``--libcurl-lib-name=libcurl_imp.lib``: specify a different name for libcurl
import library. The default is ``libcurl.lib`` which is appropriate for
static linking and is sometimes the correct choice for dynamic linking as
well. The other possibility for dynamic linking is ``libcurl_imp.lib``.
+- ``--avoid-stdio``: on windows, a process and each library it is using
+ may be linked to its own version of the C runtime (msvcrt).
+ FILE pointers from one C runtime may not be passed to another C runtime.
+ This option prevents direct passing of FILE pointers from Python to libcurl,
+ thus permitting Python and libcurl to be linked against different C runtimes.
+ This option may carry a performance penalty when Python file objects are
+ given directly to PycURL in CURLOPT_READDATA, CURLOPT_WRITEDATA or
+ CURLOPT_WRITEHEADER options. This option applies only on Python 2; on
+ Python 3, file objects no longer expose C library FILE pointers and the
+ C runtime issue does not exist. On Python 3, this option is recognized but
+ does nothing.
A good ``setup.py`` target to use is ``bdist_wininst`` which produces an
executable installer that you can run to install PycURL.
diff --git a/setup.py b/setup.py
index da627ae..5adc91d 100644
--- a/setup.py
+++ b/setup.py
@@ -240,9 +240,14 @@ class ExtensionConfiguration(object):
self.define_macros.append(('HAVE_CURL_SSL', 1))
if not self.libraries:
self.libraries.append("curl")
+
# Add extra compile flag for MacOS X
if sys.platform[:-1] == "darwin":
self.extra_link_args.append("-flat_namespace")
+
+ # Recognize --avoid-stdio on Unix so that it can be tested
+ if scan_argv('--avoid-stdio') is not None:
+ self.extra_compile_args.append("-DAVOID_STDIO")
def configure_windows(self):
@@ -279,6 +284,9 @@ class ExtensionConfiguration(object):
fail("libcurl.lib does not exist at %s.\nCurl directory must point to compiled libcurl (bin/include/lib subdirectories): %s" %(libcurl_lib_path, curl_dir))
self.extra_objects.append(libcurl_lib_path)
+ if scan_argv('--avoid-stdio') is not None:
+ self.extra_compile_args.append("-DAVOID_STDIO")
+
# make pycurl binary work on windows xp.
# we use inet_ntop which was added in vista and implement a fallback.
# our implementation will not be compiled with _WIN32_WINNT targeting
@@ -339,9 +347,12 @@ def get_bdist_msi_version_hack():
def strip_pycurl_options():
if sys.platform == 'win32':
- options = ['--curl-dir=', '--curl-lib-name=', '--use-libcurl-dll']
+ options = [
+ '--curl-dir=', '--curl-lib-name=', '--use-libcurl-dll',
+ '--avoid-stdio',
+ ]
else:
- options = ['--openssl-dir=', '--curl-config=']
+ options = ['--openssl-dir=', '--curl-config=', '--avoid-stdio']
for option in options:
scan_argv(option)
diff --git a/src/pycurl.c b/src/pycurl.c
index 6e347d9..5f6afaa 100644
--- a/src/pycurl.c
+++ b/src/pycurl.c
@@ -2244,7 +2244,7 @@ do_curl_setopt(CurlObject *self, PyObject *args)
#undef IS_LONG_OPTION
#undef IS_OFF_T_OPTION
-#if PY_MAJOR_VERSION < 3
+#if PY_MAJOR_VERSION < 3 && !defined(PYCURL_AVOID_STDIO)
/* Handle the case of file objects */
if (PyFile_Check(obj)) {
FILE *fp;