]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/unbound/libunbound/python/file_py3.i
Fix IPv6 socket option race condition and use after free.
[FreeBSD/FreeBSD.git] / contrib / unbound / libunbound / python / file_py3.i
1 /*
2  * file_py3.i: Typemaps for FILE* for Python 3
3  *
4  * Copyright (c) 2011, Karel Slany (karel.slany AT nic.cz)
5  * All rights reserved.
6  * 
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  * 
10  *     * Redistributions of source code must retain the above copyright notice,
11  *       this list of conditions and the following disclaimer.
12  *     * Redistributions in binary form must reproduce the above copyright
13  *       notice, this list of conditions and the following disclaimer in the
14  *       documentation and/or other materials provided with the distribution.
15  *     * Neither the name of the organization nor the names of its
16  *       contributors may be used to endorse or promote products derived from this
17  *       software without specific prior written permission.
18  * 
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 %{
33 #include <unistd.h>
34 #include <fcntl.h>
35 %}
36
37 %types(FILE *);
38
39 //#define SWIG_FILE3_DEBUG
40
41 /* converts basic file descriptor flags onto a string */
42 %fragment("fdfl_to_str", "header") {
43 const char *
44 fdfl_to_str(int fdfl) {
45
46   static const char * const file_mode[] = {"w+", "w", "r"};
47
48   if (fdfl & O_RDWR) {
49     return file_mode[0];
50   } else if (fdfl & O_WRONLY) {
51     return file_mode[1];
52   } else {
53     return file_mode[2];
54   }
55 }
56 }
57
58 %fragment("is_obj_file", "header") {
59 int
60 is_obj_file(PyObject *obj) {
61   int fd, fdfl;
62   if (!PyLong_Check(obj) &&                                /* is not an integer */
63       PyObject_HasAttrString(obj, "fileno") &&             /* has fileno method */
64       (PyObject_CallMethod(obj, "flush", NULL) != NULL) && /* flush() succeeded */
65       ((fd = PyObject_AsFileDescriptor(obj)) != -1) &&     /* got file descriptor */
66       ((fdfl = fcntl(fd, F_GETFL)) != -1)                  /* got descriptor flags */
67     ) {
68     return 1;
69   }
70   else {
71     return 0;
72   }
73 }
74 }
75
76 %fragment("obj_to_file","header", fragment="fdfl_to_str,is_obj_file") {
77 FILE *
78 obj_to_file(PyObject *obj) {
79   int fd, fdfl;
80   FILE *fp;
81   if (is_obj_file(obj)) {
82     fd = PyObject_AsFileDescriptor(obj);
83     fdfl = fcntl(fd, F_GETFL);
84     fp = fdopen(dup(fd), fdfl_to_str(fdfl)); /* the FILE* must be flushed
85                                                 and closed after being used */
86 #ifdef SWIG_FILE3_DEBUG
87     fprintf(stderr, "opening fd %d (fl %d \"%s\") as FILE %p\n",
88             fd, fdfl, fdfl_to_str(fdfl), (void *)fp);
89 #endif
90     return fp;
91   }
92   return NULL;
93 }
94 }
95
96 /* returns -1 if error occurred */
97 /* caused magic SWIG Syntax errors when was commented out */
98 #if 0
99 %fragment("dispose_file", "header") {
100 int
101 dispose_file(FILE **fp) {
102 #ifdef SWIG_FILE3_DEBUG
103   fprintf(stderr, "flushing FILE %p\n", (void *)fp);
104 #endif
105   if (*fp == NULL) {
106     return 0;
107   }
108   if ((fflush(*fp) == 0) &&  /* flush file */
109       (fclose(*fp) == 0)) {  /* close file */
110     *fp = NULL;
111     return 0;
112   }
113   return -1;
114 }
115 }
116 #endif
117
118 %typemap(arginit, noblock = 1) FILE* {
119   $1 = NULL;
120 }
121
122 /*
123  * added due to ub_ctx_debugout since since it is overloaded:
124  * takes void* and FILE*. In reality only FILE* but the wrapper
125  * and the function is declared in such way.
126  */
127 %typemap(typecheck, noblock = 1, fragment = "is_obj_file", precedence = SWIG_TYPECHECK_POINTER) FILE* {
128   $1 = is_obj_file($input);
129 }
130
131 %typemap(check, noblock = 1) FILE* {
132   if ($1 == NULL) {
133     /* The generated wrapper function raises TypeError on mismatching types. */
134     SWIG_exception_fail(SWIG_TypeError, "in method '" "$symname" "', argument "
135                         "$argnum"" of type '" "$type""'");
136   }
137 }
138
139 %typemap(in, noblock = 1, fragment = "obj_to_file") FILE* {
140   $1 = obj_to_file($input);
141 }
142
143 /*
144  * Commented out due the way how ub_ctx_debugout() uses the parameter.
145  * This typemap would cause the FILE* to be closed after return from
146  * the function. This caused Python interpreter to crash, since the
147  * function just stores the FILE* internally in ctx and use it for
148  * logging. So we'll leave the closing of the file on the OS.
149  */
150 /*%typemap(freearg, noblock = 1, fragment = "dispose_file") FILE* {
151   if (dispose_file(&$1) == -1) {
152     SWIG_exception_fail(SWIG_IOError, "closing file in method '" "$symname" "', argument "
153                         "$argnum"" of type '" "$type""'");
154   }
155 }*/