@@ -161,6 +161,57 @@ static int strv_converter(PyObject* obj, void *_result) {
161161 return 0 ;
162162}
163163
164+ static int long_as_fd (PyObject * obj , int * fd ) {
165+ long num = long_AsLong (obj );
166+ if (PyErr_Occurred ())
167+ return -1 ;
168+
169+ if ((int ) num != num ) {
170+ PyErr_SetString (PyExc_OverflowError , "Value too large" );
171+ return -1 ;
172+ }
173+
174+ * fd = (int ) num ;
175+ return 0 ;
176+ }
177+
178+ /**
179+ * Convert a Python sequence object into an int array.
180+ */
181+ static int intlist_converter (PyObject * obj , int * * _result , size_t * _len ) {
182+ _cleanup_free_ int * result = NULL ;
183+ Py_ssize_t i , len ;
184+
185+ assert (_result );
186+ assert (_len );
187+
188+ if (!PySequence_Check (obj ))
189+ return 0 ;
190+
191+ len = PySequence_Length (obj );
192+ result = new0 (int , len );
193+ if (!result ) {
194+ set_error (- ENOMEM , NULL , NULL );
195+ return 0 ;
196+ }
197+
198+ for (i = 0 ; i < len ; i ++ ) {
199+ PyObject * item ;
200+ int fd ;
201+
202+ item = PySequence_ITEM (obj , i );
203+ if (long_as_fd (item , & fd ) < 0 )
204+ return 0 ;
205+
206+ result [i ] = fd ;
207+ }
208+
209+ * _result = result ;
210+ * _len = len ;
211+ result = NULL ;
212+ return 1 ;
213+ }
214+
164215static void Reader_dealloc (Reader * self ) {
165216 sd_journal_close (self -> j );
166217 Py_TYPE (self )-> tp_free ((PyObject * )self );
@@ -185,36 +236,31 @@ PyDoc_STRVAR(Reader__doc__,
185236 "exiting the block." );
186237static int Reader_init (Reader * self , PyObject * args , PyObject * keywds ) {
187238 int flags = 0 , r ;
188- PyObject * _path = NULL ;
189- _cleanup_strv_free_ char * * files = NULL ;
239+ PyObject * _path = NULL , * _files = NULL ;
190240
191241 static const char * const kwlist [] = {"flags" , "path" , "files" , NULL };
192242 if (!PyArg_ParseTupleAndKeywords (args , keywds , "|iO&O&:__init__" , (char * * ) kwlist ,
193243 & flags ,
194244 null_converter , & _path ,
195- strv_converter , & files ))
245+ null_converter , & _files ))
196246 return -1 ;
197247
198- if (!!flags + !!_path + !!files > 1 ) {
248+ if (!!flags + !!_path + !!_files > 1 ) {
199249 PyErr_SetString (PyExc_ValueError ,
200250 "cannot use more than one of flags, path, and files" );
201251 return -1 ;
202252 }
203253
204254 if (_path ) {
205255 if (long_Check (_path )) {
206- long directory_fd = long_AsLong (_path );
207- if (PyErr_Occurred ())
208- return -1 ;
256+ int fd ;
209257
210- if ((int ) directory_fd != directory_fd ) {
211- PyErr_SetString (PyExc_OverflowError , "Value too large" );
258+ if (long_as_fd (_path , & fd ) < 0 )
212259 return -1 ;
213- }
214260
215261#ifdef HAVE_JOURNAL_OPEN_DIRECTORY_FD
216262 Py_BEGIN_ALLOW_THREADS
217- r = sd_journal_open_directory_fd (& self -> j , (int ) directory_fd , 0 );
263+ r = sd_journal_open_directory_fd (& self -> j , (int ) fd , 0 );
218264 Py_END_ALLOW_THREADS
219265#else
220266 r = - ENOSYS ;
@@ -231,11 +277,31 @@ static int Reader_init(Reader *self, PyObject *args, PyObject *keywds) {
231277 r = sd_journal_open_directory (& self -> j , path , 0 );
232278 Py_END_ALLOW_THREADS
233279 }
234- } else if (files ) {
280+ } else if (_files ) {
235281#ifdef HAVE_JOURNAL_OPEN_FILES
236- Py_BEGIN_ALLOW_THREADS
237- r = sd_journal_open_files (& self -> j , (const char * * ) files , 0 );
238- Py_END_ALLOW_THREADS
282+ _cleanup_Py_DECREF_ PyObject * item0 = NULL ;
283+
284+ item0 = PySequence_GetItem (_files , 0 );
285+ if (item0 == NULL || !PyLong_Check (item0 )) {
286+ _cleanup_strv_free_ char * * files = NULL ;
287+
288+ if (!strv_converter (_files , & files ))
289+ return -1 ;
290+
291+ Py_BEGIN_ALLOW_THREADS
292+ r = sd_journal_open_files (& self -> j , (const char * * ) files , 0 );
293+ Py_END_ALLOW_THREADS
294+ } else {
295+ _cleanup_free_ int * fds = NULL ;
296+ size_t n_fds ;
297+
298+ if (!intlist_converter (_files , & fds , & n_fds ))
299+ return -1 ;
300+
301+ Py_BEGIN_ALLOW_THREADS
302+ r = sd_journal_open_files_fd (& self -> j , fds , n_fds , 0 );
303+ Py_END_ALLOW_THREADS
304+ }
239305#else
240306 r = - ENOSYS ;
241307#endif
0 commit comments