aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--erts/emulator/beam/atom.names1
-rw-r--r--erts/emulator/beam/beam_emu.c55
-rw-r--r--erts/emulator/beam/bif.c188
-rw-r--r--erts/emulator/beam/bif.tab17
-rw-r--r--erts/emulator/beam/dist.c32
-rw-r--r--erts/emulator/beam/erl_alloc.c6
-rw-r--r--erts/emulator/beam/erl_bif_ddll.c6
-rw-r--r--erts/emulator/beam/erl_bif_timer.c6
-rw-r--r--erts/emulator/beam/erl_bif_trace.c34
-rw-r--r--erts/emulator/beam/erl_db_util.c12
-rw-r--r--erts/emulator/beam/erl_gc.c18
-rw-r--r--erts/emulator/beam/erl_message.c182
-rw-r--r--erts/emulator/beam/erl_message.h13
-rw-r--r--erts/emulator/beam/erl_nif.c6
-rw-r--r--erts/emulator/beam/erl_process.c34
-rw-r--r--erts/emulator/beam/erl_process.h12
-rw-r--r--erts/emulator/beam/erl_trace.c51
-rw-r--r--erts/emulator/beam/io.c30
-rw-r--r--erts/emulator/beam/utils.c6
-rw-r--r--erts/emulator/drivers/common/efile_drv.c488
-rw-r--r--erts/preloaded/ebin/prim_file.beambin46736 -> 38764 bytes
-rw-r--r--erts/preloaded/src/prim_file.erl649
-rw-r--r--lib/dtrace/c_src/Makefile.in10
-rw-r--r--lib/dtrace/examples/efile_drv.d3
-rw-r--r--lib/dtrace/src/dtrace.erl41
-rw-r--r--lib/hipe/cerl/erl_bif_types.erl35
-rw-r--r--lib/kernel/src/file.erl160
-rw-r--r--lib/kernel/src/file_io_server.erl15
-rw-r--r--lib/kernel/src/file_server.erl106
-rw-r--r--lib/kernel/test/prim_file_SUITE.erl108
30 files changed, 1489 insertions, 835 deletions
diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names
index 7be40976f6..9ce1068b23 100644
--- a/erts/emulator/beam/atom.names
+++ b/erts/emulator/beam/atom.names
@@ -248,6 +248,7 @@ atom global_heaps_size
atom Gt='>'
atom grun
atom group_leader
+atom have_dt_utag
atom heap_block_size
atom heap_size
atom heap_sizes
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index 1dbe2cad00..deeb7357d6 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -1892,23 +1892,52 @@ void process_main(void)
save_calls(c_p, &exp_receive);
}
if (ERL_MESSAGE_TOKEN(msgp) == NIL) {
- SEQ_TRACE_TOKEN(c_p) = NIL;
+#ifdef HAVE_DTRACE
+ if (DT_UTAG(c_p) != NIL) {
+ if (DT_UTAG_FLAGS(c_p) & DT_UTAG_PERMANENT) {
+ SEQ_TRACE_TOKEN(c_p) = am_have_dt_utag;
+ if (DT_UTAG_FLAGS(c_p) & DT_UTAG_SPREADING)
+ erts_fprintf(stderr,"XXX: PaN: Dtrace -> (%T) stop spreading tag %T with message %T\r\n",c_p->id,DT_UTAG(c_p),ERL_MESSAGE_TERM(msgp));
+ } else {
+ erts_fprintf(stderr,"XXX: PaN: Dtrace -> (%T) kill tag %T with message %T\r\n",c_p->id,DT_UTAG(c_p),ERL_MESSAGE_TERM(msgp));
+ DT_UTAG(c_p) = NIL;
+ SEQ_TRACE_TOKEN(c_p) = NIL;
+ }
+ } else {
+#endif
+ SEQ_TRACE_TOKEN(c_p) = NIL;
+#ifdef HAVE_DTRACE
+ }
+ DT_UTAG_FLAGS(c_p) &= ~DT_UTAG_SPREADING;
+#endif
} else if (ERL_MESSAGE_TOKEN(msgp) != am_undefined) {
Eterm msg;
SEQ_TRACE_TOKEN(c_p) = ERL_MESSAGE_TOKEN(msgp);
- ASSERT(is_tuple(SEQ_TRACE_TOKEN(c_p)));
- ASSERT(SEQ_TRACE_TOKEN_ARITY(c_p) == 5);
- ASSERT(is_small(SEQ_TRACE_TOKEN_SERIAL(c_p)));
- ASSERT(is_small(SEQ_TRACE_TOKEN_LASTCNT(c_p)));
- ASSERT(is_small(SEQ_TRACE_TOKEN_FLAGS(c_p)));
- ASSERT(is_pid(SEQ_TRACE_TOKEN_SENDER(c_p)));
- c_p->seq_trace_lastcnt = unsigned_val(SEQ_TRACE_TOKEN_SERIAL(c_p));
- if (c_p->seq_trace_clock < unsigned_val(SEQ_TRACE_TOKEN_SERIAL(c_p))) {
- c_p->seq_trace_clock = unsigned_val(SEQ_TRACE_TOKEN_SERIAL(c_p));
+#ifdef HAVE_DTRACE
+ if (ERL_MESSAGE_TOKEN(msgp) == am_have_dt_utag) {
+ if (DT_UTAG(c_p) == NIL) {
+ DT_UTAG(c_p) = ERL_MESSAGE_DT_UTAG(msgp);
+ }
+ DT_UTAG_FLAGS(c_p) |= DT_UTAG_SPREADING;
+ erts_fprintf(stderr,"XXX: PaN: Dtrace -> (%T) receive tag (%T) with message %T\r\n",c_p->id, DT_UTAG(c_p), ERL_MESSAGE_TERM(msgp));
+ } else {
+#endif
+ ASSERT(is_tuple(SEQ_TRACE_TOKEN(c_p)));
+ ASSERT(SEQ_TRACE_TOKEN_ARITY(c_p) == 5);
+ ASSERT(is_small(SEQ_TRACE_TOKEN_SERIAL(c_p)));
+ ASSERT(is_small(SEQ_TRACE_TOKEN_LASTCNT(c_p)));
+ ASSERT(is_small(SEQ_TRACE_TOKEN_FLAGS(c_p)));
+ ASSERT(is_pid(SEQ_TRACE_TOKEN_SENDER(c_p)));
+ c_p->seq_trace_lastcnt = unsigned_val(SEQ_TRACE_TOKEN_SERIAL(c_p));
+ if (c_p->seq_trace_clock < unsigned_val(SEQ_TRACE_TOKEN_SERIAL(c_p))) {
+ c_p->seq_trace_clock = unsigned_val(SEQ_TRACE_TOKEN_SERIAL(c_p));
+ }
+ msg = ERL_MESSAGE_TERM(msgp);
+ seq_trace_output(SEQ_TRACE_TOKEN(c_p), msg, SEQ_TRACE_RECEIVE,
+ c_p->id, c_p);
+#ifdef HAVE_DTRACE
}
- msg = ERL_MESSAGE_TERM(msgp);
- seq_trace_output(SEQ_TRACE_TOKEN(c_p), msg, SEQ_TRACE_RECEIVE,
- c_p->id, c_p);
+#endif
}
if (DTRACE_ENABLED(message_receive)) {
Eterm token2 = NIL;
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index ebdca87f4a..6478e54996 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -563,7 +563,11 @@ erts_queue_monitor_message(Process *p,
ref_copy = copy_struct(ref, ref_size, &hp, ohp);
tup = TUPLE5(hp, am_DOWN, ref_copy, type, item_copy, reason_copy);
- erts_queue_message(p, p_locksp, bp, tup, NIL);
+ erts_queue_message(p, p_locksp, bp, tup, NIL
+#ifdef HAVE_DTRACE
+ , NIL
+#endif
+ );
}
static BIF_RETTYPE
@@ -1944,7 +1948,11 @@ do_send(Process *p, Eterm to, Eterm msg, int suspend) {
if (ERTS_PROC_GET_SAVED_CALLS_BUF(p))
save_calls(p, &exp_send);
- if (SEQ_TRACE_TOKEN(p) != NIL) {
+ if (SEQ_TRACE_TOKEN(p) != NIL
+#ifdef HAVE_DTRACE
+ && SEQ_TRACE_TOKEN(p) != am_have_dt_utag
+#endif
+ ) {
seq_trace_update_send(p);
seq_trace_output(SEQ_TRACE_TOKEN(p), msg,
SEQ_TRACE_SEND, portid, p);
@@ -4226,13 +4234,21 @@ BIF_RETTYPE system_flag_2(BIF_ALIST_2)
for (i = 0; i < erts_max_processes; i++) {
if (process_tab[i] != (Process*) 0) {
Process* p = process_tab[i];
+#ifdef HAVE_DTRACE
+ p->seq_trace_token = (p->dt_utag != NIL) ? am_have_dt_utag : NIL;
+#else
p->seq_trace_token = NIL;
+#endif
p->seq_trace_clock = 0;
p->seq_trace_lastcnt = 0;
ERTS_SMP_MSGQ_MV_INQ2PRIVQ(p);
mp = p->msg.first;
while(mp != NULL) {
+#ifdef HAVE_DTRACE
+ ERL_MESSAGE_TOKEN(mp) = (ERL_MESSAGE_DT_UTAG(mp) != NIL) ? am_have_dt_utag : NIL;
+#else
ERL_MESSAGE_TOKEN(mp) = NIL;
+#endif
mp = mp->next;
}
}
@@ -4630,3 +4646,171 @@ BIF_RETTYPE get_module_info_2(BIF_ALIST_2)
}
BIF_RET(ret);
}
+
+BIF_RETTYPE put_utag_1(BIF_ALIST_1)
+{
+#ifdef HAVE_DTRACE
+ Eterm otag;
+ if (BIF_ARG_1 == am_undefined) {
+ otag = (DT_UTAG(BIF_P) == NIL) ? am_undefined : DT_UTAG(BIF_P);
+ DT_UTAG(BIF_P) = NIL;
+ DT_UTAG_FLAGS(BIF_P) = 0;
+ if (SEQ_TRACE_TOKEN(BIF_P) == am_have_dt_utag) {
+ SEQ_TRACE_TOKEN(BIF_P) = NIL;
+ }
+ BIF_RET(otag);
+ }
+ if (!is_binary(BIF_ARG_1)) {
+ BIF_ERROR(BIF_P,BADARG);
+ }
+ otag = (DT_UTAG(BIF_P) == NIL) ? am_undefined : DT_UTAG(BIF_P);
+ DT_UTAG(BIF_P) = BIF_ARG_1;
+ DT_UTAG_FLAGS(BIF_P) |= DT_UTAG_PERMANENT;
+ if (SEQ_TRACE_TOKEN(BIF_P) == NIL) {
+ SEQ_TRACE_TOKEN(BIF_P) = am_have_dt_utag;
+ }
+ BIF_RET(otag);
+#else
+ BIF_RET(am_undefined);
+#endif
+}
+
+BIF_RETTYPE get_utag_0(BIF_ALIST_0)
+{
+#ifdef HAVE_DTRACE
+ BIF_RET((DT_UTAG(BIF_P) == NIL || !(DT_UTAG_FLAGS(BIF_P) & DT_UTAG_PERMANENT)) ? am_undefined : DT_UTAG(BIF_P));
+#else
+ BIF_RET(am_undefined);
+#endif
+}
+BIF_RETTYPE get_utag_data_0(BIF_ALIST_0)
+{
+#ifdef HAVE_DTRACE
+ BIF_RET((DT_UTAG(BIF_P) == NIL) ? am_undefined : DT_UTAG(BIF_P));
+#else
+ BIF_RET(am_undefined);
+#endif
+}
+BIF_RETTYPE prepend_vm_utag_data_1(BIF_ALIST_1)
+{
+#ifdef HAVE_DTRACE
+ Eterm b;
+ Eterm *hp;
+ hp = HAlloc(BIF_P,2);
+ if (is_binary((DT_UTAG(BIF_P)))) {
+ Uint sz = binary_size(DT_UTAG(BIF_P));
+ int i;
+ unsigned char *p,*q;
+ byte *temp_alloc = NULL;
+ b = new_binary(BIF_P,NULL,sz+1);
+ q = binary_bytes(b);
+ p = erts_get_aligned_binary_bytes(DT_UTAG(BIF_P),&temp_alloc);
+ for(i=0;i<sz;++i) {
+ q[i] = p[i];
+ }
+ erts_free_aligned_binary_bytes(temp_alloc);
+ q[sz] = '\0';
+ } else {
+ b = new_binary(BIF_P,(byte *)"\0",1);
+ }
+ BIF_RET(CONS(hp,b,BIF_ARG_1));
+#else
+ BIF_RET(BIF_ARG_1);
+#endif
+}
+BIF_RETTYPE append_vm_utag_data_1(BIF_ALIST_1)
+{
+#ifdef HAVE_DTRACE
+ Eterm b;
+ Eterm *hp;
+ hp = HAlloc(BIF_P,2);
+ if (is_binary((DT_UTAG(BIF_P)))) {
+ Uint sz = binary_size(DT_UTAG(BIF_P));
+ int i;
+ unsigned char *p,*q;
+ byte *temp_alloc = NULL;
+ b = new_binary(BIF_P,NULL,sz+1);
+ q = binary_bytes(b);
+ p = erts_get_aligned_binary_bytes(DT_UTAG(BIF_P),&temp_alloc);
+ for(i=0;i<sz;++i) {
+ q[i] = p[i];
+ }
+ erts_free_aligned_binary_bytes(temp_alloc);
+ q[sz] = '\0';
+ } else {
+ b = new_binary(BIF_P,(byte *)"\0",1);
+ }
+ BIF_RET(CONS(hp,BIF_ARG_1,b));
+#else
+ BIF_RET(BIF_ARG_1);
+#endif
+}
+BIF_RETTYPE spread_utag_1(BIF_ALIST_1)
+{
+#ifdef HAVE_DTRACE
+ Eterm ret;
+ Eterm *hp;
+#endif
+ if (BIF_ARG_1 != am_true && BIF_ARG_1 != am_false) {
+ BIF_ERROR(BIF_P,BADARG);
+ }
+#ifdef HAVE_DTRACE
+ hp = HAlloc(BIF_P,3);
+ ret = TUPLE2(hp,make_small(DT_UTAG_FLAGS(BIF_P)),DT_UTAG(BIF_P));
+ if (DT_UTAG(BIF_P) != NIL) {
+ if (BIF_ARG_1 == am_true) {
+ DT_UTAG_FLAGS(BIF_P) |= DT_UTAG_SPREADING;
+ erts_fprintf(stderr,"XXX: PaN: Dtrace -> (%T) start spreading tag %T\r\n",BIF_P->id,DT_UTAG(BIF_P));
+ } else {
+ DT_UTAG_FLAGS(BIF_P) &= ~DT_UTAG_SPREADING;
+ erts_fprintf(stderr,"XXX: PaN: Dtrace -> (%T) stop spreading tag %T\r\n",BIF_P->id,DT_UTAG(BIF_P));
+ }
+ }
+ BIF_RET(ret);
+#else
+ BIF_RET(am_true);
+#endif
+}
+BIF_RETTYPE restore_utag_1(BIF_ALIST_1)
+{
+#ifdef HAVE_DTRACE
+ Eterm *tpl;
+ Uint x;
+ if (is_not_tuple(BIF_ARG_1)) {
+ BIF_ERROR(BIF_P,BADARG);
+ }
+ tpl = tuple_val(BIF_ARG_1);
+ if(arityval(*tpl) != 2 || is_not_small(tpl[1]) || (is_not_binary(tpl[2]) && tpl[2] != NIL)) {
+ BIF_ERROR(BIF_P,BADARG);
+ }
+ if (tpl[2] == NIL) {
+ if (DT_UTAG(BIF_P) != NIL) {
+ erts_fprintf(stderr,"XXX: PaN: Dtrace -> (%T) restore Killing tag!\r\n",BIF_P->id);
+ }
+ DT_UTAG(BIF_P) = NIL;
+ if (SEQ_TRACE_TOKEN(BIF_P) == am_have_dt_utag) {
+ SEQ_TRACE_TOKEN(BIF_P) = NIL;
+ }
+ DT_UTAG_FLAGS(BIF_P) = 0;
+ } else {
+ x = unsigned_val(tpl[1]) & (DT_UTAG_SPREADING | DT_UTAG_PERMANENT);
+ if (!(x & DT_UTAG_SPREADING) && (DT_UTAG_FLAGS(BIF_P) & DT_UTAG_SPREADING)) {
+ erts_fprintf(stderr,"XXX: PaN: Dtrace -> (%T) restore stop spreading tag %T\r\n",BIF_P->id,tpl[2]);
+ } else if ((x & DT_UTAG_SPREADING) && !(DT_UTAG_FLAGS(BIF_P) & DT_UTAG_SPREADING)) {
+ erts_fprintf(stderr,"XXX: PaN: Dtrace -> (%T) restore start spreading tag %T\r\n",BIF_P->id,tpl[2]);
+ }
+ DT_UTAG_FLAGS(BIF_P) = x;
+ DT_UTAG(BIF_P) = tpl[2];
+ if (SEQ_TRACE_TOKEN(BIF_P) == NIL) {
+ SEQ_TRACE_TOKEN(BIF_P) = am_have_dt_utag;
+ }
+ }
+#else
+ if (BIF_ARG_1 != am_true) {
+ BIF_ERROR(BIF_P,BADARG);
+ }
+#endif
+ BIF_RET(am_true);
+}
+
+
diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab
index 007c884a6a..7940544156 100644
--- a/erts/emulator/beam/bif.tab
+++ b/erts/emulator/beam/bif.tab
@@ -814,6 +814,23 @@ bif erlang:check_old_code/1
#
bif erlang:universaltime_to_posixtime/1
bif erlang:posixtime_to_universaltime/1
+
+#
+# New in R15B01
+#
+
+# The dtrace BIF's are always present, but give dummy results if dynamic trace is not enabled in the build
+bif erlang:put_utag/1
+bif erlang:get_utag/0
+bif erlang:get_utag_data/0
+bif erlang:spread_utag/1
+bif erlang:restore_utag/1
+
+# These are dummies even with enabled dynamic trace unless vm probes are enabled.
+# They are also internal, for dtrace tags sent to the VM's own drivers (efile)
+bif erlang:prepend_vm_utag_data/1
+bif erlang:append_vm_utag_data/1
+
#
# Obsolete
#
diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c
index ba55a1918a..43fc910054 100644
--- a/erts/emulator/beam/dist.c
+++ b/erts/emulator/beam/dist.c
@@ -382,7 +382,11 @@ static void doit_node_link_net_exits(ErtsLink *lnk, void *vnecp)
Eterm tup;
Eterm *hp = erts_alloc_message_heap(3,&bp,&ohp,rp,&rp_locks);
tup = TUPLE2(hp, am_nodedown, name);
- erts_queue_message(rp, &rp_locks, bp, tup, NIL);
+ erts_queue_message(rp, &rp_locks, bp, tup, NIL
+#ifdef HAVE_DTRACE
+ , NIL
+#endif
+ );
}
erts_smp_proc_unlock(rp, rp_locks);
}
@@ -750,7 +754,11 @@ erts_dsig_send_msg(ErtsDSigData *dsdp, Eterm remote, Eterm message)
DTRACE_CHARBUF(receiver_name, 64);
UseTmpHeapNoproc(5);
- if (SEQ_TRACE_TOKEN(sender) != NIL) {
+ if (SEQ_TRACE_TOKEN(sender) != NIL
+#ifdef HAVE_DTRACE
+ && SEQ_TRACE_TOKEN(sender) != am_have_dt_utag
+#endif
+ ) {
seq_trace_update_send(sender);
token = SEQ_TRACE_TOKEN(sender);
seq_trace_output(token, message, SEQ_TRACE_SEND, remote, sender);
@@ -799,7 +807,11 @@ erts_dsig_send_reg_msg(ErtsDSigData *dsdp, Eterm remote_name, Eterm message)
DTRACE_CHARBUF(receiver_name, 128);
UseTmpHeapNoproc(6);
- if (SEQ_TRACE_TOKEN(sender) != NIL) {
+ if (SEQ_TRACE_TOKEN(sender) != NIL
+#ifdef HAVE_DTRACE
+ && SEQ_TRACE_TOKEN(sender) != am_have_dt_utag
+#endif
+ ) {
seq_trace_update_send(sender);
token = SEQ_TRACE_TOKEN(sender);
seq_trace_output(token, message, SEQ_TRACE_SEND, remote_name, sender);
@@ -851,7 +863,11 @@ erts_dsig_send_exit_tt(ErtsDSigData *dsdp, Eterm local, Eterm remote,
DTRACE_CHARBUF(reason_str, 128);
UseTmpHeapNoproc(6);
- if (token != NIL) {
+ if (token != NIL
+#ifdef HAVE_DTRACE
+ && token != am_have_dt_utag
+#endif
+ ) {
seq_trace_update_send(dsdp->proc);
seq_trace_output_exit(token, reason, SEQ_TRACE_SEND, remote, local);
ctl = TUPLE5(&ctl_heap[0],
@@ -866,7 +882,7 @@ erts_dsig_send_exit_tt(ErtsDSigData *dsdp, Eterm local, Eterm remote,
erts_snprintf(remote_name, sizeof(remote_name),
"{%T,%s}", remote, node_name);
erts_snprintf(reason_str, sizeof(reason), "%T", reason);
- if (token != NIL) {
+ if (token != NIL && token != am_have_dt_utag) {
tok_label = signed_val(SEQ_TRACE_T_LABEL(token));
tok_lastcnt = signed_val(SEQ_TRACE_T_LASTCNT(token));
tok_serial = signed_val(SEQ_TRACE_T_SERIAL(token));
@@ -3094,7 +3110,11 @@ send_nodes_mon_msg(Process *rp,
}
ASSERT(hend == hp);
- erts_queue_message(rp, rp_locksp, bp, msg, NIL);
+ erts_queue_message(rp, rp_locksp, bp, msg, NIL
+#ifdef HAVE_DTRACE
+ , NIL
+#endif
+ );
}
static void
diff --git a/erts/emulator/beam/erl_alloc.c b/erts/emulator/beam/erl_alloc.c
index df27186680..d575e30092 100644
--- a/erts/emulator/beam/erl_alloc.c
+++ b/erts/emulator/beam/erl_alloc.c
@@ -3001,7 +3001,11 @@ reply_alloc_info(void *vair)
HRelease(rp, hp_end, hp);
}
- erts_queue_message(rp, &rp_locks, bp, msg, NIL);
+ erts_queue_message(rp, &rp_locks, bp, msg, NIL
+#ifdef HAVE_DTRACE
+ , NIL
+#endif
+ );
if (air->req_sched == sched_id)
rp_locks &= ~ERTS_PROC_LOCK_MAIN;
diff --git a/erts/emulator/beam/erl_bif_ddll.c b/erts/emulator/beam/erl_bif_ddll.c
index 3326fd84df..b58c5ab761 100644
--- a/erts/emulator/beam/erl_bif_ddll.c
+++ b/erts/emulator/beam/erl_bif_ddll.c
@@ -1762,7 +1762,11 @@ static void notify_proc(Process *proc, Eterm ref, Eterm driver_name, Eterm type,
hp += REF_THING_SIZE;
mess = TUPLE5(hp,type,r,am_driver,driver_name,tag);
}
- erts_queue_message(proc, &rp_locks, bp, mess, am_undefined);
+ erts_queue_message(proc, &rp_locks, bp, mess, am_undefined
+#ifdef HAVE_DTRACE
+ , NIL
+#endif
+ );
erts_smp_proc_unlock(proc, rp_locks);
ERTS_SMP_CHK_NO_PROC_LOCKS;
}
diff --git a/erts/emulator/beam/erl_bif_timer.c b/erts/emulator/beam/erl_bif_timer.c
index a922a33da3..fbc2f08c09 100644
--- a/erts/emulator/beam/erl_bif_timer.c
+++ b/erts/emulator/beam/erl_bif_timer.c
@@ -373,7 +373,11 @@ bif_timer_timeout(ErtsBifTimer* btm)
message = TUPLE3(hp, am_timeout, ref, message);
}
- erts_queue_message(rp, &rp_locks, bp, message, NIL);
+ erts_queue_message(rp, &rp_locks, bp, message, NIL
+#ifdef HAVE_DTRACE
+ , NIL
+#endif
+ );
erts_smp_proc_unlock(rp, rp_locks);
erts_smp_proc_dec_refc(rp);
}
diff --git a/erts/emulator/beam/erl_bif_trace.c b/erts/emulator/beam/erl_bif_trace.c
index b0a58c80ea..c518aa6866 100644
--- a/erts/emulator/beam/erl_bif_trace.c
+++ b/erts/emulator/beam/erl_bif_trace.c
@@ -1744,9 +1744,17 @@ Eterm erts_seq_trace(Process *p, Eterm arg1, Eterm arg2,
return THE_NON_VALUE;
}
if (build_result) {
+#ifdef HAVE_DTRACE
+ old_value = (SEQ_TRACE_TOKEN(p) == am_have_dt_utag) ? NIL : SEQ_TRACE_TOKEN(p);
+#else
old_value = SEQ_TRACE_TOKEN(p);
+#endif
}
+#ifdef HAVE_DTRACE
+ SEQ_TRACE_TOKEN(p) = (DT_UTAG(p) != NIL) ? am_have_dt_utag : NIL;
+#else
SEQ_TRACE_TOKEN(p) = NIL;
+#endif
return old_value;
}
else {
@@ -1759,7 +1767,11 @@ new_seq_trace_token(Process* p)
{
Eterm* hp;
- if (SEQ_TRACE_TOKEN(p) == NIL) {
+ if (SEQ_TRACE_TOKEN(p) == NIL
+#ifdef HAVE_DTRACE
+ || SEQ_TRACE_TOKEN(p) == am_have_dt_utag
+#endif
+ ) {
hp = HAlloc(p, 6);
SEQ_TRACE_TOKEN(p) = TUPLE5(hp, make_small(0), /* Flags */
make_small(0), /* Label */
@@ -1779,7 +1791,11 @@ BIF_RETTYPE erl_seq_trace_info(Process *p, Eterm item)
BIF_ERROR(p, BADARG);
}
- if (SEQ_TRACE_TOKEN(p) == NIL) {
+ if (SEQ_TRACE_TOKEN(p) == NIL
+#ifdef HAVE_DTRACE
+ || SEQ_TRACE_TOKEN(p) == am_have_dt_utag
+#endif
+ ) {
if ((item == am_send) || (item == am_receive) ||
(item == am_print) || (item == am_timestamp)) {
hp = HAlloc(p,3);
@@ -1836,8 +1852,13 @@ BIF_RETTYPE seq_trace_info_1(BIF_ALIST_1)
*/
BIF_RETTYPE seq_trace_print_1(BIF_ALIST_1)
{
- if (SEQ_TRACE_TOKEN(BIF_P) == NIL)
+ if (SEQ_TRACE_TOKEN(BIF_P) == NIL
+#ifdef HAVE_DTRACE
+ || SEQ_TRACE_TOKEN(BIF_P) == am_have_dt_utag
+#endif
+ ) {
BIF_RET(am_false);
+ }
seq_trace_update_send(BIF_P);
seq_trace_output(SEQ_TRACE_TOKEN(BIF_P), BIF_ARG_1,
SEQ_TRACE_PRINT, NIL, BIF_P);
@@ -1854,8 +1875,13 @@ BIF_RETTYPE seq_trace_print_1(BIF_ALIST_1)
*/
BIF_RETTYPE seq_trace_print_2(BIF_ALIST_2)
{
- if (SEQ_TRACE_TOKEN(BIF_P) == NIL)
+ if (SEQ_TRACE_TOKEN(BIF_P) == NIL
+#ifdef HAVE_DTRACE
+ || SEQ_TRACE_TOKEN(BIF_P) == am_have_dt_utag
+#endif
+ ) {
BIF_RET(am_false);
+ }
if (!(is_atom(BIF_ARG_1) || is_small(BIF_ARG_1))) {
BIF_ERROR(BIF_P, BADARG);
}
diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c
index 4821a7d9fb..eb05ceaaf1 100644
--- a/erts/emulator/beam/erl_db_util.c
+++ b/erts/emulator/beam/erl_db_util.c
@@ -2203,7 +2203,11 @@ restart:
*esp++ = am_true;
break;
case matchIsSeqTrace:
- if (SEQ_TRACE_TOKEN(c_p) != NIL)
+ if (SEQ_TRACE_TOKEN(c_p) != NIL
+#ifdef HAVE_DTRACE
+ && SEQ_TRACE_TOKEN(c_p) != am_have_dt_utag
+#endif
+ )
*esp++ = am_true;
else
*esp++ = am_false;
@@ -2227,7 +2231,11 @@ restart:
--esp;
break;
case matchGetSeqToken:
- if (SEQ_TRACE_TOKEN(c_p) == NIL)
+ if (SEQ_TRACE_TOKEN(c_p) == NIL
+#ifdef HAVE_DTRACE
+ || SEQ_TRACE_TOKEN(c_p) == am_have_dt_utag
+#endif
+ )
*esp++ = NIL;
else {
Eterm sender = SEQ_TRACE_TOKEN_SENDER(c_p);
diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c
index 679a3645ba..6dfccfe52f 100644
--- a/erts/emulator/beam/erl_gc.c
+++ b/erts/emulator/beam/erl_gc.c
@@ -1935,7 +1935,13 @@ setup_rootset(Process *p, Eterm *objv, int nobj, Rootset *rootset)
roots[n].sz = 1;
n++;
}
-
+#ifdef HAVE_DTRACE
+ if (is_not_immed(p->dt_utag)) {
+ roots[n].v = &p->dt_utag;
+ roots[n].sz = 1;
+ n++;
+ }
+#endif
ASSERT(is_nil(p->tracer_proc) ||
is_internal_pid(p->tracer_proc) ||
is_internal_port(p->tracer_proc));
@@ -2472,6 +2478,13 @@ offset_mqueue(Process *p, Sint offs, char* area, Uint area_size)
if (is_boxed(mesg) && in_area(ptr_val(mesg), area, area_size)) {
ERL_MESSAGE_TOKEN(mp) = offset_ptr(mesg, offs);
}
+#ifdef HAVE_DTRACE
+ mesg = ERL_MESSAGE_DT_UTAG(mp);
+ if (is_boxed(mesg) && in_area(ptr_val(mesg), area, area_size)) {
+ ERL_MESSAGE_DT_UTAG(mp) = offset_ptr(mesg, offs);
+ }
+#endif
+
ASSERT((is_nil(ERL_MESSAGE_TOKEN(mp)) ||
is_tuple(ERL_MESSAGE_TOKEN(mp)) ||
is_atom(ERL_MESSAGE_TOKEN(mp))));
@@ -2491,6 +2504,9 @@ offset_one_rootset(Process *p, Sint offs, char* area, Uint area_size,
offset_heap_ptr(&p->fvalue, 1, offs, area, area_size);
offset_heap_ptr(&p->ftrace, 1, offs, area, area_size);
offset_heap_ptr(&p->seq_trace_token, 1, offs, area, area_size);
+#ifdef HAVE_DTRACE
+ offset_heap_ptr(&p->dt_utag, 1, offs, area, area_size);
+#endif
offset_heap_ptr(&p->group_leader, 1, offs, area, area_size);
offset_mqueue(p, offs, area, area_size);
offset_heap_ptr(p->stop, (STACK_START(p) - p->stop), offs, area, area_size);
diff --git a/erts/emulator/beam/erl_message.c b/erts/emulator/beam/erl_message.c
index 786d6ac52c..dc59b9c2c4 100644
--- a/erts/emulator/beam/erl_message.c
+++ b/erts/emulator/beam/erl_message.c
@@ -393,13 +393,26 @@ erts_queue_dist_message(Process *rcvr,
receiver_name, size_object(msg), rcvr->msg.len,
tok_label, tok_lastcnt, tok_serial);
}
- erts_queue_message(rcvr, rcvr_locks, mbuf, msg, token);
+ erts_queue_message(rcvr, rcvr_locks, mbuf, msg, token
+#ifdef HAVE_DTRACE
+ , NIL
+#endif
+ );
}
else {
/* Enqueue message on external format */
ERL_MESSAGE_TERM(mp) = THE_NON_VALUE;
- ERL_MESSAGE_TOKEN(mp) = token;
+#ifdef HAVE_DTRACE
+ ERL_MESSAGE_DT_UTAG(mp) = NIL;
+ if (token == am_have_dt_utag) {
+ ERL_MESSAGE_TOKEN(mp) = NIL;
+ } else {
+#endif
+ ERL_MESSAGE_TOKEN(mp) = token;
+#ifdef HAVE_DTRACE
+ }
+#endif
mp->next = NULL;
if (DTRACE_ENABLED(message_queued)) {
@@ -431,7 +444,11 @@ erts_queue_message(Process* receiver,
ErtsProcLocks *receiver_locks,
ErlHeapFragment* bp,
Eterm message,
- Eterm seq_trace_token)
+ Eterm seq_trace_token
+#ifdef HAVE_DTRACE
+ , Eterm dt_utag
+#endif
+)
{
ErlMessage* mp;
#ifdef ERTS_SMP
@@ -472,6 +489,9 @@ erts_queue_message(Process* receiver,
ERL_MESSAGE_TERM(mp) = message;
ERL_MESSAGE_TOKEN(mp) = seq_trace_token;
+#ifdef HAVE_DTRACE
+ ERL_MESSAGE_DT_UTAG(mp) = dt_utag;
+#endif
mp->next = NULL;
mp->data.heap_frag = bp;
@@ -547,6 +567,9 @@ erts_move_msg_mbuf_to_heap(Eterm** hpp, ErlOffHeap* off_heap, ErlMessage *msg)
Sint offs;
Uint sz;
ErlHeapFragment *bp;
+#ifdef HAVE_DTRACE
+ Eterm utag;
+#endif
#ifdef HARD_DEBUG
ProcBin *dbg_mso_start = off_heap->mso;
@@ -556,32 +579,56 @@ erts_move_msg_mbuf_to_heap(Eterm** hpp, ErlOffHeap* off_heap, ErlMessage *msg)
ErlHeapFragment *dbg_bp;
Uint *dbg_hp, *dbg_thp_start;
Uint dbg_term_sz, dbg_token_sz;
+#ifdef HAVE_DTRACE
+ Eterm dbg_utag;
+ Uint dbg_utag_sz;
+#endif
#endif
bp = msg->data.heap_frag;
term = ERL_MESSAGE_TERM(msg);
token = ERL_MESSAGE_TOKEN(msg);
+#ifdef HAVE_DTRACE
+ utag = ERL_MESSAGE_DT_UTAG(msg);
+#endif
if (!bp) {
+#ifdef HAVE_DTRACE
+ ASSERT(is_immed(term) && is_immed(token) && is_immed(utag));
+#else
ASSERT(is_immed(term) && is_immed(token));
+#endif
return;
}
#ifdef HARD_DEBUG
dbg_term_sz = size_object(term);
dbg_token_sz = size_object(token);
+ dbg_bp = new_message_buffer(dbg_term_sz + dbg_token_sz);
+#ifdef HAVE_DTRACE
+ dbg_utag_sz = size_object(utag);
+ dbg_bp = new_message_buffer(dbg_term_sz + dbg_token_sz + dbg_utag_sz );
+#endif
/*ASSERT(dbg_term_sz + dbg_token_sz == erts_msg_used_frag_sz(msg));
Copied size may be smaller due to removed SubBins's or garbage.
Copied size may be larger due to duplicated shared terms.
*/
- dbg_bp = new_message_buffer(dbg_term_sz + dbg_token_sz);
dbg_hp = dbg_bp->mem;
dbg_term = copy_struct(term, dbg_term_sz, &dbg_hp, &dbg_bp->off_heap);
dbg_token = copy_struct(token, dbg_token_sz, &dbg_hp, &dbg_bp->off_heap);
- dbg_thp_start = *hpp;
+#ifdef HAVE_DTRACE
+ dbg_utag = copy_struct(utag, dbg_utag_sz, &dbg_hp, &dbg_bp->off_heap);
+#endif
+ dbg_thp_start = *hpp;
#endif
if (bp->next != NULL) {
- move_multi_frags(hpp, off_heap, bp, msg->m, 2);
+ move_multi_frags(hpp, off_heap, bp, msg->m,
+#ifdef HAVE_DTRACE
+ 3
+#else
+ 2
+#endif
+ );
goto copy_done;
}
@@ -683,6 +730,16 @@ erts_move_msg_mbuf_to_heap(Eterm** hpp, ErlOffHeap* off_heap, ErlMessage *msg)
ASSERT(hp > ptr_val(ERL_MESSAGE_TERM(msg)));
#endif
}
+#ifdef HAVE_DTRACE
+ if (is_not_immed(utag)) {
+ ASSERT(in_heapfrag(ptr_val(utag), bp));
+ ERL_MESSAGE_DT_UTAG(msg) = offset_ptr(utag, offs);
+#ifdef HARD_DEBUG
+ ASSERT(dbg_thp_start <= ptr_val(ERL_MESSAGE_DT_UTAG(msg)));
+ ASSERT(hp > ptr_val(ERL_MESSAGE_DT_UTAG(msg)));
+#endif
+ }
+#endif
copy_done:
@@ -749,6 +806,9 @@ copy_done:
#ifdef HARD_DEBUG
ASSERT(eq(ERL_MESSAGE_TERM(msg), dbg_term));
ASSERT(eq(ERL_MESSAGE_TOKEN(msg), dbg_token));
+#ifdef HAVE_DTRACE
+ ASSERT(eq(ERL_MESSAGE_DT_UTAG(msg), dbg_utag));
+#endif
free_message_buffer(dbg_bp);
#endif
@@ -841,42 +901,85 @@ erts_send_message(Process* sender,
}
if (SEQ_TRACE_TOKEN(sender) != NIL && !(flags & ERTS_SND_FLG_NO_SEQ_TRACE)) {
Eterm* hp;
+ Eterm stoken = SEQ_TRACE_TOKEN(sender);
+ Uint seq_trace_size = 0;
+#ifdef HAVE_DTRACE
+ Uint dt_utag_size = 0;
+ Eterm utag = NIL;
+#endif
- BM_SWAP_TIMER(send,size);
+ BM_SWAP_TIMER(send,size);
msize = size_object(message);
- BM_SWAP_TIMER(size,send);
+ BM_SWAP_TIMER(size,send);
+
+#ifdef HAVE_DTRACE
+ if (stoken != am_have_dt_utag) {
+#endif
- seq_trace_update_send(sender);
- seq_trace_output(SEQ_TRACE_TOKEN(sender), message, SEQ_TRACE_SEND,
- receiver->id, sender);
- bp = new_message_buffer(msize + 6 /* TUPLE5 */);
+ seq_trace_update_send(sender);
+ seq_trace_output(stoken, message, SEQ_TRACE_SEND,
+ receiver->id, sender);
+ seq_trace_size = 6; /* TUPLE5 */
+#ifdef HAVE_DTRACE
+ }
+ if (DT_UTAG_FLAGS(sender) & DT_UTAG_SPREADING) {
+ dt_utag_size = size_object(DT_UTAG(sender));
+ } else if (stoken == am_have_dt_utag ) {
+ stoken = NIL;
+ }
+#endif
+
+ bp = new_message_buffer(msize + seq_trace_size
+#ifdef HAVE_DTRACE
+ + dt_utag_size
+#endif
+ );
hp = bp->mem;
BM_SWAP_TIMER(send,copy);
- token = copy_struct(SEQ_TRACE_TOKEN(sender),
- 6 /* TUPLE5 */,
+ token = copy_struct(stoken,
+ seq_trace_size,
&hp,
&bp->off_heap);
message = copy_struct(message, msize, &hp, &bp->off_heap);
+#ifdef HAVE_DTRACE
+ if (DT_UTAG_FLAGS(sender) & DT_UTAG_SPREADING) {
+ utag = copy_struct(DT_UTAG(sender), dt_utag_size, &hp, &bp->off_heap);
+ erts_fprintf(stderr,"XXX: PaN: Dtrace -> (%T) Spreading tag (%T) with message %T!\r\n",sender->id, utag, message);
+ }
+#if 0
+ DT_UTAG_FLAGS(sender) &= ~DT_UTAG_SPREADING;
+ if (!(DT_UTAG_FLAGS(sender) & DT_UTAG_PERMANENT)) {
+ erts_fprintf(stderr,"XXX: PaN: Dtrace -> (%T) Killing tag!\r\n",sender->id);
+ DT_UTAG(sender) = NIL;
+ if (SEQ_TRACE_TOKEN(sender) == am_have_dt_utag) {
+ SEQ_TRACE_TOKEN(sender) = NIL;
+ }
+ }
+#endif
+#endif
BM_MESSAGE_COPIED(msize);
BM_SWAP_TIMER(copy,send);
if (DTRACE_ENABLED(message_send)) {
- Eterm token2 = NIL;
-
- token2 = SEQ_TRACE_TOKEN(sender);
- tok_label = signed_val(SEQ_TRACE_T_LABEL(token2));
- tok_lastcnt = signed_val(SEQ_TRACE_T_LASTCNT(token2));
- tok_serial = signed_val(SEQ_TRACE_T_SERIAL(token2));
- DTRACE6(message_send, sender_name, receiver_name,
- msize, tok_label, tok_lastcnt, tok_serial);
+ if (stoken != NIL) {
+ tok_label = signed_val(SEQ_TRACE_T_LABEL(stoken));
+ tok_lastcnt = signed_val(SEQ_TRACE_T_LASTCNT(stoken));
+ tok_serial = signed_val(SEQ_TRACE_T_SERIAL(stoken));
+ }
+ DTRACE6(message_send, sender_name, receiver_name,
+ msize, tok_label, tok_lastcnt, tok_serial);
}
erts_queue_message(receiver,
receiver_locks,
bp,
message,
- token);
+ token
+#ifdef HAVE_DTRACE
+ , utag
+#endif
+ );
BM_SWAP_TIMER(send,system);
#ifdef HYBRID
} else {
@@ -909,6 +1012,9 @@ erts_send_message(Process* sender,
size_object(message)msize, tok_label, tok_lastcnt, tok_serial);
ERL_MESSAGE_TERM(mp) = message;
ERL_MESSAGE_TOKEN(mp) = NIL;
+#ifdef HAVE_DTRACE
+ ERL_MESSAGE_DT_UTAG(mp) = NIL;
+#endif
mp->next = NULL;
LINK_MESSAGE(receiver, mp);
ACTIVATE(receiver);
@@ -951,6 +1057,9 @@ erts_send_message(Process* sender,
mp->data.attached = NULL;
ERL_MESSAGE_TERM(mp) = message;
ERL_MESSAGE_TOKEN(mp) = NIL;
+#ifdef HAVE_DTRACE
+ ERL_MESSAGE_DT_UTAG(mp) = NIL;
+#endif
mp->next = NULL;
/*
* We move 'in queue' to 'private queue' and place
@@ -984,7 +1093,11 @@ erts_send_message(Process* sender,
BM_SWAP_TIMER(copy,send);
DTRACE6(message_send, sender_name, receiver_name,
msize, tok_label, tok_lastcnt, tok_serial);
- erts_queue_message(receiver, receiver_locks, bp, message, token);
+ erts_queue_message(receiver, receiver_locks, bp, message, token
+#ifdef HAVE_DTRACE
+ , NIL
+#endif
+ );
BM_SWAP_TIMER(send,system);
#else
ErlMessage* mp = message_alloc();
@@ -1008,6 +1121,9 @@ erts_send_message(Process* sender,
(uint32_t)msize, tok_label, tok_lastcnt, tok_serial);
ERL_MESSAGE_TERM(mp) = message;
ERL_MESSAGE_TOKEN(mp) = NIL;
+#ifdef HAVE_DTRACE
+ ERL_MESSAGE_DT_UTAG(mp) = NIL;
+#endif
mp->next = NULL;
mp->data.attached = NULL;
LINK_MESSAGE(receiver, mp);
@@ -1046,7 +1162,11 @@ erts_deliver_exit_message(Eterm from, Process *to, ErtsProcLocks *to_locksp,
Eterm temptoken;
ErlHeapFragment* bp = NULL;
- if (token != NIL) {
+ if (token != NIL
+#ifdef HAVE_DTRACE
+ && token != am_have_dt_utag
+#endif
+ ) {
ASSERT(is_tuple(token));
sz_reason = size_object(reason);
@@ -1061,7 +1181,11 @@ erts_deliver_exit_message(Eterm from, Process *to, ErtsProcLocks *to_locksp,
/* the trace token must in this case be updated by the caller */
seq_trace_output(token, save, SEQ_TRACE_SEND, to->id, NULL);
temptoken = copy_struct(token, sz_token, &hp, &bp->off_heap);
- erts_queue_message(to, to_locksp, bp, save, temptoken);
+ erts_queue_message(to, to_locksp, bp, save, temptoken
+#ifdef HAVE_DTRACE
+ , NIL
+#endif
+ );
} else {
ErlOffHeap *ohp;
sz_reason = size_object(reason);
@@ -1078,7 +1202,11 @@ erts_deliver_exit_message(Eterm from, Process *to, ErtsProcLocks *to_locksp,
? from
: copy_struct(from, sz_from, &hp, ohp));
save = TUPLE3(hp, am_EXIT, from_copy, mess);
- erts_queue_message(to, to_locksp, bp, save, NIL);
+ erts_queue_message(to, to_locksp, bp, save, NIL
+#ifdef HAVE_DTRACE
+ , NIL
+#endif
+ );
}
}
diff --git a/erts/emulator/beam/erl_message.h b/erts/emulator/beam/erl_message.h
index 5aca0db6fe..98321dd2c6 100644
--- a/erts/emulator/beam/erl_message.h
+++ b/erts/emulator/beam/erl_message.h
@@ -70,11 +70,18 @@ typedef struct erl_mesg {
ErlHeapFragment *heap_frag;
void *attached;
} data;
+#ifdef HAVE_DTRACE
+ Eterm m[3]; /* m[0] = message, m[1] = seq trace token, m[3] = dynamic trace user tag */
+#else
Eterm m[2]; /* m[0] = message, m[1] = seq trace token */
+#endif
} ErlMessage;
#define ERL_MESSAGE_TERM(mp) ((mp)->m[0])
#define ERL_MESSAGE_TOKEN(mp) ((mp)->m[1])
+#ifdef HAVE_DTRACE
+#define ERL_MESSAGE_DT_UTAG(mp) ((mp)->m[2])
+#endif
/* Size of default message buffer (erl_message.c) */
#define ERL_MESSAGE_BUF_SZ 500
@@ -221,7 +228,11 @@ ErlHeapFragment* erts_resize_message_buffer(ErlHeapFragment *, Uint,
Eterm *, Uint);
void free_message_buffer(ErlHeapFragment *);
void erts_queue_dist_message(Process*, ErtsProcLocks*, ErtsDistExternal *, Eterm);
-void erts_queue_message(Process*, ErtsProcLocks*, ErlHeapFragment*, Eterm, Eterm);
+void erts_queue_message(Process*, ErtsProcLocks*, ErlHeapFragment*, Eterm, Eterm
+#ifdef HAVE_DTRACE
+ , Eterm dt_utag
+#endif
+);
void erts_deliver_exit_message(Eterm, Process*, ErtsProcLocks *, Eterm, Eterm);
void erts_send_message(Process*, Process*, ErtsProcLocks*, Eterm, unsigned);
void erts_link_mbuf_to_proc(Process *proc, ErlHeapFragment *bp);
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index dc4049327d..ebc771b016 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -351,7 +351,11 @@ int enif_send(ErlNifEnv* env, const ErlNifPid* to_pid,
if (flush_me) {
flush_env(env); /* Needed for ERTS_HOLE_CHECK */
}
- erts_queue_message(rp, &rp_locks, frags, msg, am_undefined);
+ erts_queue_message(rp, &rp_locks, frags, msg, am_undefined
+#ifdef HAVE_DTRACE
+ , NIL
+#endif
+ );
if (rp_locks) {
ERTS_SMP_LC_ASSERT(rp_locks == (rp_had_locks | (ERTS_PROC_LOCK_MSGQ |
ERTS_PROC_LOCK_STATUS)));
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index 1173624f51..6771e00c7e 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -679,7 +679,11 @@ reply_sched_wall_time(void *vswtrp)
hpp = &hp;
}
- erts_queue_message(rp, &rp_locks, bp, msg, NIL);
+ erts_queue_message(rp, &rp_locks, bp, msg, NIL
+#ifdef HAVE_DTRACE
+ , NIL
+#endif
+ );
if (swtrp->req_sched == esdp->no)
rp_locks &= ~ERTS_PROC_LOCK_MAIN;
@@ -7260,6 +7264,10 @@ erl_create_process(Process* parent, /* Parent of process (default group leader).
p->seq_trace_lastcnt = 0;
p->seq_trace_clock = 0;
SEQ_TRACE_TOKEN(p) = NIL;
+#ifdef HAVE_DTRACE
+ DT_UTAG(p) = NIL;
+ DT_UTAG_FLAGS(p) = 0;
+#endif
p->parent = parent->id == ERTS_INVALID_PID ? NIL : parent->id;
#ifdef HYBRID
@@ -7851,7 +7859,11 @@ static ERTS_INLINE void
send_exit_message(Process *to, ErtsProcLocks *to_locksp,
Eterm exit_term, Uint term_size, Eterm token)
{
- if (token == NIL) {
+ if (token == NIL
+#ifdef HAVE_DTRACE
+ || token == am_have_dt_utag
+#endif
+ ) {
Eterm* hp;
Eterm mess;
ErlHeapFragment* bp;
@@ -7859,7 +7871,11 @@ send_exit_message(Process *to, ErtsProcLocks *to_locksp,
hp = erts_alloc_message_heap(term_size, &bp, &ohp, to, to_locksp);
mess = copy_struct(exit_term, term_size, &hp, ohp);
- erts_queue_message(to, to_locksp, bp, mess, NIL);
+ erts_queue_message(to, to_locksp, bp, mess, NIL
+#ifdef HAVE_DTRACE
+ , NIL
+#endif
+ );
} else {
ErlHeapFragment* bp;
Eterm* hp;
@@ -7875,7 +7891,11 @@ send_exit_message(Process *to, ErtsProcLocks *to_locksp,
/* the trace token must in this case be updated by the caller */
seq_trace_output(token, mess, SEQ_TRACE_SEND, to->id, NULL);
temp_token = copy_struct(token, sz_token, &hp, &bp->off_heap);
- erts_queue_message(to, to_locksp, bp, mess, temp_token);
+ erts_queue_message(to, to_locksp, bp, mess, temp_token
+#ifdef HAVE_DTRACE
+ , NIL
+#endif
+ );
}
}
@@ -7981,7 +8001,11 @@ send_exit_signal(Process *c_p, /* current process if and only
if (ERTS_PROC_IS_TRAPPING_EXITS(rp)
&& (reason != am_kill || (flags & ERTS_XSIG_FLG_IGN_KILL))) {
- if (is_not_nil(token) && token_update)
+ if (is_not_nil(token)
+#ifdef HAVE_DTRACE
+ && token != am_have_dt_utag
+#endif
+ && token_update)
seq_trace_update_send(token_update);
if (is_value(exit_tuple))
send_exit_message(rp, rp_locks, exit_tuple, exit_tuple_sz, token);
diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h
index d671638ce8..35b31b1009 100644
--- a/erts/emulator/beam/erl_process.h
+++ b/erts/emulator/beam/erl_process.h
@@ -683,6 +683,10 @@ struct process {
Uint seq_trace_lastcnt;
Eterm seq_trace_token; /* Sequential trace token (tuple size 5 see below) */
+#ifdef HAVE_DTRACE
+ Eterm dt_utag; /* Place to store the dynamc trace user tag */
+ Uint dt_utag_flags; /* flag field for the dt_utag */
+#endif
BeamInstr initial[3]; /* Initial module(0), function(1), arity(2), often used instead
of pointer to funcinfo instruction, hence the BeamInstr datatype */
BeamInstr* current; /* Current Erlang function, part of the funcinfo:
@@ -998,6 +1002,14 @@ extern struct erts_system_profile_flags_t erts_system_profile_flags;
#define SEQ_TRACE_PRINT (1 << 2)
#define SEQ_TRACE_TIMESTAMP (1 << 3)
+#ifdef HAVE_DTRACE
+#define DT_UTAG_PERMANENT (1 << 0)
+#define DT_UTAG_SPREADING (1 << 1)
+#define DT_UTAG(P) ((P)->dt_utag)
+#define DT_UTAG_FLAGS(P) ((P)->dt_utag_flags)
+#endif
+
+
#ifdef ERTS_SMP
/* Status flags ... */
#define ERTS_PROC_SFLG_PENDADD2SCHEDQ (((Uint32) 1) << 0) /* Pending
diff --git a/erts/emulator/beam/erl_trace.c b/erts/emulator/beam/erl_trace.c
index b1d1e1d9b0..a4aed0122b 100644
--- a/erts/emulator/beam/erl_trace.c
+++ b/erts/emulator/beam/erl_trace.c
@@ -125,8 +125,13 @@ do { \
enqueue_sys_msg_unlocked(SYS_MSG_TYPE_TRACE, (FPID), (TPID), (MSG), (BP)); \
} while(0)
#else
+#ifdef HAVE_DTRACE
#define ERTS_ENQ_TRACE_MSG(FPID, TPROC, MSG, BP) \
- erts_queue_message((TPROC), NULL, (BP), (MSG), NIL)
+ erts_queue_message((TPROC), NULL, (BP), (MSG), NIL, NIL)
+#else
+#define ERTS_ENQ_TRACE_MSG(FPID, TPROC, MSG, BP) \
+ erts_queue_message((TPROC), NULL, (BP), (MSG), NIL)
+#endif
#endif
/*
@@ -583,7 +588,11 @@ profile_send(Eterm from, Eterm message) {
hp = erts_alloc_message_heap(sz, &bp, &off_heap, profile_p, 0);
msg = copy_struct(message, sz, &hp, &bp->off_heap);
- erts_queue_message(profile_p, NULL, bp, msg, NIL);
+ erts_queue_message(profile_p, NULL, bp, msg, NIL
+#ifdef HAVE_DTRACE
+ , NIL
+#endif
+ );
}
}
@@ -994,9 +1003,13 @@ seq_trace_update_send(Process *p)
{
Eterm seq_tracer = erts_get_system_seq_tracer();
ASSERT((is_tuple(SEQ_TRACE_TOKEN(p)) || is_nil(SEQ_TRACE_TOKEN(p))));
- if ( (p->id == seq_tracer) || (SEQ_TRACE_TOKEN(p) == NIL))
+ if ( (p->id == seq_tracer) || (SEQ_TRACE_TOKEN(p) == NIL)
+#ifdef HAVE_DTRACE
+ || (SEQ_TRACE_TOKEN(p) == am_have_dt_utag)
+#endif
+ ) {
return 0;
-
+ }
SEQ_TRACE_TOKEN_SENDER(p) = p->id; /* Internal pid */
SEQ_TRACE_TOKEN_SERIAL(p) =
make_small(++(p -> seq_trace_clock));
@@ -1178,7 +1191,11 @@ seq_trace_output_generic(Eterm token, Eterm msg, Uint type,
enqueue_sys_msg_unlocked(SYS_MSG_TYPE_SEQTRACE, NIL, NIL, mess, bp);
erts_smp_mtx_unlock(&smq_mtx);
#else
- erts_queue_message(tracer, NULL, bp, mess, NIL); /* trace_token must be NIL here */
+ erts_queue_message(tracer, NULL, bp, mess, NIL
+#ifdef HAVE_DTRACE
+ , NIL
+#endif
+ ); /* trace_token must be NIL here */
#endif
}
}
@@ -2469,7 +2486,11 @@ monitor_long_gc(Process *p, Uint time) {
#ifdef ERTS_SMP
enqueue_sys_msg(SYS_MSG_TYPE_SYSMON, p->id, NIL, msg, bp);
#else
- erts_queue_message(monitor_p, NULL, bp, msg, NIL);
+ erts_queue_message(monitor_p, NULL, bp, msg, NIL
+#ifdef HAVE_DTRACE
+ , NIL
+#endif
+ );
#endif
}
@@ -2541,7 +2562,11 @@ monitor_large_heap(Process *p) {
#ifdef ERTS_SMP
enqueue_sys_msg(SYS_MSG_TYPE_SYSMON, p->id, NIL, msg, bp);
#else
- erts_queue_message(monitor_p, NULL, bp, msg, NIL);
+ erts_queue_message(monitor_p, NULL, bp, msg, NIL
+#ifdef HAVE_DTRACE
+ , NIL
+#endif
+ );
#endif
}
@@ -2571,7 +2596,11 @@ monitor_generic(Process *p, Eterm type, Eterm spec) {
#ifdef ERTS_SMP
enqueue_sys_msg(SYS_MSG_TYPE_SYSMON, p->id, NIL, msg, bp);
#else
- erts_queue_message(monitor_p, NULL, bp, msg, NIL);
+ erts_queue_message(monitor_p, NULL, bp, msg, NIL
+#ifdef HAVE_DTRACE
+ , NIL
+#endif
+ );
#endif
}
@@ -3357,7 +3386,11 @@ sys_msg_dispatcher_func(void *unused)
}
else {
queue_proc_msg:
- erts_queue_message(proc,&proc_locks,smqp->bp,smqp->msg,NIL);
+ erts_queue_message(proc,&proc_locks,smqp->bp,smqp->msg,NIL
+#ifdef HAVE_DTRACE
+ , NIL
+#endif
+ );
#ifdef DEBUG_PRINTOUTS
erts_fprintf(stderr, "delivered\n");
#endif
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c
index 81f79b8f85..75ea53c2b7 100644
--- a/erts/emulator/beam/io.c
+++ b/erts/emulator/beam/io.c
@@ -1564,7 +1564,11 @@ deliver_result(Eterm sender, Eterm pid, Eterm res)
hp = erts_alloc_message_heap(sz_res + 3, &bp, &ohp, rp, &rp_locks);
res = copy_struct(res, sz_res, &hp, ohp);
tuple = TUPLE2(hp, sender, res);
- erts_queue_message(rp, &rp_locks, bp, tuple, NIL);
+ erts_queue_message(rp, &rp_locks, bp, tuple, NIL
+#ifdef HAVE_DTRACE
+ , NIL
+#endif
+ );
erts_smp_proc_unlock(rp, rp_locks);
erts_smp_proc_dec_refc(rp);
}
@@ -1653,7 +1657,11 @@ static void deliver_read_message(Port* prt, Eterm to,
tuple = TUPLE2(hp, prt->id, tuple);
hp += 3;
- erts_queue_message(rp, &rp_locks, bp, tuple, am_undefined);
+ erts_queue_message(rp, &rp_locks, bp, tuple, am_undefined
+#ifdef HAVE_DTRACE
+ , NIL
+#endif
+ );
erts_smp_proc_unlock(rp, rp_locks);
erts_smp_proc_dec_refc(rp);
}
@@ -1806,7 +1814,11 @@ deliver_vec_message(Port* prt, /* Port */
tuple = TUPLE2(hp, prt->id, tuple);
hp += 3;
- erts_queue_message(rp, &rp_locks, bp, tuple, am_undefined);
+ erts_queue_message(rp, &rp_locks, bp, tuple, am_undefined
+#ifdef HAVE_DTRACE
+ , NIL
+#endif
+ );
erts_smp_proc_unlock(rp, rp_locks);
erts_smp_proc_dec_refc(rp);
}
@@ -2772,7 +2784,11 @@ void driver_report_exit(int ix, int status)
hp += 3;
tuple = TUPLE2(hp, prt->id, tuple);
- erts_queue_message(rp, &rp_locks, bp, tuple, am_undefined);
+ erts_queue_message(rp, &rp_locks, bp, tuple, am_undefined
+#ifdef HAVE_DTRACE
+ , NIL
+#endif
+ );
erts_smp_proc_unlock(rp, rp_locks);
erts_smp_proc_dec_refc(rp);
@@ -3322,7 +3338,11 @@ driver_deliver_term(ErlDrvPort port,
HRelease(rp, hp_end, hp);
}
/* send message */
- erts_queue_message(rp, &rp_locks, bp, mess, am_undefined);
+ erts_queue_message(rp, &rp_locks, bp, mess, am_undefined
+#ifdef HAVE_DTRACE
+ , NIL
+#endif
+ );
}
else {
if (b2t.ix > b2t.used)
diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c
index 49b6618f73..2efcd19162 100644
--- a/erts/emulator/beam/utils.c
+++ b/erts/emulator/beam/utils.c
@@ -1697,7 +1697,11 @@ static int do_send_to_logger(Eterm tag, Eterm gleader, char *buf, int len)
erts_queue_error_logger_message(from, tuple3, bp);
}
#else
- erts_queue_message(p, NULL /* only used for smp build */, bp, tuple3, NIL);
+ erts_queue_message(p, NULL /* only used for smp build */, bp, tuple3, NIL
+#ifdef HAVE_DTRACE
+ , NIL
+#endif
+ );
#endif
return 0;
}
diff --git a/erts/emulator/drivers/common/efile_drv.c b/erts/emulator/drivers/common/efile_drv.c
index 293f024e45..62b582f76a 100644
--- a/erts/emulator/drivers/common/efile_drv.c
+++ b/erts/emulator/drivers/common/efile_drv.c
@@ -100,7 +100,7 @@
#endif
#include <stdlib.h>
-// Need (NON)BLOCKING macros for sendfile
+/* Need (NON)BLOCKING macros for sendfile */
#ifndef WANT_NONBLOCKING
#define WANT_NONBLOCKING
#endif
@@ -112,7 +112,7 @@
#include "erl_threads.h"
#include "zlib.h"
#include "gzio.h"
-#include "dtrace-wrapper.h"
+#include "dtrace-wrapper.h"
#include <ctype.h>
#include <sys/types.h>
@@ -149,10 +149,6 @@ typedef struct {
dt_private *get_dt_private(int);
#else /* HAVE_DTRACE */
-typedef struct {
- char dummy; /* Unused except to quiet some compilers */
-} dt_private;
-
#define DTRACE_INVOKE_SETUP(op) do {} while (0)
#define DTRACE_INVOKE_SETUP_BY_NAME(op) do {} while (0)
#define DTRACE_INVOKE_RETURN(op) do {} while (0)
@@ -212,6 +208,9 @@ typedef struct {
#ifdef FILENAMES_16BIT
+#ifdef HAVE_DTRACE
+#error 16bit characters in filenames and dtrace in combination is not supported.
+#endif
# define FILENAME_BYTELEN(Str) filename_len_16bit(Str)
# define FILENAME_COPY(To,From) filename_cpy_16bit((To),(From))
# define FILENAME_CHARSIZE 2
@@ -432,8 +431,6 @@ struct t_data
int sched_i1;
Uint64 sched_i2;
char sched_utag[DTRACE_EFILE_BUFSIZ+1];
-#else
- char sched_utag[1];
#endif
int result_ok;
Efile_error errInfo;
@@ -2027,8 +2024,11 @@ static void cq_execute(file_descriptor *desc) {
}
static struct t_data *async_write(file_descriptor *desc, int *errp,
- int reply, Uint32 reply_size,
- Sint64 *dt_i1, Sint64 *dt_i2, Sint64 *dt_i3) {
+ int reply, Uint32 reply_size
+#ifdef HAVE_DTRACE
+ ,Sint64 *dt_i1, Sint64 *dt_i2, Sint64 *dt_i3
+#endif
+) {
struct t_data *d;
if (! (d = EF_ALLOC(sizeof(struct t_data) - 1))) {
if (errp) *errp = ENOMEM;
@@ -2041,11 +2041,13 @@ static struct t_data *async_write(file_descriptor *desc, int *errp,
d->c.writev.port = desc->port;
d->c.writev.q_mtx = desc->q_mtx;
d->c.writev.size = desc->write_buffered;
+#ifdef HAVE_DTRACE
if (dt_i1 != NULL) {
*dt_i1 = d->fd;
*dt_i2 = d->flags;
*dt_i3 = d->c.writev.size;
}
+#endif
d->reply = reply;
d->c.writev.free_size = 0;
d->c.writev.reply_size = reply_size;
@@ -2057,16 +2059,24 @@ static struct t_data *async_write(file_descriptor *desc, int *errp,
return d;
}
-static int flush_write(file_descriptor *desc, int *errp,
- dt_private *dt_priv, char *dt_utag) {
+static int flush_write(file_descriptor *desc, int *errp
+#ifdef HAVE_DTRACE
+ , dt_private *dt_priv, char *dt_utag
+#endif
+) {
int result = 0;
+#ifdef HAVE_DTRACE
Sint64 dt_i1 = 0, dt_i2 = 0, dt_i3 = 0;
+#endif
struct t_data *d = NULL;
MUTEX_LOCK(desc->q_mtx);
if (desc->write_buffered > 0) {
- if ((d = async_write(desc, errp, 0, 0,
- &dt_i1, &dt_i2, &dt_i3)) == NULL) {
+ if ((d = async_write(desc, errp, 0, 0
+#ifdef HAVE_DTRACE
+ ,&dt_i1, &dt_i2, &dt_i3
+#endif
+ )) == NULL) {
result = -1;
}
}
@@ -2101,10 +2111,17 @@ static int check_write_error(file_descriptor *desc, int *errp) {
return 0;
}
-static int flush_write_check_error(file_descriptor *desc, int *errp,
- dt_private *dt_priv, char *dt_utag) {
+static int flush_write_check_error(file_descriptor *desc, int *errp
+#ifdef HAVE_DTRACE
+ , dt_private *dt_priv, char *dt_utag
+#endif
+ ) {
int r;
- if ( (r = flush_write(desc, errp, dt_priv, dt_utag)) != 0) {
+ if ( (r = flush_write(desc, errp
+#ifdef HAVE_DTRACE
+ , dt_priv, dt_utag
+#endif
+ )) != 0) {
check_write_error(desc, NULL);
return r;
} else {
@@ -2113,8 +2130,11 @@ static int flush_write_check_error(file_descriptor *desc, int *errp,
}
static struct t_data *async_lseek(file_descriptor *desc, int *errp, int reply,
- Sint64 offset, int origin,
- Sint64 *dt_i1, Sint64 *dt_i2, Sint64 *dt_i3) {
+ Sint64 offset, int origin
+#ifdef HAVE_DTRACE
+ , Sint64 *dt_i1, Sint64 *dt_i2, Sint64 *dt_i3
+#endif
+ ) {
struct t_data *d;
if (! (d = EF_ALLOC(sizeof(struct t_data)))) {
*errp = ENOMEM;
@@ -2126,11 +2146,13 @@ static struct t_data *async_lseek(file_descriptor *desc, int *errp, int reply,
d->reply = reply;
d->c.lseek.offset = offset;
d->c.lseek.origin = origin;
+#ifdef HAVE_DTRACE
if (dt_i1 != NULL) {
*dt_i1 = d->fd;
*dt_i2 = d->c.lseek.offset;
*dt_i3 = d->c.lseek.origin;
}
+#endif
d->invoke = invoke_lseek;
d->free = free_data;
d->level = 1;
@@ -2147,18 +2169,26 @@ static void flush_read(file_descriptor *desc) {
}
}
-static int lseek_flush_read(file_descriptor *desc, int *errp,
- dt_private *dt_priv, char *dt_utag) {
+static int lseek_flush_read(file_descriptor *desc, int *errp
+#ifdef HAVE_DTRACE
+ ,dt_private *dt_priv, char *dt_utag
+#endif
+ ) {
int r = 0;
size_t read_size = desc->read_size;
+#ifdef HAVE_DTRACE
Sint64 dt_i1 = 0, dt_i2 = 0, dt_i3 = 0;
+#endif
struct t_data *d;
flush_read(desc);
if (read_size != 0) {
if ((d = async_lseek(desc, errp, 0,
- -((ssize_t)read_size), EFILE_SEEK_CUR,
- &dt_i1, &dt_i2, &dt_i3)) == NULL) {
+ -((ssize_t)read_size), EFILE_SEEK_CUR
+#ifdef HAVE_DTRACE
+ , &dt_i1, &dt_i2, &dt_i3
+#endif
+ )) == NULL) {
r = -1;
} else {
#ifdef HAVE_DTRACE
@@ -2490,13 +2520,13 @@ file_output(ErlDrvData e, char* buf, ErlDrvSizeT count)
char* name; /* Points to the filename in buf. */
int command;
struct t_data *d = NULL;
- ERTS_DECLARE_DUMMY(char *dt_utag) = NULL;
- char *dt_s1 = NULL, *dt_s2 = NULL;
- ERTS_DECLARE_DUMMY(Sint64 dt_i1) = 0;
- ERTS_DECLARE_DUMMY(Sint64 dt_i2) = 0;
- ERTS_DECLARE_DUMMY(Sint64 dt_i3) = 0;
- ERTS_DECLARE_DUMMY(Sint64 dt_i4) = 0;
#ifdef HAVE_DTRACE
+ char *dt_utag = NULL;
+ char *dt_s1 = NULL, *dt_s2 = NULL;
+ Sint64 dt_i1 = 0;
+ Sint64 dt_i2 = 0;
+ Sint64 dt_i3 = 0;
+ Sint64 dt_i4 = 0;
dt_private *dt_priv = get_dt_private(0);
#endif /* HAVE_DTRACE */
@@ -2513,8 +2543,10 @@ file_output(ErlDrvData e, char* buf, ErlDrvSizeT count)
d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + FILENAME_BYTELEN(name) + FILENAME_CHARSIZE);
FILENAME_COPY(d->b, name);
+#ifdef HAVE_DTRACE
dt_s1 = d->b;
- dt_utag = name + strlen(d->b) + 1;
+ dt_utag = name + FILENAME_BYTELEN(name) + FILENAME_CHARSIZE;
+#endif
d->command = command;
d->invoke = invoke_mkdir;
d->free = free_data;
@@ -2526,8 +2558,10 @@ file_output(ErlDrvData e, char* buf, ErlDrvSizeT count)
d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + FILENAME_BYTELEN(name) + FILENAME_CHARSIZE);
FILENAME_COPY(d->b, name);
+#ifdef HAVE_DTRACE
dt_s1 = d->b;
- dt_utag = name + strlen(d->b) + 1;
+ dt_utag = name + FILENAME_BYTELEN(name) + FILENAME_CHARSIZE;
+#endif
d->command = command;
d->invoke = invoke_rmdir;
d->free = free_data;
@@ -2539,8 +2573,10 @@ file_output(ErlDrvData e, char* buf, ErlDrvSizeT count)
d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + FILENAME_BYTELEN(name) + FILENAME_CHARSIZE);
FILENAME_COPY(d->b, name);
+#ifdef HAVE_DTRACE
dt_s1 = d->b;
- dt_utag = name + strlen(d->b) + 1;
+ dt_utag = name + FILENAME_BYTELEN(name) + FILENAME_CHARSIZE;
+#endif
d->command = command;
d->invoke = invoke_delete_file;
d->free = free_data;
@@ -2557,10 +2593,12 @@ file_output(ErlDrvData e, char* buf, ErlDrvSizeT count)
+ FILENAME_BYTELEN(new_name) + FILENAME_CHARSIZE);
FILENAME_COPY(d->b, name);
- dt_s1 = d->b;
FILENAME_COPY(d->b + namelen, new_name);
+#ifdef HAVE_DTRACE
+ dt_s1 = d->b;
dt_s2 = d->b + namelen;
- dt_utag = buf + namelen + strlen(dt_s2) + 1;
+ dt_utag = buf + namelen + FILENAME_BYTELEN(name) + FILENAME_CHARSIZE;
+#endif
d->flags = desc->flags;
d->fd = fd;
d->command = command;
@@ -2574,8 +2612,10 @@ file_output(ErlDrvData e, char* buf, ErlDrvSizeT count)
d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + FILENAME_BYTELEN(name) + FILENAME_CHARSIZE);
FILENAME_COPY(d->b, name);
+#ifdef HAVE_DTRACE
dt_s1 = d->b;
- dt_utag = name + strlen(d->b) + 1;
+ dt_utag = name + FILENAME_BYTELEN(name) + FILENAME_CHARSIZE;
+#endif
d->command = command;
d->invoke = invoke_chdir;
d->free = free_data;
@@ -2587,7 +2627,9 @@ file_output(ErlDrvData e, char* buf, ErlDrvSizeT count)
d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + RESBUFSIZE + 1);
d->drive = *(uchar*)buf;
+#ifdef HAVE_DTRACE
dt_utag = buf + 1;
+#endif
d->command = command;
d->invoke = invoke_pwd;
d->free = free_data;
@@ -2603,8 +2645,10 @@ file_output(ErlDrvData e, char* buf, ErlDrvSizeT count)
FILENAME_CHARSIZE);
FILENAME_COPY(d->b, name);
+#ifdef HAVE_DTRACE
dt_s1 = d->b;
- dt_utag = name + strlen(d->b) + 1;
+ dt_utag = name + FILENAME_BYTELEN(name) + FILENAME_CHARSIZE;
+#endif
d->dir_handle = NULL;
d->command = command;
d->invoke = invoke_readdir;
@@ -2629,9 +2673,10 @@ file_output(ErlDrvData e, char* buf, ErlDrvSizeT count)
dir_handle = NULL;
resbuf[0] = FILE_RESP_LFNAME;
+#ifdef HAVE_DTRACE
dt_s1 = name;
- dt_utag = name + strlen(dt_s1) + 1;
-
+ dt_utag = name + FILENAME_BYTELEN(name) + FILENAME_CHARSIZE;
+#endif
/* Fill the buffer with multiple directory listings before sending it to the
* receiving process. READDIR_CHUNKS is minimum number of files sent to the
* receiver.
@@ -2680,11 +2725,13 @@ file_output(ErlDrvData e, char* buf, ErlDrvSizeT count)
FILENAME_CHARSIZE);
d->flags = get_int32((uchar*)buf);
- dt_i1 = d->flags;
name = buf+4;
FILENAME_COPY(d->b, name);
+#ifdef HAVE_DTRACE
+ dt_i1 = d->flags;
dt_s1 = d->b;
- dt_utag = name + strlen(d->b) + 1;
+ dt_utag = name + FILENAME_BYTELEN(d->b) + FILENAME_CHARSIZE;
+#endif
d->command = command;
d->invoke = invoke_open;
d->free = free_data;
@@ -2696,9 +2743,11 @@ file_output(ErlDrvData e, char* buf, ErlDrvSizeT count)
{
d = EF_SAFE_ALLOC(sizeof(struct t_data));
- dt_utag = name;
d->fd = fd;
+#ifdef HAVE_DTRACE
+ dt_utag = name;
dt_i1 = fd;
+#endif
d->command = command;
d->invoke = invoke_fdatasync;
d->free = free_data;
@@ -2710,9 +2759,11 @@ file_output(ErlDrvData e, char* buf, ErlDrvSizeT count)
{
d = EF_SAFE_ALLOC(sizeof(struct t_data));
- dt_utag = name;
d->fd = fd;
+#ifdef HAVE_DTRACE
+ dt_utag = name;
dt_i1 = fd;
+#endif
d->command = command;
d->invoke = invoke_fsync;
d->free = free_data;
@@ -2728,13 +2779,15 @@ file_output(ErlDrvData e, char* buf, ErlDrvSizeT count)
FILENAME_CHARSIZE);
FILENAME_COPY(d->b, name);
- dt_utag = name + strlen(d->b) + 1;
d->fd = fd;
+#ifdef HAVE_DTRACE
+ dt_utag = name + FILENAME_BYTELEN(d->b) + FILENAME_CHARSIZE;
if (command == FILE_LSTAT) {
dt_s1 = d->b;
} else {
dt_i1 = fd;
}
+#endif
d->command = command;
d->invoke = invoke_flstat;
d->free = free_data;
@@ -2746,11 +2799,13 @@ file_output(ErlDrvData e, char* buf, ErlDrvSizeT count)
{
d = EF_SAFE_ALLOC(sizeof(struct t_data));
- dt_utag = name;
d->flags = desc->flags;
d->fd = fd;
+#ifdef HAVE_DTRACE
+ dt_utag = name;
dt_i1 = fd;
dt_i2 = d->flags;
+#endif
d->command = command;
d->invoke = invoke_truncate;
d->free = free_data;
@@ -2764,18 +2819,20 @@ file_output(ErlDrvData e, char* buf, ErlDrvSizeT count)
+ FILENAME_BYTELEN(buf + 9*4) + FILENAME_CHARSIZE);
d->info.mode = get_int32(buf + 0 * 4);
- dt_i1 = d->info.mode;
d->info.uid = get_int32(buf + 1 * 4);
- dt_i2 = d->info.uid;
d->info.gid = get_int32(buf + 2 * 4);
- dt_i3 = d->info.gid;
d->info.accessTime = (time_t)((Sint64)get_int64(buf + 3 * 4));
d->info.modifyTime = (time_t)((Sint64)get_int64(buf + 5 * 4));
d->info.cTime = (time_t)((Sint64)get_int64(buf + 7 * 4));
FILENAME_COPY(d->b, buf + 9*4);
+#ifdef HAVE_DTRACE
+ dt_i1 = d->info.mode;
+ dt_i2 = d->info.uid;
+ dt_i3 = d->info.gid;
dt_s1 = d->b;
- dt_utag = buf + 9 * 4 + strlen(d->b) + 1;
+ dt_utag = buf + 9 * 4 + FILENAME_BYTELEN(d->b) + FILENAME_CHARSIZE;
+#endif
d->command = command;
d->invoke = invoke_write_info;
d->free = free_data;
@@ -2788,8 +2845,10 @@ file_output(ErlDrvData e, char* buf, ErlDrvSizeT count)
d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + RESBUFSIZE + 1);
FILENAME_COPY(d->b, name);
+#ifdef HAVE_DTRACE
dt_s1 = d->b;
- dt_utag = name + strlen(d->b) + 1;
+ dt_utag = name + FILENAME_BYTELEN(d->b) + FILENAME_CHARSIZE;
+#endif
d->command = command;
d->invoke = invoke_readlink;
d->free = free_data;
@@ -2801,8 +2860,10 @@ file_output(ErlDrvData e, char* buf, ErlDrvSizeT count)
{
d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + RESBUFSIZE + 1);
FILENAME_COPY(d->b, name);
+#ifdef HAVE_DTRACE
dt_s1 = d->b;
- dt_utag = name + strlen(d->b) + 1;
+ dt_utag = name + FILENAME_BYTELEN(d->b) + FILENAME_CHARSIZE;
+#endif
d->command = command;
d->invoke = invoke_altname;
d->free = free_data;
@@ -2822,10 +2883,12 @@ file_output(ErlDrvData e, char* buf, ErlDrvSizeT count)
+ FILENAME_BYTELEN(new_name) + FILENAME_CHARSIZE);
FILENAME_COPY(d->b, name);
- dt_s1 = d->b;
FILENAME_COPY(d->b + namelen, new_name);
+#ifdef HAVE_DTRACE
+ dt_s1 = d->b;
dt_s2 = d->b + namelen;
- dt_utag = buf + namelen + strlen(dt_s2) + 1;
+ dt_utag = buf + namelen + FILENAME_BYTELEN(dt_s2) + FILENAME_CHARSIZE;
+#endif
d->flags = desc->flags;
d->fd = fd;
d->command = command;
@@ -2846,10 +2909,12 @@ file_output(ErlDrvData e, char* buf, ErlDrvSizeT count)
+ FILENAME_BYTELEN(new_name) + FILENAME_CHARSIZE);
FILENAME_COPY(d->b, name);
- dt_s1 = d->b;
FILENAME_COPY(d->b + namelen, new_name);
+#ifdef HAVE_DTRACE
+ dt_s1 = d->b;
dt_s2 = d->b + namelen;
- dt_utag = buf + namelen + strlen(dt_s2) + 1;
+ dt_utag = buf + namelen + FILENAME_BYTELEN(dt_s2) + FILENAME_CHARSIZE;
+#endif
d->flags = desc->flags;
d->fd = fd;
d->command = command;
@@ -2864,18 +2929,20 @@ file_output(ErlDrvData e, char* buf, ErlDrvSizeT count)
d = EF_SAFE_ALLOC(sizeof(struct t_data));
d->fd = fd;
- dt_i1 = d->fd;
d->command = command;
d->invoke = invoke_fadvise;
d->free = free_data;
d->level = 2;
d->c.fadvise.offset = get_int64((uchar*) buf);
- dt_i2 = d->c.fadvise.offset;
d->c.fadvise.length = get_int64(((uchar*) buf) + sizeof(Sint64));
- dt_i3 = d->c.fadvise.length;
d->c.fadvise.advise = get_int32(((uchar*) buf) + 2 * sizeof(Sint64));
+#ifdef HAVE_DTRACE
+ dt_i1 = d->fd;
+ dt_i2 = d->c.fadvise.offset;
+ dt_i3 = d->c.fadvise.length;
dt_i4 = d->c.fadvise.advise;
dt_utag = buf + 3 * sizeof(Sint64);
+#endif
goto done;
}
@@ -2920,8 +2987,6 @@ file_flush(ErlDrvData e) {
#endif
#ifdef HAVE_DTRACE
dt_private *dt_priv = get_dt_private(dt_driver_io_worker_base);
-#else
- dt_private *dt_priv = NULL;
#endif
TRACE_C('f');
@@ -2933,8 +2998,11 @@ file_flush(ErlDrvData e) {
#ifdef DEBUG
r =
#endif
- flush_write(desc, NULL, dt_priv,
- (desc->d == NULL) ? NULL : desc->d->sched_utag);
+ flush_write(desc, NULL
+#ifdef HAVE_DTRACE
+ , dt_priv, (desc->d == NULL) ? NULL : desc->d->sched_utag
+#endif
+ );
/* Only possible reason for bad return value is ENOMEM, and
* there is nobody to tell...
*/
@@ -2978,8 +3046,6 @@ file_timeout(ErlDrvData e) {
enum e_timer timer_state = desc->timer_state;
#ifdef HAVE_DTRACE
dt_private *dt_priv = get_dt_private(dt_driver_io_worker_base);
-#else
- dt_private *dt_priv = NULL;
#endif
TRACE_C('t');
@@ -2998,8 +3064,11 @@ file_timeout(ErlDrvData e) {
#ifdef DEBUG
int r =
#endif
- flush_write(desc, NULL, dt_priv,
- (desc->d == NULL) ? NULL : desc->d->sched_utag);
+ flush_write(desc, NULL
+#ifdef HAVE_DTRACE
+ , dt_priv, (desc->d == NULL) ? NULL : desc->d->sched_utag
+#endif
+ );
/* Only possible reason for bad return value is ENOMEM, and
* there is nobody to tell...
*/
@@ -3021,15 +3090,14 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) {
int p, q;
int err;
struct t_data *d = NULL;
+#ifdef HAVE_DTRACE
Sint64 dt_i1 = 0, dt_i2 = 0, dt_i3 = 0;
- ERTS_DECLARE_DUMMY(Sint64 dt_i4) = 0;
+ Sint64 dt_i4 = 0;
char *dt_utag = NULL;
- ERTS_DECLARE_DUMMY(char *dt_s1) = NULL;
-#ifdef HAVE_DTRACE
+ char *dt_s1 = NULL;
dt_private *dt_priv = get_dt_private(dt_driver_io_worker_base);
-#else
- dt_private *dt_priv = NULL;
#endif
+
TRACE_C('v');
p = 0; q = 1;
@@ -3048,9 +3116,15 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) {
switch (command) {
case FILE_CLOSE: {
+#ifdef HAVE_DTRACE
dt_utag = EV_CHAR_P(ev, p, q);
+#endif
flush_read(desc);
- if (flush_write_check_error(desc, &err, dt_priv, dt_utag) < 0) {
+ if (flush_write_check_error(desc, &err
+#ifdef HAVE_DTRACE
+ , dt_priv, dt_utag
+#endif
+ ) < 0) {
reply_posix_error(desc, err);
goto done;
}
@@ -3061,9 +3135,11 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) {
d->command = command;
d->reply = !0;
d->fd = desc->fd;
- dt_i1 = d->fd;
d->flags = desc->flags;
+#ifdef HAVE_DTRACE
+ dt_i1 = d->fd;
dt_i2 = d->flags;
+#endif
d->invoke = invoke_close;
d->free = free_data;
d->level = 2;
@@ -3086,8 +3162,14 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) {
reply_posix_error(desc, EINVAL);
goto done;
}
+#ifdef HAVE_DTRACE
dt_utag = EV_CHAR_P(ev, p, q);
- if (flush_write_check_error(desc, &err, dt_priv, dt_utag) < 0) {
+#endif
+ if (flush_write_check_error(desc, &err
+#ifdef HAVE_DTRACE
+ , dt_priv, dt_utag
+#endif
+ ) < 0) {
reply_posix_error(desc, err);
goto done;
}
@@ -3095,7 +3177,11 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) {
if (desc->read_bufsize == 0 && desc->read_binp != NULL && desc->read_size > 0) {
/* We have allocated a buffer for line mode but should not really have a
read-ahead buffer... */
- if (lseek_flush_read(desc, &err, dt_priv) < 0) {
+ if (lseek_flush_read(desc, &err
+#ifdef HAVE_DTRACE
+ , dt_priv, dt_utag
+#endif
+ ) < 0) {
reply_posix_error(desc, err);
goto done;
}
@@ -3171,14 +3257,16 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) {
d->command = command;
d->reply = !0;
d->fd = desc->fd;
- dt_i1 = d->fd;
d->flags = desc->flags;
- dt_i2 = d->flags;
d->c.read.binp = desc->read_binp;
d->c.read.bin_offset = desc->read_offset + desc->read_size;
d->c.read.bin_size = desc->read_binp->orig_size - d->c.read.bin_offset;
d->c.read.size = size;
+#ifdef HAVE_DTRACE
+ dt_i1 = d->fd;
+ dt_i2 = d->flags;
dt_i3 = d->c.read.size;
+#endif
driver_binary_inc_refc(d->c.read.binp);
d->invoke = invoke_read;
d->free = free_read;
@@ -3196,12 +3284,22 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) {
* allocated binary + dealing with offsets and lengts are done in file_async ready
* for this OP.
*/
+#ifdef HAVE_DTRACE
dt_utag = EV_CHAR_P(ev, p, q);
- if (flush_write_check_error(desc, &err, dt_priv, dt_utag) < 0) {
+#endif
+ if (flush_write_check_error(desc, &err
+#ifdef HAVE_DTRACE
+ , dt_priv, dt_utag
+#endif
+ ) < 0) {
reply_posix_error(desc, err);
goto done;
}
- if (ev->size != 1+strlen(dt_utag)+1) {
+ if (ev->size != 1
+#ifdef HAVE_DTRACE
+ + FILENAME_BYTELEN(dt_utag) + FILENAME_CHARSIZE
+#endif
+ ) {
/* Wrong command length */
reply_posix_error(desc, EINVAL);
goto done;
@@ -3253,41 +3351,43 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) {
d->command = command;
d->reply = !0;
d->fd = desc->fd;
- dt_i1 = d->fd;
d->flags = desc->flags;
- dt_i2 = d->flags;
d->c.read_line.binp = desc->read_binp;
d->c.read_line.read_offset = desc->read_offset;
d->c.read_line.read_size = desc->read_size;
+#ifdef HAVE_DTRACE
+ dt_i1 = d->fd;
+ dt_i2 = d->flags;
dt_i3 = d->c.read_line.read_offset;
+#endif
#if !ALWAYS_READ_LINE_AHEAD
d->c.read_line.read_ahead = (desc->read_bufsize > 0);
-#endif
+#ifdef HAVE_DTRACE
dt_i4 = d->c.read_line.read_ahead;
+#endif
+#endif
driver_binary_inc_refc(d->c.read.binp);
d->invoke = invoke_read_line;
d->free = free_read_line;
d->level = 1;
cq_enq(desc, d);
} goto done;
- case FILE_WRITE: {
+ case FILE_WRITE: { /* Dtrace: The dtrace user tag is not last in message,
+ but follows the message tag directly.
+ This is handled specially in prim_file.erl */
ErlDrvSizeT skip = 1;
ErlDrvSizeT size = ev->size - skip;
+#ifdef HAVE_DTRACE
dt_utag = EV_CHAR_P(ev, p, q);
- skip += strlen(dt_utag) + 1;
+ skip += FILENAME_BYTELEN(dt_utag) + FILENAME_CHARSIZE;
size = ev->size - skip;
- /*
- * Interesting dependency on using port # for key to async
- * I/O worker pool thread: lseek_flush_read() can enqueue a
- * lseek() op. If that lseek() were scheduled on a different
- * thread than the write that we'll enqueue later in this case,
- * then Bad Things could happen. This DTrace work is probably
- * well worthwhile to get a sense of how often there's head-of-
- * line blocking/unfairness during busy file I/O because of the
- * mapping of port #/key -> thread.
- */
- if (lseek_flush_read(desc, &err, dt_priv, dt_utag) < 0) {
+#endif
+ if (lseek_flush_read(desc, &err
+#ifdef HAVE_DTRACE
+ , dt_priv, dt_utag
+#endif
+ ) < 0) {
reply_posix_error(desc, err);
goto done;
}
@@ -3314,8 +3414,11 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) {
driver_set_timer(desc->port, desc->write_delay);
}
} else {
- if ((d = async_write(desc, &err, !0, size,
- &dt_i1, &dt_i2, &dt_i3)) == NULL) {
+ if ((d = async_write(desc, &err, !0, size
+#ifdef HAVE_DTRACE
+ , &dt_i1, &dt_i2, &dt_i3
+#endif
+ )) == NULL) {
MUTEX_UNLOCK(desc->q_mtx);
reply_posix_error(desc, err);
goto done;
@@ -3325,27 +3428,46 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) {
}
} goto done; /* case FILE_WRITE */
- case FILE_PWRITEV: {
+ case FILE_PWRITEV: { /* Dtrace: The dtrace user tag is not last in message,
+ but follows the message tag directly.
+ This is handled specially in prim_file.erl */
Uint32 i, j, n;
size_t total;
- char tmp;
+#ifdef HAVE_DTRACE
+ char dt_tmp;
int dt_utag_bytes = 1;
dt_utag = EV_CHAR_P(ev, p, q);
- while (EV_GET_CHAR(ev, &tmp, &p, &q) && tmp != '\0') {
+ /* This will work for UTF-8, but not for UTF-16 - extra reminder here */
+#ifdef FILENAMES_16BIT
+#error 16bit characters in filenames and dtrace in combination is not supported.
+#endif
+ while (EV_GET_CHAR(ev, &dt_tmp, &p, &q) && dt_tmp != '\0') {
dt_utag_bytes++;
}
- if (ev->size < 1+4+dt_utag_bytes
+#endif
+ if (ev->size < 1+4
+#ifdef HAVE_DTRACE
+ + dt_utag_bytes
+#endif
|| !EV_GET_UINT32(ev, &n, &p, &q)) {
/* Buffer too short to contain even the number of pos/size specs */
reply_Uint_posix_error(desc, 0, EINVAL);
goto done;
}
- if (lseek_flush_read(desc, &err, dt_priv, dt_utag) < 0) {
+ if (lseek_flush_read(desc, &err
+#ifdef HAVE_DTRACE
+ , dt_priv, dt_utag
+#endif
+ ) < 0) {
reply_Uint_posix_error(desc, 0, err);
goto done;
}
- if (flush_write_check_error(desc, &err, dt_priv, dt_utag) < 0) {
+ if (flush_write_check_error(desc, &err
+#ifdef HAVE_DTRACE
+ , dt_priv, dt_utag
+#endif
+ ) < 0) {
reply_Uint_posix_error(desc, 0, err);
goto done;
}
@@ -3358,7 +3480,11 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) {
}
goto done;
}
- if (ev->size < 1+4+8*(2*n)+dt_utag_bytes) {
+ if (ev->size < 1+4+8*(2*n)
+#ifdef HAVE_DTRACE
+ + dt_utag_bytes
+#endif
+ ) {
/* Buffer too short to contain even the pos/size specs */
reply_Uint_posix_error(desc, 0, EINVAL);
goto done;
@@ -3372,9 +3498,11 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) {
d->command = command;
d->reply = !0;
d->fd = desc->fd;
- dt_i1 = d->fd;
d->flags = desc->flags;
+#ifdef HAVE_DTRACE
+ dt_i1 = d->fd;
dt_i2 = d->flags;
+#endif
d->c.pwritev.port = desc->port;
d->c.pwritev.q_mtx = desc->q_mtx;
d->c.pwritev.n = n;
@@ -3412,14 +3540,20 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) {
}
}
d->c.pwritev.size = total;
+#ifdef HAVE_DTRACE
dt_i3 = d->c.pwritev.size;
+#endif
d->c.pwritev.free_size = 0;
if (j == 0) {
/* Trivial case - nothing to write */
EF_FREE(d);
reply_Uint(desc, 0);
} else {
- ErlDrvSizeT skip = 1 + 4 + 8 * (2*n) + dt_utag_bytes;
+ ErlDrvSizeT skip = 1 + 4 + 8 * (2*n)
+#ifdef HAVE_DTRACE
+ + dt_utag_bytes
+#endif
+ ;
if (skip + total != ev->size) {
/* Actual amount of data does not match
* total of all pos/size specs
@@ -3440,33 +3574,55 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) {
}
} goto done; /* case FILE_PWRITEV: */
- case FILE_PREADV: {
+ case FILE_PREADV: { /* Dtrace: The dtrace user tag is not last in message,
+ but follows the message tag directly.
+ This is handled specially in prim_file.erl */
register void * void_ptr;
Uint32 i, n;
ErlIOVec *res_ev;
- char tmp;
+#ifdef HAVE_DTRACE
+ char dt_tmp;
int dt_utag_bytes = 1;
-
+ /* This will work for UTF-8, but not for UTF-16 - extra reminder here */
+#ifdef FILENAMES_16BIT
+#error 16bit characters in filenames and dtrace in combination is not supported.
+#endif
dt_utag = EV_CHAR_P(ev, p, q);
- while (EV_GET_CHAR(ev, &tmp, &p, &q) && tmp != '\0') {
+ while (EV_GET_CHAR(ev, &dt_tmp, &p, &q) && dt_tmp != '\0') {
dt_utag_bytes++;
}
- if (lseek_flush_read(desc, &err, dt_priv, dt_utag) < 0) {
+#endif
+ if (lseek_flush_read(desc, &err
+#ifdef HAVE_DTRACE
+ , dt_priv, dt_utag
+#endif
+ ) < 0) {
reply_posix_error(desc, err);
goto done;
}
- if (flush_write_check_error(desc, &err, dt_priv, dt_utag) < 0) {
+ if (flush_write_check_error(desc, &err
+#ifdef HAVE_DTRACE
+ , dt_priv, dt_utag
+#endif
+ ) < 0) {
reply_posix_error(desc, err);
goto done;
}
- if (ev->size < 1+8+dt_utag_bytes
+ if (ev->size < 1+8
+#ifdef HAVE_DTRACE
+ + dt_utag_bytes
+#endif
|| !EV_GET_UINT32(ev, &n, &p, &q)
|| !EV_GET_UINT32(ev, &n, &p, &q)) {
/* Buffer too short to contain even the number of pos/size specs */
reply_posix_error(desc, EINVAL);
goto done;
}
- if (ev->size < 1+8+8*(2*n)+dt_utag_bytes) {
+ if (ev->size < 1+8+8*(2*n)
+#ifdef HAVE_DTRACE
+ + dt_utag_bytes
+#endif
+ ) {
/* Buffer wrong length to contain the pos/size specs */
reply_posix_error(desc, EINVAL);
goto done;
@@ -3485,9 +3641,11 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) {
d->command = command;
d->reply = !0;
d->fd = desc->fd;
- dt_i1 = d->fd;
d->flags = desc->flags;
+#ifdef HAVE_DTRACE
+ dt_i1 = d->fd;
dt_i2 = d->flags;
+#endif
d->c.preadv.n = n;
d->c.preadv.cnt = 0;
d->c.preadv.size = 0;
@@ -3515,7 +3673,9 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) {
#else
size = ((size_t)sizeH<<32) | sizeL;
#endif
+#ifdef HAVE_DTRACE
dt_i3 += size;
+#endif
if (! (res_ev->binv[i] = driver_alloc_binary(size))) {
reply_posix_error(desc, ENOMEM);
break;
@@ -3572,17 +3732,30 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) {
reply_posix_error(desc, EINVAL);
goto done;
}
+#ifdef HAVE_DTRACE
dt_utag = EV_CHAR_P(ev, p, q);
- if (lseek_flush_read(desc, &err, dt_priv, dt_utag) < 0) {
+#endif
+ if (lseek_flush_read(desc, &err
+#ifdef HAVE_DTRACE
+ , dt_priv, dt_utag
+#endif
+ ) < 0) {
reply_posix_error(desc, err);
goto done;
}
- if (flush_write_check_error(desc, &err, dt_priv, dt_utag) < 0) {
+ if (flush_write_check_error(desc, &err
+#ifdef HAVE_DTRACE
+ , dt_priv, dt_utag
+#endif
+ ) < 0) {
reply_posix_error(desc, err);
goto done;
}
- if ((d = async_lseek(desc, &err, !0, offset, origin,
- &dt_i1, &dt_i2, &dt_i3)) == NULL) {
+ if ((d = async_lseek(desc, &err, !0, offset, origin
+#ifdef HAVE_DTRACE
+ , &dt_i1, &dt_i2, &dt_i3
+#endif
+ )) == NULL) {
reply_posix_error(desc, err);
goto done;
}
@@ -3595,11 +3768,22 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) {
reply_posix_error(desc, ENOENT);
goto done;
}
+#ifndef HAVE_DTRACE
+ /* In the dtrace case, the iov has an extra element, the dtrace utag - we will need
+ another test to see that
+ the filename is in a single buffer: */
if (ev->size-1 != ev->iov[q].iov_len-p) {
/* Name not in one single buffer */
reply_posix_error(desc, EINVAL);
goto done;
}
+#else
+ if (((byte *)ev->iov[q].iov_base)[ev->iov[q].iov_len-1] != '\0') {
+ /* Name not in one single buffer */
+ reply_posix_error(desc, EINVAL);
+ goto done;
+ }
+#endif
filename = EV_CHAR_P(ev, p, q);
d = EF_ALLOC(sizeof(struct t_data) -1 + FILENAME_BYTELEN(filename) + FILENAME_CHARSIZE);
if (! d) {
@@ -3610,8 +3794,22 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) {
d->reply = !0;
/* Copy name */
FILENAME_COPY(d->b, filename);
- dt_s1 = d->b;
- dt_utag = filename + strlen(d->b) + 1;
+#ifdef HAVE_DTRACE
+ {
+ char dt_tmp;
+
+ /* This will work for UTF-8, but not for UTF-16 - extra reminder here */
+#ifdef FILENAMES_16BIT
+#error 16bit characters in filenames and dtrace in combination is not supported.
+#endif
+ while (EV_GET_CHAR(ev, &dt_tmp, &p, &q) && dt_tmp != '\0')
+ ;
+ dt_s1 = d->b;
+ dt_utag = EV_CHAR_P(ev, p, q);
+ if (*dt_utag != 0)
+ fprintf(stderr,"dt_utag = %s\r\n",dt_utag);
+ }
+#endif
d->c.read_file.binp = NULL;
d->invoke = invoke_read_file;
d->free = free_read_file;
@@ -3650,12 +3848,22 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) {
reply_posix_error(desc, EINVAL);
goto done;
}
+#ifdef HAVE_DTRACE
dt_utag = EV_CHAR_P(ev, p, q);
- if (lseek_flush_read(desc, &err, dt_priv, dt_utag) < 0) {
+#endif
+ if (lseek_flush_read(desc, &err
+#ifdef HAVE_DTRACE
+ , dt_priv, dt_utag
+#endif
+ ) < 0) {
reply_posix_error(desc, err);
goto done;
}
- if (flush_write_check_error(desc, &err, dt_priv, dt_utag) < 0) {
+ if (flush_write_check_error(desc, &err
+#ifdef HAVE_DTRACE
+ , dt_priv, dt_utag
+#endif
+ ) < 0) {
reply_posix_error(desc, err);
goto done;
}
@@ -3672,13 +3880,15 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) {
d->command = command;
d->reply = !0;
d->fd = desc->fd;
- dt_i1 = d->fd;
d->flags = desc->flags;
- dt_i2 = d->flags;
d->c.preadv.offsets[0] = hdr_offset;
- dt_i3 = d->c.preadv.offsets[0];
d->c.preadv.size = max_size;
+#ifdef HAVE_DTRACE
+ dt_i1 = d->fd;
+ dt_i2 = d->flags;
+ dt_i3 = d->c.preadv.offsets[0];
dt_i4 = d->c.preadv.size;
+#endif
res_ev = &d->c.preadv.eiov;
/* XXX possible alignment problems here for weird machines */
res_ev->iov = void_ptr = d + 1;
@@ -3700,12 +3910,17 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) {
reply_posix_error(desc, EINVAL);
goto done;
}
+#ifdef HAVE_DTRACE
dt_i1 = opt;
dt_utag = EV_CHAR_P(ev, p, q);
+#endif
switch (opt) {
case FILE_OPT_DELAYED_WRITE: {
Uint32 sizeH, sizeL, delayH, delayL;
- if (ev->size != 1+1+4*sizeof(Uint32)+strlen(dt_utag)+1
+ if (ev->size != 1+1+4*sizeof(Uint32)
+#ifdef HAVE_DTRACE
+ + FILENAME_BYTELEN(dt_utag) + FILENAME_CHARSIZE
+#endif
|| !EV_GET_UINT32(ev, &sizeH, &p, &q)
|| !EV_GET_UINT32(ev, &sizeL, &p, &q)
|| !EV_GET_UINT32(ev, &delayH, &p, &q)
@@ -3732,13 +3947,18 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) {
#else
desc->write_delay = ((unsigned long)delayH << 32) | delayL;
#endif
+#ifdef HAVE_DTRACE
dt_i2 = desc->write_delay;
+#endif
TRACE_C('K');
reply_ok(desc);
} goto done;
case FILE_OPT_READ_AHEAD: {
Uint32 sizeH, sizeL;
- if (ev->size != 1+1+2*sizeof(Uint32)+strlen(dt_utag)+1
+ if (ev->size != 1+1+2*sizeof(Uint32)
+#ifdef HAVE_DTRACE
+ + FILENAME_BYTELEN(dt_utag)+FILENAME_CHARSIZE
+#endif
|| !EV_GET_UINT32(ev, &sizeH, &p, &q)
|| !EV_GET_UINT32(ev, &sizeL, &p, &q)) {
/* Buffer has wrong length to contain the option values */
@@ -3754,7 +3974,9 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) {
#else
desc->read_bufsize = ((size_t)sizeH << 32) | sizeL;
#endif
+#ifdef HAVE_DTRACE
dt_i2 = desc->read_bufsize;
+#endif
TRACE_C('K');
reply_ok(desc);
} goto done;
@@ -3841,11 +4063,19 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) {
} /* switch(command) */
- if (lseek_flush_read(desc, &err, dt_priv, dt_utag) < 0) {
+ if (lseek_flush_read(desc, &err
+#ifdef HAVE_DTRACE
+ , dt_priv, dt_utag
+#endif
+ ) < 0) {
reply_posix_error(desc, err);
goto done;
}
- if (flush_write_check_error(desc, &err, dt_priv, dt_utag) < 0) {
+ if (flush_write_check_error(desc, &err
+#ifdef HAVE_DTRACE
+ , dt_priv, dt_utag
+#endif
+ ) < 0) {
reply_posix_error(desc, err);
goto done;
} else {
diff --git a/erts/preloaded/ebin/prim_file.beam b/erts/preloaded/ebin/prim_file.beam
index 6778fe353c..88c07ab4eb 100644
--- a/erts/preloaded/ebin/prim_file.beam
+++ b/erts/preloaded/ebin/prim_file.beam
Binary files differ
diff --git a/erts/preloaded/src/prim_file.erl b/erts/preloaded/src/prim_file.erl
index 46ce3ab1a4..f7861514ae 100644
--- a/erts/preloaded/src/prim_file.erl
+++ b/erts/preloaded/src/prim_file.erl
@@ -25,59 +25,39 @@
%%% Interface towards a single file's contents. Uses ?FD_DRV.
%% Generic file contents operations
-
--export([
- open/2, open/3,
- close/1, close/2,
- datasync/1, datasync/2,
- sync/1, sync/2,
- advise/4, advise/5,
- position/2, position/3,
- truncate/1, truncate/2,
- write/2, write/3,
- pwrite/2, pwrite/3, pwrite/4,
- read/2, read/3,
- read_line/1, read_line/2,
- pread/2, pread/3, pread/4,
- copy/3, copy/4,
- sendfile/10
- ]).
+-export([open/2, close/1, datasync/1, sync/1, advise/4, position/2, truncate/1,
+ write/2, pwrite/2, pwrite/3, read/2, read_line/1, pread/2, pread/3,
+ copy/3, sendfile/10]).
%% Specialized file operations
--export([open/1]).
--export([read_file/1, read_file/2, read_file/3, write_file/2, write_file/3]).
--export([ipread_s32bu_p32bu/3, ipread_s32bu_p32bu/4]).
+-export([open/1, open/3]).
+-export([read_file/1, read_file/2, write_file/2]).
+-export([ipread_s32bu_p32bu/3]).
%%% Interface towards file system and metadata. Uses ?DRV.
%% Takes an optional port (opens a ?DRV port per default) as first argument.
-
--export([
- get_cwd/0, get_cwd/1, get_cwd/3,
- set_cwd/1, set_cwd/3,
- delete/1, delete/2, delete/3,
- rename/2, rename/3, rename/4,
- make_dir/1, make_dir/3,
- del_dir/1, del_dir/3,
- read_file_info/1, read_file_info/2, read_file_info/3, read_file_info/4,
- altname/1, altname/3,
- write_file_info/2, write_file_info/4, write_file_info/5,
- make_link/2, make_link/3, make_link/4,
- make_symlink/2, make_symlink/3, make_symlink/4,
- read_link/1, read_link/3,
- read_link_info/1, read_link_info/2, read_link_info/3, read_link_info/4,
- list_dir/1, list_dir/3
- ]).
+-export([get_cwd/0, get_cwd/1, get_cwd/2,
+ set_cwd/1, set_cwd/2,
+ delete/1, delete/2,
+ rename/2, rename/3,
+ make_dir/1, make_dir/2,
+ del_dir/1, del_dir/2,
+ read_file_info/1, read_file_info/2, read_file_info/3,
+ altname/1, altname/2,
+ write_file_info/2, write_file_info/3, write_file_info/4,
+ make_link/2, make_link/3,
+ make_symlink/2, make_symlink/3,
+ read_link/1, read_link/2,
+ read_link_info/1, read_link_info/2, read_link_info/3,
+ list_dir/1, list_dir/2]).
%% How to start and stop the ?DRV port.
-export([start/0, stop/1]).
%% Debug exports
--export([open_int/4, open_int/5, open_mode/1, open_mode/4]).
-
-%% For DTrace/Systemtap tracing
--export([get_dtrace_utag/0]).
+-export([open_int/4, open_mode/1, open_mode/4]).
%%%-----------------------------------------------------------------
%%% Includes and defines
@@ -175,21 +155,30 @@
%%% Supposed to be called by applications through module file.
-%% Opens a file. Returns {error, Reason} | {ok, FileDescriptor}.
-open(File, ModeList) ->
- open(File, ModeList, get_dtrace_utag()).
+%% Opens a file using the driver port Port. Returns {error, Reason}
+%% | {ok, FileDescriptor}
+open(Port, File, ModeList) when is_port(Port),
+ (is_list(File) orelse is_binary(File)),
+ is_list(ModeList) ->
+ case open_mode(ModeList) of
+ {Mode, _Portopts, _Setopts} ->
+ open_int(Port, File, Mode, []);
+ Reason ->
+ {error, Reason}
+ end;
+open(_,_,_) ->
+ {error, badarg}.
-open(File, ModeList, DTraceUtag)
- when (is_list(File) orelse is_binary(File)),
- is_list(ModeList),
- (is_list(DTraceUtag) orelse is_binary(DTraceUtag)) ->
+%% Opens a file. Returns {error, Reason} | {ok, FileDescriptor}.
+open(File, ModeList) when (is_list(File) orelse is_binary(File)),
+ is_list(ModeList) ->
case open_mode(ModeList) of
{Mode, Portopts, Setopts} ->
- open_int({?FD_DRV, Portopts}, File, Mode, Setopts, DTraceUtag);
+ open_int({?FD_DRV, Portopts},File, Mode, Setopts);
Reason ->
{error, Reason}
end;
-open(_, _, _) ->
+open(_, _) ->
{error, badarg}.
%% Opens a port that can be used for open/3 or read_file/2.
@@ -204,34 +193,29 @@ open(Portopts) when is_list(Portopts) ->
open(_) ->
{error, badarg}.
-open_int(Arg, File, Mode, Setopts) ->
- open_int(Arg, File, Mode, Setopts, get_dtrace_utag()).
-
-open_int({Driver, Portopts}, File, Mode, Setopts, DTraceUtag) ->
- %% TODO: add DTraceUtag to drv_open()?
+open_int({Driver, Portopts}, File, Mode, Setopts) ->
case drv_open(Driver, Portopts) of
{ok, Port} ->
- open_int(Port, File, Mode, Setopts, DTraceUtag);
+ open_int(Port, File, Mode, Setopts);
{error, _} = Error ->
Error
end;
-open_int(Port, File, Mode, Setopts, DTraceUtag) ->
+open_int(Port, File, Mode, Setopts) ->
M = Mode band ?EFILE_MODE_MASK,
- case drv_command(Port, [<<?FILE_OPEN, M:32>>,
- pathname(File), enc_utag(DTraceUtag)]) of
+ case drv_command(Port, [<<?FILE_OPEN, M:32>>, pathname(File)]) of
{ok, Number} ->
- open_int_setopts(Port, Number, Setopts, DTraceUtag);
+ open_int_setopts(Port, Number, Setopts);
Error ->
drv_close(Port),
Error
end.
-open_int_setopts(Port, Number, [], _DTraceUtag) ->
+open_int_setopts(Port, Number, []) ->
{ok, #file_descriptor{module = ?MODULE, data = {Port, Number}}};
-open_int_setopts(Port, Number, [Cmd | Tail], DTraceUtag) ->
- case drv_command(Port, [Cmd, enc_utag(DTraceUtag)]) of
+open_int_setopts(Port, Number, [Cmd | Tail]) ->
+ case drv_command(Port, Cmd) of
ok ->
- open_int_setopts(Port, Number, Tail, DTraceUtag);
+ open_int_setopts(Port, Number, Tail);
Error ->
drv_close(Port),
Error
@@ -241,64 +225,50 @@ open_int_setopts(Port, Number, [Cmd | Tail], DTraceUtag) ->
%% Returns ok.
-close(Arg) ->
- close(Arg, get_dtrace_utag()).
-
-close(#file_descriptor{module = ?MODULE, data = {Port, _}}, DTraceUtag)
- when (is_list(DTraceUtag) orelse is_binary(DTraceUtag)) ->
- case drv_command(Port, [<<?FILE_CLOSE>>, enc_utag(DTraceUtag)]) of
+close(#file_descriptor{module = ?MODULE, data = {Port, _}}) ->
+ case drv_command(Port, <<?FILE_CLOSE>>) of
ok ->
drv_close(Port);
Error ->
Error
end;
%% Closes a port opened with open/1.
-close(Port, _DTraceUtag) when is_port(Port) ->
+close(Port) when is_port(Port) ->
drv_close(Port).
--define(ADVISE(Offs, Len, Adv, BUtag),
+-define(ADVISE(Offs, Len, Adv),
<<?FILE_ADVISE, Offs:64/signed, Len:64/signed,
- Adv:32/signed, BUtag/binary>>).
+ Adv:32/signed>>).
%% Returns {error, Reason} | ok.
-advise(FD, Offset, Length, Advise) ->
- advise(FD, Offset, Length, Advise, get_dtrace_utag()).
-
advise(#file_descriptor{module = ?MODULE, data = {Port, _}},
- Offset, Length, Advise, DTraceUtag)
- when (is_list(DTraceUtag) orelse is_binary(DTraceUtag)) ->
- BUtag = term_to_binary(enc_utag(DTraceUtag)),
+ Offset, Length, Advise) ->
case Advise of
normal ->
- Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_NORMAL, BUtag),
+ Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_NORMAL),
drv_command(Port, Cmd);
random ->
- Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_RANDOM, BUtag),
+ Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_RANDOM),
drv_command(Port, Cmd);
sequential ->
- Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_SEQUENTIAL, BUtag),
+ Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_SEQUENTIAL),
drv_command(Port, Cmd);
will_need ->
- Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_WILLNEED, BUtag),
+ Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_WILLNEED),
drv_command(Port, Cmd);
dont_need ->
- Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_DONTNEED, BUtag),
+ Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_DONTNEED),
drv_command(Port, Cmd);
no_reuse ->
- Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_NOREUSE, BUtag),
+ Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_NOREUSE),
drv_command(Port, Cmd);
_ ->
{error, einval}
end.
%% Returns {error, Reason} | ok.
-write(Desc, Bytes) ->
- write(Desc, Bytes, get_dtrace_utag()).
-
-write(#file_descriptor{module = ?MODULE, data = {Port, _}}, Bytes, DTraceUtag)
- when (is_list(DTraceUtag) orelse is_binary(DTraceUtag)) ->
- %% This is rare case where DTraceUtag is not at end of command list.
- case drv_command(Port, [?FILE_WRITE,enc_utag(DTraceUtag),Bytes]) of
+write(#file_descriptor{module = ?MODULE, data = {Port, _}}, Bytes) ->
+ case drv_command_nt(Port, [?FILE_WRITE,erlang:prepend_vm_utag_data(Bytes)],false,undefined) of
{ok, _Size} ->
ok;
Error ->
@@ -308,40 +278,39 @@ write(#file_descriptor{module = ?MODULE, data = {Port, _}}, Bytes, DTraceUtag)
%% Returns ok | {error, {WrittenCount, Reason}}
pwrite(#file_descriptor{module = ?MODULE, data = {Port, _}}, L)
when is_list(L) ->
- pwrite_int(Port, L, 0, [], [], get_dtrace_utag()).
+ pwrite_int(Port, L, 0, [], []).
-pwrite_int(_, [], 0, [], [], _DTraceUtag) ->
+pwrite_int(_, [], 0, [], []) ->
ok;
-pwrite_int(Port, [], N, Spec, Data, DTraceUtag) ->
- Header = list_to_binary([<<?FILE_PWRITEV>>, enc_utag(DTraceUtag),
- <<N:32>>, reverse(Spec)]),
- case drv_command_raw(Port, [Header | reverse(Data)]) of
+pwrite_int(Port, [], N, Spec, Data) ->
+ Header = list_to_binary([?FILE_PWRITEV, erlang:prepend_vm_utag_data(<<N:32>>) | reverse(Spec)]),
+ case drv_command_nt(Port, [Header | reverse(Data)], false, undefined) of
{ok, _Size} ->
ok;
Error ->
Error
end;
-pwrite_int(Port, [{Offs, Bytes} | T], N, Spec, Data, DTraceUtag)
+pwrite_int(Port, [{Offs, Bytes} | T], N, Spec, Data)
when is_integer(Offs) ->
if
-(?LARGEFILESIZE) =< Offs, Offs < ?LARGEFILESIZE ->
- pwrite_int(Port, T, N, Spec, Data, Offs, Bytes, DTraceUtag);
+ pwrite_int(Port, T, N, Spec, Data, Offs, Bytes);
true ->
{error, einval}
end;
-pwrite_int(_, [_|_], _N, _Spec, _Data, _DTraceUtag) ->
+pwrite_int(_, [_|_], _N, _Spec, _Data) ->
{error, badarg}.
-pwrite_int(Port, T, N, Spec, Data, Offs, Bin, DTraceUtag)
+pwrite_int(Port, T, N, Spec, Data, Offs, Bin)
when is_binary(Bin) ->
Size = byte_size(Bin),
pwrite_int(Port, T, N+1,
[<<Offs:64/signed, Size:64>> | Spec],
- [Bin | Data], DTraceUtag);
-pwrite_int(Port, T, N, Spec, Data, Offs, Bytes, DTraceUtag) ->
+ [Bin | Data]);
+pwrite_int(Port, T, N, Spec, Data, Offs, Bytes) ->
try list_to_binary(Bytes) of
Bin ->
- pwrite_int(Port, T, N, Spec, Data, Offs, Bin, DTraceUtag)
+ pwrite_int(Port, T, N, Spec, Data, Offs, Bin)
catch
error:Reason ->
{error, Reason}
@@ -350,28 +319,11 @@ pwrite_int(Port, T, N, Spec, Data, Offs, Bytes, DTraceUtag) ->
%% Returns {error, Reason} | ok.
-pwrite(#file_descriptor{module = ?MODULE, data = {Port, _}}, L, DTraceUtag)
- when is_list(L),
- (is_list(DTraceUtag) orelse is_binary(DTraceUtag)) ->
- pwrite_int(Port, L, 0, [], [], DTraceUtag);
-
-pwrite(#file_descriptor{module = ?MODULE, data = {Port, _}}, Offs, Bytes)
+pwrite(#file_descriptor{module = ?MODULE, data = {Port, _}}, Offs, Bytes)
when is_integer(Offs) ->
- pwrite_int2(Port, Offs, Bytes, get_dtrace_utag());
-pwrite(#file_descriptor{module = ?MODULE}, _, _) ->
- {error, badarg}.
-
-pwrite(#file_descriptor{module = ?MODULE, data = {Port, _}}, Offs, Bytes, DTraceUtag)
- when is_integer(Offs),
- (is_list(DTraceUtag) orelse is_binary(DTraceUtag)) ->
- pwrite_int2(Port, Offs, Bytes, DTraceUtag);
-pwrite(#file_descriptor{module = ?MODULE}, _, _, _DTraceUtag) ->
- {error, badarg}.
-
-pwrite_int2(Port, Offs, Bytes, DTraceUtag) ->
if
-(?LARGEFILESIZE) =< Offs, Offs < ?LARGEFILESIZE ->
- case pwrite_int(Port, [], 0, [], [], Offs, Bytes, DTraceUtag) of
+ case pwrite_int(Port, [], 0, [], [], Offs, Bytes) of
{error, {_, Reason}} ->
{error, Reason};
Result ->
@@ -379,30 +331,22 @@ pwrite_int2(Port, Offs, Bytes, DTraceUtag) ->
end;
true ->
{error, einval}
- end.
-
-%% Returns {error, Reason} | ok.
-datasync(FD) ->
- datasync(FD, get_dtrace_utag()).
+ end;
+pwrite(#file_descriptor{module = ?MODULE}, _, _) ->
+ {error, badarg}.
-datasync(#file_descriptor{module = ?MODULE, data = {Port, _}}, DTraceUtag)
- when (is_list(DTraceUtag) orelse is_binary(DTraceUtag)) ->
- drv_command(Port, [?FILE_FDATASYNC, enc_utag(DTraceUtag)]).
%% Returns {error, Reason} | ok.
-sync(FD) ->
- sync(FD, get_dtrace_utag()).
+datasync(#file_descriptor{module = ?MODULE, data = {Port, _}}) ->
+ drv_command(Port, [?FILE_FDATASYNC]).
-sync(#file_descriptor{module = ?MODULE, data = {Port, _}}, DTraceUtag)
- when (is_list(DTraceUtag) orelse is_binary(DTraceUtag)) ->
- drv_command(Port, [?FILE_FSYNC, enc_utag(DTraceUtag)]).
+%% Returns {error, Reason} | ok.
+sync(#file_descriptor{module = ?MODULE, data = {Port, _}}) ->
+ drv_command(Port, [?FILE_FSYNC]).
%% Returns {ok, Data} | eof | {error, Reason}.
-read_line(FD) ->
- read_line(FD, get_dtrace_utag()).
-
-read_line(#file_descriptor{module = ?MODULE, data = {Port, _}}, DTraceUtag) ->
- case drv_command(Port, [<<?FILE_READ_LINE>>, enc_utag(DTraceUtag)]) of
+read_line(#file_descriptor{module = ?MODULE, data = {Port, _}}) ->
+ case drv_command(Port, <<?FILE_READ_LINE>>) of
{ok, {0, _Data}} ->
eof;
{ok, {_Size, Data}} ->
@@ -422,17 +366,11 @@ read_line(#file_descriptor{module = ?MODULE, data = {Port, _}}, DTraceUtag) ->
end.
%% Returns {ok, Data} | eof | {error, Reason}.
-read(FD, Size) ->
- read(FD, Size, get_dtrace_utag()).
-
-read(#file_descriptor{module = ?MODULE, data = {Port, _}}, Size, DTraceUtag)
- when is_integer(Size),
- 0 =< Size,
- (is_list(DTraceUtag) orelse is_binary(DTraceUtag)) ->
+read(#file_descriptor{module = ?MODULE, data = {Port, _}}, Size)
+ when is_integer(Size), 0 =< Size ->
if
Size < ?LARGEFILESIZE ->
- case drv_command(Port, [<<?FILE_READ, Size:64>>,
- enc_utag(DTraceUtag)]) of
+ case drv_command(Port, <<?FILE_READ, Size:64>>) of
{ok, {0, _Data}} when Size =/= 0 ->
eof;
{ok, {_Size, Data}} ->
@@ -441,8 +379,7 @@ read(#file_descriptor{module = ?MODULE, data = {Port, _}}, Size, DTraceUtag)
%% Garbage collecting here might help if
%% the current processes have some old binaries left.
erlang:garbage_collect(),
- case drv_command(Port, [<<?FILE_READ, Size:64>>,
- enc_utag(DTraceUtag)]) of
+ case drv_command(Port, <<?FILE_READ, Size:64>>) of
{ok, {0, _Data}} when Size =/= 0 ->
eof;
{ok, {_Size, Data}} ->
@@ -460,43 +397,35 @@ read(#file_descriptor{module = ?MODULE, data = {Port, _}}, Size, DTraceUtag)
%% Returns {ok, [Data|eof, ...]} | {error, Reason}
pread(#file_descriptor{module = ?MODULE, data = {Port, _}}, L)
when is_list(L) ->
- pread_int(Port, L, 0, [], get_dtrace_utag()).
+ pread_int(Port, L, 0, []).
-pread_int(_, [], 0, [], _DTraceUtag) ->
+pread_int(_, [], 0, []) ->
{ok, []};
-pread_int(Port, [], N, Spec, DTraceUtag) ->
- drv_command(Port, [<<?FILE_PREADV>>, enc_utag(DTraceUtag),
- <<0:32, N:32>>, reverse(Spec)]);
-pread_int(Port, [{Offs, Size} | T], N, Spec, DTraceUtag)
+pread_int(Port, [], N, Spec) ->
+ drv_command_nt(Port, [?FILE_PREADV, erlang:prepend_vm_utag_data(<<0:32, N:32>>) | reverse(Spec)],false, undefined);
+pread_int(Port, [{Offs, Size} | T], N, Spec)
when is_integer(Offs), is_integer(Size), 0 =< Size ->
if
-(?LARGEFILESIZE) =< Offs, Offs < ?LARGEFILESIZE,
Size < ?LARGEFILESIZE ->
- pread_int(Port, T, N+1, [<<Offs:64/signed, Size:64>> | Spec],
- DTraceUtag);
+ pread_int(Port, T, N+1, [<<Offs:64/signed, Size:64>> | Spec]);
true ->
{error, einval}
end;
-pread_int(_, [_|_], _N, _Spec, _DTraceUtag) ->
+pread_int(_, [_|_], _N, _Spec) ->
{error, badarg}.
+
+
%% Returns {ok, Data} | eof | {error, Reason}.
-pread(#file_descriptor{module = ?MODULE, data = {Port, _}}, L, DTraceUtag)
- when is_list(L),
- (is_list(DTraceUtag) orelse is_binary(DTraceUtag)) ->
- pread_int(Port, L, 0, [], get_dtrace_utag());
-pread(FD, Offs, Size)
+pread(#file_descriptor{module = ?MODULE, data = {Port, _}}, Offs, Size)
when is_integer(Offs), is_integer(Size), 0 =< Size ->
- pread(FD, Offs, Size, get_dtrace_utag()).
-
-pread(#file_descriptor{module = ?MODULE, data = {Port, _}}, Offs, Size, DTraceUtag)
- when (is_list(DTraceUtag) orelse is_binary(DTraceUtag)) ->
if
-(?LARGEFILESIZE) =< Offs, Offs < ?LARGEFILESIZE,
Size < ?LARGEFILESIZE ->
- case drv_command(Port,
- [<<?FILE_PREADV>>, enc_utag(DTraceUtag),
- <<0:32, 1:32, Offs:64/signed, Size:64>>]) of
+ case drv_command_nt(Port,
+ [?FILE_PREADV, erlang:prepend_vm_utag_data(<<0:32, 1:32,
+ Offs:64/signed, Size:64>>)], false, undefined) of
{ok, [eof]} ->
eof;
{ok, [Data]} ->
@@ -507,22 +436,17 @@ pread(#file_descriptor{module = ?MODULE, data = {Port, _}}, Offs, Size, DTraceUt
true ->
{error, einval}
end;
-pread(_, _, _, _) ->
+pread(#file_descriptor{module = ?MODULE, data = {_, _}}, _, _) ->
{error, badarg}.
%% Returns {ok, Position} | {error, Reason}.
-position(FD, At) ->
- position(FD, At, get_dtrace_utag()).
-
-position(#file_descriptor{module = ?MODULE, data = {Port, _}}, At, DTraceUtag)
- when (is_list(DTraceUtag) orelse is_binary(DTraceUtag)) ->
+position(#file_descriptor{module = ?MODULE, data = {Port, _}}, At) ->
case lseek_position(At) of
{Offs, Whence}
when -(?LARGEFILESIZE) =< Offs, Offs < ?LARGEFILESIZE ->
- drv_command(Port, [<<?FILE_LSEEK, Offs:64/signed, Whence:32>>,
- enc_utag(DTraceUtag)]);
+ drv_command(Port, <<?FILE_LSEEK, Offs:64/signed, Whence:32>>);
{_, _} ->
{error, einval};
Reason ->
@@ -530,89 +454,63 @@ position(#file_descriptor{module = ?MODULE, data = {Port, _}}, At, DTraceUtag)
end.
%% Returns {error, Reaseon} | ok.
-truncate(FD) ->
- truncate(FD, get_dtrace_utag()).
-
-truncate(#file_descriptor{module = ?MODULE, data = {Port, _}}, DTraceUtag)
- when (is_list(DTraceUtag) orelse is_binary(DTraceUtag)) ->
- drv_command(Port, [<<?FILE_TRUNCATE>>, enc_utag(DTraceUtag)]).
+truncate(#file_descriptor{module = ?MODULE, data = {Port, _}}) ->
+ drv_command(Port, <<?FILE_TRUNCATE>>).
%% Returns {error, Reason} | {ok, BytesCopied}
-copy(Source, Dest, Length) ->
- copy(Source, Dest, Length, get_dtrace_utag()).
-
copy(#file_descriptor{module = ?MODULE} = Source,
#file_descriptor{module = ?MODULE} = Dest,
- Length, DTraceUtag)
+ Length)
when is_integer(Length), Length >= 0;
- is_atom(Length),
- (is_list(DTraceUtag) orelse is_binary(DTraceUtag)) ->
+ is_atom(Length) ->
%% XXX Should be moved down to the driver for optimization.
- file:copy_opened(Source, Dest, Length, DTraceUtag).
-
+ file:copy_opened(Source, Dest, Length).
-ipread_s32bu_p32bu(FD, Offs, Arg) ->
- ipread_s32bu_p32bu(FD, Offs, Arg, get_dtrace_utag()).
ipread_s32bu_p32bu(#file_descriptor{module = ?MODULE,
data = {_, _}} = Handle,
Offs,
- Infinity,
- DTraceUtag)
- when is_atom(Infinity),
- (is_list(DTraceUtag) orelse is_binary(DTraceUtag)) ->
+ Infinity) when is_atom(Infinity) ->
ipread_s32bu_p32bu(Handle, Offs, (1 bsl 31)-1);
ipread_s32bu_p32bu(#file_descriptor{module = ?MODULE, data = {Port, _}},
Offs,
- MaxSize,
- DTraceUtag)
- when is_integer(Offs),
- is_integer(MaxSize),
- (is_list(DTraceUtag) orelse is_binary(DTraceUtag)) ->
+ MaxSize)
+ when is_integer(Offs), is_integer(MaxSize) ->
if
-(?LARGEFILESIZE) =< Offs, Offs < ?LARGEFILESIZE,
0 =< MaxSize, MaxSize < (1 bsl 31) ->
- drv_command(Port, [<<?FILE_IPREAD, ?IPREAD_S32BU_P32BU,
- Offs:64, MaxSize:32>>, enc_utag(DTraceUtag)]);
+ drv_command(Port, <<?FILE_IPREAD, ?IPREAD_S32BU_P32BU,
+ Offs:64, MaxSize:32>>);
true ->
{error, einval}
end;
ipread_s32bu_p32bu(#file_descriptor{module = ?MODULE, data = {_, _}},
_Offs,
- _MaxSize,
- _DTraceUtag) ->
+ _MaxSize) ->
{error, badarg}.
%% Returns {ok, Contents} | {error, Reason}
read_file(File) when (is_list(File) orelse is_binary(File)) ->
- read_file(File, get_dtrace_utag());
-read_file(_) ->
- {error, badarg}.
-
-read_file(File, DTraceUtag)
- when (is_list(File) orelse is_binary(File)),
- (is_list(DTraceUtag) orelse is_binary(DTraceUtag))->
case drv_open(?FD_DRV, [binary]) of
{ok, Port} ->
- Result = read_file(Port, File, DTraceUtag),
+ Result = read_file(Port, File),
close(Port),
Result;
{error, _} = Error ->
Error
end;
-read_file(_, _) ->
+read_file(_) ->
{error, badarg}.
%% Takes a Port opened with open/1.
-read_file(Port, File, DTraceUtag) when is_port(Port),
+read_file(Port, File) when is_port(Port),
(is_list(File) orelse is_binary(File)) ->
- Cmd = [?FILE_READ_FILE |
- list_to_binary([pathname(File), enc_utag(DTraceUtag)])],
+ Cmd = [?FILE_READ_FILE | pathname(File)],
case drv_command(Port, Cmd) of
{error, enomem} ->
%% It could possibly help to do a
@@ -624,30 +522,22 @@ read_file(Port, File, DTraceUtag) when is_port(Port),
Result ->
Result
end;
-read_file(_,_,_) ->
+read_file(_,_) ->
{error, badarg}.
%% Returns {error, Reason} | ok.
-write_file(File, Bin) ->
- write_file(File, Bin, get_dtrace_utag()).
-
-write_file(File, Bin, DTraceUtag)
- when (is_list(File) orelse is_binary(File)),
- (is_list(DTraceUtag) orelse is_binary(DTraceUtag)) ->
- OldUtag = put(dtrace_utag, DTraceUtag), % TODO: API?
+write_file(File, Bin) when (is_list(File) orelse is_binary(File)) ->
case open(File, [binary, write]) of
{ok, Handle} ->
Result = write(Handle, Bin),
close(Handle),
- put(dtrace_utag, OldUtag),
Result;
Error ->
- put(dtrace_utag, OldUtag),
Error
end;
-write_file(_, _, _) ->
+write_file(_, _) ->
{error, badarg}.
@@ -711,56 +601,54 @@ stop(Port) when is_port(Port) ->
-%% get_cwd/{0,1,3}
+%% get_cwd/{0,1,2}
get_cwd() ->
- get_cwd_int(0, get_dtrace_utag()).
+ get_cwd_int(0).
get_cwd(Port) when is_port(Port) ->
- get_cwd_int(Port, 0, get_dtrace_utag());
+ get_cwd_int(Port, 0);
get_cwd([]) ->
- get_cwd_int(0, get_dtrace_utag());
+ get_cwd_int(0);
get_cwd([Letter, $: | _]) when $a =< Letter, Letter =< $z ->
- get_cwd_int(Letter - $a + 1, get_dtrace_utag());
+ get_cwd_int(Letter - $a + 1);
get_cwd([Letter, $: | _]) when $A =< Letter, Letter =< $Z ->
- get_cwd_int(Letter - $A + 1, get_dtrace_utag());
+ get_cwd_int(Letter - $A + 1);
get_cwd([_|_]) ->
{error, einval};
get_cwd(_) ->
{error, badarg}.
-get_cwd(Port, [], DTraceUtag) when is_port(Port) ->
- get_cwd_int(Port, 0, DTraceUtag);
-get_cwd(Port, no_drive, DTraceUtag) when is_port(Port) ->
- get_cwd_int(Port, 0, DTraceUtag);
-get_cwd(Port, [Letter, $: | _], DTraceUtag)
+get_cwd(Port, []) when is_port(Port) ->
+ get_cwd_int(Port, 0);
+get_cwd(Port, [Letter, $: | _])
when is_port(Port), $a =< Letter, Letter =< $z ->
- get_cwd_int(Port, Letter - $a + 1, DTraceUtag);
-get_cwd(Port, [Letter, $: | _], DTraceUtag)
+ get_cwd_int(Port, Letter - $a + 1);
+get_cwd(Port, [Letter, $: | _])
when is_port(Port), $A =< Letter, Letter =< $Z ->
- get_cwd_int(Port, Letter - $A + 1, DTraceUtag);
-get_cwd(Port, [_|_], _DTraceUtag) when is_port(Port) ->
+ get_cwd_int(Port, Letter - $A + 1);
+get_cwd(Port, [_|_]) when is_port(Port) ->
{error, einval};
-get_cwd(_, _, _DTraceUtag) ->
+get_cwd(_, _) ->
{error, badarg}.
-get_cwd_int(Drive, DTraceUtag) ->
- get_cwd_int({?DRV, [binary]}, Drive, DTraceUtag).
+get_cwd_int(Drive) ->
+ get_cwd_int({?DRV, [binary]}, Drive).
-get_cwd_int(Port, Drive, DTraceUtag) ->
- drv_command(Port, list_to_binary([?FILE_PWD, Drive, enc_utag(DTraceUtag)])).
+get_cwd_int(Port, Drive) ->
+ drv_command(Port, <<?FILE_PWD, Drive>>).
-%% set_cwd/{1,3}
+%% set_cwd/{1,2}
set_cwd(Dir) ->
- set_cwd_int({?DRV, [binary]}, Dir, get_dtrace_utag()).
+ set_cwd_int({?DRV, [binary]}, Dir).
-set_cwd(Port, Dir, DTraceUtag) when is_port(Port) ->
- set_cwd_int(Port, Dir, DTraceUtag).
+set_cwd(Port, Dir) when is_port(Port) ->
+ set_cwd_int(Port, Dir).
-set_cwd_int(Port, Dir0, DTraceUtag) ->
+set_cwd_int(Port, Dir0) ->
Dir =
(catch
case os:type() of
@@ -770,7 +658,7 @@ set_cwd_int(Port, Dir0, DTraceUtag) ->
%% must call get_cwd from here and use
%% absname/2, since
%% absname/1 uses file:get_cwd ...
- case get_cwd_int(Port, 0, "") of
+ case get_cwd_int(Port, 0) of
{ok, AbsPath} ->
filename:absname(Dir0, AbsPath);
_Badcwd ->
@@ -781,86 +669,78 @@ set_cwd_int(Port, Dir0, DTraceUtag) ->
end),
%% Dir is now either a string or an EXIT tuple.
%% An EXIT tuple will fail in the following catch.
- drv_command(Port, [?FILE_CHDIR, pathname(Dir), enc_utag(DTraceUtag)]).
+ drv_command(Port, [?FILE_CHDIR, pathname(Dir)]).
-%% delete/{1,2,3}
+%% delete/{1,2}
delete(File) ->
- delete_int({?DRV, [binary]}, File, get_dtrace_utag()).
+ delete_int({?DRV, [binary]}, File).
delete(Port, File) when is_port(Port) ->
- delete_int(Port, File, get_dtrace_utag()).
+ delete_int(Port, File).
-delete(Port, File, DTraceUtag) when is_port(Port) ->
- delete_int(Port, File, DTraceUtag).
+delete_int(Port, File) ->
+ drv_command(Port, [?FILE_DELETE, pathname(File)]).
-delete_int(Port, File, DTraceUtag) ->
- drv_command(Port, [?FILE_DELETE, pathname(File), enc_utag(DTraceUtag)]).
-
-%% rename/{2,3,4}
+%% rename/{2,3}
rename(From, To) ->
- rename_int({?DRV, [binary]}, From, To, get_dtrace_utag()).
+ rename_int({?DRV, [binary]}, From, To).
rename(Port, From, To) when is_port(Port) ->
- rename_int(Port, From, To, get_dtrace_utag()).
-
-rename(Port, From, To, DTraceUtag) when is_port(Port) ->
- rename_int(Port, From, To, DTraceUtag).
+ rename_int(Port, From, To).
-rename_int(Port, From, To, DTraceUtag) ->
- drv_command(Port, [?FILE_RENAME, pathname(From), pathname(To),
- enc_utag(DTraceUtag)]).
+rename_int(Port, From, To) ->
+ drv_command(Port, [?FILE_RENAME, pathname(From), pathname(To)]).
-%% make_dir/{1,3}
+%% make_dir/{1,2}
make_dir(Dir) ->
- make_dir_int({?DRV, [binary]}, Dir, get_dtrace_utag()).
+ make_dir_int({?DRV, [binary]}, Dir).
-make_dir(Port, Dir, DTraceUtag) when is_port(Port) ->
- make_dir_int(Port, Dir, DTraceUtag).
+make_dir(Port, Dir) when is_port(Port) ->
+ make_dir_int(Port, Dir).
-make_dir_int(Port, Dir, DTraceUtag) ->
- drv_command(Port, [?FILE_MKDIR, pathname(Dir), enc_utag(DTraceUtag)]).
+make_dir_int(Port, Dir) ->
+ drv_command(Port, [?FILE_MKDIR, pathname(Dir)]).
-%% del_dir/{1,3}
+%% del_dir/{1,2}
del_dir(Dir) ->
- del_dir_int({?DRV, [binary]}, Dir, get_dtrace_utag()).
+ del_dir_int({?DRV, [binary]}, Dir).
+
+del_dir(Port, Dir) when is_port(Port) ->
+ del_dir_int(Port, Dir).
-del_dir(Port, Dir, DTraceUtag) when is_port(Port) ->
- del_dir_int(Port, Dir, DTraceUtag).
+del_dir_int(Port, Dir) ->
+ drv_command(Port, [?FILE_RMDIR, pathname(Dir)]).
-del_dir_int(Port, Dir, DTraceUtag) ->
- drv_command(Port, [?FILE_RMDIR, pathname(Dir), enc_utag(DTraceUtag)]).
-%% read_file_info/{1,2,3,4}
+
+%% read_file_info/{1,2,3}
read_file_info(File) ->
- read_file_info_int({?DRV, [binary]}, File, local, get_dtrace_utag()).
+ read_file_info_int({?DRV, [binary]}, File, local).
read_file_info(Port, File) when is_port(Port) ->
- read_file_info_int(Port, File, local, get_dtrace_utag());
+ read_file_info_int(Port, File, local);
read_file_info(File, Opts) ->
- read_file_info_int({?DRV, [binary]}, File, plgv(time, Opts, local), get_dtrace_utag()).
-
-read_file_info(Port, File, Opts) when is_port(Port), is_list(Opts) ->
- read_file_info_int(Port, File, plgv(time, Opts, local), get_dtrace_utag()).
+ read_file_info_int({?DRV, [binary]}, File, plgv(time, Opts, local)).
-read_file_info(Port, File, Opts, DTraceUtag) when is_port(Port) ->
- read_file_info_int(Port, File, plgv(time, Opts, local), DTraceUtag).
+read_file_info(Port, File, Opts) when is_port(Port) ->
+ read_file_info_int(Port, File, plgv(time, Opts, local)).
-read_file_info_int(Port, File, TimeType, DTraceUtag) ->
+read_file_info_int(Port, File, TimeType) ->
try
- case drv_command(Port, [?FILE_FSTAT, pathname(File), enc_utag(DTraceUtag)]) of
+ case drv_command(Port, [?FILE_FSTAT, pathname(File)]) of
{ok, FI} -> {ok, FI#file_info{
ctime = from_seconds(FI#file_info.ctime, TimeType),
mtime = from_seconds(FI#file_info.mtime, TimeType),
@@ -872,33 +752,30 @@ read_file_info_int(Port, File, TimeType, DTraceUtag) ->
error:_ -> {error, badarg}
end.
-%% altname/{1,3}
-altname(File) ->
- altname_int({?DRV, [binary]}, File, get_dtrace_utag()).
+%% altname/{1,2}
-altname(Port, File, DTraceUtag) when is_port(Port) ->
- altname_int(Port, File, DTraceUtag).
+altname(File) ->
+ altname_int({?DRV, [binary]}, File).
-altname_int(Port, File, DTraceUtag) ->
- drv_command(Port, [?FILE_ALTNAME, pathname(File), enc_utag(DTraceUtag)]).
+altname(Port, File) when is_port(Port) ->
+ altname_int(Port, File).
+altname_int(Port, File) ->
+ drv_command(Port, [?FILE_ALTNAME, pathname(File)]).
-%% write_file_info/{2,3,4,5}
+%% write_file_info/{2,3,4}
write_file_info(File, Info) ->
- write_file_info_int({?DRV, [binary]}, File, Info, local, get_dtrace_utag()).
+ write_file_info_int({?DRV, [binary]}, File, Info, local).
write_file_info(Port, File, Info) when is_port(Port) ->
- write_file_info_int(Port, File, Info, local, get_dtrace_utag());
+ write_file_info_int(Port, File, Info, local);
write_file_info(File, Info, Opts) ->
- write_file_info_int({?DRV, [binary]}, File, Info, plgv(time, Opts, local), get_dtrace_utag()).
+ write_file_info_int({?DRV, [binary]}, File, Info, plgv(time, Opts, local)).
write_file_info(Port, File, Info, Opts) when is_port(Port) ->
- write_file_info_int(Port, File, Info, plgv(time, Opts, local), get_dtrace_utag()).
-
-write_file_info(Port, File, Info, Opts, DTraceUtag) when is_port(Port) ->
- write_file_info_int(Port, File, Info, plgv(time, Opts, local), DTraceUtag).
+ write_file_info_int(Port, File, Info, plgv(time, Opts, local)).
write_file_info_int(Port, File,
#file_info{mode=Mode,
@@ -907,8 +784,7 @@ write_file_info_int(Port, File,
atime=Atime0,
mtime=Mtime0,
ctime=Ctime0},
- TimeType,
- DTraceUtag) ->
+ TimeType) ->
% Atime and/or Mtime might be undefined
% - use localtime() for atime, if atime is undefined
@@ -927,13 +803,12 @@ write_file_info_int(Port, File,
int_to_int64bytes(to_seconds(Atime, TimeType)),
int_to_int64bytes(to_seconds(Mtime, TimeType)),
int_to_int64bytes(to_seconds(Ctime, TimeType)),
- pathname(File),
- enc_utag(DTraceUtag)
- ])
+ pathname(File)])
catch
error:_ -> {error, badarg}
end.
+
file_info_validate_atime(Atime, _) when Atime =/= undefined -> Atime;
file_info_validate_atime(undefined, local) -> erlang:localtime();
file_info_validate_atime(undefined, universal) -> erlang:universaltime();
@@ -945,72 +820,63 @@ file_info_validate_mtime(Mtime, _) -> Mtime.
file_info_validate_ctime(undefined, Mtime) -> Mtime;
file_info_validate_ctime(Ctime, _) -> Ctime.
-%% make_link/{2,3,4}
+%% make_link/{2,3}
make_link(Old, New) ->
- make_link_int({?DRV, [binary]}, Old, New, get_dtrace_utag()).
+ make_link_int({?DRV, [binary]}, Old, New).
make_link(Port, Old, New) when is_port(Port) ->
- make_link_int(Port, Old, New, get_dtrace_utag()).
+ make_link_int(Port, Old, New).
-make_link(Port, Old, New, DTraceUtag) when is_port(Port) ->
- make_link_int(Port, Old, New, DTraceUtag).
+make_link_int(Port, Old, New) ->
+ drv_command(Port, [?FILE_LINK, pathname(Old), pathname(New)]).
-make_link_int(Port, Old, New, DTraceUtag) ->
- drv_command(Port, [?FILE_LINK, pathname(Old), pathname(New),
- enc_utag(DTraceUtag)]).
-
-%% make_symlink/{2,3,4}
+%% make_symlink/{2,3}
make_symlink(Old, New) ->
- make_symlink_int({?DRV, [binary]}, Old, New, get_dtrace_utag()).
+ make_symlink_int({?DRV, [binary]}, Old, New).
make_symlink(Port, Old, New) when is_port(Port) ->
- make_symlink_int(Port, Old, New, get_dtrace_utag()).
-
-make_symlink(Port, Old, New, DTraceUtag) when is_port(Port) ->
- make_symlink_int(Port, Old, New, DTraceUtag).
+ make_symlink_int(Port, Old, New).
-make_symlink_int(Port, Old, New, DTraceUtag) ->
- drv_command(Port, [?FILE_SYMLINK, pathname(Old), pathname(New),
- enc_utag(DTraceUtag)]).
+make_symlink_int(Port, Old, New) ->
+ drv_command(Port, [?FILE_SYMLINK, pathname(Old), pathname(New)]).
-%% read_link/{1,3}
+%% read_link/{2,3}
read_link(Link) ->
- read_link_int({?DRV, [binary]}, Link, get_dtrace_utag()).
+ read_link_int({?DRV, [binary]}, Link).
-read_link(Port, Link, DTraceUtag) when is_port(Port) ->
- read_link_int(Port, Link, DTraceUtag).
+read_link(Port, Link) when is_port(Port) ->
+ read_link_int(Port, Link).
-read_link_int(Port, Link, DTraceUtag) ->
- drv_command(Port, [?FILE_READLINK, pathname(Link), enc_utag(DTraceUtag)]).
+read_link_int(Port, Link) ->
+ drv_command(Port, [?FILE_READLINK, pathname(Link)]).
-%% read_link_info/{1,2,3,4}
+%% read_link_info/{2,3}
read_link_info(Link) ->
- read_link_info_int({?DRV, [binary]}, Link, local, get_dtrace_utag()).
+ read_link_info_int({?DRV, [binary]}, Link, local).
read_link_info(Port, Link) when is_port(Port) ->
- read_link_info_int(Port, Link, local, get_dtrace_utag());
+ read_link_info_int(Port, Link, local);
+
read_link_info(Link, Opts) ->
- read_link_info_int({?DRV, [binary]}, Link, plgv(time, Opts, local), get_dtrace_utag()).
+ read_link_info_int({?DRV, [binary]}, Link, plgv(time, Opts, local)).
read_link_info(Port, Link, Opts) when is_port(Port) ->
- read_link_info_int(Port, Link, plgv(time, Opts, local), get_dtrace_utag()).
+ read_link_info_int(Port, Link, plgv(time, Opts, local)).
-read_link_info(Port, Link, Opts, DTraceUtag) when is_port(Port) ->
- read_link_info_int(Port, Link, plgv(time, Opts, local), DTraceUtag).
-read_link_info_int(Port, Link, TimeType, DTraceUtag) ->
+read_link_info_int(Port, Link, TimeType) ->
try
- case drv_command(Port, [?FILE_LSTAT, pathname(Link), enc_utag(DTraceUtag)]) of
+ case drv_command(Port, [?FILE_LSTAT, pathname(Link)]) of
{ok, FI} -> {ok, FI#file_info{
ctime = from_seconds(FI#file_info.ctime, TimeType),
mtime = from_seconds(FI#file_info.mtime, TimeType),
@@ -1022,16 +888,16 @@ read_link_info_int(Port, Link, TimeType, DTraceUtag) ->
error:_ -> {error, badarg}
end.
-%% list_dir/{1,3}
+%% list_dir/{1,2}
list_dir(Dir) ->
- list_dir_int({?DRV, [binary]}, Dir, get_dtrace_utag()).
+ list_dir_int({?DRV, [binary]}, Dir).
-list_dir(Port, Dir, DTraceUtag) when is_port(Port) ->
- list_dir_int(Port, Dir, DTraceUtag).
+list_dir(Port, Dir) when is_port(Port) ->
+ list_dir_int(Port, Dir).
-list_dir_int(Port, Dir, DTraceUtag) ->
- drv_command(Port, [?FILE_READDIR, pathname(Dir), enc_utag(DTraceUtag)], []).
+list_dir_int(Port, Dir) ->
+ drv_command(Port, [?FILE_READDIR, pathname(Dir)], []).
@@ -1057,12 +923,17 @@ drv_open(Driver, Portopts) ->
%% Closes a port in a safe way. Returns ok.
drv_close(Port) ->
- try erlang:port_close(Port) catch error:_ -> ok end,
- receive %% Ugly workaround in case the caller==owner traps exits
- {'EXIT', Port, _Reason} ->
- ok
- after 0 ->
- ok
+ Save = erlang:spread_utag(false),
+ try
+ try erlang:port_close(Port) catch error:_ -> ok end,
+ receive %% Ugly workaround in case the caller==owner traps exits
+ {'EXIT', Port, _Reason} ->
+ ok
+ after 0 ->
+ ok
+ end
+ after
+ erlang:restore_utag(Save)
end.
@@ -1072,9 +943,6 @@ drv_close(Port) ->
%% then closed after the result has been received.
%% Returns {ok, Result} or {error, Reason}.
-drv_command_raw(Port, Command) ->
- drv_command(Port, Command, false, undefined).
-
drv_command(Port, Command) ->
drv_command(Port, Command, undefined).
@@ -1090,7 +958,8 @@ drv_command(Port, Command, R) ->
end.
drv_command(Port, Command, Validated, R) when is_port(Port) ->
- try erlang:port_command(Port, Command) of
+ Save = erlang:spread_utag(false),
+ try erlang:port_command(Port, erlang:append_vm_utag_data(Command)) of
true ->
drv_get_response(Port, R)
catch
@@ -1109,6 +978,8 @@ drv_command(Port, Command, Validated, R) when is_port(Port) ->
end;
error:Reason ->
{error, Reason}
+ after
+ erlang:restore_utag(Save)
end;
drv_command({Driver, Portopts}, Command, Validated, R) ->
case drv_open(Driver, Portopts) of
@@ -1119,6 +990,30 @@ drv_command({Driver, Portopts}, Command, Validated, R) ->
Error ->
Error
end.
+drv_command_nt(Port, Command, Validated, R) when is_port(Port) ->
+ Save = erlang:spread_utag(false),
+ try erlang:port_command(Port, Command) of
+ true ->
+ drv_get_response(Port, R)
+ catch
+ %% If the Command is valid, knowing that the port is a port,
+ %% a badarg error must mean it is a dead port, that is:
+ %% a currently invalid filehandle, -> einval, not badarg.
+ error:badarg when Validated ->
+ {error, einval};
+ error:badarg ->
+ try erlang:iolist_size(Command) of
+ _ -> % Valid
+ {error, einval}
+ catch
+ error:_ ->
+ {error, badarg}
+ end;
+ error:Reason ->
+ {error, Reason}
+ after
+ erlang:restore_utag(Save)
+ end.
@@ -1469,6 +1364,7 @@ reverse(L, T) -> lists:reverse(L, T).
pathname(File) ->
(catch prim_file:internal_name2native(File)).
+
%% proplist:get_value/3
plgv(K, [{K, V}|_], _) -> V;
plgv(K, [_|KVs], D) -> plgv(K, KVs, D);
@@ -1492,16 +1388,3 @@ to_seconds({_,_} = Datetime, universal) ->
erlang:universaltime_to_posixtime(Datetime);
to_seconds({_,_} = Datetime, local) ->
erlang:universaltime_to_posixtime(erlang:localtime_to_universaltime(Datetime)).
-
-get_dtrace_utag() ->
- %% We cannot call dtrace:get_utag() because this is prim_file.erl.
- %% We must reimplement it here.
- case get('_dtrace_utag_@_@') of
- undefined ->
- <<>>;
- X ->
- X
- end.
-
-enc_utag(UTag) ->
- [UTag, 0].
diff --git a/lib/dtrace/c_src/Makefile.in b/lib/dtrace/c_src/Makefile.in
index 831ce5ce75..4d5f59a63d 100644
--- a/lib/dtrace/c_src/Makefile.in
+++ b/lib/dtrace/c_src/Makefile.in
@@ -76,7 +76,7 @@ before_DTrace_OBJS = $(OBJDIR)/dtrace$(TYPEMARKER).o
## NIF_MAKEFILE = $(PRIVDIR)/Makefile
# Higher-level makefiles says that we can only compile on UNIX flavors
-NIF_LIB = $(LIBDIR)/dtrace$(TYPEMARKER).so
+NIF_LIB = $(LIBDIR)/dtrace$(TYPEMARKER).@DED_EXT@
ifeq ($(HOST_OS),)
HOST_OS := $(shell $(ERL_TOP)/erts/autoconf/config.guess)
@@ -121,14 +121,14 @@ $(OBJDIR)/%$(TYPEMARKER).o: %.c $(DTRACE_USER_HEADER)
$(INSTALL_DIR) $(OBJDIR)
$(CC) -c -o $@ $(ALL_CFLAGS) $<
-$(LIBDIR)/dtrace$(TYPEMARKER).so: $(OBJS)
+$(NIF_LIB): $(OBJS)
$(INSTALL_DIR) $(LIBDIR)
$(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS)
clean:
- rm -f $(LIBDIR)/dtrace.so
- rm -f $(LIBDIR)/dtrace.debug.so
- rm -f $(LIBDIR)/dtrace.valgrind.so
+ rm -f $(LIBDIR)/dtrace.@DED_EXT@
+ rm -f $(LIBDIR)/dtrace.debug.@DED_EXT@
+ rm -f $(LIBDIR)/dtrace.valgrind.@DED_EXT@
rm -f $(OBJDIR)/dtrace.o
rm -f $(OBJDIR)/dtrace.debug.o
rm -f $(OBJDIR)/dtrace.valgrind.o
diff --git a/lib/dtrace/examples/efile_drv.d b/lib/dtrace/examples/efile_drv.d
index c9c8080dba..085995ce58 100644
--- a/lib/dtrace/examples/efile_drv.d
+++ b/lib/dtrace/examples/efile_drv.d
@@ -71,7 +71,8 @@ erlang*:::efile_drv-entry
arg4 == NULL ? "" : copyinstr(arg4),
arg5 == NULL ? "" : copyinstr(arg5), arg6, arg7,
/* NOTE: port name in args[10] is experimental */
- copyinstr((user_addr_t) args[10]))
+ (args[10] == NULL) ?
+ "?" : copyinstr((user_addr_t) args[10]));
}
erlang*:::efile_drv-int*
diff --git a/lib/dtrace/src/dtrace.erl b/lib/dtrace/src/dtrace.erl
index 6951c03215..71a1a3480e 100644
--- a/lib/dtrace/src/dtrace.erl
+++ b/lib/dtrace/src/dtrace.erl
@@ -35,12 +35,10 @@
%%% then the driver will ignore the user's input and use a default
%%% value of 0 or NULL, respectively.
--define(DTRACE_UT_KEY, '_dtrace_utag_@_@'). % Match prim_file:get_dtrace_utag()!
-
-export([init/0, available/0,
user_trace_s1/1, % TODO: unify with pid & tag args like user_trace_i4s4
p/0, p/1, p/2, p/3, p/4, p/5, p/6, p/7, p/8]).
--export([put_utag/1, get_utag/0]).
+-export([put_utag/1, get_utag/0, get_utag_data/0, spread_utag/1, restore_utag/1]).
-export([scaff/0]). % Development only
-export([user_trace_i4s4/9]). % Know what you're doing!
@@ -188,24 +186,29 @@ user_trace_int(I1, I2, I3, I4, S1, S2, S3, S4) ->
false
end.
--spec put_utag(undefined | iolist()) -> ok.
-
-put_utag(undefined) ->
- put_utag(<<>>);
-put_utag(T) when is_binary(T) ->
- put(?DTRACE_UT_KEY, T),
- ok;
-put_utag(T) when is_list(T) ->
- put(?DTRACE_UT_KEY, list_to_binary(T)),
- ok.
+-spec put_utag(undefined | iodata()) -> binary() | undefined.
+put_utag(Data) ->
+ erlang:put_utag(unicode:characters_to_binary(Data)).
+-spec get_utag() -> binary() | undefined.
get_utag() ->
- case get(?DTRACE_UT_KEY) of
- undefined ->
- <<>>;
- X ->
- X
- end.
+ erlang:get_utag().
+
+-spec get_utag_data() -> binary() | undefined.
+%% Gets utag if set, otherwise the spread utag data from last incoming message
+get_utag_data() ->
+ erlang:get_utag_data().
+
+-spec spread_utag(boolean()) -> true | {non_neg_integer(), binary() | []}.
+%% Makes the utag behave as a sequential trace token, will spread with messages to be picked up by someone using
+%% get_utag_data or get_drv_utag_data.
+spread_utag(B) ->
+ erlang:spread_utag(B).
+
+-spec restore_utag(true | {non_neg_integer(), binary() | []}) -> true.
+restore_utag(T) ->
+ erlang:restore_utag(T).
+
%% Scaffolding to write tedious code: quick brute force and not 100% correct.
diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl
index a7ce17eb53..260f216725 100644
--- a/lib/hipe/cerl/erl_bif_types.erl
+++ b/lib/hipe/cerl/erl_bif_types.erl
@@ -614,6 +614,10 @@ type(erlang, adler32_combine, 3, Xs) ->
type(erlang, append, 2, Xs) -> type(erlang, '++', 2, Xs); % alias
type(erlang, append_element, 2, Xs) ->
strict(arg_types(erlang, append_element, 2), Xs, fun (_) -> t_tuple() end);
+type(erlang, append_vm_utag_data, 1, Xs) ->
+ strict(arg_types(erlang, append_vm_utag_data, 1),
+ Xs,
+ fun(_) -> t_iodata() end);
type(erlang, apply, 2, Xs) ->
Fun = fun ([X, _Y]) ->
case t_is_fun(X) of
@@ -800,6 +804,10 @@ type(erlang, get_module_info, 2, Xs) ->
type(erlang, get_stacktrace, 0, _) ->
t_list(t_tuple([t_atom(), t_atom(), t_sup([t_arity(), t_list()]),
t_list()]));
+type(erlang, get_utag, 0, _) ->
+ t_sup(t_binary(), t_atom('undefined'));
+type(erlang, get_utag_data, 0, _) ->
+ t_sup(t_binary(), t_atom('undefined'));
type(erlang, group_leader, 0, _) -> t_pid();
type(erlang, group_leader, 2, Xs) ->
strict(arg_types(erlang, group_leader, 2), Xs,
@@ -1186,6 +1194,10 @@ type(erlang, port_set_data, 2, Xs) ->
strict(arg_types(erlang, port_set_data, 2), Xs,
fun (_) -> t_atom('true') end);
type(erlang, pre_loaded, 0, _) -> t_list(t_atom());
+type(erlang, prepend_vm_utag_data, 1, Xs) ->
+ strict(arg_types(erlang, prepend_vm_utag_data, 1),
+ Xs,
+ fun(_) -> t_iodata() end);
type(erlang, process_display, 2, _) -> t_atom('true');
type(erlang, process_flag, 2, Xs) ->
T_process_flag_returns = t_sup([t_boolean(), t_atom(), t_non_neg_integer()]),
@@ -1303,6 +1315,9 @@ type(erlang, purge_module, 1, Xs) ->
fun (_) -> t_atom('true') end);
type(erlang, put, 2, Xs) ->
strict(arg_types(erlang, put, 2), Xs, fun (_) -> t_any() end);
+type(erlang, put_utag, 1, Xs) ->
+ strict(arg_types(erlang, put_utag, 1), Xs,
+ fun(_) -> t_sup(t_binary(), t_atom('undefined')) end);
type(erlang, raise, 3, _) -> t_none();
type(erlang, read_timer, 1, Xs) ->
strict(arg_types(erlang, read_timer, 1), Xs,
@@ -1312,6 +1327,8 @@ type(erlang, ref_to_list, 1, Xs) ->
type(erlang, register, 2, Xs) ->
strict(arg_types(erlang, register, 2), Xs, fun (_) -> t_atom('true') end);
type(erlang, registered, 0, _) -> t_list(t_atom());
+type(erlang, restore_utag, 1, Xs) ->
+ strict(arg_types(erlang, restore_utag, 1), Xs, fun(_) -> t_atom('true') end);
type(erlang, resume_process, 1, Xs) ->
strict(arg_types(erlang, resume_process, 1), Xs,
fun (_) -> t_any() end); %% TODO: overapproximation -- fix this
@@ -1426,6 +1443,10 @@ type(erlang, spawn_opt, 4, Xs) ->
type(erlang, split_binary, 2, Xs) ->
strict(arg_types(erlang, split_binary, 2), Xs,
fun (_) -> t_tuple([t_binary(), t_binary()]) end);
+type(erlang, spread_utag, 1, Xs) ->
+ strict(arg_types(erlang, spread_utag, 1), Xs,
+ fun(_) -> t_sup(t_tuple([t_non_neg_integer(), t_sup(t_binary(), t_nil())]),
+ t_atom('true')) end);
type(erlang, start_timer, 3, Xs) ->
strict(arg_types(erlang, start_timer, 3), Xs, fun (_) -> t_reference() end);
type(erlang, statistics, 1, Xs) ->
@@ -3422,6 +3443,8 @@ arg_types(erlang, append, 2) ->
arg_types(erlang, '++', 2);
arg_types(erlang, append_element, 2) ->
[t_tuple(), t_any()];
+arg_types(erlang, append_vm_utag_data, 1) ->
+ [t_iodata()];
arg_types(erlang, apply, 2) ->
[t_sup(t_tuple([t_module(),
t_atom()]),
@@ -3547,6 +3570,10 @@ arg_types(erlang, get_module_info, 1) ->
[t_atom()];
arg_types(erlang, get_module_info, 2) ->
[t_atom(), t_module_info_2()];
+arg_types(erlang, get_utag, 0) ->
+ [];
+arg_types(erlang, get_utag_data, 0) ->
+ [];
arg_types(erlang, group_leader, 0) ->
[];
arg_types(erlang, group_leader, 2) ->
@@ -3763,6 +3790,8 @@ arg_types(erlang, port_set_data, 2) ->
[t_sup(t_port(), t_atom()), t_any()];
arg_types(erlang, pre_loaded, 0) ->
[];
+arg_types(erlang, prepend_vm_utag_data, 1) ->
+ [t_iodata()];
arg_types(erlang, process_display, 2) ->
[t_pid(), t_atom('backtrace')];
arg_types(erlang, process_flag, 2) ->
@@ -3789,6 +3818,8 @@ arg_types(erlang, purge_module, 1) ->
[t_atom()];
arg_types(erlang, put, 2) ->
[t_any(), t_any()];
+arg_types(erlang, put_utag, 1) ->
+ [t_sup(t_binary(), t_atom('undefined'))];
arg_types(erlang, raise, 3) ->
OldStyleType = t_list(t_tuple([t_atom(), t_atom(),
t_sup([t_arity(), t_list()])])),
@@ -3802,6 +3833,8 @@ arg_types(erlang, register, 2) ->
[t_atom(), t_sup(t_port(), t_pid())];
arg_types(erlang, registered, 0) ->
[];
+arg_types(erlang, restore_utag, 1) ->
+ [t_sup(t_tuple([t_non_neg_integer(), t_sup(t_binary(), t_nil())]), t_atom('true'))];
arg_types(erlang, resume_process, 1) ->
[t_pid()]; % intended for debugging only
arg_types(erlang, round, 1) ->
@@ -3860,6 +3893,8 @@ arg_types(erlang, spawn_opt, 4) ->
[t_node(), t_atom(), t_list(), t_list(t_spawn_options())];
arg_types(erlang, split_binary, 2) ->
[t_binary(), t_non_neg_integer()];
+arg_types(erlang, spread_utag, 1) ->
+ [t_boolean()];
arg_types(erlang, start_timer, 3) ->
[t_non_neg_integer(), t_sup(t_pid(), t_atom()), t_any()];
arg_types(erlang, statistics, 1) ->
diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl
index aecb9f7923..3a618976f5 100644
--- a/lib/kernel/src/file.erl
+++ b/lib/kernel/src/file.erl
@@ -39,7 +39,7 @@
-export([ipread_s32bu_p32bu/3]).
%% Generic file contents.
-export([open/2, close/1, advise/4,
- read/2, write/2,
+ read/2, write/2,
pread/2, pread/3, pwrite/2, pwrite/3,
read_line/1,
position/2, truncate/1, datasync/1, sync/1,
@@ -62,7 +62,7 @@
%% Internal export to prim_file and ram_file until they implement
%% an efficient copy themselves.
--export([copy_opened/4]).
+-export([copy_opened/3]).
-export([ipread_s32bu_p32bu_int/3]).
@@ -166,7 +166,7 @@ pid2name(Pid) when is_pid(Pid) ->
Reason :: posix().
get_cwd() ->
- call(get_cwd, [no_drive, get_dtrace_utag()]).
+ call(get_cwd, []).
-spec get_cwd(Drive) -> {ok, Dir} | {error, Reason} when
Drive :: string(),
@@ -174,21 +174,21 @@ get_cwd() ->
Reason :: posix() | badarg.
get_cwd(Drive) ->
- check_and_call(get_cwd, [file_name(Drive), get_dtrace_utag()]).
+ check_and_call(get_cwd, [file_name(Drive)]).
-spec set_cwd(Dir) -> ok | {error, Reason} when
Dir :: name(),
Reason :: posix() | badarg.
set_cwd(Dirname) ->
- check_and_call(set_cwd, [file_name(Dirname), get_dtrace_utag()]).
+ check_and_call(set_cwd, [file_name(Dirname)]).
-spec delete(Filename) -> ok | {error, Reason} when
Filename :: name(),
Reason :: posix() | badarg.
delete(Name) ->
- check_and_call(delete, [file_name(Name), get_dtrace_utag()]).
+ check_and_call(delete, [file_name(Name)]).
-spec rename(Source, Destination) -> ok | {error, Reason} when
Source :: name(),
@@ -196,21 +196,21 @@ delete(Name) ->
Reason :: posix() | badarg.
rename(From, To) ->
- check_and_call(rename, [file_name(From), file_name(To), get_dtrace_utag()]).
+ check_and_call(rename, [file_name(From), file_name(To)]).
-spec make_dir(Dir) -> ok | {error, Reason} when
Dir :: name(),
Reason :: posix() | badarg.
make_dir(Name) ->
- check_and_call(make_dir, [file_name(Name), get_dtrace_utag()]).
+ check_and_call(make_dir, [file_name(Name)]).
-spec del_dir(Dir) -> ok | {error, Reason} when
Dir :: name(),
Reason :: posix() | badarg.
del_dir(Name) ->
- check_and_call(del_dir, [file_name(Name), get_dtrace_utag()]).
+ check_and_call(del_dir, [file_name(Name)]).
-spec read_file_info(Filename) -> {ok, FileInfo} | {error, Reason} when
Filename :: name(),
@@ -218,7 +218,7 @@ del_dir(Name) ->
Reason :: posix() | badarg.
read_file_info(Name) ->
- check_and_call(read_file_info, [file_name(Name), get_dtrace_utag()]).
+ check_and_call(read_file_info, [file_name(Name)]).
-spec read_file_info(Filename, Opts) -> {ok, FileInfo} | {error, Reason} when
Filename :: name(),
@@ -227,12 +227,12 @@ read_file_info(Name) ->
Reason :: posix() | badarg.
read_file_info(Name, Opts) when is_list(Opts) ->
- check_and_call(read_file_info, [file_name(Name), Opts, get_dtrace_utag()]).
+ check_and_call(read_file_info, [file_name(Name), Opts]).
-spec altname(Name :: name()) -> any().
altname(Name) ->
- check_and_call(altname, [file_name(Name), get_dtrace_utag()]).
+ check_and_call(altname, [file_name(Name)]).
-spec read_link_info(Name) -> {ok, FileInfo} | {error, Reason} when
Name :: name(),
@@ -240,7 +240,7 @@ altname(Name) ->
Reason :: posix() | badarg.
read_link_info(Name) ->
- check_and_call(read_link_info, [file_name(Name), get_dtrace_utag()]).
+ check_and_call(read_link_info, [file_name(Name)]).
-spec read_link_info(Name, Opts) -> {ok, FileInfo} | {error, Reason} when
Name :: name(),
@@ -249,7 +249,7 @@ read_link_info(Name) ->
Reason :: posix() | badarg.
read_link_info(Name, Opts) when is_list(Opts) ->
- check_and_call(read_link_info, [file_name(Name),Opts, get_dtrace_utag()]).
+ check_and_call(read_link_info, [file_name(Name),Opts]).
-spec read_link(Name) -> {ok, Filename} | {error, Reason} when
@@ -258,7 +258,7 @@ read_link_info(Name, Opts) when is_list(Opts) ->
Reason :: posix() | badarg.
read_link(Name) ->
- check_and_call(read_link, [file_name(Name), get_dtrace_utag()]).
+ check_and_call(read_link, [file_name(Name)]).
-spec write_file_info(Filename, FileInfo) -> ok | {error, Reason} when
Filename :: name(),
@@ -266,7 +266,7 @@ read_link(Name) ->
Reason :: posix() | badarg.
write_file_info(Name, Info = #file_info{}) ->
- check_and_call(write_file_info, [file_name(Name), Info, get_dtrace_utag()]).
+ check_and_call(write_file_info, [file_name(Name), Info]).
-spec write_file_info(Filename, FileInfo, Opts) -> ok | {error, Reason} when
Filename :: name(),
@@ -275,7 +275,7 @@ write_file_info(Name, Info = #file_info{}) ->
Reason :: posix() | badarg.
write_file_info(Name, Info = #file_info{}, Opts) when is_list(Opts) ->
- check_and_call(write_file_info, [file_name(Name), Info, Opts, get_dtrace_utag()]).
+ check_and_call(write_file_info, [file_name(Name), Info, Opts]).
-spec list_dir(Dir) -> {ok, Filenames} | {error, Reason} when
Dir :: name(),
@@ -283,7 +283,7 @@ write_file_info(Name, Info = #file_info{}, Opts) when is_list(Opts) ->
Reason :: posix() | badarg.
list_dir(Name) ->
- check_and_call(list_dir, [file_name(Name), get_dtrace_utag()]).
+ check_and_call(list_dir, [file_name(Name)]).
-spec read_file(Filename) -> {ok, Binary} | {error, Reason} when
Filename :: name(),
@@ -291,7 +291,7 @@ list_dir(Name) ->
Reason :: posix() | badarg | terminated | system_limit.
read_file(Name) ->
- check_and_call(read_file, [file_name(Name), get_dtrace_utag()]).
+ check_and_call(read_file, [file_name(Name)]).
-spec make_link(Existing, New) -> ok | {error, Reason} when
Existing :: name(),
@@ -299,7 +299,7 @@ read_file(Name) ->
Reason :: posix() | badarg.
make_link(Old, New) ->
- check_and_call(make_link, [file_name(Old), file_name(New), get_dtrace_utag()]).
+ check_and_call(make_link, [file_name(Old), file_name(New)]).
-spec make_symlink(Existing, New) -> ok | {error, Reason} when
Existing :: name(),
@@ -307,7 +307,7 @@ make_link(Old, New) ->
Reason :: posix() | badarg.
make_symlink(Old, New) ->
- check_and_call(make_symlink, [file_name(Old), file_name(New), get_dtrace_utag()]).
+ check_and_call(make_symlink, [file_name(Old), file_name(New)]).
-spec write_file(Filename, Bytes) -> ok | {error, Reason} when
Filename :: name(),
@@ -315,7 +315,7 @@ make_symlink(Old, New) ->
Reason :: posix() | badarg | terminated | system_limit.
write_file(Name, Bin) ->
- check_and_call(write_file, [file_name(Name), make_binary(Bin), get_dtrace_utag()]).
+ check_and_call(write_file, [file_name(Name), make_binary(Bin)]).
%% This whole operation should be moved to the file_server and prim_file
%% when it is time to change file server protocol again.
@@ -367,7 +367,7 @@ raw_write_file_info(Name, #file_info{} = Info) ->
case check_args(Args) of
ok ->
[FileName] = Args,
- ?PRIM_FILE:write_file_info(FileName, Info, get_dtrace_utag());
+ ?PRIM_FILE:write_file_info(FileName, Info);
Error ->
Error
end.
@@ -400,7 +400,7 @@ open(Item, ModeList) when is_list(ModeList) ->
[FileName | _] = Args,
%% We rely on the returned Handle (in {ok, Handle})
%% being a pid() or a #file_descriptor{}
- ?PRIM_FILE:open(FileName, ModeList, get_dtrace_utag());
+ ?PRIM_FILE:open(FileName, ModeList);
Error ->
Error
end
@@ -421,7 +421,7 @@ open(Item, ModeList) when is_list(ModeList) ->
case check_args(Args) of
ok ->
[FileName | _] = Args,
- call(open, [FileName, ModeList, get_dtrace_utag()]);
+ call(open, [FileName, ModeList]);
Error ->
Error
end
@@ -466,10 +466,7 @@ close(_) ->
advise(File, Offset, Length, Advise) when is_pid(File) ->
R = file_request(File, {advise, Offset, Length, Advise}),
wait_file_reply(File, R);
-advise(#file_descriptor{module = prim_file = Module} = Handle, Offset, Length, Advise) ->
- Module:advise(Handle, Offset, Length, Advise, get_dtrace_utag());
advise(#file_descriptor{module = Module} = Handle, Offset, Length, Advise) ->
- %% DTrace TODO: ram_file and other file drivers not yet DTrace'ified.
Module:advise(Handle, Offset, Length, Advise);
advise(_, _, _, _) ->
{error, badarg}.
@@ -480,25 +477,17 @@ advise(_, _, _, _) ->
Data :: string() | binary(),
Reason :: posix() | badarg | terminated.
-read(File, Sz) ->
- read(File, Sz, get_dtrace_utag()).
-
-read(File, Sz, _DTraceUtag)
- when (is_pid(File) orelse is_atom(File)), is_integer(Sz), Sz >= 0 ->
+read(File, Sz) when (is_pid(File) orelse is_atom(File)), is_integer(Sz), Sz >= 0 ->
case io:request(File, {get_chars, '', Sz}) of
Data when is_list(Data); is_binary(Data) ->
{ok, Data};
Other ->
Other
end;
-read(#file_descriptor{module = prim_file = Module} = Handle, Sz, DTraceUtag)
- when is_integer(Sz), Sz >= 0 ->
- Module:read(Handle, Sz, DTraceUtag);
-read(#file_descriptor{module = Module} = Handle, Sz, _DTraceUtag)
+read(#file_descriptor{module = Module} = Handle, Sz)
when is_integer(Sz), Sz >= 0 ->
- %% DTrace TODO: ram_file and other file drivers not yet DTrace'ified.
Module:read(Handle, Sz);
-read(_, _, _) ->
+read(_, _) ->
{error, badarg}.
-spec read_line(IoDevice) -> {ok, Data} | eof | {error, Reason} when
@@ -513,10 +502,7 @@ read_line(File) when (is_pid(File) orelse is_atom(File)) ->
Other ->
Other
end;
-read_line(#file_descriptor{module = prim_file = Module} = Handle) ->
- Module:read_line(Handle, get_dtrace_utag());
read_line(#file_descriptor{module = Module} = Handle) ->
- %% DTrace TODO: ram_file and other file drivers not yet DTrace'ified.
Module:read_line(Handle);
read_line(_) ->
{error, badarg}.
@@ -530,10 +516,7 @@ read_line(_) ->
pread(File, L) when is_pid(File), is_list(L) ->
pread_int(File, L, []);
-pread(#file_descriptor{module = prim_file = Module} = Handle, L) when is_list(L) ->
- Module:pread(Handle, L, get_dtrace_utag());
pread(#file_descriptor{module = Module} = Handle, L) when is_list(L) ->
- %% DTrace TODO: ram_file and other file drivers not yet DTrace'ified.
Module:pread(Handle, L);
pread(_, _) ->
{error, badarg}.
@@ -565,7 +548,6 @@ pread(File, At, Sz) when is_pid(File), is_integer(Sz), Sz >= 0 ->
wait_file_reply(File, R);
pread(#file_descriptor{module = Module} = Handle, Offs, Sz)
when is_integer(Sz), Sz >= 0 ->
- %% DTrace TODO: ram_file and other file drivers not yet DTrace'ified.
Module:pread(Handle, Offs, Sz);
pread(_, _, _) ->
{error, badarg}.
@@ -575,22 +557,16 @@ pread(_, _, _) ->
Bytes :: iodata(),
Reason :: posix() | badarg | terminated.
-write(File, Bytes) ->
- write(File, Bytes, get_dtrace_utag()).
-
-write(File, Bytes, _DTraceUtag) when (is_pid(File) orelse is_atom(File)) ->
+write(File, Bytes) when (is_pid(File) orelse is_atom(File)) ->
case make_binary(Bytes) of
Bin when is_binary(Bin) ->
io:request(File, {put_chars,Bin});
Error ->
Error
end;
-write(#file_descriptor{module = prim_file = Module} = Handle, Bytes, DTraceUtag) ->
- Module:write(Handle, Bytes, DTraceUtag);
-write(#file_descriptor{module = Module} = Handle, Bytes, _DTraceUtag) ->
- %% DTrace TODO: ram_file and other file drivers not yet DTrace'ified.
+write(#file_descriptor{module = Module} = Handle, Bytes) ->
Module:write(Handle, Bytes);
-write(_, _, _) ->
+write(_, _) ->
{error, badarg}.
-spec pwrite(IoDevice, LocBytes) -> ok | {error, {N, Reason}} when
@@ -601,10 +577,7 @@ write(_, _, _) ->
pwrite(File, L) when is_pid(File), is_list(L) ->
pwrite_int(File, L, 0);
-pwrite(#file_descriptor{module = prim_file = Module} = Handle, L) when is_list(L) ->
- Module:pwrite(Handle, L, get_dtrace_utag());
pwrite(#file_descriptor{module = Module} = Handle, L) when is_list(L) ->
- %% DTrace TODO: ram_file and other file drivers not yet DTrace'ified.
Module:pwrite(Handle, L);
pwrite(_, _) ->
{error, badarg}.
@@ -631,7 +604,6 @@ pwrite(File, At, Bytes) when is_pid(File) ->
R = file_request(File, {pwrite, At, Bytes}),
wait_file_reply(File, R);
pwrite(#file_descriptor{module = Module} = Handle, Offs, Bytes) ->
- %% DTrace TODO: ram_file and other file drivers not yet DTrace'ified.
Module:pwrite(Handle, Offs, Bytes);
pwrite(_, _, _) ->
{error, badarg}.
@@ -643,10 +615,7 @@ pwrite(_, _, _) ->
datasync(File) when is_pid(File) ->
R = file_request(File, datasync),
wait_file_reply(File, R);
-datasync(#file_descriptor{module = prim_file = Module} = Handle) ->
- Module:datasync(Handle, get_dtrace_utag());
datasync(#file_descriptor{module = Module} = Handle) ->
- %% DTrace TODO: ram_file and other file drivers not yet DTrace'ified.
Module:datasync(Handle);
datasync(_) ->
{error, badarg}.
@@ -658,10 +627,7 @@ datasync(_) ->
sync(File) when is_pid(File) ->
R = file_request(File, sync),
wait_file_reply(File, R);
-sync(#file_descriptor{module = prim_file = Module} = Handle) ->
- Module:sync(Handle, get_dtrace_utag());
sync(#file_descriptor{module = Module} = Handle) ->
- %% DTrace TODO: ram_file and other file drivers not yet DTrace'ified.
Module:sync(Handle);
sync(_) ->
{error, badarg}.
@@ -675,10 +641,7 @@ sync(_) ->
position(File, At) when is_pid(File) ->
R = file_request(File, {position,At}),
wait_file_reply(File, R);
-position(#file_descriptor{module = prim_file = Module} = Handle, At) ->
- Module:position(Handle, At, get_dtrace_utag());
position(#file_descriptor{module = Module} = Handle, At) ->
- %% DTrace TODO: ram_file and other file drivers not yet DTrace'ified.
Module:position(Handle, At);
position(_, _) ->
{error, badarg}.
@@ -690,10 +653,7 @@ position(_, _) ->
truncate(File) when is_pid(File) ->
R = file_request(File, truncate),
wait_file_reply(File, R);
-truncate(#file_descriptor{module = prim_file = Module} = Handle) ->
- Module:truncate(Handle, get_dtrace_utag());
truncate(#file_descriptor{module = Module} = Handle) ->
- %% DTrace TODO: ram_file and other file drivers not yet DTrace'ified.
Module:truncate(Handle);
truncate(_) ->
{error, badarg}.
@@ -734,7 +694,7 @@ copy_int(Source, Dest, Length)
when is_pid(Source), is_pid(Dest);
is_pid(Source), is_record(Dest, file_descriptor);
is_record(Source, file_descriptor), is_pid(Dest) ->
- copy_opened_int(Source, Dest, Length, get_dtrace_utag());
+ copy_opened_int(Source, Dest, Length, 0);
%% Copy between open raw files, both handled by the same module
copy_int(#file_descriptor{module = Module} = Source,
#file_descriptor{module = Module} = Dest,
@@ -743,14 +703,14 @@ copy_int(#file_descriptor{module = Module} = Source,
%% Copy between open raw files of different modules
copy_int(#file_descriptor{} = Source,
#file_descriptor{} = Dest, Length) ->
- copy_opened_int(Source, Dest, Length, get_dtrace_utag());
+ copy_opened_int(Source, Dest, Length, 0);
%% Copy between filenames, let the server do the copy
copy_int({SourceName, SourceOpts}, {DestName, DestOpts}, Length)
when is_list(SourceOpts), is_list(DestOpts) ->
check_and_call(copy,
[file_name(SourceName), SourceOpts,
file_name(DestName), DestOpts,
- Length, get_dtrace_utag()]);
+ Length]);
%% Filename -> open file; must open Source and do client copy
copy_int({SourceName, SourceOpts}, Dest, Length)
when is_list(SourceOpts), is_pid(Dest);
@@ -761,8 +721,7 @@ copy_int({SourceName, SourceOpts}, Dest, Length)
Source ->
case open(Source, [read | SourceOpts]) of
{ok, Handle} ->
- Result = copy_opened_int(Handle, Dest, Length,
- get_dtrace_utag()),
+ Result = copy_opened_int(Handle, Dest, Length, 0),
close(Handle),
Result;
{error, _} = Error ->
@@ -779,8 +738,7 @@ copy_int(Source, {DestName, DestOpts}, Length)
Dest ->
case open(Dest, [write | DestOpts]) of
{ok, Handle} ->
- Result = copy_opened_int(Source, Handle, Length,
- get_dtrace_utag()),
+ Result = copy_opened_int(Source, Handle, Length, 0),
close(Handle),
Result;
{error, _} = Error ->
@@ -815,46 +773,45 @@ copy_int(Source, Dest, Length) ->
-copy_opened(Source, Dest, Length, DTraceUtag)
+copy_opened(Source, Dest, Length)
when is_integer(Length), Length >= 0;
is_atom(Length) ->
- copy_opened_int(Source, Dest, Length, DTraceUtag);
-copy_opened(_, _, _, _) ->
+ copy_opened_int(Source, Dest, Length);
+copy_opened(_, _, _) ->
{error, badarg}.
%% Here we know that Length is either an atom or an integer >= 0
%% (by the way, atoms > integers)
-copy_opened_int(Source, Dest, Length, DTraceUtag)
+copy_opened_int(Source, Dest, Length)
when is_pid(Source), is_pid(Dest) ->
- copy_opened_int(Source, Dest, Length, 0, DTraceUtag);
-copy_opened_int(Source, Dest, Length, DTraceUtag)
+ copy_opened_int(Source, Dest, Length, 0);
+copy_opened_int(Source, Dest, Length)
when is_pid(Source), is_record(Dest, file_descriptor) ->
- copy_opened_int(Source, Dest, Length, 0, DTraceUtag);
-copy_opened_int(Source, Dest, Length, DTraceUtag)
+ copy_opened_int(Source, Dest, Length, 0);
+copy_opened_int(Source, Dest, Length)
when is_record(Source, file_descriptor), is_pid(Dest) ->
- copy_opened_int(Source, Dest, Length, 0, DTraceUtag);
-copy_opened_int(Source, Dest, Length, DTraceUtag)
+ copy_opened_int(Source, Dest, Length, 0);
+copy_opened_int(Source, Dest, Length)
when is_record(Source, file_descriptor), is_record(Dest, file_descriptor) ->
- copy_opened_int(Source, Dest, Length, 0, DTraceUtag);
-copy_opened_int(_, _, _, _) ->
+ copy_opened_int(Source, Dest, Length, 0);
+copy_opened_int(_, _, _) ->
{error, badarg}.
%% Here we know that Source and Dest are handles to open files, Length is
%% as above, and Copied is an integer >= 0
%% Copy loop in client process
-copy_opened_int(_, _, Length, Copied, _DTraceUtag)
- when Length =< 0 -> % atom() > integer()
+copy_opened_int(_, _, Length, Copied) when Length =< 0 -> % atom() > integer()
{ok, Copied};
-copy_opened_int(Source, Dest, Length, Copied, DTraceUtag) ->
+copy_opened_int(Source, Dest, Length, Copied) ->
N = if Length > 65536 -> 65536; true -> Length end, % atom() > integer() !
- case read(Source, N, DTraceUtag) of
+ case read(Source, N) of
{ok, Data} ->
M = if is_binary(Data) -> byte_size(Data);
is_list(Data) -> length(Data)
end,
- case write(Dest, Data, DTraceUtag) of
+ case write(Dest, Data) of
ok ->
if M < N ->
%% Got less than asked for - must be end of file
@@ -864,8 +821,7 @@ copy_opened_int(Source, Dest, Length, Copied, DTraceUtag) ->
NewLength = if is_atom(Length) -> Length;
true -> Length-M
end,
- copy_opened_int(Source, Dest, NewLength, Copied+M,
- DTraceUtag)
+ copy_opened_int(Source, Dest, NewLength, Copied+M)
end;
{error, _} = Error ->
Error
@@ -885,8 +841,6 @@ copy_opened_int(Source, Dest, Length, Copied, DTraceUtag) ->
ipread_s32bu_p32bu(File, Pos, MaxSize) when is_pid(File) ->
ipread_s32bu_p32bu_int(File, Pos, MaxSize);
-ipread_s32bu_p32bu(#file_descriptor{module = prim_file = Module} = Handle, Pos, MaxSize) ->
- Module:ipread_s32bu_p32bu(Handle, Pos, MaxSize, get_dtrace_utag());
ipread_s32bu_p32bu(#file_descriptor{module = Module} = Handle, Pos, MaxSize) ->
Module:ipread_s32bu_p32bu(Handle, Pos, MaxSize);
ipread_s32bu_p32bu(_, _, _) ->
@@ -1467,7 +1421,10 @@ call(Command, Args) when is_list(Args) ->
check_and_call(Command, Args) when is_list(Args) ->
case check_args(Args) of
ok ->
- call(Command, Args);
+ X = erlang:spread_utag(true),
+ Y = call(Command, Args),
+ erlang:restore_utag(X),
+ Y;
Error ->
Error
end.
@@ -1502,6 +1459,3 @@ wait_file_reply(From, Ref) ->
%% receive {'EXIT', From, _} -> ok after 0 -> ok end,
{error, terminated}
end.
-
-get_dtrace_utag() ->
- dtrace:get_utag().
diff --git a/lib/kernel/src/file_io_server.erl b/lib/kernel/src/file_io_server.erl
index cc0343031b..14da9c1a55 100644
--- a/lib/kernel/src/file_io_server.erl
+++ b/lib/kernel/src/file_io_server.erl
@@ -21,7 +21,7 @@
%% A simple file server for io to one file instance per server instance.
-export([format_error/1]).
--export([start/4, start_link/4]).
+-export([start/3, start_link/3]).
-export([count_and_find/3]).
@@ -43,18 +43,18 @@ format_error({_Line, Mod, Reason}) ->
format_error(ErrorId) ->
erl_posix_msg:message(ErrorId).
-start(Owner, FileName, ModeList, DTraceUtag)
+start(Owner, FileName, ModeList)
when is_pid(Owner), (is_list(FileName) orelse is_binary(FileName)), is_list(ModeList) ->
- do_start(spawn, Owner, FileName, ModeList, DTraceUtag).
+ do_start(spawn, Owner, FileName, ModeList).
-start_link(Owner, FileName, ModeList, DTraceUtag)
+start_link(Owner, FileName, ModeList)
when is_pid(Owner), (is_list(FileName) orelse is_binary(FileName)), is_list(ModeList) ->
- do_start(spawn_link, Owner, FileName, ModeList, DTraceUtag).
+ do_start(spawn_link, Owner, FileName, ModeList).
%%%-----------------------------------------------------------------
%%% Server starter, dispatcher and helpers
-do_start(Spawn, Owner, FileName, ModeList, DTraceUtag) ->
+do_start(Spawn, Owner, FileName, ModeList) ->
Self = self(),
Ref = make_ref(),
Pid =
@@ -63,12 +63,11 @@ do_start(Spawn, Owner, FileName, ModeList, DTraceUtag) ->
%% process_flag(trap_exit, true),
case parse_options(ModeList) of
{ReadMode, UnicodeMode, Opts} ->
- case ?PRIM_FILE:open(FileName, Opts, DTraceUtag) of
+ case ?PRIM_FILE:open(FileName, Opts) of
{error, Reason} = Error ->
Self ! {Ref, Error},
exit(Reason);
{ok, Handle} ->
- put(dtrace_utag, DTraceUtag), % TODO: API?
%% XXX must I handle R6 nodes here?
M = erlang:monitor(process, Owner),
Self ! {Ref, ok},
diff --git a/lib/kernel/src/file_server.erl b/lib/kernel/src/file_server.erl
index 82adc45795..fc6cd823c9 100644
--- a/lib/kernel/src/file_server.erl
+++ b/lib/kernel/src/file_server.erl
@@ -76,7 +76,6 @@ stop() ->
init([]) ->
process_flag(trap_exit, true),
- put(dtrace_utag, atom_to_list(?FILE_SERVER)),
case ?PRIM_FILE:start() of
{ok, Handle} ->
ets:new(?FILE_IO_SERVER_TABLE, [named_table]),
@@ -100,9 +99,9 @@ init([]) ->
{'reply', 'eof' | 'ok' | {'error', term()} | {'ok', term()}, state()} |
{'stop', 'normal', 'stopped', state()}.
-handle_call({open, Name, ModeList, DTraceUtag}, {Pid, _Tag} = _From, Handle)
+handle_call({open, Name, ModeList}, {Pid, _Tag} = _From, Handle)
when is_list(ModeList) ->
- Child = ?FILE_IO_SERVER:start_link(Pid, Name, ModeList, DTraceUtag),
+ Child = ?FILE_IO_SERVER:start_link(Pid, Name, ModeList),
case Child of
{ok, P} when is_pid(P) ->
ets:insert(?FILE_IO_SERVER_TABLE, {P, Name});
@@ -111,86 +110,87 @@ handle_call({open, Name, ModeList, DTraceUtag}, {Pid, _Tag} = _From, Handle)
end,
{reply, Child, Handle};
-handle_call({open, _Name, _Mode, _DTraceUtag}, _From, Handle) ->
+handle_call({open, _Name, _Mode}, _From, Handle) ->
{reply, {error, einval}, Handle};
-handle_call({read_file, Name, DTraceUtag}, _From, Handle) ->
- {reply, ?PRIM_FILE:read_file(Name, DTraceUtag), Handle};
+handle_call({read_file, Name}, _From, Handle) ->
+ {reply, ?PRIM_FILE:read_file(Name), Handle};
-handle_call({write_file, Name, Bin, DTraceUtag}, _From, Handle) ->
- {reply, ?PRIM_FILE:write_file(Name, Bin, DTraceUtag), Handle};
+handle_call({write_file, Name, Bin}, _From, Handle) ->
+ {reply, ?PRIM_FILE:write_file(Name, Bin), Handle};
-handle_call({set_cwd, Name, DTraceUtag}, _From, Handle) ->
- {reply, ?PRIM_FILE:set_cwd(Handle, Name, DTraceUtag), Handle};
+handle_call({set_cwd, Name}, _From, Handle) ->
+ {reply, ?PRIM_FILE:set_cwd(Handle, Name), Handle};
-handle_call({delete, Name, DTraceUtag}, _From, Handle) ->
- {reply, ?PRIM_FILE:delete(Handle, Name, DTraceUtag), Handle};
+handle_call({delete, Name}, _From, Handle) ->
+ {reply, ?PRIM_FILE:delete(Handle, Name), Handle};
-handle_call({rename, Fr, To, DTraceUtag}, _From, Handle) ->
- {reply, ?PRIM_FILE:rename(Handle, Fr, To, DTraceUtag), Handle};
+handle_call({rename, Fr, To}, _From, Handle) ->
+ {reply, ?PRIM_FILE:rename(Handle, Fr, To), Handle};
-handle_call({make_dir, Name, DTraceUtag}, _From, Handle) ->
- {reply, ?PRIM_FILE:make_dir(Handle, Name, DTraceUtag), Handle};
+handle_call({make_dir, Name}, _From, Handle) ->
+ {reply, ?PRIM_FILE:make_dir(Handle, Name), Handle};
-handle_call({del_dir, Name, DTraceUtag}, _From, Handle) ->
- {reply, ?PRIM_FILE:del_dir(Handle, Name, DTraceUtag), Handle};
+handle_call({del_dir, Name}, _From, Handle) ->
+ {reply, ?PRIM_FILE:del_dir(Handle, Name), Handle};
-handle_call({list_dir, Name, DTraceUtag}, _From, Handle) ->
- {reply, ?PRIM_FILE:list_dir(Handle, Name, DTraceUtag), Handle};
+handle_call({list_dir, Name}, _From, Handle) ->
+ {reply, ?PRIM_FILE:list_dir(Handle, Name), Handle};
handle_call(get_cwd, _From, Handle) ->
- {reply, ?PRIM_FILE:get_cwd(Handle, no_drive, "TODO-fixme"), Handle};
-handle_call({get_cwd, no_drive, DTraceUtag}, _From, Handle) ->
- {reply, ?PRIM_FILE:get_cwd(Handle, no_drive, DTraceUtag), Handle};
-handle_call({get_cwd, Name, DTraceUtag}, _From, Handle) ->
- {reply, ?PRIM_FILE:get_cwd(Handle, Name, DTraceUtag), Handle};
+ {reply, ?PRIM_FILE:get_cwd(Handle), Handle};
+handle_call({get_cwd}, _From, Handle) ->
+ {reply, ?PRIM_FILE:get_cwd(Handle), Handle};
+handle_call({get_cwd, Name}, _From, Handle) ->
+ {reply, ?PRIM_FILE:get_cwd(Handle, Name), Handle};
-handle_call({read_file_info, Name, DTraceUtag}, _From, Handle) ->
- {reply, ?PRIM_FILE:read_file_info(Handle, Name, [], DTraceUtag), Handle};
-handle_call({read_file_info, Name, Opts, DTraceUtag}, _From, Handle) ->
- {reply, ?PRIM_FILE:read_file_info(Handle, Name, Opts, DTraceUtag), Handle};
+handle_call({read_file_info, Name}, _From, Handle) ->
+ {reply, ?PRIM_FILE:read_file_info(Handle, Name), Handle};
-handle_call({altname, Name, DTraceUtag}, _From, Handle) ->
- {reply, ?PRIM_FILE:altname(Handle, Name, DTraceUtag), Handle};
+handle_call({read_file_info, Name, Opts}, _From, Handle) ->
+ {reply, ?PRIM_FILE:read_file_info(Handle, Name, Opts), Handle};
-handle_call({write_file_info, Name, Info, DTraceUtag}, _From, Handle) ->
- {reply, ?PRIM_FILE:write_file_info(Handle, Name, Info, [], DTraceUtag), Handle};
-handle_call({write_file_info, Name, Info, Opts, DTraceUtag}, _From, Handle) ->
- {reply, ?PRIM_FILE:write_file_info(Handle, Name, Info, Opts, DTraceUtag), Handle};
+handle_call({altname, Name}, _From, Handle) ->
+ {reply, ?PRIM_FILE:altname(Handle, Name), Handle};
-handle_call({read_link_info, Name, DTraceUtag}, _From, Handle) ->
- {reply, ?PRIM_FILE:read_link_info(Handle, Name, [], DTraceUtag), Handle};
-handle_call({read_link_info, Name, Opts, DTraceUtag}, _From, Handle) ->
- {reply, ?PRIM_FILE:read_link_info(Handle, Name, Opts, DTraceUtag), Handle};
+handle_call({write_file_info, Name, Info}, _From, Handle) ->
+ {reply, ?PRIM_FILE:write_file_info(Handle, Name, Info), Handle};
-handle_call({read_link, Name, DTraceUtag}, _From, Handle) ->
- {reply, ?PRIM_FILE:read_link(Handle, Name, DTraceUtag), Handle};
+handle_call({write_file_info, Name, Info, Opts}, _From, Handle) ->
+ {reply, ?PRIM_FILE:write_file_info(Handle, Name, Info, Opts), Handle};
-handle_call({make_link, Old, New, DTraceUtag}, _From, Handle) ->
- {reply, ?PRIM_FILE:make_link(Handle, Old, New, DTraceUtag), Handle};
+handle_call({read_link_info, Name}, _From, Handle) ->
+ {reply, ?PRIM_FILE:read_link_info(Handle, Name), Handle};
-handle_call({make_symlink, Old, New, DTraceUtag}, _From, Handle) ->
- {reply, ?PRIM_FILE:make_symlink(Handle, Old, New, DTraceUtag), Handle};
+handle_call({read_link_info, Name, Opts}, _From, Handle) ->
+ {reply, ?PRIM_FILE:read_link_info(Handle, Name, Opts), Handle};
-handle_call({copy, SourceName, SourceOpts, DestName, DestOpts, Length, DTraceUtag},
+handle_call({read_link, Name}, _From, Handle) ->
+ {reply, ?PRIM_FILE:read_link(Handle, Name), Handle};
+
+handle_call({make_link, Old, New}, _From, Handle) ->
+ {reply, ?PRIM_FILE:make_link(Handle, Old, New), Handle};
+
+handle_call({make_symlink, Old, New}, _From, Handle) ->
+ {reply, ?PRIM_FILE:make_symlink(Handle, Old, New), Handle};
+
+handle_call({copy, SourceName, SourceOpts, DestName, DestOpts, Length},
_From, Handle) ->
Reply =
- case ?PRIM_FILE:open(SourceName, [read, binary | SourceOpts],
- DTraceUtag) of
+ case ?PRIM_FILE:open(SourceName, [read, binary | SourceOpts]) of
{ok, Source} ->
SourceReply =
case ?PRIM_FILE:open(DestName,
- [write, binary | DestOpts],
- DTraceUtag) of
+ [write, binary | DestOpts]) of
{ok, Dest} ->
DestReply =
- ?PRIM_FILE:copy(Source, Dest, Length, DTraceUtag),
- ?PRIM_FILE:close(Dest, DTraceUtag),
+ ?PRIM_FILE:copy(Source, Dest, Length),
+ ?PRIM_FILE:close(Dest),
DestReply;
{error, _} = Error ->
Error
end,
- ?PRIM_FILE:close(Source, DTraceUtag),
+ ?PRIM_FILE:close(Source),
SourceReply;
{error, _} = Error ->
Error
diff --git a/lib/kernel/test/prim_file_SUITE.erl b/lib/kernel/test/prim_file_SUITE.erl
index 9575762b12..3e2202922c 100644
--- a/lib/kernel/test/prim_file_SUITE.erl
+++ b/lib/kernel/test/prim_file_SUITE.erl
@@ -70,7 +70,7 @@
%% compile time.
-define(PRIM_FILE_call(F, H, A),
case H of
- [] -> apply(?PRIM_FILE, F, A -- ["utag"]);
+ [] -> apply(?PRIM_FILE, F, A);
_ -> apply(?PRIM_FILE, F, [H | A])
end).
@@ -255,31 +255,31 @@ make_del_dir(Config, Handle, Suffix) ->
?line NewDir = filename:join(RootDir,
atom_to_list(?MODULE)
++"_mk-dir"++Suffix),
- ?line ok = ?PRIM_FILE_call(make_dir, Handle, [NewDir, "utag"]),
- ?line {error, eexist} = ?PRIM_FILE_call(make_dir, Handle, [NewDir, "utag"]),
- ?line ok = ?PRIM_FILE_call(del_dir, Handle, [NewDir, "utag"]),
- ?line {error, enoent} = ?PRIM_FILE_call(del_dir, Handle, [NewDir, "utag"]),
+ ?line ok = ?PRIM_FILE_call(make_dir, Handle, [NewDir]),
+ ?line {error, eexist} = ?PRIM_FILE_call(make_dir, Handle, [NewDir]),
+ ?line ok = ?PRIM_FILE_call(del_dir, Handle, [NewDir]),
+ ?line {error, enoent} = ?PRIM_FILE_call(del_dir, Handle, [NewDir]),
% Make sure we are not in a directory directly under test_server
% as that would result in eacess errors when trying to delere '..',
% because there are processes having that directory as current.
- ?line ok = ?PRIM_FILE_call(make_dir, Handle, [NewDir, "utag"]),
+ ?line ok = ?PRIM_FILE_call(make_dir, Handle, [NewDir]),
?line {ok, CurrentDir} = ?PRIM_FILE_call(get_cwd, Handle, []),
- ?line ok = ?PRIM_FILE_call(set_cwd, Handle, [NewDir, "utag"]),
+ ?line ok = ?PRIM_FILE_call(set_cwd, Handle, [NewDir]),
try
%% Check that we get an error when trying to create...
%% a deep directory
?line NewDir2 = filename:join(RootDir,
atom_to_list(?MODULE)
++"_mk-dir-noexist/foo"),
- ?line {error, enoent} = ?PRIM_FILE_call(make_dir, Handle, [NewDir2, "utag"]),
+ ?line {error, enoent} = ?PRIM_FILE_call(make_dir, Handle, [NewDir2]),
%% a nameless directory
- ?line {error, enoent} = ?PRIM_FILE_call(make_dir, Handle, ["", "utag"]),
+ ?line {error, enoent} = ?PRIM_FILE_call(make_dir, Handle, [""]),
%% a directory with illegal name
- ?line {error, badarg} = ?PRIM_FILE_call(make_dir, Handle, ['mk-dir', "utag"]),
+ ?line {error, badarg} = ?PRIM_FILE_call(make_dir, Handle, ['mk-dir']),
%% a directory with illegal name, even if it's a (bad) list
- ?line {error, badarg} = ?PRIM_FILE_call(make_dir, Handle, [[1,2,3,{}], "utag"]),
+ ?line {error, badarg} = ?PRIM_FILE_call(make_dir, Handle, [[1,2,3,{}]]),
%% Maybe this isn't an error, exactly, but worth mentioning anyway:
%% ok = ?PRIM_FILE:make_dir([$f,$o,$o,0,$b,$a,$r])),
@@ -292,17 +292,17 @@ make_del_dir(Config, Handle, Suffix) ->
%% Try deleting some bad directories
%% Deleting the parent directory to the current, sounds dangerous, huh?
%% Don't worry ;-) the parent directory should never be empty, right?
- ?line case ?PRIM_FILE_call(del_dir, Handle, ["..", "utag"]) of
+ ?line case ?PRIM_FILE_call(del_dir, Handle, [".."]) of
{error, eexist} -> ok;
{error, eacces} -> ok; %OpenBSD
{error, einval} -> ok %FreeBSD
end,
- ?line {error, enoent} = ?PRIM_FILE_call(del_dir, Handle, ["", "utag"]),
- ?line {error, badarg} = ?PRIM_FILE_call(del_dir, Handle, [[3,2,1,{}], "utag"]),
+ ?line {error, enoent} = ?PRIM_FILE_call(del_dir, Handle, [""]),
+ ?line {error, badarg} = ?PRIM_FILE_call(del_dir, Handle, [[3,2,1,{}]]),
?line test_server:timetrap_cancel(Dog)
after
- ?line ok = ?PRIM_FILE_call(set_cwd, Handle, [CurrentDir, "utag"])
+ ?line ok = ?PRIM_FILE_call(set_cwd, Handle, [CurrentDir])
end,
ok.
@@ -324,7 +324,7 @@ cur_dir_0(Config, Handle) ->
%% Find out the current dir, and cd to it ;-)
?line {ok,BaseDir} = ?PRIM_FILE_call(get_cwd, Handle, []),
?line Dir1 = BaseDir ++ "", %% Check that it's a string
- ?line ok = ?PRIM_FILE_call(set_cwd, Handle, [Dir1, "utag"]),
+ ?line ok = ?PRIM_FILE_call(set_cwd, Handle, [Dir1]),
?line DirName = atom_to_list(?MODULE) ++
case Handle of
[] ->
@@ -336,40 +336,40 @@ cur_dir_0(Config, Handle) ->
%% Make a new dir, and cd to that
?line RootDir = ?config(priv_dir,Config),
?line NewDir = filename:join(RootDir, DirName),
- ?line ok = ?PRIM_FILE_call(make_dir, Handle, [NewDir, "utag"]),
+ ?line ok = ?PRIM_FILE_call(make_dir, Handle, [NewDir]),
?line io:format("cd to ~s",[NewDir]),
- ?line ok = ?PRIM_FILE_call(set_cwd, Handle, [NewDir, "utag"]),
+ ?line ok = ?PRIM_FILE_call(set_cwd, Handle, [NewDir]),
%% Create a file in the new current directory, and check that it
%% really is created there
?line UncommonName = "uncommon.fil",
?line {ok,Fd} = ?PRIM_FILE:open(UncommonName, [read, write]),
?line ok = ?PRIM_FILE:close(Fd),
- ?line {ok,NewDirFiles} = ?PRIM_FILE_call(list_dir, Handle, [".", "utag"]),
+ ?line {ok,NewDirFiles} = ?PRIM_FILE_call(list_dir, Handle, ["."]),
?line true = lists:member(UncommonName,NewDirFiles),
%% Delete the directory and return to the old current directory
%% and check that the created file isn't there (too!)
?line expect({error, einval}, {error, eacces}, {error, eexist},
- ?PRIM_FILE_call(del_dir, Handle, [NewDir, "utag"])),
- ?line ?PRIM_FILE_call(delete, Handle, [UncommonName, "utag"]),
- ?line {ok,[]} = ?PRIM_FILE_call(list_dir, Handle, [".", "utag"]),
- ?line ok = ?PRIM_FILE_call(set_cwd, Handle, [Dir1, "utag"]),
+ ?PRIM_FILE_call(del_dir, Handle, [NewDir])),
+ ?line ?PRIM_FILE_call(delete, Handle, [UncommonName]),
+ ?line {ok,[]} = ?PRIM_FILE_call(list_dir, Handle, ["."]),
+ ?line ok = ?PRIM_FILE_call(set_cwd, Handle, [Dir1]),
?line io:format("cd back to ~s",[Dir1]),
- ?line ok = ?PRIM_FILE_call(del_dir, Handle, [NewDir, "utag"]),
- ?line {error, enoent} = ?PRIM_FILE_call(set_cwd, Handle, [NewDir, "utag"]),
- ?line ok = ?PRIM_FILE_call(set_cwd, Handle, [Dir1, "utag"]),
+ ?line ok = ?PRIM_FILE_call(del_dir, Handle, [NewDir]),
+ ?line {error, enoent} = ?PRIM_FILE_call(set_cwd, Handle, [NewDir]),
+ ?line ok = ?PRIM_FILE_call(set_cwd, Handle, [Dir1]),
?line io:format("cd back to ~s",[Dir1]),
- ?line {ok,OldDirFiles} = ?PRIM_FILE_call(list_dir, Handle, [".", "utag"]),
+ ?line {ok,OldDirFiles} = ?PRIM_FILE_call(list_dir, Handle, ["."]),
?line false = lists:member(UncommonName,OldDirFiles),
%% Try doing some bad things
?line {error, badarg} =
- ?PRIM_FILE_call(set_cwd, Handle, [{foo,bar}, "utag"]),
+ ?PRIM_FILE_call(set_cwd, Handle, [{foo,bar}]),
?line {error, enoent} =
- ?PRIM_FILE_call(set_cwd, Handle, ["", "utag"]),
+ ?PRIM_FILE_call(set_cwd, Handle, [""]),
?line {error, enoent} =
- ?PRIM_FILE_call(set_cwd, Handle, [".......a......", "utag"]),
+ ?PRIM_FILE_call(set_cwd, Handle, [".......a......"]),
?line {ok,BaseDir} =
?PRIM_FILE_call(get_cwd, Handle, []), %% Still there?
@@ -405,10 +405,10 @@ cur_dir_1(Config, Handle) ->
?line case os:type() of
{unix, _} ->
?line {error, enotsup} =
- ?PRIM_FILE_call(get_cwd, Handle, ["d:", "utag"]);
+ ?PRIM_FILE_call(get_cwd, Handle, ["d:"]);
vxworks ->
?line {error, enotsup} =
- ?PRIM_FILE_call(get_cwd, Handle, ["d:", "utag"]);
+ ?PRIM_FILE_call(get_cwd, Handle, ["d:"]);
{win32, _} ->
win_cur_dir_1(Config, Handle)
end,
@@ -422,7 +422,7 @@ win_cur_dir_1(_Config, Handle) ->
%% and try to get current directory for that drive.
?line [Drive, $:|_] = BaseDir,
- ?line {ok, BaseDir} = ?PRIM_FILE_call(get_cwd, Handle, [[Drive, $:], "utag"]),
+ ?line {ok, BaseDir} = ?PRIM_FILE_call(get_cwd, Handle, [[Drive, $:]]),
io:format("BaseDir = ~s\n", [BaseDir]),
%% Unfortunately, there is no way to move away from the
@@ -1027,7 +1027,7 @@ file_write_file_info(Config, Handle, Suffix) ->
?line ok = ?PRIM_FILE:write_file(Name, "hello"),
?line Time = {{1997, 01, 02}, {12, 35, 42}},
?line Info = #file_info{mode=8#400, atime=Time, mtime=Time, ctime=Time},
- ?line ok = ?PRIM_FILE_call(write_file_info, Handle, [Name, Info, "utag"]),
+ ?line ok = ?PRIM_FILE_call(write_file_info, Handle, [Name, Info]),
%% Read back the times.
@@ -1050,12 +1050,12 @@ file_write_file_info(Config, Handle, Suffix) ->
%% Make the file writable again.
?line ?PRIM_FILE_call(write_file_info, Handle,
- [Name, #file_info{mode=8#600}, "utag"]),
+ [Name, #file_info{mode=8#600}]),
?line ok = ?PRIM_FILE:write_file(Name, "hello again"),
%% And unwritable.
?line ?PRIM_FILE_call(write_file_info, Handle,
- [Name, #file_info{mode=8#400}, "utag"]),
+ [Name, #file_info{mode=8#400}]),
?line {error, eacces} = ?PRIM_FILE:write_file(Name, "hello again"),
%% Write the times again.
@@ -1063,7 +1063,7 @@ file_write_file_info(Config, Handle, Suffix) ->
?line NewTime = {{1997, 02, 15}, {13, 18, 20}},
?line NewInfo = #file_info{atime=NewTime, mtime=NewTime, ctime=NewTime},
- ?line ok = ?PRIM_FILE_call(write_file_info, Handle, [Name, NewInfo, "utag"]),
+ ?line ok = ?PRIM_FILE_call(write_file_info, Handle, [Name, NewInfo]),
?line {ok, ActualInfo2} =
?PRIM_FILE_call(read_file_info, Handle, [Name]),
?line #file_info{atime=NewActAtime, mtime=NewTime,
@@ -1081,7 +1081,7 @@ file_write_file_info(Config, Handle, Suffix) ->
%% Make the file writeable again, so that we can remove the
%% test suites ... :-)
?line ?PRIM_FILE_call(write_file_info, Handle,
- [Name, #file_info{mode=8#600}, "utag"]),
+ [Name, #file_info{mode=8#600}]),
?line test_server:timetrap_cancel(Dog),
ok.
@@ -1390,11 +1390,11 @@ delete(Config, Handle, Suffix) ->
%% Check that the file is readable
?line {ok, Fd2} = ?PRIM_FILE:open(Name, [read]),
?line ok = ?PRIM_FILE:close(Fd2),
- ?line ok = ?PRIM_FILE_call(delete, Handle, [Name, "utag"]),
+ ?line ok = ?PRIM_FILE_call(delete, Handle, [Name]),
%% Check that the file is not readable anymore
?line {error, _} = ?PRIM_FILE:open(Name, [read]),
%% Try deleting a nonexistent file
- ?line {error, enoent} = ?PRIM_FILE_call(delete, Handle, [Name, "utag"]),
+ ?line {error, enoent} = ?PRIM_FILE_call(delete, Handle, [Name]),
?line test_server:timetrap_cancel(Dog),
ok.
@@ -1895,14 +1895,14 @@ make_link(Config, Handle, Suffix) ->
?line NewDir = filename:join(RootDir,
atom_to_list(?MODULE)
++"_make_link"++Suffix),
- ?line ok = ?PRIM_FILE_call(make_dir, Handle, [NewDir, "utag"]),
+ ?line ok = ?PRIM_FILE_call(make_dir, Handle, [NewDir]),
?line Name = filename:join(NewDir, "a_file"),
?line ok = ?PRIM_FILE:write_file(Name, "some contents\n"),
?line Alias = filename:join(NewDir, "an_alias"),
?line Result =
- case ?PRIM_FILE_call(make_link, Handle, [Name, Alias, "utag"]) of
+ case ?PRIM_FILE_call(make_link, Handle, [Name, Alias]) of
{error, enotsup} ->
{skipped, "Links not supported on this platform"};
ok ->
@@ -1913,12 +1913,12 @@ make_link(Config, Handle, Suffix) ->
%% since they are not used on symbolic links.
?line {ok, Info} =
- ?PRIM_FILE_call(read_link_info, Handle, [Name, "utag"]),
+ ?PRIM_FILE_call(read_link_info, Handle, [Name]),
?line {ok, Info} =
- ?PRIM_FILE_call(read_link_info, Handle, [Alias, "utag"]),
+ ?PRIM_FILE_call(read_link_info, Handle, [Alias]),
?line #file_info{links = 2, type = regular} = Info,
?line {error, eexist} =
- ?PRIM_FILE_call(make_link, Handle, [Name, Alias, "utag"]),
+ ?PRIM_FILE_call(make_link, Handle, [Name, Alias]),
ok
end,
@@ -1956,30 +1956,30 @@ symlinks(Config, Handle, Suffix) ->
?line NewDir = filename:join(RootDir,
atom_to_list(?MODULE)
++"_make_symlink"++Suffix),
- ?line ok = ?PRIM_FILE_call(make_dir, Handle, [NewDir, "utag"]),
+ ?line ok = ?PRIM_FILE_call(make_dir, Handle, [NewDir]),
?line Name = filename:join(NewDir, "a_plain_file"),
?line ok = ?PRIM_FILE:write_file(Name, "some stupid content\n"),
?line Alias = filename:join(NewDir, "a_symlink_alias"),
?line Result =
- case ?PRIM_FILE_call(make_symlink, Handle, [Name, Alias, "utag"]) of
+ case ?PRIM_FILE_call(make_symlink, Handle, [Name, Alias]) of
{error, enotsup} ->
{skipped, "Links not supported on this platform"};
ok ->
?line {ok, Info1} =
- ?PRIM_FILE_call(read_file_info, Handle, [Name, "utag"]),
+ ?PRIM_FILE_call(read_file_info, Handle, [Name]),
?line {ok, Info1} =
- ?PRIM_FILE_call(read_file_info, Handle, [Alias, "utag"]),
+ ?PRIM_FILE_call(read_file_info, Handle, [Alias]),
?line {ok, Info1} =
- ?PRIM_FILE_call(read_link_info, Handle, [Name, "utag"]),
+ ?PRIM_FILE_call(read_link_info, Handle, [Name]),
?line #file_info{links = 1, type = regular} = Info1,
?line {ok, Info2} =
- ?PRIM_FILE_call(read_link_info, Handle, [Alias, "utag"]),
+ ?PRIM_FILE_call(read_link_info, Handle, [Alias]),
?line #file_info{links=1, type=symlink} = Info2,
?line {ok, Name} =
- ?PRIM_FILE_call(read_link, Handle, [Alias, "utag"]),
+ ?PRIM_FILE_call(read_link, Handle, [Alias]),
ok
end,
@@ -2003,7 +2003,7 @@ list_dir_limit(Config) when is_list(Config) ->
?line NewDir = filename:join(RootDir,
atom_to_list(?MODULE)++"_list_dir_limit"),
?line {ok, Handle1} = ?PRIM_FILE:start(),
- ?line ok = ?PRIM_FILE_call(make_dir, Handle1, [NewDir, "utag"]),
+ ?line ok = ?PRIM_FILE_call(make_dir, Handle1, [NewDir]),
Ref = erlang:start_timer(MaxTime*1000, self(), []),
?line Result = list_dir_limit_loop(NewDir, Handle1, Ref, MaxNumber, 0),
?line Time = case erlang:cancel_timer(Ref) of
@@ -2054,7 +2054,7 @@ list_dir_limit_loop(Dir, Handle, Ref, N, Cnt) ->
end.
list_dir_check(Dir, Handle, Cnt) ->
- case ?PRIM_FILE:list_dir(Handle, Dir, "utag") of
+ case ?PRIM_FILE:list_dir(Handle, Dir) of
{ok, ListDir} ->
case length(ListDir) of
Cnt ->