blob: e634b01eaf729545480c65e5b6b1bc6a9c92b2dd [file] [log] [blame]
Jean-Paul Calderone897bc252008-02-18 20:50:23 -05001/*
2 * util.h
3 *
Jean-Paul Calderone8671c852011-03-02 19:26:20 -05004 * Copyright (C) AB Strakt
5 * See LICENSE for details.
Jean-Paul Calderone897bc252008-02-18 20:50:23 -05006 *
7 * Export utility functions and macros.
8 * See the file RATIONALE for a short explanation of why this module was written.
9 *
10 * Reviewed 2001-07-23
11 *
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050012 */
13#ifndef PyOpenSSL_UTIL_H_
14#define PyOpenSSL_UTIL_H_
15
16#include <Python.h>
17#include <openssl/err.h>
18
19/*
20 * pymemcompat written by Michael Hudson and lets you program to the
Jean-Paul Calderone40b32a22010-01-27 16:56:44 -050021 * Python 2.3 memory API while keeping backwards compatibility.
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050022 */
23#include "pymemcompat.h"
24
Jean-Paul Calderoneef853eb2010-08-10 19:47:06 -040025/*
26 * py3k defines macros that help with Python 2.x/3.x compatibility.
27 */
28#include "py3k.h"
29
30
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050031extern PyObject *error_queue_to_list(void);
Rick Deand369c932009-07-08 11:48:33 -050032extern void exception_from_error_queue(PyObject *the_Error);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050033extern void flush_error_queue(void);
34
35/*
36 * These are needed because there is no "official" way to specify
37 * WHERE to save the thread state.
38 */
39#ifdef WITH_THREAD
Jean-Paul Calderone00db9da2008-09-21 17:42:34 -040040
41/*
42 * Get the current Python threadstate and put it somewhere any code running
43 * in this thread can get it, if it needs to restore the threadstate to run
44 * some Python.
45 */
46# define MY_BEGIN_ALLOW_THREADS(ignored) \
Jean-Paul Calderoned3feb012009-03-22 12:21:17 -040047 PyThread_delete_key_value(_pyOpenSSL_tstate_key); \
Jean-Paul Calderone00db9da2008-09-21 17:42:34 -040048 PyThread_set_key_value(_pyOpenSSL_tstate_key, PyEval_SaveThread());
49
50/*
51 * Get the previous Python threadstate and restore it.
52 */
53# define MY_END_ALLOW_THREADS(ignored) \
54 PyEval_RestoreThread(PyThread_get_key_value(_pyOpenSSL_tstate_key));
55
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050056#else
57# define MY_BEGIN_ALLOW_THREADS(st)
58# define MY_END_ALLOW_THREADS(st) { st = NULL; }
59#endif
60
61#if !defined(PY_MAJOR_VERSION) || PY_VERSION_HEX < 0x02000000
62static int
63PyModule_AddObject(PyObject *m, char *name, PyObject *o)
64{
65 PyObject *dict;
66 if (!PyModule_Check(m) || o == NULL)
67 return -1;
68 dict = PyModule_GetDict(m);
69 if (dict == NULL)
70 return -1;
71 if (PyDict_SetItemString(dict, name, o))
72 return -1;
73 Py_DECREF(o);
74 return 0;
75}
76
77static int
78PyModule_AddIntConstant(PyObject *m, char *name, long value)
79{
80 return PyModule_AddObject(m, name, PyInt_FromLong(value));
81}
82
83static int PyObject_AsFileDescriptor(PyObject *o)
84{
85 int fd;
86 PyObject *meth;
87
88 if (PyInt_Check(o)) {
89 fd = PyInt_AsLong(o);
90 }
91 else if (PyLong_Check(o)) {
92 fd = PyLong_AsLong(o);
93 }
94 else if ((meth = PyObject_GetAttrString(o, "fileno")) != NULL)
95 {
96 PyObject *fno = PyEval_CallObject(meth, NULL);
97 Py_DECREF(meth);
98 if (fno == NULL)
99 return -1;
100
101 if (PyInt_Check(fno)) {
102 fd = PyInt_AsLong(fno);
103 Py_DECREF(fno);
104 }
105 else if (PyLong_Check(fno)) {
106 fd = PyLong_AsLong(fno);
107 Py_DECREF(fno);
108 }
109 else {
110 PyErr_SetString(PyExc_TypeError, "fileno() returned a non-integer");
111 Py_DECREF(fno);
112 return -1;
113 }
114 }
115 else {
116 PyErr_SetString(PyExc_TypeError, "argument must be an int, or have a fileno() method.");
117 return -1;
118 }
119
120 if (fd < 0) {
121 PyErr_Format(PyExc_ValueError, "file descriptor cannot be a negative integer (%i)", fd);
122 return -1;
123 }
124 return fd;
125}
126#endif
127
Ziga Seilnacht679c4262009-09-01 01:32:29 +0200128#if !defined(PY_SSIZE_T_MIN)
129typedef int Py_ssize_t;
130#define PY_SSIZE_T_MAX INT_MAX
131#define PY_SSIZE_T_MIN INT_MIN
132#endif
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500133
Jean-Paul Calderonedd467fb2010-08-12 20:44:32 -0400134#if (PY_VERSION_HEX < 0x02600000)
Jean-Paul Calderonea5a032f2010-08-12 20:03:32 -0400135extern PyObject* PyOpenSSL_LongToHex(PyObject *o);
136#else
137#define PyOpenSSL_LongToHex(o) PyNumber_ToBase(o, 16)
138#endif
139
Jean-Paul Calderone5163f572011-04-22 18:38:16 -0400140#ifndef Py_TYPE
141#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
142#endif
143
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500144#endif