[apparmor] [PATCH]: raise exception in python bindings when something fails

Arkadiusz Miśkiewicz arekm at maven.pl
Fri Mar 7 12:02:32 UTC 2014


Current libapparmor python bindings are very "unpythonic". Also lack
ability to access "why" information in case of failure.

In python when something fail the normal behaviour is exception
to occur. In case of apparmor functions die silently and require
user to verify returned value.

And here comes second problem. In C api when return value is -1
(and the same value is returned in python API) we can access errno
to get information why this occured. Unfortunately in python there
is no way to access the same information.  Pythonic way of accessing
errno is via exception (which is never raised in python bindings currently).

So the patch adds exceptions on failures. First %exception creates
a wrapper that swig adds to each function listed below. Empty %exception
causes that the rest of code (beside listed functions) won't be wrapped.

How this works? Example on apparmor disabled system:

>>> LibAppArmor.aa_change_hat(hat, random.randint(1, sys.maxint))

>>> LibAppArmor.aa_change_hat(hat, random.randint(1, sys.maxint))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 22] Invalid argument

so pythonic way of accessing "why":
>>> try:
...     LibAppArmor.aa_change_hat(hat, random.randint(1, sys.maxint))
... except OSError, e:
...     print e.errno

Signed-off-by: Arkadiusz Miśkiewicz <arekm at maven.pl>

diff -urN apparmor-2.8.3.org/libraries/libapparmor/swig/SWIG/libapparmor.i apparmor-2.8.3/libraries/libapparmor/swig/SWIG/libapparmor.i
--- apparmor-2.8.3.org/libraries/libapparmor/swig/SWIG/libapparmor.i	2011-08-09 15:48:56.000000000 +0200
+++ apparmor-2.8.3/libraries/libapparmor/swig/SWIG/libapparmor.i	2014-03-07 12:32:04.000000000 +0100
@@ -9,6 +9,16 @@
 %include "typemaps.i"
 %include "aalogparse.h"
+%exception {
+  $action
+  if (result < 0) {
+    PyErr_SetFromErrno(PyExc_OSError);
+    return NULL;
+  }
 /* swig doesn't like the macro magic we do in apparmor.h so the fn prototypes
  * are manually inserted here
@@ -27,3 +37,5 @@
 extern int aa_getcon(char **con, char **mode);
 extern int aa_getpeercon_raw(int fd, char *buffer, int *size);
 extern int aa_getpeercon(int fd, char **con);

Arkadiusz Miśkiewicz, arekm / maven.pl

More information about the AppArmor mailing list