#include "structmember.h"
#include <arpa/inet.h>
#include "py_rxgen.h"
+#include "afs_py.h"
#include "rxgen.h"
PyObject *py_rxgen_get_struct(const void *p, PyObject **cache,
PyBuffer_Release(&view);
return -1;
}
+
+static int py_rxgen_received_abort_cmp(const void *key, const void *_entry)
+{
+ const struct kafs_abort_list *entry = _entry;
+
+ return (uint32_t)(unsigned long)key - entry->id;
+}
+
+/*
+ * Turn a received abort into a Python exception
+ */
+PyObject *py_rxgen_received_abort(struct rx_call *call)
+{
+ const struct kafs_abort_list *entry;
+ PyObject *ex;
+
+ entry = bsearch((void *)(unsigned long)call->abort_code,
+ kafs_abort_map,
+ sizeof(kafs_abort_map) / sizeof(kafs_abort_map[0]),
+ sizeof(kafs_abort_map[0]),
+ py_rxgen_received_abort_cmp);
+
+ if (entry)
+ ex = entry->obj;
+ else
+ ex = kafs_remote_abort;
+
+ return PyErr_Format(ex, "Aborted %u", call->abort_code);
+}
PyObject *cache,
int (*premarshal)(PyObject *object));
+/*
+ * Abort mapping
+ */
+struct kafs_abort_list {
+ uint32_t id;
+ PyObject *obj;
+};
+
+extern PyObject *py_rxgen_received_abort(struct rx_call *call);
+
#endif /* _PY_RXGEN_H */
* SUCH DAMAGE.
*/
+package KA_
+
const AUTHENTICATE_OLD = 1;
const CHANGEPASSWORD = 2;
const GETTICKET_OLD = 3;
--- /dev/null
+/* -*-c-*-
+ ****************************************************************************
+ * Copyright IBM Corporation 1988, 1989 - All Rights Reserved *
+ * *
+ * Permission to use, copy, modify, and distribute this software and its *
+ * documentation for any purpose and without fee is hereby granted, *
+ * provided that the above copyright notice appear in all copies and *
+ * that both that copyright notice and this permission notice appear in *
+ * supporting documentation, and that the name of IBM not be used in *
+ * advertising or publicity pertaining to distribution of the software *
+ * without specific, written prior permission. *
+ * *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL *
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL IBM *
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY *
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER *
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING *
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *
+ ****************************************************************************
+ */
+
+package RXGEN_
+
+/* Error codes */
+const RXGEN_CC_MARSHAL = -450;
+const RXGEN_CC_UNMARSHAL = -451;
+const RXGEN_SS_MARSHAL = -452;
+const RXGEN_SS_UNMARSHAL = -453;
+const RXGEN_DECODE = -454;
+const RXGEN_OPCODE = -455;
+const RXGEN_SS_XDRFREE = -456;
+const RXGEN_CC_XDRFREE = -457;
print PYOUT " */\n";
print PYOUT "PyObject *kafs_remote_abort;\n";
+ foreach $_ (sort(keys(%packages))) {
+ my $pkg = $packages{$_};
+ my $codes = $pkg->{abort_codes};
+ next unless (@{$codes});
+ print PYOUT "PyObject *kafs_", $pkg->{name}, "_abort;\n";
+ }
+
+ print PYOUT "\n";
+ print PYHDR "extern struct kafs_abort_list kafs_abort_map[", $abort_count, "];\n";
+
+ my %abort_table_map = ();
+ my $index = 0;
+ print PYOUT "struct kafs_abort_list kafs_abort_map[", $abort_count, "] = {\n";
+ foreach my $id (sort {$a <=> $b} keys(%abort_ids)) {
+ my $name = $abort_ids{$id};
+ print PYOUT "\t{ .id = ", $name, " }, /* ", $id, " */\n";
+ $abort_table_map{$name} = $index++;
+ }
+ print PYOUT "};\n\n";
+
# Emit python structure wrapper static method table
print PYOUT "\n";
print PYOUT "/*\n";
}
}
+ # Emit a base remote abort class that all others can be subclassed off
print PYOUT "\n";
print PYOUT "\tkafs_remote_abort = PyErr_NewException(\"kafs.RemoteAbort\", NULL, NULL);\n";
print PYOUT "\tif (!kafs_remote_abort)\n";
print PYOUT "\tPy_INCREF(kafs_remote_abort);\n";
print PYOUT "\tPyModule_AddObject(m, \"RemoteAbort\", kafs_remote_abort);\n";
+ foreach $_ (sort(keys(%packages))) {
+ my $pkg = $packages{$_};
+ my $codes = $pkg->{abort_codes};
+ next unless (@{$codes});
+
+ my $pkg_abort = $pkg->{name} . "Abort";
+ my $pkg_sym = "kafs_" . $pkg->{name} . "_abort";
+
+ print PYOUT "\n";
+ print PYOUT "\t", $pkg_sym, " = PyErr_NewException(\"kafs.", $pkg_abort, "\", kafs_remote_abort, NULL);\n";
+ print PYOUT "\tif (!", $pkg_sym, ")\n";
+ print PYOUT "\t\treturn NULL;\n";
+ print PYOUT "\tPy_INCREF(", $pkg_sym, ");\n";
+ print PYOUT "\tPyModule_AddObject(m, \"", $pkg_abort, "\", ", $pkg_sym, ");\n";
+
+ foreach my $code (sort(@{$codes})) {
+ my $code_abort = "Abort" . $code;
+ my $code_sym = "kafs_abort_map[" . $abort_table_map{$code} . "].obj";
+
+ print PYOUT "\n";
+ print PYOUT "\t", $code_sym, " = PyErr_NewException(\"kafs.", $code_abort, "\", ", $pkg_sym, ", NULL);\n";
+ print PYOUT "\tif (!", $code_sym, ")\n";
+ print PYOUT "\t\treturn NULL;\n";
+ print PYOUT "\tPy_INCREF(", $code_sym, ");\n";
+ print PYOUT "\tPyModule_AddObject(m, \"", $code_abort, "\", ", $code_sym, ");\n";
+ }
+ }
+
print PYOUT "\n";
print PYOUT "\treturn m;\n";
print PYOUT "}\n";
print PYOUT "enomem:\n";
print PYOUT "\t\tres = PyExc_MemoryError;\n";
print PYOUT "\telse if (errno == ECONNABORTED)\n";
- print PYOUT "\t\tres = PyErr_Format(kafs_remote_abort, \"Aborted %u\", call->abort_code);\n";
- #print PYOUT "\t\tres = PyLong_FromLong(call->abort_code);\n";
+ print PYOUT "\t\tres = py_rxgen_received_abort(call);\n";
print PYOUT "\telse\n";
print PYOUT "\t\tres = PyErr_SetFromErrno(PyExc_IOError);\n";
print PYOUT "\trxrpc_terminate_call(call, ENOMEM);\n";
our %func_names = (); # Function name uniquifier
our %constants = (); # Constants
our %packages = (); # Packages
-our @abort_codes = (); # Abort codes
+our $abort_codes = (); # Abort codes
+our %abort_syms = (); # Abort symbol to code map
+our %abort_ids = (); # Abort code to symbol map
+our $abort_count = 0; # Number of abort codes
our @py_type_defs = (); # Python type definitions
our @py_func_defs = (); # Python function definitions
$pkg = {
name => $name,
prefix => $prefix,
+ abort_codes => [],
};
$packages{$prefix} = $pkg;
+ $abort_codes = $pkg->{abort_codes};
next;
}
val => $v,
where => $where,
};
- push @abort_codes, $c if $error_codes;
+ if ($error_codes) {
+ if ($v < 0) {
+ $v = 0xffffffff + $v + 1;
+ }
+
+ die $where, ": Duplicate abort ID"
+ if (exists $abort_ids{$v});
+ push @{$abort_codes}, $c;
+ $abort_syms{$c} = $v;
+ $abort_ids{$v} = $c;
+ $abort_count++;
+ }
next;
}
print "Extracted ", scalar @structs, " structs\n";
print "Extracted ", scalar keys %types, " types\n";
print "Extracted ", scalar @funcs, " functions\n";
-print "Extracted ", scalar @abort_codes, " abort codes\n";
+
+my @no_abort_codes = ();
+foreach $_ (sort(keys(%packages))) {
+ my $pkg = $packages{$_};
+ if (@{$pkg->{abort_codes}}) {
+ print "Extracted ", scalar @{$pkg->{abort_codes}}, " ", $pkg->{name}, " abort codes\n";
+ } else {
+ push @no_abort_codes, $pkg->{name};
+ }
+}
+print "No abort codes for ", join(" ", @no_abort_codes), "\n" if (@no_abort_codes);
###############################################################################
#
try:
list_one(params, vl_conn, attributes)
found -= 1
- except kafs.RemoteAbort as msg:
- if str(msg) == "Aborted 363524":
- continue
- elif str(msg) == "Aborted 363549":
- break
- else:
- raise
+ except kafs.AbortVL_NOENT:
+ continue
+ except kafs.AbortVL_INDEXERANGE:
+ break
if found <= 0:
break