aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2021-02-19 20:30:41 +0100
committerMattias Andrée <maandree@kth.se>2021-02-19 20:30:49 +0100
commitc27fd70b5e4c3efe5ad034069108414d36f9bd9e (patch)
treeec0befb659ebeca4a68c45b052e713fb2ad26f05 /src
parentimprove readme (diff)
downloadpython-bus-c27fd70b5e4c3efe5ad034069108414d36f9bd9e.tar.gz
python-bus-c27fd70b5e4c3efe5ad034069108414d36f9bd9e.tar.bz2
python-bus-c27fd70b5e4c3efe5ad034069108414d36f9bd9e.tar.xz
some improvments + license change3.1.2
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'src')
-rw-r--r--src/bus.py399
-rw-r--r--src/native_bus.pyx579
2 files changed, 0 insertions, 978 deletions
diff --git a/src/bus.py b/src/bus.py
deleted file mode 100644
index 08e8a9b..0000000
--- a/src/bus.py
+++ /dev/null
@@ -1,399 +0,0 @@
-# -*- python -*-
-'''
-MIT/X Consortium License
-
-Copyright © 2015 Mattias Andrée <maandree@member.fsf.org>
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-'''
-
-
-class Bus:
- '''
- Message broadcasting interprocess communication
- '''
-
-
- RDONLY = 1
- '''
- Open the bus for reading only
- '''
-
- WRONLY = 0
- '''
- Open the bus for writing only
- '''
-
- RDWR = 0
- '''
- Open the bus for both reading and writing only
- '''
-
- EXCL = 2
- '''
- Fail to create bus if its file already exists
- '''
-
- INTR = 4
- '''
- Fail if interrupted
- '''
-
- NOWAIT = 1
- '''
- Function shall fail with `os.errno.EAGAIN`
- if the it would block and this flag is used
- '''
-
-
- def __init__(self, pathname : str = None):
- '''
- Constructor
-
- @param pathname:str The pathname of the bus, `None` if `create` should select a random pathname
- '''
- self.pathname = pathname
- self.bus = None
-
-
- def __del__(self):
- '''
- Destructor
- '''
- self.close()
-
-
- def create(self, flags : int = 0) -> str:
- '''
- Create the bus
-
- @param flags:or_flag `Bus.EXCL` (if the pathname is not `None`) to fail if the file
- already exists, otherwise if the file exists, nothing will happen;
- `Bus.INTR` to fail if interrupted
- @return :str The pathname of the bus
- '''
- from native_bus import bus_create_wrapped
- (self.pathname, e) = bus_create_wrapped(self.pathname, flags)
- if self.pathname is None:
- raise self.__oserror(e)
- return self.pathname
-
-
- def unlink(self):
- '''
- Remove the bus
- '''
- from native_bus import bus_unlink_wrapped
- (r, e) = bus_unlink_wrapped(self.pathname)
- if r == -1:
- raise self.__oserror(e)
-
-
- def open(self, flags : int = 0):
- '''
- Open an existing bus
-
- @param flags:int `Bus.RDONLY`, `Bus.WRONLY` or `Bus.RDWR`, the value must not be negative
- '''
- from native_bus import bus_close_wrapped, bus_allocate, bus_open_wrapped
- if self.bus is not None:
- (r, e) = bus_close_wrapped(self.bus)
- if r == -1:
- raise self.__oserror(e)
- else:
- (self.bus, e) = bus_allocate()
- if self.bus == 0:
- raise self.__oserror(e)
- (r, e) = bus_open_wrapped(self.bus, self.pathname, flags)
- if r == -1:
- raise self.__oserror(e)
-
-
- def close(self):
- '''
- Close the bus
- '''
- try:
- from native_bus import bus_close_wrapped, bus_deallocate
- except:
- return
- if self.bus is not None:
- (r, e) = bus_close_wrapped(self.bus)
- if r == -1:
- raise self.__oserror(e)
- bus_deallocate(self.bus)
- self.bus = None
-
-
- def write(self, message : str, flags : int = 0):
- '''
- Broadcast a message a bus
-
- @param message:str The message to write, may not be longer than 2047 bytes
- after UTF-8 encoding
- @param flags:int `Bus.NOWAIT` if the function shall fail with `os.errno.EAGAIN`
- if there is another process attempting to broadcast on the bus
- '''
- from native_bus import bus_write_wrapped
- (r, e) = bus_write_wrapped(self.bus, message, flags)
- if r == -1:
- raise self.__oserror(e)
-
-
- def write_timed(self, message : str, timeout : float, clock_id : int = None):
- '''
- Broadcast a message a bus
-
- @param message:str The message to write, may not be longer than 2047 bytes
- after UTF-8 encoding
- @param timeout:float The time the function shall fail with `os.errno.EAGAIN`,
- if it has not already completed
- @param clock_id:int? The clock `timeout` is measured in, it must be a
- predictable clock, if `None`, `timeout` is measured in
- relative time instead of absolute time
- '''
- from native_bus import bus_write_timed_wrapped
- if clock_id is None:
- import time
- clock_id = time.CLOCK_MONOTONIC_RAW
- timeout += time.clock_gettime(clock_id)
- (r, e) = bus_write_timed_wrapped(self.bus, message, timeout, clock_id)
- if r == -1:
- raise self.__oserror(e)
-
-
- def read(self, callback : callable, user_data = None):
- '''
- Listen (in a loop, forever) for new message on a bus
-
- @param callback:(message:str?, user_data:¿U?=user_data)→int
- Function to call when a message is received, the
- input parameters will be the read message and
- `user_data` from the function's [`Bus.read`] parameter
- with the same name. The message must have been parsed
- or copied when `callback` returns as it may be over
- overridden after that time. `callback` should
- return either of the the values:
- 0: stop listening
- 1: continue listening
- -1: an error has occurred
- However, the function [`Bus.read`] will invoke
- `callback` with `message` set to `None` one time
- directly after it has started listening on the bus.
- This is to the the program now it can safely continue
- with any action that requires that the programs is
- listening on the bus.
- NB! The received message will not be decoded from UTF-8
- @param user_data:¿U? See description of `callback`
- '''
- from native_bus import bus_read_wrapped
- (r, e) = bus_read_wrapped(self.bus, callback, user_data)
- if r == -1:
- raise self.__oserror(e)
-
-
- def read_timed(self, callback : callable, timeout : float, clock_id : int = None, user_data = None):
- '''
- Listen (in a loop, forever) for new message on a bus
-
- @param callback:(message:str?, user_data:¿U?=user_data)→int
- Function to call when a message is received, the
- input parameters will be the read message and
- `user_data` from the function's [`Bus.read`] parameter
- with the same name. The message must have been parsed
- or copied when `callback` returns as it may be over
- overridden after that time. `callback` should
- return either of the the values:
- 0: stop listening
- 1: continue listening
- -1: an error has occurred
- However, the function [`Bus.read`] will invoke
- `callback` with `message` set to `None` one time
- directly after it has started listening on the bus.
- This is to the the program now it can safely continue
- with any action that requires that the programs is
- listening on the bus.
- NB! The received message will not be decoded from UTF-8
- @param timeout:float The time the function shall fail with `os.errno.EAGAIN`,
- if it has not already completed, note that the callback
- function may or may not have been called
- @param clock_id:int? The clock `timeout` is measured in, it must be a
- predictable clock, if `None`, `timeout` is measured in
- relative time instead of absolute time
- @param user_data:¿U? See description of `callback`
- '''
- from native_bus import bus_read_timed_wrapped
- if clock_id is None:
- import time
- clock_id = time.CLOCK_MONOTONIC_RAW
- timeout += time.clock_gettime(clock_id)
- (r, e) = bus_read_timed_wrapped(self.bus, callback, user_data, timeout, clock_id)
- if r == -1:
- raise self.__oserror(e)
-
-
- def poll_start(self):
- '''
- 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.
- '''
- from native_bus import bus_poll_start_wrapped
- (r, e) = bus_poll_start_wrapped(self.bus)
- if r == -1:
- raise self.__oserror(e)
-
-
- def poll_stop(self):
- '''
- Announce that the thread has stopped listening on the bus.
- This is required so that the thread does not cause others
- to wait indefinitely.
- '''
- from native_bus import bus_poll_stop_wrapped
- (r, e) = bus_poll_stop_wrapped(self.bus)
- if r == -1:
- raise self.__oserror(e)
-
-
- def poll(self, flags : int = 0) -> bytes:
- '''
- 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 flags:int `Bus.NOWAIT` if the bus should fail with `os.errno.EAGAIN`
- if there isn't already a message available on the bus
- @return :bytes The received message
- NB! The received message will not be decoded from UTF-8
- '''
- from native_bus import bus_poll_wrapped
- (message, e) = bus_poll_wrapped(self.bus, flags)
- if message is None:
- raise self.__oserror(e)
- return message
-
-
- def poll_timed(self, timeout : float, clock_id : int = None) -> bytes:
- '''
- 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_timed` again or `Bus.poll_stop`.
-
- @param timeout:float The time the function shall fail with `os.errno.EAGAIN`,
- if it has not already completed
- @param clock_id:int? The clock `timeout` is measured in, it must be a
- predictable clock, if `None`, `timeout` is measured in
- relative time instead of absolute time
- @return :bytes The received message
- NB! The received message will not be decoded from UTF-8
- '''
- from native_bus import bus_poll_timed_wrapped
- if clock_id is None:
- import time
- clock_id = time.CLOCK_MONOTONIC_RAW
- timeout += time.clock_gettime(clock_id)
- (message, e) = bus_poll_timed_wrapped(self.bus, timeout, clock_id)
- if message is None:
- raise self.__oserror(e)
- return message
-
-
- def chown(self, owner = None, group = None):
- '''
- Change the ownership of a bus
-
- `os.stat` can be used of the bus's associated file to get the bus's ownership
-
- @param owner:int|str? The user ID or username of the bus's new owner,
- if `None`, keep current
- @param group:int|str|...? The group ID or groupname of the bus's new group,
- if `None`, keep current, `...` to use the owner's group
- '''
- from native_bus import bus_chown_wrapped
- if (owner is None) or (group is None):
- from os import stat
- attr = stat(self.pathname)
- if owner is None: owner = attr.st_uid
- if group is None: group = attr.st_gid
- if isinstance(owner, str):
- import pwd
- owner = pwd.getpwnam(owner).pw_uid
- if isinstance(group, str):
- import grp
- group = grp.getgrnam(group).gr_gid
- elif group is ...:
- import pwd
- group = pwd.getpwuid(owner).pw_gid
- (r, e) = bus_chown_wrapped(self.pathname, owner, group)
- if r == -1:
- raise self.__oserror(e)
-
-
- def chmod(self, mode : int, mask : int = None):
- '''
- Change the permissions for a bus
-
- `os.stat` can be used of the bus's associated file to get the bus's permissions
-
- @param mode:int 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
- @param mask:int? Bits to clear before setting the bits in `mode`, if `None`,
- all bits are cleared
- '''
- from native_bus import bus_chmod_wrapped
- if mask is not None:
- from os import stat
- current = stat(self.pathname).st_mode
- if current & 0o700: current |= 0o700
- if current & 0o70: current |= 0o70
- if current & 0o7: current |= 0o7
- if mask & 0o700: mask |= 0o700
- if mask & 0o70: mask |= 0o70
- if mask & 0o7: mask |= 0o7
- current &= ~mask
- mode |= current
- (r, e) = bus_chmod_wrapped(self.pathname, mode)
- if r == -1:
- raise self.__oserror(e)
-
-
- def __oserror(self, err : int):
- '''
- Create an OSError
-
- @param err:int The value of errno
- @return :OSError The OS error
- '''
- import os
- err = OSError(err, os.strerror(err))
- if err.errno == os.errno.ENOENT:
- err.filename = self.pathname
- return err
-
diff --git a/src/native_bus.pyx b/src/native_bus.pyx
deleted file mode 100644
index 861c16f..0000000
--- a/src/native_bus.pyx
+++ /dev/null
@@ -1,579 +0,0 @@
-# -*- python -*-
-'''
-MIT/X Consortium License
-
-Copyright © 2015 Mattias Andrée <maandree@member.fsf.org>
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-'''
-
-cimport cython
-
-from libc.stdlib cimport malloc, free
-from libc.errno cimport errno
-from posix.types cimport uid_t, gid_t, mode_t, clockid_t, time_t
-
-cdef struct timespec:
- time_t tv_sec
- long tv_nsec
-ctypedef timespec timespec_t
-
-
-cdef extern int bus_create(const char *, int, char **)
-'''
-Create a new bus
-
-@param file The pathname of the bus, `NULL` to create a random one
-@param flags `BUS_EXCL` (if `file` is not `NULL`) to fail if the file
- already exists, otherwise if the file exists, nothing
- will happen;
- `BUS_INTR` to fail if interrupted
-@param out_file Output parameter for the pathname of the bus
-@return 0 on success, -1 on error
-'''
-
-cdef extern int bus_unlink(const char *)
-'''
-Remove a bus
-
-@param file The pathname of the bus
-@return 0 on success, -1 on error
-'''
-
-cdef extern int bus_open(long, const char *, int)
-'''
-Open an existing bus
-
-@param bus Bus information to fill
-@param file The filename of the bus
-@param flags `BUS_RDONLY`, `BUS_WRONLY` or `BUS_RDWR`,
- the value must not be negative
-@return 0 on success, -1 on error
-'''
-
-cdef extern int bus_close(long)
-'''
-Close a bus
-
-@param bus Bus information
-@return 0 on success, -1 on error
-'''
-
-cdef extern int bus_write(long, const char *, int)
-'''
-Broadcast a message a bus
-
-@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
-@return 0 on success, -1 on error
-'''
-
-cdef extern int bus_write_timed(long, const char *, timespec_t *, clockid_t)
-'''
-Broadcast a message a bus
-
-@param bus Bus information
-@param message The message to write, may not be longer than
- `BUS_MEMORY_SIZE` including the NUL-termination
-@param timeout The time the operation shall fail with errno set
- to `EAGAIN` if not completed
-@param clockid The ID of the clock the `timeout` is measured with,
- it most be a predictable clock
-@return 0 on success, -1 on error
-'''
-
-cdef extern int bus_read(long, int (*)(const char *, void *), void *)
-'''
-Listen (in a loop, forever) for new message on a bus
-
-@param bus Bus information
-@param callback Function to call when a message is received, the
- input parameters will be the read message and
- `user_data` from `bus_read`'s parameter with the
- same name. The message must have been parsed or
- copied when `callback` returns as it may be over
- overridden after that time. `callback` should
- return either of the the values:
- 0: stop listening
- 1: continue listening
- -1: an error has occurred
-@param user_data Parameter passed to `callback`
-@return 0 on success, -1 on error
-'''
-
-cdef extern int bus_read_timed(long, int (*)(const char *, void *), void *, timespec_t *, clockid_t)
-'''
-Listen (in a loop, forever) for new message on a bus
-
-@param bus Bus information
-@param callback Function to call when a message is received, the
- input parameters will be the read message and
- `user_data` from `bus_read`'s parameter with the
- same name. The message must have been parsed or
- copied when `callback` returns as it may be over
- overridden after that time. `callback` should
- return either of the the values:
- 0: stop listening
- 1: continue listening
- -1: an error has occurred
-@param user_data Parameter passed to `callback`
-@param timeout The time the operation shall fail with errno set
- to `EAGAIN` if not completed, note that the callback
- function may or may not have been called
-@param clockid The ID of the clock the `timeout` is measured with,
- it most be a predictable clock
-@return 0 on success, -1 on error
-'''
-
-cdef extern int bus_poll_start(long)
-'''
-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
-@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, int)
-'''
-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
-@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
-@return The received message, `NULL` on error
-'''
-
-cdef extern const char *bus_poll_timed(long, timespec_t *, clockid_t)
-'''
-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_timed` again or `bus_poll_stop`.
-
-@param bus Bus information
-@param timeout The time the operation shall fail with errno set
- to `EAGAIN` if not completed
-@param clockid The ID of the clock the `timeout` is measured with,
- it most be a predictable clock
-@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() -> tuple:
- '''
- Allocate memory for a bus
-
- @return :int The address of the allocated memory
- @return :int The value of `errno`
- '''
- n = 2 * sizeof(long long) + sizeof(int) + sizeof(char *)
- r = <long>malloc(n)
- e = errno
- return (r, e)
-
-
-def bus_deallocate(address : int):
- '''
- Deallocate memory for a bus
-
- @param address:int The address of the allocated memory
- '''
- free(<void *><long>address)
-
-
-def bus_create_wrapped(file : str, flags : int) -> tuple:
- '''
- Create a new bus
-
- @param file:str The pathname of the bus, `None` to create a random one
- @param flags:int `BUS_EXCL` (if `file` is not `None`) to fail if the file
- already exists, otherwise if the file exists, nothing
- will happen;
- `BUS_INTR` to fail if interrupted
- @return :str The pathname of the bus, `None` on error;
- `file` is returned unless `file` is `None`
- @return :int The value of `errno`
- '''
- cdef const char* cfile
- cdef char* ofile
- cdef bytes bs
- if file is not None:
- bs = file.encode('utf-8') + bytes([0])
- cfile = bs
- r = bus_create(cfile, flags, <char **>NULL)
- e = errno
- return (file if r == 0 else None, e)
- r = bus_create(<char *>NULL, flags, &ofile)
- e = errno
- if r == 0:
- bs = ofile
- return (bs.decode('utf-8', 'strict'), e)
- return (None, e)
-
-
-def bus_unlink_wrapped(file : str) -> tuple:
- '''
- Remove a bus
-
- @param file:str The pathname of the bus
- @return :int 0 on success, -1 on error
- @return :int The value of `errno`
- '''
- cdef const char* cfile
- cdef bytes bs
- bs = file.encode('utf-8') + bytes([0])
- cfile = bs
- r = bus_unlink(cfile)
- e = errno
- return (r, e)
-
-
-def bus_open_wrapped(bus : int, file : str, flags : int) -> tuple:
- '''
- Open an existing bus
-
- @param bus:int Bus information to fill
- @param file:str The filename of the bus
- @param flags:int `BUS_RDONLY`, `BUS_WRONLY` or `BUS_RDWR`,
- the value must not be negative
- @return :int 0 on success, -1 on error
- @return :int The value of `errno`
- '''
- cdef const char* cfile
- cdef bytes bs
- bs = file.encode('utf-8') + bytes([0])
- cfile = bs
- r = bus_open(<long>bus, cfile, <int>flags)
- e = errno
- return (r, e)
-
-
-def bus_close_wrapped(bus : int) -> tuple:
- '''
- Close a bus
-
- @param bus:int Bus information
- @return :int 0 on success, -1 on error
- @return :int The value of `errno`
- '''
- r = bus_close(<long>bus)
- e = errno
- return (r, e)
-
-
-def bus_write_wrapped(bus : int, message : str, flags : int) -> tuple:
- '''
- Broadcast a message a bus
-
- @param bus:int Bus information
- @param message:str The message to write, may not be longer than
- `BUS_MEMORY_SIZE` including the NUL-termination
- @param flags:int `BUS_NOWAIT` fail with errno set to `os.errno.EAGAIN`
- if other process is attempting to write
- @return :int 0 on success, -1 on error
- @return :int The value of `errno`
- '''
- cdef const char* cmessage
- cdef bytes bs
- bs = message.encode('utf-8') + bytes([0])
- cmessage = bs
- r = bus_write(<long>bus, cmessage, <int>flags)
- e = errno
- return (r, e)
-
-
-def bus_write_timed_wrapped(bus : int, message : str, timeout : float, clock_id : int) -> tuple:
- '''
- Broadcast a message a bus
-
- @param bus:int Bus information
- @param message:str The message to write, may not be longer than
- `BUS_MEMORY_SIZE` including the NUL-termination
- @param timeout:float The time the function shall fail with `os.errno.EAGAIN`,
- if it has not already completed
- @param clock_id:int The clock `timeout` is measured in, it must be a
- predictable clock
- @return :int 0 on success, -1 on error
- @return :int The value of `errno`
- '''
- cdef const char* cmessage
- cdef bytes bs
- cdef timespec_t timeout_spec
- bs = message.encode('utf-8') + bytes([0])
- cmessage = bs
- timeout_spec.tv_sec = <time_t>int(timeout)
- timeout_spec.tv_nsec = <long>int((timeout - int(timeout)) * 1000000000)
- r = bus_write_timed(<long>bus, cmessage, &timeout_spec, <clockid_t>clock_id)
- e = errno
- return (r, e)
-
-
-cdef int bus_callback_wrapper(const char *message, user_data):
- cdef bytes bs
- callback, user_data = tuple(<object>user_data)
- if message is NULL:
- return <int>callback(None, user_data)
- else:
- bs = message
- return <int>callback(bs, user_data)
-
-
-def bus_read_wrapped(bus : int, callback : callable, user_data) -> tuple:
- '''
- Listen (in a loop, forever) for new message on a bus
-
- @param bus:int Bus information
- @param callback:(str?, ¿U?)→int Function to call when a message is received, the
- input parameters will be the read message and
- `user_data` from `bus_read`'s parameter with the
- same name. The message must have been parsed or
- copied when `callback` returns as it may be over
- overridden after that time. `callback` should
- return either of the the values:
- 0: stop listening
- 1: continue listening
- -1: an error has occurred
- @param user_data:¿U? Parameter passed to `callback`
- @return :int 0 on success, -1 on error
- @return :int The value of `errno`
- '''
- user = (callback, user_data)
- r = bus_read(<long>bus, <int (*)(const char *, void *)>&bus_callback_wrapper, <void *>user)
- e = errno
- return (r, e)
-
-
-def bus_read_timed_wrapped(bus : int, callback : callable, user_data, timeout : float, clock_id : int) -> tuple:
- '''
- Listen (in a loop, forever) for new message on a bus
-
- @param bus:int Bus information
- @param callback:(str?, ¿U?)→int Function to call when a message is received, the
- input parameters will be the read message and
- `user_data` from `bus_read`'s parameter with the
- same name. The message must have been parsed or
- copied when `callback` returns as it may be over
- overridden after that time. `callback` should
- return either of the the values:
- 0: stop listening
- 1: continue listening
- -1: an error has occurred
- @param timeout:float The time the function shall fail with `os.errno.EAGAIN`,
- if it has not already completed, note that the callback
- function may or may not have been called
- @param clock_id:int The clock `timeout` is measured in, it must be a
- predictable clock
- @param user_data:¿U? Parameter passed to `callback`
- @return :int 0 on success, -1 on error
- @return :int The value of `errno`
- '''
- cdef timespec_t timeout_spec
- user = (callback, user_data)
- timeout_spec.tv_sec = <time_t>int(timeout)
- timeout_spec.tv_nsec = <long>int((timeout - int(timeout)) * 1000000000)
- r = bus_read_timed(<long>bus, <int (*)(const char *, void *)>&bus_callback_wrapper,
- <void *>user, &timeout_spec, <clockid_t>clock_id)
- e = errno
- return (r, e)
-
-
-def bus_poll_start_wrapped(bus : int) -> tuple:
- '''
- 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:int Bus information
- @return :int 0 on success, -1 on error
- @return :int The value of `errno`
- '''
- r = bus_poll_start(<long>bus)
- e = errno
- return (r, e)
-
-
-def bus_poll_stop_wrapped(bus : int) -> tuple:
- '''
- 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:int Bus information
- @return :int 0 on success, -1 on error
- @return :int The value of `errno`
- '''
- r = bus_poll_stop(<long>bus)
- e = errno
- return (r, e)
-
-
-def bus_poll_wrapped(bus : int, flags : int) -> tuple:
- '''
- 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:int Bus information
- @param flags:int `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
- @return :bytes The received message, `None` on error
- @return :int The value of `errno`
- '''
- cdef const char* msg
- cdef bytes bs
- msg = bus_poll(<long>bus, <int>flags)
- e = errno
- if msg is NULL:
- return (None, e)
- bs = msg
- return (bs, e)
-
-
-def bus_poll_timed_wrapped(bus : int, timeout : float, clock_id : int) -> tuple:
- '''
- 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_timed_wrapped` again or
- `bus_poll_stop_wrapped`.
-
- @param bus:int Bus information
- @param timeout:float The time the function shall fail with `os.errno.EAGAIN`,
- if it has not already completed
- @param clock_id:int The clock `timeout` is measured in, it must be a
- predictable clock
- @return :bytes The received message, `None` on error
- @return :int The value of `errno`
- '''
- cdef const char* msg
- cdef bytes bs
- cdef timespec_t timeout_spec
- timeout_spec.tv_sec = <time_t>int(timeout)
- timeout_spec.tv_nsec = <long>int((timeout - int(timeout)) * 1000000000)
- msg = bus_poll_timed(<long>bus, &timeout_spec, <clockid_t>clock_id)
- e = errno
- if msg is NULL:
- return (None, e)
- bs = msg
- return (bs, e)
-
-
-def bus_chown_wrapped(file : str, owner : int, group : int) -> tuple:
- '''
- 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:str The pathname of the bus
- @param owner:int The user ID of the bus's new owner
- @param group:int The group ID of the bus's new group
- @return :int 0 on success, -1 on error
- @return :int The value of `errno`
- '''
- cdef const char* cfile
- cdef bytes bs
- bs = file.encode('utf-8') + bytes([0])
- cfile = bs
- r = bus_chown(cfile, <uid_t>owner, <gid_t>group)
- e = errno
- return (r, e)
-
-
-def bus_chmod_wrapped(file : str, mode : int) -> tuple:
- '''
- 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:str The pathname of the bus
- @param mode:int 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 :int 0 on success, -1 on error
- @return :int The value of `errno`
- '''
- cdef const char* cfile
- cdef bytes bs
- bs = file.encode('utf-8') + bytes([0])
- cfile = bs
- r = bus_chmod(cfile, <mode_t>mode)
- e = errno
- return (r, e)
-