~barry/ubuntu/oneiric/pycurl/bug-788514

« back to all changes in this revision

Viewing changes to src/pycurl.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-05-24 13:00:47 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20070524130047-f1eds51xycdubvpt
Tags: 7.16.2.1-2ubuntu1
* Merge from Debian; remaining changes:
  - Build a python-pycurl-dbg package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: pycurl.c,v 1.114 2006/08/10 11:41:16 kjetilja Exp $ */
 
1
/* $Id: pycurl.c,v 1.133 2007/04/23 17:24:21 kjetilja Exp $ */
2
2
 
3
3
/* PycURL -- cURL Python module
4
4
 *
5
5
 * Authors:
6
 
 *  Copyright (C) 2001-2006 by Kjetil Jacobsen <kjetilja at gmail.com>
7
 
 *  Copyright (C) 2001-2006 by Markus F.X.J. Oberhumer <markus at oberhumer.com>
 
6
 *  Copyright (C) 2001-2007 by Kjetil Jacobsen <kjetilja at gmail.com>
 
7
 *  Copyright (C) 2001-2007 by Markus F.X.J. Oberhumer <markus at oberhumer.com>
8
8
 *
9
9
 * Contributions:
10
10
 *  Tino Lange <Tino.Lange at gmx.de>
19
19
 *  Victor Lascurain <bittor at eleka.net>
20
20
 *  K.S.Sreeram <sreeram at tachyontech.net>
21
21
 *  Jayne <corvine at gmail.com>
 
22
 *  Bastian Kleineidam
 
23
 *  Mark Eichin
 
24
 *  Aaron Hill <visine19 at hotmail.com>
22
25
 *
23
26
 * See file COPYING for license information.
24
27
 */
47
50
#if !defined(PY_VERSION_HEX) || (PY_VERSION_HEX < 0x02020000)
48
51
#  error "Need Python version 2.2 or greater to compile pycurl."
49
52
#endif
50
 
#if !defined(LIBCURL_VERSION_NUM) || (LIBCURL_VERSION_NUM < 0x070f05)
51
 
#  error "Need libcurl version 7.15.5 or greater to compile pycurl."
 
53
#if !defined(LIBCURL_VERSION_NUM) || (LIBCURL_VERSION_NUM < 0x071002)
 
54
#  error "Need libcurl version 7.16.2 or greater to compile pycurl."
 
55
#endif
 
56
 
 
57
/* Python < 2.5 compat for Py_ssize_t */
 
58
#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
 
59
typedef int Py_ssize_t;
 
60
#define PY_SSIZE_T_MAX INT_MAX
 
61
#define PY_SSIZE_T_MIN INT_MIN
52
62
#endif
53
63
 
54
64
#undef UNUSED
83
93
 
84
94
/* Calculate the number of OBJECTPOINT options we need to store */
85
95
#define OPTIONS_SIZE    ((int)CURLOPT_LASTENTRY % 10000)
 
96
#define MOPTIONS_SIZE   ((int)CURLMOPT_LASTENTRY % 10000)
86
97
static int OPT_INDEX(int o)
87
98
{
88
99
    assert(o >= CURLOPTTYPE_OBJECTPOINT);
116
127
    fd_set read_fd_set;
117
128
    fd_set write_fd_set;
118
129
    fd_set exc_fd_set;
 
130
    /* callbacks */
 
131
    PyObject *t_cb;
 
132
    PyObject *s_cb;
119
133
} CurlMultiObject;
120
134
 
