aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/test/send_term_SUITE_data/send_term_drv.c
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/test/send_term_SUITE_data/send_term_drv.c')
-rw-r--r--erts/emulator/test/send_term_SUITE_data/send_term_drv.c718
1 files changed, 718 insertions, 0 deletions
diff --git a/erts/emulator/test/send_term_SUITE_data/send_term_drv.c b/erts/emulator/test/send_term_SUITE_data/send_term_drv.c
new file mode 100644
index 0000000000..6638de0560
--- /dev/null
+++ b/erts/emulator/test/send_term_SUITE_data/send_term_drv.c
@@ -0,0 +1,718 @@
+/* ``The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved via the world wide web at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * The Initial Developer of the Original Code is Ericsson Utvecklings AB.
+ * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
+ * AB. All Rights Reserved.''
+ *
+ * $Id$
+ */
+
+#include "erl_driver.h"
+#include <errno.h>
+#include <string.h>
+
+static ErlDrvPort erlang_port;
+static ErlDrvData send_term_drv_start(ErlDrvPort port, char *command);
+static void send_term_drv_stop(ErlDrvData drv_data);
+static void send_term_drv_run(ErlDrvData drv_data, char *buf, int len);
+
+
+static int make_ext_term_list(ErlDrvTermData *td, int bad);
+
+#define FAIL_TERM(M, L) fail_term((M), (L), __LINE__)
+
+static ErlDrvEntry send_term_drv_entry = {
+ NULL,
+ send_term_drv_start,
+ send_term_drv_stop,
+ send_term_drv_run,
+ NULL,
+ NULL,
+ "send_term_drv",
+};
+
+DRIVER_INIT(send_term_drv)
+{
+ erlang_port = (ErlDrvPort)-1;
+ return &send_term_drv_entry;
+}
+
+static ErlDrvData send_term_drv_start(ErlDrvPort port, char *buf)
+{
+ if (erlang_port != (ErlDrvPort)-1) {
+ return ERL_DRV_ERROR_GENERAL;
+ }
+
+ erlang_port = port;
+ return (ErlDrvData)port;
+}
+
+static void send_term_drv_stop(ErlDrvData drv_data)
+{
+}
+
+static void output_term(ErlDrvTermData* msg, int len);
+static void fail_term(ErlDrvTermData* msg, int len, int line);
+
+static void send_term_drv_run(ErlDrvData port, char *buf, int count)
+{
+ ErlDrvTermData msg[1024];
+
+ switch (*buf) {
+ case 0:
+ msg[0] = ERL_DRV_NIL;
+ output_term(msg, 1);
+ break;
+
+ case 1: /* Most term types inside a tuple. */
+ {
+ double f = 3.1416;
+
+ msg[0] = ERL_DRV_ATOM;
+ msg[1] = driver_mk_atom("blurf"),
+ msg[2] = ERL_DRV_INT;
+ msg[3] = (ErlDrvTermData) 42;
+ msg[4] = ERL_DRV_NIL;
+ msg[5] = ERL_DRV_INT;
+ msg[6] = (ErlDrvTermData) -42;
+ msg[7] = ERL_DRV_TUPLE;
+ msg[8] = (ErlDrvTermData) 0;
+ msg[9] = ERL_DRV_PORT;
+ msg[10] = driver_mk_port(erlang_port);
+ msg[11] = ERL_DRV_STRING_CONS;
+ msg[12] = (ErlDrvTermData) "abc";
+ msg[13] = (ErlDrvTermData) 3;
+ msg[14] = ERL_DRV_LIST;
+ msg[15] = (ErlDrvTermData) 3;
+ msg[16] = ERL_DRV_STRING;
+ msg[17] = (ErlDrvTermData) "kalle";
+ msg[18] = (ErlDrvTermData) 5;
+ msg[19] = ERL_DRV_FLOAT;
+ msg[20] = (ErlDrvTermData) &f;
+ msg[21] = ERL_DRV_PID;
+ msg[22] = driver_connected(erlang_port);
+ msg[23] = ERL_DRV_TUPLE;
+ msg[24] = (ErlDrvTermData) 7;
+ output_term(msg, 25);
+ }
+ break;
+
+ case 2: /* Deep stack */
+ {
+ int i;
+
+ for (i = 0; i < 400; i += 2) {
+ msg[i] = ERL_DRV_INT;
+ msg[i+1] = (ErlDrvTermData) (i / 2);
+ }
+ msg[i] = ERL_DRV_NIL;
+ msg[i+1] = ERL_DRV_LIST;
+ msg[i+2] = (ErlDrvTermData) 201;
+ output_term(msg, i+3);
+ }
+ break;
+
+ case 3: /* Binaries */
+ {
+ ErlDrvBinary* bin;
+ int i;
+
+ bin = driver_alloc_binary(256);
+ for (i = 0; i < 256; i++) {
+ bin->orig_bytes[i] = i;
+ }
+ msg[0] = ERL_DRV_BINARY;
+ msg[1] = (ErlDrvTermData) bin;
+ msg[2] = (ErlDrvTermData) 256;
+ msg[3] = (ErlDrvTermData) 0;
+ msg[4] = ERL_DRV_BINARY;
+ msg[5] = (ErlDrvTermData) bin;
+ msg[6] = (ErlDrvTermData) 256-23-17;
+ msg[7] = (ErlDrvTermData) 23;
+ msg[8] = ERL_DRV_TUPLE;
+ msg[9] = (ErlDrvTermData) 2;
+ output_term(msg, 10);
+ driver_free_binary(bin);
+ }
+ break;
+
+ case 4: /* Pids */
+ msg[0] = ERL_DRV_PID;
+ msg[1] = driver_connected(erlang_port);
+ msg[2] = ERL_DRV_PID;
+ msg[3] = driver_caller(erlang_port);
+ msg[4] = ERL_DRV_TUPLE;
+ msg[5] = (ErlDrvTermData) 2;
+ output_term(msg, 6);
+ break;
+
+ case 5:
+ output_term(msg, make_ext_term_list(msg, 0));
+ break;
+
+ case 6:
+ msg[0] = ERL_DRV_INT;
+ msg[1] = ~((ErlDrvTermData) 0);
+ msg[2] = ERL_DRV_UINT;
+ msg[3] = ~((ErlDrvTermData) 0);
+ msg[4] = ERL_DRV_TUPLE;
+ msg[5] = (ErlDrvTermData) 2;
+ output_term(msg, 6);
+ break;
+
+ case 7: {
+ int len = 0;
+ char buf[1024];
+ memset(buf, 17, sizeof(buf));
+ /* empty heap binary */
+ msg[len++] = ERL_DRV_BUF2BINARY;
+ msg[len++] = (ErlDrvTermData) NULL; /* NULL is ok if size == 0 */
+ msg[len++] = (ErlDrvTermData) 0;
+ /* empty heap binary again */
+ msg[len++] = ERL_DRV_BUF2BINARY;
+ msg[len++] = (ErlDrvTermData) &buf[0]; /* ptr is ok if size == 0 */
+ msg[len++] = (ErlDrvTermData) 0;
+ /* heap binary */
+ msg[len++] = ERL_DRV_BUF2BINARY;
+ msg[len++] = (ErlDrvTermData) &buf[0];
+ msg[len++] = (ErlDrvTermData) 17;
+ /* off heap binary */
+ msg[len++] = ERL_DRV_BUF2BINARY;
+ msg[len++] = (ErlDrvTermData) &buf[0];
+ msg[len++] = (ErlDrvTermData) sizeof(buf);
+
+ msg[len++] = ERL_DRV_TUPLE;
+ msg[len++] = (ErlDrvTermData) 4;
+
+ output_term(msg, len);
+ break;
+ }
+
+ case 8:
+ msg[0] = ERL_DRV_NIL;
+ output_term(msg, 1);
+ break;
+
+ case 9:
+ msg[0] = ERL_DRV_ATOM;
+ msg[1] = (ErlDrvTermData) driver_mk_atom("");
+ output_term(msg, 2);
+ break;
+
+ case 10:
+ msg[0] = ERL_DRV_ATOM;
+ msg[1] = (ErlDrvTermData) driver_mk_atom("an_atom");
+ output_term(msg, 2);
+ break;
+
+ case 11:
+ msg[0] = ERL_DRV_INT;
+ msg[1] = (ErlDrvTermData) -4711;
+ output_term(msg, 2);
+ break;
+
+ case 12:
+ msg[0] = ERL_DRV_UINT;
+ msg[1] = (ErlDrvTermData) 4711;
+ output_term(msg, 2);
+
+ break;
+ case 13:
+ msg[0] = ERL_DRV_PORT;
+ msg[1] = driver_mk_port(erlang_port);
+ output_term(msg, 2);
+ break;
+
+ case 14: {
+ ErlDrvBinary *dbin = driver_alloc_binary(0);
+ msg[0] = ERL_DRV_BINARY;
+ msg[1] = (ErlDrvTermData) dbin;
+ msg[2] = (ErlDrvTermData) 0;
+ msg[3] = (ErlDrvTermData) 0;
+ output_term(msg, 4);
+ driver_free_binary(dbin);
+ break;
+ }
+
+ case 15: {
+ char buf[] = "hejsan";
+ ErlDrvBinary *dbin = driver_alloc_binary(sizeof(buf)-1);
+ if (dbin)
+ memcpy((void *) dbin->orig_bytes, (void *) buf, sizeof(buf)-1);
+ msg[0] = ERL_DRV_BINARY;
+ msg[1] = (ErlDrvTermData) dbin;
+ msg[2] = (ErlDrvTermData) (dbin ? sizeof(buf)-1 : 0);
+ msg[3] = (ErlDrvTermData) 0;
+ output_term(msg, 4);
+ driver_free_binary(dbin);
+ break;
+ }
+
+ case 16:
+ msg[0] = ERL_DRV_BUF2BINARY;
+ msg[1] = (ErlDrvTermData) NULL;
+ msg[2] = (ErlDrvTermData) 0;
+ output_term(msg, 3);
+ break;
+
+ case 17: {
+ char buf[] = "";
+ msg[0] = ERL_DRV_BUF2BINARY;
+ msg[1] = (ErlDrvTermData) buf;
+ msg[2] = (ErlDrvTermData) sizeof(buf)-1;
+ output_term(msg, 3);
+ break;
+ }
+
+ case 18: {
+ char buf[] = "hoppsan";
+ msg[0] = ERL_DRV_BUF2BINARY;
+ msg[1] = (ErlDrvTermData) buf;
+ msg[2] = (ErlDrvTermData) sizeof(buf)-1;
+ output_term(msg, 3);
+ break;
+ }
+
+ case 19:
+ msg[0] = ERL_DRV_STRING;
+ msg[1] = (ErlDrvTermData) buf;
+ msg[2] = (ErlDrvTermData) 0;
+ output_term(msg, 3);
+ break;
+
+ case 20: {
+ char buf[] = "";
+ msg[0] = ERL_DRV_STRING;
+ msg[1] = (ErlDrvTermData) buf;
+ msg[2] = (ErlDrvTermData) sizeof(buf)-1;
+ output_term(msg, 3);
+ break;
+ }
+
+ case 21: {
+ char buf[] = "hippsan";
+ msg[0] = ERL_DRV_STRING;
+ msg[1] = (ErlDrvTermData) buf;
+ msg[2] = (ErlDrvTermData) sizeof(buf)-1;
+ output_term(msg, 3);
+ break;
+ }
+
+ case 22:
+ msg[0] = ERL_DRV_TUPLE;
+ msg[1] = (ErlDrvTermData) 0;
+ output_term(msg, 2);
+ break;
+
+ case 23:
+ msg[0] = ERL_DRV_NIL;
+ msg[1] = ERL_DRV_LIST;
+ msg[2] = (ErlDrvTermData) 1;
+ output_term(msg, 3);
+ break;
+
+ case 24:
+ msg[0] = ERL_DRV_PID;
+ msg[1] = driver_connected(erlang_port);
+ output_term(msg, 2);
+ break;
+
+ case 25:
+ msg[0] = ERL_DRV_NIL;
+ msg[1] = ERL_DRV_STRING_CONS;
+ msg[2] = (ErlDrvTermData) "";
+ msg[3] = (ErlDrvTermData) 0;
+ output_term(msg, 4);
+ break;
+
+ case 26: {
+ double my_float = 0.0;
+ msg[0] = ERL_DRV_FLOAT;
+ msg[1] = (ErlDrvTermData) &my_float;
+ output_term(msg, 2);
+ break;
+ }
+
+ case 27: {
+ char buf[] = {131, 106}; /* [] */
+ msg[0] = ERL_DRV_EXT2TERM;
+ msg[1] = (ErlDrvTermData) buf;
+ msg[2] = (ErlDrvTermData) sizeof(buf);
+ output_term(msg, 3);
+ break;
+ }
+
+ case 28: {
+ ErlDrvUInt64 x = ~((ErlDrvUInt64) 0);
+ msg[0] = ERL_DRV_UINT64;
+ msg[1] = (ErlDrvTermData) &x;
+ output_term(msg, 2);
+
+ break;
+ }
+
+ case 29: {
+ ErlDrvUInt64 x = ((ErlDrvUInt64) 4711) << 32;
+ msg[0] = ERL_DRV_UINT64;
+ msg[1] = (ErlDrvTermData) &x;
+ output_term(msg, 2);
+
+ break;
+ }
+
+ case 30: {
+ ErlDrvUInt64 x = 4711;
+ msg[0] = ERL_DRV_UINT64;
+ msg[1] = (ErlDrvTermData) &x;
+ output_term(msg, 2);
+
+ break;
+ }
+
+ case 31: {
+ ErlDrvUInt64 x = 0;
+ msg[0] = ERL_DRV_UINT64;
+ msg[1] = (ErlDrvTermData) &x;
+ output_term(msg, 2);
+
+ break;
+ }
+
+ case 32: {
+ ErlDrvSInt64 x = ((((ErlDrvUInt64) 0x7fffffff) << 32)
+ | ((ErlDrvUInt64) 0xffffffff));
+ msg[0] = ERL_DRV_INT64;
+ msg[1] = (ErlDrvTermData) &x;
+ output_term(msg, 2);
+
+ break;
+ }
+
+ case 33: {
+ ErlDrvSInt64 x = (ErlDrvSInt64) (((ErlDrvUInt64) 4711) << 32);
+ msg[0] = ERL_DRV_INT64;
+ msg[1] = (ErlDrvTermData) &x;
+ output_term(msg, 2);
+
+ break;
+ }
+
+ case 34: {
+ ErlDrvSInt64 x = 4711;
+ msg[0] = ERL_DRV_INT64;
+ msg[1] = (ErlDrvTermData) &x;
+ output_term(msg, 2);
+
+ break;
+ }
+
+ case 35: {
+ ErlDrvSInt64 x = 0;
+ msg[0] = ERL_DRV_INT64;
+ msg[1] = (ErlDrvTermData) &x;
+ output_term(msg, 2);
+
+ break;
+ }
+
+ case 36: {
+ ErlDrvSInt64 x = -1;
+ msg[0] = ERL_DRV_INT64;
+ msg[1] = (ErlDrvTermData) &x;
+ output_term(msg, 2);
+
+ break;
+ }
+
+ case 37: {
+ ErlDrvSInt64 x = -4711;
+ msg[0] = ERL_DRV_INT64;
+ msg[1] = (ErlDrvTermData) &x;
+ output_term(msg, 2);
+
+ break;
+ }
+
+ case 38: {
+ ErlDrvSInt64 x = ((ErlDrvSInt64) ((ErlDrvUInt64) 4711) << 32)*-1;
+ msg[0] = ERL_DRV_INT64;
+ msg[1] = (ErlDrvTermData) &x;
+ output_term(msg, 2);
+
+ break;
+ }
+
+ case 39: {
+ ErlDrvSInt64 x = ((ErlDrvSInt64) 1) << 63;
+ msg[0] = ERL_DRV_INT64;
+ msg[1] = (ErlDrvTermData) &x;
+ output_term(msg, 2);
+
+ break;
+ }
+
+
+ case 127: /* Error cases */
+ {
+ long refc;
+ ErlDrvBinary* bin = driver_alloc_binary(256);
+
+ FAIL_TERM(msg, 0);
+
+ msg[0] = ERL_DRV_LIST;
+ msg[1] = (ErlDrvTermData) 0;
+ FAIL_TERM(msg, 2);
+
+ /* Not an atom */
+ msg[0] = ERL_DRV_ATOM;
+ msg[1] = (ErlDrvTermData) driver_connected(erlang_port);
+ FAIL_TERM(msg, 2);
+ msg[0] = ERL_DRV_ATOM;
+ msg[1] = driver_term_nil;
+ FAIL_TERM(msg, 2);
+
+ /* Not a pid */
+ msg[0] = ERL_DRV_PID;
+ msg[1] = (ErlDrvTermData) driver_mk_atom("blurf");
+ FAIL_TERM(msg, 2);
+ msg[0] = ERL_DRV_PID;
+ msg[1] = driver_term_nil;
+ FAIL_TERM(msg, 2);
+
+ /* Not a port */
+ msg[0] = ERL_DRV_PORT;
+ msg[1] = (ErlDrvTermData) driver_mk_atom("blurf");
+ FAIL_TERM(msg, 2);
+ msg[0] = ERL_DRV_PORT;
+ msg[1] = driver_term_nil;
+ FAIL_TERM(msg, 2);
+
+ /* Missing parameter on stack */
+ msg[0] = ERL_DRV_STRING_CONS;
+ msg[1] = (ErlDrvTermData) "abc";
+ msg[2] = (ErlDrvTermData) 3;
+ FAIL_TERM(msg, 3);
+
+ /*
+ * The first binary reference is correct, the second is incorrect.
+ * There should not be any "binary leak".
+ */
+ msg[0] = ERL_DRV_BINARY;
+ msg[1] = (ErlDrvTermData) bin;
+ msg[2] = (ErlDrvTermData) 256;
+ msg[3] = (ErlDrvTermData) 0;
+ msg[4] = ERL_DRV_BINARY;
+ msg[5] = (ErlDrvTermData) bin;
+ msg[6] = (ErlDrvTermData) 257;
+ msg[7] = (ErlDrvTermData) 0;
+ msg[8] = ERL_DRV_TUPLE;
+ msg[9] = (ErlDrvTermData) 2;
+ FAIL_TERM(msg, 10);
+
+ msg[0] = ERL_DRV_BINARY;
+ msg[1] = (ErlDrvTermData) bin;
+ msg[2] = (ErlDrvTermData) 256;
+ msg[3] = (ErlDrvTermData) 0;
+ msg[4] = ERL_DRV_BINARY;
+ msg[5] = (ErlDrvTermData) bin;
+ msg[6] = (ErlDrvTermData) 256;
+ msg[7] = (ErlDrvTermData) 50;
+ msg[8] = ERL_DRV_TUPLE;
+ msg[9] = (ErlDrvTermData) 2;
+ FAIL_TERM(msg, 10);
+
+ /*
+ * We have succefully built two binaries. We expect the ref count
+ * to be 1 (SMP) or 3 (non-SMP).
+ */
+ refc = driver_binary_get_refc(bin);
+ if (refc > 3) {
+ char sbuf[128];
+ sprintf(sbuf, "bad_refc:%d", refc);
+ driver_failure_atom(erlang_port, sbuf);
+ }
+ driver_free_binary(bin);
+
+
+ FAIL_TERM(msg, make_ext_term_list(msg, 1));
+
+
+ /*
+ * Check that we fail for missing args.
+ *
+ * We setup valid terms but pass a too small size. We
+ * want valid terms since we want to verify that the
+ * failure really is due to the small size.
+ */
+ msg[0] = ERL_DRV_ATOM;
+ msg[1] = (ErlDrvTermData) driver_mk_atom("an_atom");
+ FAIL_TERM(msg, 1);
+
+ msg[0] = ERL_DRV_INT;
+ msg[1] = (ErlDrvTermData) -4711;
+ FAIL_TERM(msg, 1);
+
+ msg[0] = ERL_DRV_UINT;
+ msg[1] = (ErlDrvTermData) 4711;
+ FAIL_TERM(msg, 1);
+
+ msg[0] = ERL_DRV_PORT;
+ msg[1] = driver_mk_port(erlang_port);
+ FAIL_TERM(msg, 1);
+
+ {
+ char buf[] = "hejsan";
+ ErlDrvBinary *dbin = driver_alloc_binary(sizeof(buf)-1);
+ if (!dbin)
+ driver_failure_posix(erlang_port, ENOMEM);
+ else {
+ memcpy((void *) dbin->orig_bytes, (void *) buf, sizeof(buf)-1);
+ msg[0] = ERL_DRV_BINARY;
+ msg[1] = (ErlDrvTermData) dbin;
+ msg[2] = (ErlDrvTermData) sizeof(buf)-1;
+ msg[3] = (ErlDrvTermData) 0;
+ FAIL_TERM(msg, 1);
+ FAIL_TERM(msg, 2);
+ FAIL_TERM(msg, 3);
+ driver_free_binary(dbin);
+ }
+ }
+
+ {
+ char buf[] = "hoppsan";
+ msg[0] = ERL_DRV_BUF2BINARY;
+ msg[1] = (ErlDrvTermData) buf;
+ msg[2] = (ErlDrvTermData) sizeof(buf)-1;
+ FAIL_TERM(msg, 1);
+ FAIL_TERM(msg, 2);
+ }
+
+ {
+ char buf[] = "hippsan";
+ msg[0] = ERL_DRV_STRING;
+ msg[1] = (ErlDrvTermData) buf;
+ msg[2] = (ErlDrvTermData) sizeof(buf)-1;
+ FAIL_TERM(msg, 1);
+ FAIL_TERM(msg, 2);
+ }
+
+ msg[0] = ERL_DRV_TUPLE;
+ msg[1] = (ErlDrvTermData) 0;
+ FAIL_TERM(msg, 1);
+
+ msg[0] = ERL_DRV_NIL;
+ msg[1] = ERL_DRV_LIST;
+ msg[2] = (ErlDrvTermData) 1;
+ FAIL_TERM(msg, 2);
+
+ msg[0] = ERL_DRV_PID;
+ msg[1] = driver_connected(erlang_port);
+ FAIL_TERM(msg, 1);
+
+ msg[0] = ERL_DRV_NIL;
+ msg[1] = ERL_DRV_STRING_CONS;
+ msg[2] = (ErlDrvTermData) "";
+ msg[3] = (ErlDrvTermData) 0;
+ FAIL_TERM(msg, 2);
+ FAIL_TERM(msg, 3);
+
+ {
+ double my_float = 0.0;
+ msg[0] = ERL_DRV_FLOAT;
+ msg[1] = (ErlDrvTermData) &my_float;
+ FAIL_TERM(msg, 1);
+ }
+
+ {
+ char buf[] = {131, 106}; /* [] */
+ msg[0] = ERL_DRV_EXT2TERM;
+ msg[1] = (ErlDrvTermData) buf;
+ msg[2] = (ErlDrvTermData) sizeof(buf);
+ FAIL_TERM(msg, 1);
+ FAIL_TERM(msg, 2);
+ }
+
+ /* Signal end of test case */
+ msg[0] = ERL_DRV_NIL;
+ driver_output_term(erlang_port, msg, 1);
+ }
+ break;
+
+ default:
+ driver_failure_atom(erlang_port, "bad_request");
+ break;
+ }
+}
+
+static void output_term(ErlDrvTermData* msg, int len)
+{
+ if (driver_output_term(erlang_port, msg, len) <= 0) {
+ driver_failure_atom(erlang_port, "driver_output_term_failed");
+ }
+}
+
+static void fail_term(ErlDrvTermData* msg, int len, int line)
+{
+ int status = driver_output_term(erlang_port, msg, len);
+
+ if (status == 1) {
+ char buf[1024];
+ sprintf(buf, "%s:%d: unexpected success", __FILE__, line);
+ driver_failure_atom(erlang_port, buf);
+ } else if (status == 0) {
+ char buf[1024];
+ sprintf(buf, "%s:%d: unexpected port error", __FILE__, line);
+ driver_failure_atom(erlang_port, buf);
+ }
+}
+
+#include "ext_terms.h"
+
+/*
+ * <<131,103,100,0,12,97,110,111,100,101,64,103,111,114,98,97,103,0,0,0,36,0,0,0,0,1>>
+ * is a valid pid: <0.36.0>
+ *
+ * We replace the nodename tag (atom tag: 100) with a pid tag (103) to get an
+ * invalid pid.
+ */
+static unsigned char bad_ext_term[] = {
+ 131,103,103,0,12,97,110,111,100,101,64,103,111,114,98,97,103,0,0,0,36,0,0,0,0,1
+ /* ^
+ * |
+ * The bad tag.
+ */
+};
+
+static int make_ext_term_list(ErlDrvTermData *td, int bad)
+{
+ int tdix = 0;
+ int i;
+ for (i = 0; i < NO_OF_EXT_TERMS; i++) {
+ td[tdix++] = ERL_DRV_EXT2TERM;
+ td[tdix++] = (ErlDrvTermData) &ext_terms[i].ext[0];
+ td[tdix++] = (ErlDrvTermData) ext_terms[i].ext_size;
+ td[tdix++] = ERL_DRV_EXT2TERM;
+ td[tdix++] = (ErlDrvTermData) &ext_terms[i].cext[0];
+ td[tdix++] = (ErlDrvTermData) ext_terms[i].cext_size;
+ td[tdix++] = ERL_DRV_TUPLE;
+ td[tdix++] = (ErlDrvTermData) 2;
+ }
+ if (bad) { /* Include a bad ext term */
+ td[tdix++] = ERL_DRV_EXT2TERM;
+ td[tdix++] = (ErlDrvTermData) &bad_ext_term[0];
+ td[tdix++] = (ErlDrvTermData) sizeof(bad_ext_term);
+ }
+ td[tdix++] = ERL_DRV_NIL;
+ td[tdix++] = ERL_DRV_LIST;
+ td[tdix++] = (ErlDrvTermData) (NO_OF_EXT_TERMS + (bad ? 2 : 1));
+ return tdix;
+}