2013-03-16 03:01:10 +04:00
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd .
Copyright 2013 Zbigniew Jędrzejewski - Szmek < zbyszek @ in . waw . pl >
systemd is free software ; you can redistribute it and / or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation ; either version 2.1 of the License , or
( at your option ) any later version .
systemd is distributed in the hope that it will be useful , but
WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
Lesser General Public License for more details .
You should have received a copy of the GNU Lesser General Public License
along with systemd ; If not , see < http : //www.gnu.org/licenses/>.
* * */
# define PY_SSIZE_T_CLEAN
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wredundant-decls"
# include <Python.h>
# pragma GCC diagnostic pop
# include <stdbool.h>
# include <assert.h>
# include <sys/socket.h>
2014-07-31 12:15:29 +04:00
# include "systemd/sd-daemon.h"
2013-03-16 03:01:10 +04:00
# include "pyutil.h"
2014-02-20 21:35:03 +04:00
# include "macro.h"
2013-03-16 03:01:10 +04:00
PyDoc_STRVAR ( module__doc__ ,
" Python interface to the libsystemd-daemon library. \n \n "
" Provides _listen_fds, notify, booted, and is_* functions \n "
" which wrap sd_listen_fds, sd_notify, sd_booted, sd_is_* and \n "
" useful for socket activation and checking if the system is \n "
" running under systemd. "
) ;
PyDoc_STRVAR ( booted__doc__ ,
" booted() -> bool \n \n "
" Return True iff this system is running under systemd. \n "
" Wraps sd_daemon_booted(3). "
) ;
static PyObject * booted ( PyObject * self , PyObject * args ) {
int r ;
assert ( args = = NULL ) ;
r = sd_booted ( ) ;
2013-11-12 04:53:59 +04:00
if ( set_error ( r , NULL , NULL ) < 0 )
2013-05-10 02:10:30 +04:00
return NULL ;
2013-03-16 03:01:10 +04:00
return PyBool_FromLong ( r ) ;
}
2013-07-06 06:15:54 +04:00
PyDoc_STRVAR ( notify__doc__ ,
" notify(status, unset_environment=False) -> bool \n \n "
" Send a message to the init system about a status change. \n "
" Wraps sd_notify(3). " ) ;
static PyObject * notify ( PyObject * self , PyObject * args , PyObject * keywds ) {
int r ;
const char * msg ;
int unset = false ;
static const char * const kwlist [ ] = {
" status " ,
" unset_environment " ,
NULL ,
} ;
# if PY_MAJOR_VERSION >=3 && PY_MINOR_VERSION >= 3
if ( ! PyArg_ParseTupleAndKeywords ( args , keywds , " s|p:notify " ,
( char * * ) kwlist , & msg , & unset ) )
return NULL ;
# else
PyObject * obj = NULL ;
if ( ! PyArg_ParseTupleAndKeywords ( args , keywds , " s|O:notify " ,
( char * * ) kwlist , & msg , & obj ) )
return NULL ;
if ( obj ! = NULL )
unset = PyObject_IsTrue ( obj ) ;
if ( unset < 0 )
return NULL ;
# endif
r = sd_notify ( unset , msg ) ;
2013-12-30 08:39:28 +04:00
if ( set_error ( r , NULL , NULL ) < 0 )
2013-07-06 06:15:54 +04:00
return NULL ;
return PyBool_FromLong ( r ) ;
}
2013-03-16 03:01:10 +04:00
PyDoc_STRVAR ( listen_fds__doc__ ,
" _listen_fds(unset_environment=True) -> int \n \n "
" Return the number of descriptors passed to this process by the init system \n "
" as part of the socket-based activation logic. \n "
" Wraps sd_listen_fds(3). "
) ;
2013-07-06 06:15:54 +04:00
static PyObject * listen_fds ( PyObject * self , PyObject * args , PyObject * keywds ) {
2013-03-16 03:01:10 +04:00
int r ;
int unset = true ;
2013-07-06 06:15:54 +04:00
static const char * const kwlist [ ] = { " unset_environment " , NULL } ;
2013-03-16 03:01:10 +04:00
# if PY_MAJOR_VERSION >=3 && PY_MINOR_VERSION >= 3
2013-07-06 06:15:54 +04:00
if ( ! PyArg_ParseTupleAndKeywords ( args , keywds , " |p:_listen_fds " ,
( char * * ) kwlist , & unset ) )
2013-03-16 03:01:10 +04:00
return NULL ;
# else
PyObject * obj = NULL ;
2013-07-06 06:15:54 +04:00
if ( ! PyArg_ParseTupleAndKeywords ( args , keywds , " |O:_listen_fds " ,
2013-12-30 09:01:00 +04:00
( char * * ) kwlist , & obj ) )
2013-03-16 03:01:10 +04:00
return NULL ;
if ( obj ! = NULL )
unset = PyObject_IsTrue ( obj ) ;
if ( unset < 0 )
return NULL ;
# endif
r = sd_listen_fds ( unset ) ;
2013-12-30 08:39:28 +04:00
if ( set_error ( r , NULL , NULL ) < 0 )
2013-05-10 02:10:30 +04:00
return NULL ;
2013-03-16 03:01:10 +04:00
return long_FromLong ( r ) ;
}
PyDoc_STRVAR ( is_fifo__doc__ ,
" _is_fifo(fd, path) -> bool \n \n "
" Returns True iff the descriptor refers to a FIFO or a pipe. \n "
" Wraps sd_is_fifo(3). "
) ;
static PyObject * is_fifo ( PyObject * self , PyObject * args ) {
int r ;
int fd ;
const char * path = NULL ;
# if PY_MAJOR_VERSION >=3 && PY_MINOR_VERSION >= 1
if ( ! PyArg_ParseTuple ( args , " i|O&:_is_fifo " ,
& fd , Unicode_FSConverter , & path ) )
return NULL ;
# else
if ( ! PyArg_ParseTuple ( args , " i|z:_is_fifo " , & fd , & path ) )
return NULL ;
# endif
r = sd_is_fifo ( fd , path ) ;
2013-12-30 08:39:28 +04:00
if ( set_error ( r , path , NULL ) < 0 )
2013-05-10 02:10:30 +04:00
return NULL ;
2013-03-16 03:01:10 +04:00
return PyBool_FromLong ( r ) ;
}
PyDoc_STRVAR ( is_mq__doc__ ,
" _is_mq(fd, path) -> bool \n \n "
" Returns True iff the descriptor refers to a POSIX message queue. \n "
" Wraps sd_is_mq(3). "
) ;
static PyObject * is_mq ( PyObject * self , PyObject * args ) {
int r ;
int fd ;
const char * path = NULL ;
# if PY_MAJOR_VERSION >=3 && PY_MINOR_VERSION >= 1
if ( ! PyArg_ParseTuple ( args , " i|O&:_is_mq " ,
& fd , Unicode_FSConverter , & path ) )
return NULL ;
# else
if ( ! PyArg_ParseTuple ( args , " i|z:_is_mq " , & fd , & path ) )
return NULL ;
# endif
r = sd_is_mq ( fd , path ) ;
2013-12-30 08:39:28 +04:00
if ( set_error ( r , path , NULL ) < 0 )
2013-05-10 02:10:30 +04:00
return NULL ;
2013-03-16 03:01:10 +04:00
return PyBool_FromLong ( r ) ;
}
PyDoc_STRVAR ( is_socket__doc__ ,
" _is_socket(fd, family=AF_UNSPEC, type=0, listening=-1) -> bool \n \n "
" Returns True iff the descriptor refers to a socket. \n "
" Wraps sd_is_socket(3). \n \n "
" Constants for `family` are defined in the socket module. "
) ;
static PyObject * is_socket ( PyObject * self , PyObject * args ) {
int r ;
int fd , family = AF_UNSPEC , type = 0 , listening = - 1 ;
if ( ! PyArg_ParseTuple ( args , " i|iii:_is_socket " ,
& fd , & family , & type , & listening ) )
return NULL ;
r = sd_is_socket ( fd , family , type , listening ) ;
2013-12-30 08:39:28 +04:00
if ( set_error ( r , NULL , NULL ) < 0 )
2013-05-10 02:10:30 +04:00
return NULL ;
2013-03-16 03:01:10 +04:00
return PyBool_FromLong ( r ) ;
}
PyDoc_STRVAR ( is_socket_inet__doc__ ,
" _is_socket_inet(fd, family=AF_UNSPEC, type=0, listening=-1, port=0) -> bool \n \n "
" Wraps sd_is_socket_inet(3). \n \n "
" Constants for `family` are defined in the socket module. "
) ;
static PyObject * is_socket_inet ( PyObject * self , PyObject * args ) {
int r ;
int fd , family = AF_UNSPEC , type = 0 , listening = - 1 , port = 0 ;
if ( ! PyArg_ParseTuple ( args , " i|iiii:_is_socket_inet " ,
& fd , & family , & type , & listening , & port ) )
return NULL ;
2013-05-10 02:10:30 +04:00
if ( port < 0 | | port > INT16_MAX ) {
set_error ( - EINVAL , NULL , " port must fit into uint16_t " ) ;
return NULL ;
}
2013-03-16 03:01:10 +04:00
r = sd_is_socket_inet ( fd , family , type , listening , ( uint16_t ) port ) ;
2013-12-30 08:39:28 +04:00
if ( set_error ( r , NULL , NULL ) < 0 )
2013-05-10 02:10:30 +04:00
return NULL ;
2013-03-16 03:01:10 +04:00
return PyBool_FromLong ( r ) ;
}
PyDoc_STRVAR ( is_socket_unix__doc__ ,
" _is_socket_unix(fd, type, listening, path) -> bool \n \n "
" Wraps sd_is_socket_unix(3). "
) ;
static PyObject * is_socket_unix ( PyObject * self , PyObject * args ) {
int r ;
int fd , type = 0 , listening = - 1 ;
char * path = NULL ;
Py_ssize_t length = 0 ;
# if PY_MAJOR_VERSION >=3 && PY_MINOR_VERSION >= 1
2013-04-18 11:11:22 +04:00
_cleanup_Py_DECREF_ PyObject * _path = NULL ;
2013-03-16 03:01:10 +04:00
if ( ! PyArg_ParseTuple ( args , " i|iiO&:_is_socket_unix " ,
& fd , & type , & listening , Unicode_FSConverter , & _path ) )
return NULL ;
if ( _path ) {
assert ( PyBytes_Check ( _path ) ) ;
if ( PyBytes_AsStringAndSize ( _path , & path , & length ) )
return NULL ;
}
# else
if ( ! PyArg_ParseTuple ( args , " i|iiz#:_is_socket_unix " ,
& fd , & type , & listening , & path , & length ) )
return NULL ;
# endif
r = sd_is_socket_unix ( fd , type , listening , path , length ) ;
2013-12-30 08:39:28 +04:00
if ( set_error ( r , path , NULL ) < 0 )
2013-05-10 02:10:30 +04:00
return NULL ;
2013-03-16 03:01:10 +04:00
return PyBool_FromLong ( r ) ;
}
static PyMethodDef methods [ ] = {
{ " booted " , booted , METH_NOARGS , booted__doc__ } ,
2013-07-06 06:15:54 +04:00
{ " notify " , ( PyCFunction ) notify , METH_VARARGS | METH_KEYWORDS , notify__doc__ } ,
{ " _listen_fds " , ( PyCFunction ) listen_fds , METH_VARARGS | METH_KEYWORDS , listen_fds__doc__ } ,
2013-03-16 03:01:10 +04:00
{ " _is_fifo " , is_fifo , METH_VARARGS , is_fifo__doc__ } ,
{ " _is_mq " , is_mq , METH_VARARGS , is_mq__doc__ } ,
{ " _is_socket " , is_socket , METH_VARARGS , is_socket__doc__ } ,
{ " _is_socket_inet " , is_socket_inet , METH_VARARGS , is_socket_inet__doc__ } ,
{ " _is_socket_unix " , is_socket_unix , METH_VARARGS , is_socket_unix__doc__ } ,
{ NULL , NULL , 0 , NULL } /* Sentinel */
} ;
# if PY_MAJOR_VERSION < 3
2014-02-20 21:35:03 +04:00
DISABLE_WARNING_MISSING_PROTOTYPES ;
2013-03-16 03:01:10 +04:00
PyMODINIT_FUNC init_daemon ( void ) {
PyObject * m ;
m = Py_InitModule3 ( " _daemon " , methods , module__doc__ ) ;
if ( m = = NULL )
return ;
PyModule_AddIntConstant ( m , " LISTEN_FDS_START " , SD_LISTEN_FDS_START ) ;
2013-05-09 05:08:14 +04:00
PyModule_AddStringConstant ( m , " __version__ " , PACKAGE_VERSION ) ;
2013-03-16 03:01:10 +04:00
}
2014-02-20 21:35:03 +04:00
REENABLE_WARNING ;
2013-03-16 03:01:10 +04:00
# else
static struct PyModuleDef module = {
PyModuleDef_HEAD_INIT ,
" _daemon " , /* name of module */
module__doc__ , /* module documentation, may be NULL */
0 , /* size of per-interpreter state of the module */
methods
} ;
2014-02-20 21:35:03 +04:00
DISABLE_WARNING_MISSING_PROTOTYPES ;
2013-03-16 03:01:10 +04:00
PyMODINIT_FUNC PyInit__daemon ( void ) {
PyObject * m ;
m = PyModule_Create ( & module ) ;
if ( m = = NULL )
return NULL ;
2013-05-09 05:08:14 +04:00
if ( PyModule_AddIntConstant ( m , " LISTEN_FDS_START " , SD_LISTEN_FDS_START ) | |
PyModule_AddStringConstant ( m , " __version__ " , PACKAGE_VERSION ) ) {
2013-03-16 03:01:10 +04:00
Py_DECREF ( m ) ;
return NULL ;
}
return m ;
}
2014-02-20 21:35:03 +04:00
REENABLE_WARNING ;
2013-03-16 03:01:10 +04:00
# endif