121
135
typedef struct {
131
145
    struct curl_slist *quote;
132
146
    struct curl_slist *postquote;
133
147
    struct curl_slist *prequote;
134
 
    struct curl_slist *source_prequote;
135
 
    struct curl_slist *source_postquote;
136
148
    /* callbacks */
137
149
    PyObject *w_cb;
138
150
    PyObject *h_cb;
191
203
static char *PyString_AsString_NoNUL(PyObject *obj)
192
204
{
193
205
    char *s = NULL;
194
 
    int r;
 
206
    Py_ssize_t r;
195
207
    r = PyString_AsStringAndSize(obj, &s, NULL);
196
208
    if (r != 0)
197
209
        return NULL;    /* exception already set */
208
220
    PyObject *ret = NULL;
209
221
    struct curl_slist *slist_start = slist;
210
222
 
211
 
    ret = PyList_New(0);
 
223
    ret = PyList_New((Py_ssize_t)0);
212
224
    if (ret == NULL) goto error;
213
225
 
214
226
    for ( ; slist != NULL; slist = slist->next) {
274
286
    return NULL;
275
287
}
276
288
 
 
289
 
 
290
static PyThreadState *
 
291
get_thread_state_multi(const CurlMultiObject *self)
 
292
{
 
293
    /* Get the thread state for callbacks to run in when given
 
294
     * multi handles instead of regular handles
 
295
     */
 
296
    if (self == NULL)
 
297
        return NULL;
 
298
    assert(self->ob_type == p_CurlMulti_Type);
 
299
    if (self->state != NULL)
 
300
    {
 
301
        /* inside multi_perform() */
 
302
        assert(self->multi_handle != NULL);
 
303
        return self->state;
 
304
    }
 
305
    return NULL;
 
306
}
 
307
 
 
308
 
277
309
/* assert some CurlShareObject invariants */
278
310
static void
279
311
assert_share_state(const CurlShareObject *self)
585
617
    return 0;
586
618
}
587
619
 
 
620
 
 
621
static void
 
622
util_share_close(CurlShareObject *self){
 
623
    curl_share_cleanup(self->share_handle);
 
624
    share_lock_destroy(self->lock);
 
625
}
 
626
 
 
627
 
 
628
static void
 
629
do_share_dealloc(CurlShareObject *self){
 
630
    PyObject_GC_UnTrack(self);
 
631
    Py_TRASHCAN_SAFE_BEGIN(self);
 
632
 
 
633
    ZAP(self->dict);
 
634
    util_share_close(self);
 
635
 
 
636
    PyObject_GC_Del(self);
 
637
    Py_TRASHCAN_SAFE_END(self)
 
638
}
 
639
 
 
640
 
588
641
/* setopt, unsetopt*/
589
642
/* --------------- unsetopt/setopt/getinfo --------------- */
590
643
 
668
721
    self->quote = NULL;
669
722
    self->postquote = NULL;
670
723
    self->prequote = NULL;
671
 
    self->source_postquote = NULL;
672
 
    self->source_prequote = NULL;
673
724
 
674
725
    /* Set callback pointers to NULL by default */
675
726
    self->w_cb = NULL;
859
910
    SFREE(self->quote);
860
911
    SFREE(self->postquote);
861
912
    SFREE(self->prequote);
862
 
    SFREE(self->source_postquote);
863
 
    SFREE(self->source_prequote);
864
913
#undef SFREE
865
914
 
866
915
    /* Last, free the options.  This must be done after the curl handle
1116
1165
    /* handle result */
1117
1166
    if (PyString_Check(result)) {
1118
1167
        char *buf = NULL;
1119
 
        int obj_size = -1;
1120
 
        int r;
 
1168
        Py_ssize_t obj_size = -1;
 
1169
        Py_ssize_t r;
1121
1170
        r = PyString_AsStringAndSize(result, &buf, &obj_size);
1122
1171
        if (r != 0 || obj_size < 0 || obj_size > total_size) {
1123
1172
            PyErr_Format(ErrorObject, "invalid return value for read callback %ld %ld", (long)obj_size, (long)total_size);
1440
1489
    /* Handle the case of string arguments */
1441
1490
    if (PyString_Check(obj)) {
1442
1491
        char *str = NULL;
1443
 
        int len = -1;
 
1492
        Py_ssize_t len = -1;
1444
1493
        char *buf;
1445
1494
        int opt_index;
1446
1495
 
1474
1523
        case CURLOPT_URL:
1475
1524
        case CURLOPT_USERAGENT:
1476
1525
        case CURLOPT_USERPWD:
1477
 
        case CURLOPT_SOURCE_HOST:
1478
 
        case CURLOPT_SOURCE_USERPWD:
1479
 
        case CURLOPT_SOURCE_PATH:
1480
1526
        case CURLOPT_FTP_ALTERNATIVE_TO_USER:
 
1527
        case CURLOPT_SSH_PUBLIC_KEYFILE:
 
1528
        case CURLOPT_SSH_PRIVATE_KEYFILE:
1481
1529
/* FIXME: check if more of these options allow binary data */
1482
1530
            str = PyString_AsString_NoNUL(obj);
1483
1531
            if (str == NULL)
1487
1535
            if (PyString_AsStringAndSize(obj, &str, &len) != 0)
1488
1536
                return NULL;
1489
1537
            /* automatically set POSTFIELDSIZE */
1490
 
            res = curl_easy_setopt(self->handle, CURLOPT_POSTFIELDSIZE, (long)len);
 
1538
            if (len <= INT_MAX) {
 
1539
                res = curl_easy_setopt(self->handle, CURLOPT_POSTFIELDSIZE, (long)len);
 
1540
            } else {
 
1541
                res = curl_easy_setopt(self->handle, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)len);
 
1542
            }
1491
1543
            if (res != CURLE_OK) {
1492
1544
                CURLERROR_RETVAL();
1493
1545
            }
1627
1679
    if (PyList_Check(obj)) {
1628
1680
        struct curl_slist **old_slist = NULL;
1629
1681
        struct curl_slist *slist = NULL;
1630
 
        int i, len;
 
1682
        Py_ssize_t i, len;
1631
1683
 
1632
1684
        switch (option) {
1633
1685
        case CURLOPT_HTTP200ALIASES:
1645
1697
        case CURLOPT_PREQUOTE:
1646
1698
            old_slist = &self->prequote;
1647
1699
            break;
1648
 
        case CURLOPT_SOURCE_PREQUOTE:
1649
 
            old_slist = &self->source_prequote;
1650
 
            break;
1651
 
        case CURLOPT_SOURCE_POSTQUOTE:
1652
 
            old_slist = &self->source_postquote;
1653
 
            break;
1654
1700
        case CURLOPT_HTTPPOST:
1655
1701
            break;
1656
1702
        default:
1673
1719
 
1674
1720
            for (i = 0; i < len; i++) {
1675
1721
                char *nstr = NULL, *cstr = NULL;
1676
 
                int nlen = -1, clen = -1;
 
1722
                Py_ssize_t nlen = -1, clen = -1;
1677
1723
                PyObject *listitem = PyList_GetItem(obj, i);
1678
1724
 
1679
1725
                if (!PyTuple_Check(listitem)) {
1710
1756
                else if (PyTuple_Check(PyTuple_GET_ITEM(listitem, 1))) {
1711
1757
                    /* Supports content, file and content-type */
1712
1758
                    PyObject *t = PyTuple_GET_ITEM(listitem, 1);
1713
 
                    int tlen = PyTuple_Size(t);
 
1759
                    Py_ssize_t tlen = PyTuple_Size(t);
1714
1760
                    int j, k, l;
1715
1761
                    struct curl_forms *forms = NULL;
1716
1762
 
1732
1778
                    /* Iterate all the tuple members pairwise */
1733
1779
                    for (j = 0, k = 0, l = 0; j < tlen; j += 2, l++) {
1734
1780
                        char *ostr;
1735
 
                        int olen, val;
 
1781
                        Py_ssize_t olen;
 
1782
                        int val;
1736
1783
 
1737
1784
                        if (j == (tlen-1)) {
1738
1785
                            PyErr_SetString(PyExc_TypeError, "expected value");
1771
1818
                        if (val == CURLFORM_COPYCONTENTS) {
1772
1819
                            /* Contents can contain \0 bytes so we specify the length */
1773
1820
                            forms[k].option = CURLFORM_CONTENTSLENGTH;
1774
 
                            forms[k].value = (char *)olen;
 
1821
                            forms[k].value = (const char *)olen;
1775
1822
                            ++k;
1776
1823
                        }
1777
1824
                    }
2091
2138
    /* Initialize object attributes */
2092
2139
    self->dict = NULL;
2093
2140
    self->state = NULL;
 
2141
    self->t_cb = NULL;
 
2142
    self->s_cb = NULL;
2094
2143
 
2095
2144
    /* Allocate libcurl multi handle */
2096
2145
    self->multi_handle = curl_multi_init();
2103
2152
}
2104
2153
 
2105
2154
static void
2106
 
util_share_close(CurlShareObject *self){
2107
 
    curl_share_cleanup(self->share_handle);
2108
 
    share_lock_destroy(self->lock);
2109
 
}
2110
 
 
2111
 
static void
2112
2155
util_multi_close(CurlMultiObject *self)
2113
2156
{
2114
2157
    assert(self != NULL);
2120
2163
    }
2121
2164
}
2122
2165
 
2123
 
static void
2124
 
do_share_dealloc(CurlShareObject *self){
2125
 
    PyObject_GC_UnTrack(self);
2126
 
    Py_TRASHCAN_SAFE_BEGIN(self);
2127
 
 
2128
 
    ZAP(self->dict);
2129
 
    util_share_close(self);
2130
 
 
2131
 
    PyObject_GC_Del(self);
2132
 
    Py_TRASHCAN_SAFE_END(self)
2133
 
}
2134
2166
 
2135
2167
static void
2136
2168
do_multi_dealloc(CurlMultiObject *self)
2181
2213
#undef VISIT
2182
2214
}
2183
2215
 
 
2216
 
 
2217
/* --------------- setopt --------------- */
 
2218
 
 
2219
int multi_socket_callback(CURL *easy,
 
2220
                          curl_socket_t s,
 
2221
                          int what,
 
2222
                          void *userp,
 
2223
                          void *socketp)
 
2224
{
 
2225
    CurlMultiObject *self;
 
2226
    CurlObject *easy_self;
 
2227
    PyThreadState *tmp_state;
 
2228
    PyObject *arglist;
 
2229
    PyObject *result = NULL;
 
2230
    int ret;
 
2231
 
 
2232
    /* acquire thread */
 
2233
    self = (CurlMultiObject *)userp;
 
2234
    ret = curl_easy_getinfo(easy, CURLINFO_PRIVATE, &easy_self);
 
2235
    tmp_state = get_thread_state_multi(self);
 
2236
    if (tmp_state == NULL)
 
2237
        return 0;
 
2238
    PyEval_AcquireThread(tmp_state);
 
2239
 
 
2240
    /* check args */
 
2241
    if (self->s_cb == NULL)
 
2242
        goto silent_error;
 
2243
 
 
2244
    if (socketp == NULL) {
 
2245
        Py_INCREF(Py_None);
 
2246
        socketp = Py_None;
 
2247
    }
 
2248
 
 
2249
    /* run callback */
 
2250
    arglist = Py_BuildValue("(iiOO)", what, s, userp, (PyObject *)socketp);
 
2251
    if (arglist == NULL)
 
2252
        goto verbose_error;
 
2253
    result = PyEval_CallObject(self->s_cb, arglist);
 
2254
    Py_DECREF(arglist);
 
2255
    if (result == NULL)
 
2256
        goto verbose_error;
 
2257
 
 
2258
    /* return values from socket callbacks should be ignored */
 
2259
 
 
2260
silent_error:
 
2261
    Py_XDECREF(result);
 
2262
    PyEval_ReleaseThread(tmp_state);
 
2263
    return 0;
 
2264
verbose_error:
 
2265
    PyErr_Print();
 
2266
    goto silent_error;
 
2267
    return 0;
 
2268
}
 
2269
 
 
2270
 
 
2271
int multi_timer_callback(CURLM *multi,
 
2272
                         long timeout_ms,
 
2273
                         void *userp)
 
2274
{
 
2275
    CurlMultiObject *self;
 
2276
    PyThreadState *tmp_state;
 
2277
    PyObject *arglist;
 
2278
    PyObject *result = NULL;
 
2279
    int ret = 0;       /* always success */
 
2280
 
 
2281
    UNUSED(multi);
 
2282
 
 
2283
    /* acquire thread */
 
2284
    self = (CurlMultiObject *)userp;
 
2285
    tmp_state = get_thread_state_multi(self);
 
2286
    if (tmp_state == NULL)
 
2287
        return ret;
 
2288
    PyEval_AcquireThread(tmp_state);
 
2289
 
 
2290
    /* check args */
 
2291
    if (self->t_cb == NULL)
 
2292
        goto silent_error;
 
2293
 
 
2294
    /* run callback */
 
2295
    arglist = Py_BuildValue("(i)", timeout_ms);
 
2296
    if (arglist == NULL)
 
2297
        goto verbose_error;
 
2298
    result = PyEval_CallObject(self->t_cb, arglist);
 
2299
    Py_DECREF(arglist);
 
2300
    if (result == NULL)
 
2301
        goto verbose_error;
 
2302
 
 
2303
    /* return values from timer callbacks should be ignored */
 
2304
 
 
2305
silent_error:
 
2306
    Py_XDECREF(result);
 
2307
    PyEval_ReleaseThread(tmp_state);
 
2308
    return ret;
 
2309
verbose_error:
 
2310
    PyErr_Print();
 
2311
    goto silent_error;
 
2312
 
 
2313
    return 0;
 
2314
}
 
2315
 
 
2316
 
 
2317
static PyObject *
 
2318
do_multi_setopt(CurlMultiObject *self, PyObject *args)
 
2319
{
 
2320
    int option;
 
2321
    PyObject *obj;
 
2322
 
 
2323
    if (!PyArg_ParseTuple(args, "iO:setopt", &option, &obj))
 
2324
        return NULL;
 
2325
    if (check_multi_state(self, 1 | 2, "setopt") != 0)
 
2326
        return NULL;
 
2327
 
 
2328
    /* Early checks of option value */
 
2329
    if (option <= 0)
 
2330
        goto error;
 
2331
    if (option >= (int)CURLOPTTYPE_OFF_T + MOPTIONS_SIZE)
 
2332
        goto error;
 
2333
    if (option % 10000 >= MOPTIONS_SIZE)
 
2334
        goto error;
 
2335
 
 
2336
    /* Handle the case of integer arguments */
 
2337
    if (PyInt_Check(obj)) {
 
2338
        long d = PyInt_AsLong(obj);
 
2339
        switch(option) {
 
2340
        case CURLMOPT_PIPELINING:
 
2341
            curl_multi_setopt(self->multi_handle, option, d);
 
2342
            break;
 
2343
        default:
 
2344
            PyErr_SetString(PyExc_TypeError, "integers are not supported for this option");
 
2345
            return NULL;
 
2346
        }
 
2347
        Py_INCREF(Py_None);
 
2348
        return Py_None;
 
2349
    }
 
2350
    if (PyFunction_Check(obj) || PyCFunction_Check(obj) || PyMethod_Check(obj)) {
 
2351
        /* We use function types here to make sure that our callback
 
2352
         * definitions exactly match the <curl/multi.h> interface.
 
2353
         */
 
2354
        const curl_multi_timer_callback t_cb = multi_timer_callback;
 
2355
        const curl_socket_callback s_cb = multi_socket_callback;
 
2356
 
 
2357
        switch(option) {
 
2358
        case CURLMOPT_SOCKETFUNCTION:
 
2359
            curl_multi_setopt(self->multi_handle, CURLMOPT_SOCKETFUNCTION, s_cb);
 
2360
            curl_multi_setopt(self->multi_handle, CURLMOPT_SOCKETDATA, self);
 
2361
            Py_INCREF(obj);
 
2362
            self->s_cb = obj;
 
2363
            break;
 
2364
        case CURLMOPT_TIMERFUNCTION:
 
2365
            curl_multi_setopt(self->multi_handle, CURLMOPT_TIMERFUNCTION, t_cb);
 
2366
            curl_multi_setopt(self->multi_handle, CURLMOPT_TIMERDATA, self);
 
2367
            Py_INCREF(obj);
 
2368
            self->t_cb = obj;
 
2369
            break;
 
2370
        default:
 
2371
            PyErr_SetString(PyExc_TypeError, "callables are not supported for this option");
 
2372
            return NULL;
 
2373
        }
 
2374
        Py_INCREF(Py_None);
 
2375
        return Py_None;
 
2376
    }
 
2377
    /* Failed to match any of the function signatures -- return error */
 
2378
error:
 
2379
    PyErr_SetString(PyExc_TypeError, "invalid arguments to setopt");
 
2380
    return NULL;
 
2381
}
 
2382
 
 
2383
 
 
2384
/* --------------- timeout --------------- */
 
2385
 
 
2386
static PyObject *
 
2387
do_multi_timeout(CurlMultiObject *self)
 
2388
{
 
2389
    CURLMcode res;
 
2390
    long timeout;
 
2391
 
 
2392
    if (check_multi_state(self, 1 | 2, "timeout") != 0) {
 
2393
        return NULL;
 
2394
    }
 
2395
 
 
2396
    res = curl_multi_timeout(self->multi_handle, &timeout);
 
2397
    if (res != CURLM_OK) {
 
2398
        CURLERROR_MSG("timeout failed");
 
2399
    }
 
2400
 
 
2401
    /* Return number of millisecs until timeout */
 
2402
    return Py_BuildValue("i", timeout);
 
2403
}
 
2404
 
 
2405
 
 
2406
/* --------------- assign --------------- */
 
2407
 
 
2408
static PyObject *
 
2409
do_multi_assign(CurlMultiObject *self, PyObject *args)
 
2410
{
 
2411
    CURLMcode res;
 
2412
    curl_socket_t socket;
 
2413
    PyObject *obj;
 
2414
 
 
2415
    if (!PyArg_ParseTuple(args, "iO:assign", &socket, &obj))
 
2416
        return NULL;
 
2417
    if (check_multi_state(self, 1 | 2, "assign") != 0) {
 
2418
        return NULL;
 
2419
    }
 
2420
    Py_INCREF(obj);
 
2421
 
 
2422
    res = curl_multi_assign(self->multi_handle, socket, obj);
 
2423
    if (res != CURLM_OK) {
 
2424
        CURLERROR_MSG("assign failed");
 
2425
    }
 
2426
 
 
2427
    Py_INCREF(Py_None);
 
2428
    return Py_None;
 
2429
}
 
2430
 
 
2431
 
 
2432
/* --------------- socket_all --------------- */
 
2433
 
 
2434
static PyObject *
 
2435
do_multi_socket_all(CurlMultiObject *self)
 
2436
{
 
2437
    CURLMcode res;
 
2438
    int running = -1;
 
2439
 
 
2440
    if (check_multi_state(self, 1 | 2, "socket_all") != 0) {
 
2441
        return NULL;
 
2442
    }
 
2443
 
 
2444
    /* Release global lock and start */
 
2445
    self->state = PyThreadState_Get();
 
2446
    assert(self->state != NULL);
 
2447
    Py_BEGIN_ALLOW_THREADS
 
2448
    res = curl_multi_socket_all(self->multi_handle, &running);
 
2449
    Py_END_ALLOW_THREADS
 
2450
    self->state = NULL;
 
2451
 
 
2452
    /* We assume these errors are ok, otherwise throw exception */
 
2453
    if (res != CURLM_OK && res != CURLM_CALL_MULTI_PERFORM) {
 
2454
        CURLERROR_MSG("perform failed");
 
2455
    }
 
2456
 
 
2457
    /* Return a tuple with the result and the number of running handles */
 
2458
    return Py_BuildValue("(ii)", (int)res, running);
 
2459
}
 
2460
 
 
2461
 
2184
2462
/* --------------- perform --------------- */
2185
2463
 
2186
 
 
2187
2464
static PyObject *
2188
2465
do_multi_perform(CurlMultiObject *self)
2189
2466
{
2335
2612
    }
2336
2613
 
2337
2614
    /* Allocate lists. */
2338
 
    if ((read_list = PyList_New(0)) == NULL) goto error;
2339
 
    if ((write_list = PyList_New(0)) == NULL) goto error;
2340
 
    if ((except_list = PyList_New(0)) == NULL) goto error;
 
2615
    if ((read_list = PyList_New((Py_ssize_t)0)) == NULL) goto error;
 
2616
    if ((write_list = PyList_New((Py_ssize_t)0)) == NULL) goto error;
 
2617
    if ((except_list = PyList_New((Py_ssize_t)0)) == NULL) goto error;
2341
2618
 
2342
2619
    /* Populate lists */
2343
2620
    for (fd = 0; fd < max_fd + 1; fd++) {
2394
2671
        return NULL;
2395
2672
    }
2396
2673
 
2397
 
    if ((ok_list = PyList_New(0)) == NULL) goto error;
2398
 
    if ((err_list = PyList_New(0)) == NULL) goto error;
 
2674
    if ((ok_list = PyList_New((Py_ssize_t)0)) == NULL) goto error;
 
2675
    if ((err_list = PyList_New((Py_ssize_t)0)) == NULL) goto error;
2399
2676
 
2400
2677
    /* Loop through all messages */
2401
2678
    while ((msg = curl_multi_info_read(self->multi_handle, &in_queue)) != NULL) {
2539
2816
    {"fdset", (PyCFunction)do_multi_fdset, METH_NOARGS, co_multi_fdset_doc},
2540
2817
    {"info_read", (PyCFunction)do_multi_info_read, METH_VARARGS, co_multi_info_read_doc},
2541
2818
    {"perform", (PyCFunction)do_multi_perform, METH_NOARGS, NULL},
 
2819
    {"socket_all", (PyCFunction)do_multi_socket_all, METH_NOARGS, NULL},
 
2820
    {"setopt", (PyCFunction)do_multi_setopt, METH_VARARGS, NULL},
 
2821
    {"timeout", (PyCFunction)do_multi_timeout, METH_NOARGS, NULL},
 
2822
    {"assign", (PyCFunction)do_multi_assign, METH_VARARGS, NULL},
2542
2823
    {"remove_handle", (PyCFunction)do_multi_remove_handle, METH_VARARGS, NULL},
2543
2824
    {"select", (PyCFunction)do_multi_select, METH_VARARGS, co_multi_select_doc},
2544
2825
    {NULL, NULL, 0, NULL}
2793
3074
    PyObject *ret = NULL;
2794
3075
    PyObject *protocols = NULL;
2795
3076
    PyObject *tmp;
2796
 
    int i;
 
3077
    Py_ssize_t i;
2797
3078
    int stamp = CURLVERSION_NOW;
2798
3079
 
2799
3080
    UNUSED(dummy);
2820
3101
            goto error;
2821
3102
        PyTuple_SET_ITEM(protocols, i, tmp);
2822
3103
    }
2823
 
    ret = PyTuple_New(12);
 
3104
    ret = PyTuple_New((Py_ssize_t)12);
2824
3105
    if (ret == NULL)
2825
3106
        goto error;
2826
3107
 
3025
3306
    insint_c(d, "IOE_UNKNOWNCMD", CURLIOE_UNKNOWNCMD);
3026
3307
    insint_c(d, "IOE_FAILRESTART", CURLIOE_FAILRESTART);
3027
3308
 
 
3309
    /* constants for ioctl callback argument values */
 
3310
    insint_c(d, "IOCMD_NOP", CURLIOCMD_NOP);
 
3311
    insint_c(d, "IOCMD_RESTARTREAD", CURLIOCMD_RESTARTREAD);
 
3312
 
3028
3313
    /* curl_infotype: the kind of data that is passed to information_callback */
3029
3314
/* XXX do we actually need curl_infotype in pycurl ??? */
3030
3315
    insint_c(d, "INFOTYPE_TEXT", CURLINFO_TEXT);
3036
3321
    insint_c(d, "INFOTYPE_SSL_DATA_OUT", CURLINFO_SSL_DATA_OUT);
3037
3322
 
3038
3323
    /* CURLcode: error codes */
3039
 
/* FIXME: lots of error codes are missing */
3040
3324
    insint_c(d, "E_OK", CURLE_OK);
3041
3325
    insint_c(d, "E_UNSUPPORTED_PROTOCOL", CURLE_UNSUPPORTED_PROTOCOL);
 
3326
    insint_c(d, "E_FAILED_INIT", CURLE_FAILED_INIT);
 
3327
    insint_c(d, "E_URL_MALFORMAT", CURLE_URL_MALFORMAT);
 
3328
    insint_c(d, "E_COULDNT_RESOLVE_PROXY", CURLE_COULDNT_RESOLVE_PROXY);
 
3329
    insint_c(d, "E_COULDNT_RESOLVE_HOST", CURLE_COULDNT_RESOLVE_HOST);
 
3330
    insint_c(d, "E_COULDNT_CONNECT", CURLE_COULDNT_CONNECT);
 
3331
    insint_c(d, "E_FTP_WEIRD_SERVER_REPLY", CURLE_FTP_WEIRD_SERVER_REPLY);
 
3332
    insint_c(d, "E_FTP_ACCESS_DENIED", CURLE_FTP_ACCESS_DENIED);
 
3333
    insint_c(d, "E_FTP_WEIRD_PASS_REPLY", CURLE_FTP_WEIRD_PASS_REPLY);
 
3334
    insint_c(d, "E_FTP_WEIRD_USER_REPLY", CURLE_FTP_WEIRD_USER_REPLY);
 
3335
    insint_c(d, "E_FTP_WEIRD_PASV_REPLY", CURLE_FTP_WEIRD_PASV_REPLY);
 
3336
    insint_c(d, "E_FTP_WEIRD_227_FORMAT", CURLE_FTP_WEIRD_227_FORMAT);
 
3337
    insint_c(d, "E_FTP_CANT_GET_HOST", CURLE_FTP_CANT_GET_HOST);
 
3338
    insint_c(d, "E_FTP_CANT_RECONNECT", CURLE_FTP_CANT_RECONNECT);
 
3339
    insint_c(d, "E_FTP_COULDNT_SET_BINARY", CURLE_FTP_COULDNT_SET_BINARY);
 
3340
    insint_c(d, "E_PARTIAL_FILE", CURLE_PARTIAL_FILE);
 
3341
    insint_c(d, "E_FTP_COULDNT_RETR_FILE", CURLE_FTP_COULDNT_RETR_FILE);
 
3342
    insint_c(d, "E_FTP_WRITE_ERROR", CURLE_FTP_WRITE_ERROR);
 
3343
    insint_c(d, "E_FTP_QUOTE_ERROR", CURLE_FTP_QUOTE_ERROR);
 
3344
    insint_c(d, "E_HTTP_RETURNED_ERROR", CURLE_HTTP_RETURNED_ERROR);
 
3345
    insint_c(d, "E_WRITE_ERROR", CURLE_WRITE_ERROR);
 
3346
    insint_c(d, "E_FTP_COULDNT_STOR_FILE", CURLE_FTP_COULDNT_STOR_FILE);
 
3347
    insint_c(d, "E_READ_ERROR", CURLE_READ_ERROR);
 
3348
    insint_c(d, "E_OUT_OF_MEMORY", CURLE_OUT_OF_MEMORY);
 
3349
    insint_c(d, "E_OPERATION_TIMEOUTED", CURLE_OPERATION_TIMEOUTED);
 
3350
    insint_c(d, "E_FTP_COULDNT_SET_ASCII", CURLE_FTP_COULDNT_SET_ASCII);
 
3351
    insint_c(d, "E_FTP_PORT_FAILED", CURLE_FTP_PORT_FAILED);
 
3352
    insint_c(d, "E_FTP_COULDNT_USE_REST", CURLE_FTP_COULDNT_USE_REST);
 
3353
    insint_c(d, "E_FTP_COULDNT_GET_SIZE", CURLE_FTP_COULDNT_GET_SIZE);
 
3354
    insint_c(d, "E_HTTP_RANGE_ERROR", CURLE_HTTP_RANGE_ERROR);
 
3355
    insint_c(d, "E_HTTP_POST_ERROR", CURLE_HTTP_POST_ERROR);
 
3356
    insint_c(d, "E_SSL_CONNECT_ERROR", CURLE_SSL_CONNECT_ERROR);
 
3357
    insint_c(d, "E_BAD_DOWNLOAD_RESUME", CURLE_BAD_DOWNLOAD_RESUME);
 
3358
    insint_c(d, "E_FILE_COULDNT_READ_FILE", CURLE_FILE_COULDNT_READ_FILE);
 
3359
    insint_c(d, "E_LDAP_CANNOT_BIND", CURLE_LDAP_CANNOT_BIND);
 
3360
    insint_c(d, "E_LDAP_SEARCH_FAILED", CURLE_LDAP_SEARCH_FAILED);
 
3361
    insint_c(d, "E_LIBRARY_NOT_FOUND", CURLE_LIBRARY_NOT_FOUND);
 
3362
    insint_c(d, "E_FUNCTION_NOT_FOUND", CURLE_FUNCTION_NOT_FOUND);
 
3363
    insint_c(d, "E_ABORTED_BY_CALLBACK", CURLE_ABORTED_BY_CALLBACK);
 
3364
    insint_c(d, "E_BAD_FUNCTION_ARGUMENT", CURLE_BAD_FUNCTION_ARGUMENT);
 
3365
    insint_c(d, "E_INTERFACE_FAILED", CURLE_INTERFACE_FAILED);
 
3366
    insint_c(d, "E_TOO_MANY_REDIRECTS", CURLE_TOO_MANY_REDIRECTS);
 
3367
    insint_c(d, "E_UNKNOWN_TELNET_OPTION", CURLE_UNKNOWN_TELNET_OPTION);
 
3368
    insint_c(d, "E_TELNET_OPTION_SYNTAX", CURLE_TELNET_OPTION_SYNTAX);
 
3369
    insint_c(d, "E_SSL_PEER_CERTIFICATE", CURLE_SSL_PEER_CERTIFICATE);
 
3370
    insint_c(d, "E_GOT_NOTHING", CURLE_GOT_NOTHING);
 
3371
    insint_c(d, "E_SSL_ENGINE_NOTFOUND", CURLE_SSL_ENGINE_NOTFOUND);
 
3372
    insint_c(d, "E_SSL_ENGINE_SETFAILED", CURLE_SSL_ENGINE_SETFAILED);
 
3373
    insint_c(d, "E_SEND_ERROR", CURLE_SEND_ERROR);
 
3374
    insint_c(d, "E_RECV_ERROR", CURLE_RECV_ERROR);
 
3375
    insint_c(d, "E_SHARE_IN_USE", CURLE_SHARE_IN_USE);
 
3376
    insint_c(d, "E_SSL_CERTPROBLEM", CURLE_SSL_CERTPROBLEM);
 
3377
    insint_c(d, "E_SSL_CIPHER", CURLE_SSL_CIPHER);
 
3378
    insint_c(d, "E_SSL_CACERT", CURLE_SSL_CACERT);
 
3379
    insint_c(d, "E_BAD_CONTENT_ENCODING", CURLE_BAD_CONTENT_ENCODING);
 
3380
    insint_c(d, "E_LDAP_INVALID_URL", CURLE_LDAP_INVALID_URL);
 
3381
    insint_c(d, "E_FILESIZE_EXCEEDED", CURLE_FILESIZE_EXCEEDED);
 
3382
    insint_c(d, "E_FTP_SSL_FAILED", CURLE_FTP_SSL_FAILED);
 
3383
    insint_c(d, "E_SEND_FAIL_REWIND", CURLE_SEND_FAIL_REWIND);
 
3384
    insint_c(d, "E_SSL_ENGINE_INITFAILED", CURLE_SSL_ENGINE_INITFAILED);
 
3385
    insint_c(d, "E_LOGIN_DENIED", CURLE_LOGIN_DENIED);
 
3386
    insint_c(d, "E_TFTP_NOTFOUND", CURLE_TFTP_NOTFOUND);
 
3387
    insint_c(d, "E_TFTP_PERM", CURLE_TFTP_PERM);
 
3388
    insint_c(d, "E_TFTP_DISKFULL",CURLE_TFTP_DISKFULL );
 
3389
    insint_c(d, "E_TFTP_ILLEGAL",CURLE_TFTP_ILLEGAL );
 
3390
    insint_c(d, "E_TFTP_UNKNOWNID",CURLE_TFTP_UNKNOWNID );
 
3391
    insint_c(d, "E_TFTP_EXISTS", CURLE_TFTP_EXISTS);
 
3392
    insint_c(d, "E_TFTP_NOSUCHUSER",CURLE_TFTP_NOSUCHUSER );
 
3393
    insint_c(d, "E_CONV_FAILED",CURLE_CONV_FAILED );
 
3394
    insint_c(d, "E_CONV_REQD",CURLE_CONV_REQD );
 
3395
    insint_c(d, "E_SSL_CACERT_BADFILE", CURLE_SSL_CACERT_BADFILE);
 
3396
    insint_c(d, "E_REMOTE_FILE_NOT_FOUND",CURLE_REMOTE_FILE_NOT_FOUND );
 
3397
    insint_c(d, "E_SSH",CURLE_SSH );
 
3398
    insint_c(d, "E_SSL_SHUTDOWN_FAILED",CURLE_SSL_SHUTDOWN_FAILED );
3042
3399
 
3043
3400
    /* curl_proxytype: constants for setopt(PROXYTYPE, x) */
3044
3401
    insint_c(d, "PROXYTYPE_HTTP", CURLPROXY_HTTP);
3071
3428
    insint_c(d, "FORM_CONTENTTYPE", CURLFORM_CONTENTTYPE);
3072
3429
    insint_c(d, "FORM_FILENAME", CURLFORM_FILENAME);
3073
3430
 
 
3431
    /* FTP_FILEMETHOD options */
 
3432
    insint_c(d, "FTPMETHOD_DEFAULT", CURLFTPMETHOD_DEFAULT);
 
3433
    insint_c(d, "FTPMETHOD_MULTICWD", CURLFTPMETHOD_MULTICWD);
 
3434
    insint_c(d, "FTPMETHOD_NOCWD", CURLFTPMETHOD_NOCWD);
 
3435
    insint_c(d, "FTPMETHOD_SINGLECWD", CURLFTPMETHOD_SINGLECWD);
 
3436
 
3074
3437
    /* CURLoption: symbolic constants for setopt() */
3075
 
/* FIXME: reorder these to match <curl/curl.h> */
 
3438
    /* FIXME: reorder these to match <curl/curl.h> */
3076
3439
    insint_c(d, "FILE", CURLOPT_WRITEDATA);
3077
3440
    insint_c(d, "URL", CURLOPT_URL);
3078
3441
    insint_c(d, "PORT", CURLOPT_PORT);
3137
3500
    insint_c(d, "OPT_FILETIME", CURLOPT_FILETIME);
3138
3501
    insint_c(d, "MAXREDIRS", CURLOPT_MAXREDIRS);
3139
3502
    insint_c(d, "MAXCONNECTS", CURLOPT_MAXCONNECTS);
3140
 
    insint_c(d, "CLOSEPOLICY", CURLOPT_CLOSEPOLICY);
3141
3503
    insint_c(d, "FRESH_CONNECT", CURLOPT_FRESH_CONNECT);
3142
3504
    insint_c(d, "FORBID_REUSE", CURLOPT_FORBID_REUSE);
3143
3505
    insint_c(d, "RANDOM_FILE", CURLOPT_RANDOM_FILE);
3179
3541
    insint_c(d, "FTP_SSL", CURLOPT_FTP_SSL);
3180
3542
    insint_c(d, "POSTFIELDSIZE_LARGE", CURLOPT_POSTFIELDSIZE_LARGE);
3181
3543
    insint_c(d, "TCP_NODELAY", CURLOPT_TCP_NODELAY);
3182
 
    insint_c(d, "SOURCE_USERPWD", CURLOPT_SOURCE_USERPWD);
3183
 
    insint_c(d, "SOURCE_PREQUOTE", CURLOPT_SOURCE_PREQUOTE);
3184
 
    insint_c(d, "SOURCE_POSTQUOTE", CURLOPT_SOURCE_POSTQUOTE);
3185
3544
    insint_c(d, "FTPSSLAUTH", CURLOPT_FTPSSLAUTH);
3186
3545
    insint_c(d, "IOCTLFUNCTION", CURLOPT_IOCTLFUNCTION);
3187
3546
    insint_c(d, "IOCTLDATA", CURLOPT_IOCTLDATA);
3188
 
    insint_c(d, "SOURCE_URL", CURLOPT_SOURCE_URL);
3189
 
    insint_c(d, "SOURCE_QUOTE", CURLOPT_SOURCE_QUOTE);
3190
3547
    insint_c(d, "FTP_ACCOUNT", CURLOPT_FTP_ACCOUNT);
3191
3548
    insint_c(d, "IGNORE_CONTENT_LENGTH", CURLOPT_IGNORE_CONTENT_LENGTH);
3192
3549
    insint_c(d, "COOKIELIST", CURLOPT_COOKIELIST);
3193
3550
    insint_c(d, "FTP_SKIP_PASV_IP", CURLOPT_FTP_SKIP_PASV_IP);
 
3551
    insint_c(d, "FTP_FILEMETHOD", CURLOPT_FTP_FILEMETHOD);
3194
3552
    insint_c(d, "CONNECT_ONLY", CURLOPT_CONNECT_ONLY);
3195
3553
    insint_c(d, "LOCALPORT", CURLOPT_LOCALPORT);
3196
3554
    insint_c(d, "LOCALPORTRANGE", CURLOPT_LOCALPORTRANGE);
3197
3555
    insint_c(d, "FTP_ALTERNATIVE_TO_USER", CURLOPT_FTP_ALTERNATIVE_TO_USER);
3198
3556
    insint_c(d, "MAX_SEND_SPEED_LARGE", CURLOPT_MAX_SEND_SPEED_LARGE);
3199
3557
    insint_c(d, "MAX_RECV_SPEED_LARGE", CURLOPT_MAX_RECV_SPEED_LARGE);
 
3558
    insint_c(d, "SSL_SESSIONID_CACHE", CURLOPT_SSL_SESSIONID_CACHE);
 
3559
    insint_c(d, "SSH_AUTH_TYPES", CURLOPT_SSH_AUTH_TYPES);
 
3560
    insint_c(d, "SSH_PUBLIC_KEYFILE", CURLOPT_SSH_PUBLIC_KEYFILE);
 
3561
    insint_c(d, "SSH_PRIVATE_KEYFILE", CURLOPT_SSH_PRIVATE_KEYFILE);
 
3562
    insint_c(d, "FTP_SSL_CCC", CURLOPT_FTP_SSL_CCC);
 
3563
    insint_c(d, "TIMEOUT_MS", CURLOPT_TIMEOUT_MS);
 
3564
    insint_c(d, "CONNECTTIMEOUT_MS", CURLOPT_CONNECTTIMEOUT_MS);
 
3565
    insint_c(d, "HTTP_TRANSFER_DECODING", CURLOPT_HTTP_TRANSFER_DECODING);
 
3566
    insint_c(d, "HTTP_CONTENT_DECODING", CURLOPT_HTTP_CONTENT_DECODING);
 
3567
 
 
3568
    insint_c(d, "M_TIMERFUNCTION", CURLMOPT_TIMERFUNCTION);
 
3569
    insint_c(d, "M_SOCKETFUNCTION", CURLMOPT_SOCKETFUNCTION);
 
3570
    insint_c(d, "M_PIPELINING", CURLMOPT_PIPELINING);
3200
3571
 
3201
3572
    /* constants for setopt(IPRESOLVE, x) */
3202
3573
    insint_c(d, "IPRESOLVE_WHATEVER", CURL_IPRESOLVE_WHATEVER);
3226
3597
    insint_c(d, "TIMECONDITION_IFUNMODSINCE", CURL_TIMECOND_IFUNMODSINCE);
3227
3598
    insint_c(d, "TIMECONDITION_LASTMOD", CURL_TIMECOND_LASTMOD);
3228
3599
 
 
3600
    /* constants for setopt(CURLOPT_SSH_AUTH_TYPES, x) */
 
3601
    insint_c(d, "SSH_AUTH_ANY", CURLSSH_AUTH_ANY);
 
3602
    insint_c(d, "SSH_AUTH_NONE", CURLSSH_AUTH_NONE);
 
3603
    insint_c(d, "SSH_AUTH_PUBLICKEY", CURLSSH_AUTH_PUBLICKEY);
 
3604
    insint_c(d, "SSH_AUTH_PASSWORD", CURLSSH_AUTH_PASSWORD);
 
3605
    insint_c(d, "SSH_AUTH_HOST", CURLSSH_AUTH_HOST);
 
3606
    insint_c(d, "SSH_AUTH_KEYBOARD", CURLSSH_AUTH_KEYBOARD);
 
3607
    insint_c(d, "SSH_AUTH_DEFAULT", CURLSSH_AUTH_DEFAULT);
 
3608
 
3229
3609
    /* CURLINFO: symbolic constants for getinfo(x) */
3230
3610
    insint_c(d, "EFFECTIVE_URL", CURLINFO_EFFECTIVE_URL);
3231
3611
    insint_c(d, "HTTP_CODE", CURLINFO_HTTP_CODE);
3258
3638
    insint_c(d, "LASTSOCKET", CURLINFO_LASTSOCKET);
3259
3639
    insint_c(d, "FTP_ENTRY_PATH", CURLINFO_FTP_ENTRY_PATH);
3260
3640
 
3261
 
    /* curl_closepolicy: constants for setopt(CLOSEPOLICY, x) */
3262
 
    insint_c(d, "CLOSEPOLICY_OLDEST", CURLCLOSEPOLICY_OLDEST);
3263
 
    insint_c(d, "CLOSEPOLICY_LEAST_RECENTLY_USED", CURLCLOSEPOLICY_LEAST_RECENTLY_USED);
3264
 
    insint_c(d, "CLOSEPOLICY_LEAST_TRAFFIC", CURLCLOSEPOLICY_LEAST_TRAFFIC);
3265
 
    insint_c(d, "CLOSEPOLICY_SLOWEST", CURLCLOSEPOLICY_SLOWEST);
3266
 
    insint_c(d, "CLOSEPOLICY_CALLBACK", CURLCLOSEPOLICY_CALLBACK);
3267
 
 
3268
3641
    /* options for global_init() */
3269
3642
    insint(d, "GLOBAL_SSL", CURL_GLOBAL_SSL);
3270
3643
    insint(d, "GLOBAL_WIN32", CURL_GLOBAL_WIN32);