summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRickard Green <rickard@erlang.org>2023-03-20 15:07:37 +0100
committerRickard Green <rickard@erlang.org>2023-03-20 15:07:37 +0100
commit84dd335c355f9e9c7ec4b6f0d465006be1afad77 (patch)
treeb7f2998a149768eb857f73dfa5139e0932407947
parent3002f55f409f44122d3a45ac53bfd453e9aa2cb2 (diff)
downloaderlang-84dd335c355f9e9c7ec4b6f0d465006be1afad77.tar.gz
[erts] Fix error case for driver call callback
-rw-r--r--erts/emulator/beam/io.c44
1 files changed, 28 insertions, 16 deletions
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c
index d2c6dffa53..cd0f5cd412 100644
--- a/erts/emulator/beam/io.c
+++ b/erts/emulator/beam/io.c
@@ -4649,6 +4649,7 @@ erts_port_call(Process* c_p,
unsigned ret_flags = 0U;
Eterm term;
Eterm* hp;
+ ErtsPortOpResult result;
res = call_driver_call(c_p->common.id,
prt,
@@ -4662,25 +4663,36 @@ erts_port_call(Process* c_p,
finalize_imm_drv_call(&try_call_state);
if (bufp != &input_buf[0])
erts_free(ERTS_ALC_T_TMP, bufp);
- if (res == ERTS_PORT_OP_BADARG)
- return ERTS_PORT_OP_BADARG;
- hsz = erts_decode_ext_size((byte *) resp_bufp, resp_size);
- if (hsz < 0)
- return ERTS_PORT_OP_BADARG;
- hsz += 3;
- erts_factory_proc_prealloc_init(&factory, c_p, hsz);
- endp = (byte *) resp_bufp;
- term = erts_decode_ext(&factory, &endp, 0);
- if (term == THE_NON_VALUE)
- return ERTS_PORT_OP_BADARG;
- hp = erts_produce_heap(&factory,3,0);
- *retvalp = TUPLE2(hp, am_ok, term);
- erts_factory_close(&factory);
+ if (res == ERTS_PORT_OP_BADARG) {
+ result = ERTS_PORT_OP_BADARG;
+ }
+ else {
+ hsz = erts_decode_ext_size((byte *) resp_bufp, resp_size);
+ if (hsz < 0) {
+ result = ERTS_PORT_OP_BADARG;
+ }
+ else {
+ hsz += 3;
+ erts_factory_proc_prealloc_init(&factory, c_p, hsz);
+ endp = (byte *) resp_bufp;
+ term = erts_decode_ext(&factory, &endp, 0);
+ if (term == THE_NON_VALUE) {
+ result = ERTS_PORT_OP_BADARG;
+ }
+ else {
+ hp = erts_produce_heap(&factory,3,0);
+ *retvalp = TUPLE2(hp, am_ok, term);
+ result = ERTS_PORT_OP_DONE;
+ }
+ erts_factory_close(&factory);
+ }
+ }
if (resp_bufp != &resp_buf[0]
- && !(ret_flags & DRIVER_CALL_KEEP_BUFFER))
+ && !(ret_flags & DRIVER_CALL_KEEP_BUFFER)) {
driver_free(resp_bufp);
+ }
BUMP_REDS(c_p, ERTS_PORT_REDS_CALL);
- return ERTS_PORT_OP_DONE;
+ return result;
}
case ERTS_TRY_IMM_DRV_CALL_INVALID_PORT:
if (bufp != &input_buf[0])