aboutsummaryrefslogtreecommitdiffstats
path: root/src/native_bus.pyx
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/native_bus.pyx160
1 files changed, 158 insertions, 2 deletions
diff --git a/src/native_bus.pyx b/src/native_bus.pyx
index fdcf341..c3c4039 100644
--- a/src/native_bus.pyx
+++ b/src/native_bus.pyx
@@ -26,6 +26,7 @@ DEALINGS IN THE SOFTWARE.
cimport cython
from libc.stdlib cimport malloc, free
+from posix.types cimport uid_t, gid_t, mode_t
cdef extern int bus_create(const char *, int, char **)
@@ -98,6 +99,71 @@ Listen (in a loop, forever) for new message on a bus
@return 0 on success, -1 on error
'''
+cdef extern int bus_poll_start(long, int)
+'''
+Announce that the thread is listening on the bus.
+This is required so the will does not miss any
+messages due to race conditions. Additionally,
+not calling this function will cause the bus the
+misbehave, is `bus_poll` is written to expect
+this function to have been called.
+
+@param bus Bus information
+@param flags `BUS_NOWAIT` if the bus should fail and set `errno` to
+ `EAGAIN` if there isn't already a message available on
+ the bus when `bus_poll` is called
+@return 0 on success, -1 on error
+'''
+
+cdef extern int bus_poll_stop(long)
+'''
+Announce that the thread has stopped listening on the bus.
+This is required so that the thread does not cause others
+to wait indefinitely.
+
+@param bus Bus information
+@return 0 on success, -1 on error
+'''
+
+cdef extern const char *bus_poll(long)
+'''
+Wait for a message to be broadcasted on the bus.
+The caller should make a copy of the received message,
+without freeing the original copy, and parse it in a
+separate thread. When the new thread has started be
+started, the caller of this function should then
+either call `bus_poll` again or `bus_poll_stop`.
+
+@param bus Bus information
+@return The received message, `NULL` on error
+'''
+
+cdef extern int bus_chown(const char *, uid_t, gid_t)
+'''
+Change the ownership of a bus
+
+`stat(2)` can be used of the bus's associated file to get the bus's ownership
+
+@param file The pathname of the bus
+@param owner The user ID of the bus's new owner
+@param group The group ID of the bus's new group
+@return 0 on success, -1 on error
+'''
+
+cdef extern int bus_chmod(const char *, mode_t)
+'''
+Change the permissions for a bus
+
+`stat(2)` can be used of the bus's associated file to get the bus's permissions
+
+@param file The pathname of the bus
+@param mode The permissions of the bus, any permission for a user implies
+ full permissions for that user, except only the owner may
+ edit the bus's associated file
+@return 0 on success, -1 on error
+'''
+
+
def bus_allocate() -> int:
'''
@@ -193,8 +259,8 @@ def bus_write_wrapped(bus : int, message : str, flags : int) -> int:
@param bus Bus information
@param message The message to write, may not be longer than
`BUS_MEMORY_SIZE` including the NUL-termination
- @param flags `BUS_NOWAIT` fail if other process is attempting
- to write
+ @param flags `BUS_NOWAIT` fail with errno set to `os.errno.EAGAIN`
+ if other process is attempting to write
@return 0 on success, -1 on error
'''
cdef const char* cmessage
@@ -234,3 +300,93 @@ def bus_read_wrapped(bus : int, callback : callable, user_data) -> int:
user = (callback, user_data)
return bus_read(<long>bus, <int (*)(const char *, void *)>&bus_callback_wrapper, <void *>user)
+
+def bus_poll_start_wrapped(bus : int, flags : int) -> int:
+ '''
+ Announce that the thread is listening on the bus.
+ This is required so the will does not miss any
+ messages due to race conditions. Additionally,
+ not calling this function will cause the bus the
+ misbehave, is `bus_poll_wrapped` is written to expect
+ this function to have been called.
+
+ @param bus Bus information
+ @param flags `BUS_NOWAIT` if the bus should fail and set `errno` to
+ `os.errno.EAGAIN` if there isn't already a message
+ available on
+ the bus when `bus_poll` is called
+ @return 0 on success, -1 on error
+ '''
+ return bus_poll_start(<long>bus, <int>flags)
+
+
+def bus_poll_stop_wrapped(bus : int) -> int:
+ '''
+ Announce that the thread has stopped listening on the bus.
+ This is required so that the thread does not cause others
+ to wait indefinitely.
+
+ @param bus Bus information
+ @return 0 on success, -1 on error
+ '''
+ return bus_poll_stop(<long>bus)
+
+
+def bus_poll_wrapped(bus : int) -> str:
+ '''
+ Wait for a message to be broadcasted on the bus.
+ The caller should make a copy of the received message,
+ without freeing the original copy, and parse it in a
+ separate thread. When the new thread has started be
+ started, the caller of this function should then
+ either call `bus_poll_wrapped` again or
+ `bus_poll_stop_wrapped`.
+
+ @param bus Bus information
+ @return The received message, `None` on error
+ '''
+ cdef const char* msg
+ cdef bytes bs
+ msg = bus_poll(<long>bus)
+ if msg is NULL:
+ return None
+ bs = msg
+ return bs.decode('utf-8', 'strict')
+
+
+def bus_chown_wrapped(file : str, owner : int, group : int) -> int:
+ '''
+ Change the ownership of a bus
+
+ `os.stat` can be used of the bus's associated file to get the bus's ownership
+
+ @param file The pathname of the bus
+ @param owner The user ID of the bus's new owner
+ @param group The group ID of the bus's new group
+ @return 0 on success, -1 on error
+ '''
+ cdef const char* cfile
+ cdef bytes bs
+ bs = file.encode('utf-8') + bytes([0])
+ cfile = bs
+ return bus_chown(cfile, <uid_t>owner, <gid_t>group)
+
+
+def bus_chmod_wrapped(file : str, mode : int) -> int:
+ '''
+ Change the permissions for a bus
+
+ `os.stat` can be used of the bus's associated file to get the bus's permissions
+
+ @param file The pathname of the bus
+ @param mode The permissions of the bus, any permission for a user implies
+ full permissions for that user, except only the owner may
+ edit the bus's associated file
+ @return 0 on success, -1 on error
+ '''
+ cdef const char* cfile
+ cdef bytes bs
+ bs = file.encode('utf-8') + bytes([0])
+ cfile = bs
+ return bus_chmod(cfile, <mode_t>mode)
+