summaryrefslogtreecommitdiffstats
path: root/generic/tclIORChan.c
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2020-03-04 13:42:42 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2020-03-04 13:42:42 (GMT)
commit8defb7d10b69cdbe3219de6ae2dc169dc8df8bb9 (patch)
treed2f706832df81f622d3246731bef82f25668218a /generic/tclIORChan.c
parenta4154b246b048a378dd83998031d103263856c8f (diff)
downloadtcl-8defb7d10b69cdbe3219de6ae2dc169dc8df8bb9.zip
tcl-8defb7d10b69cdbe3219de6ae2dc169dc8df8bb9.tar.gz
tcl-8defb7d10b69cdbe3219de6ae2dc169dc8df8bb9.tar.bz2
Implement WideSeekProc() for all channels which have a SeekProc(). Implement Close2Proc() for all channels, as minimal wrapper around CloseProc().
Backported (with comments) and adapted from core-8-branch.
Diffstat (limited to 'generic/tclIORChan.c')
-rw-r--r--generic/tclIORChan.c150
1 files changed, 93 insertions, 57 deletions
diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c
index e862761..9969b87 100644
--- a/generic/tclIORChan.c
+++ b/generic/tclIORChan.c
@@ -33,6 +33,8 @@
static int ReflectClose(ClientData clientData,
Tcl_Interp *interp);
+static int ReflectClose2(ClientData clientData,
+ Tcl_Interp *interp, int flags);
static int ReflectInput(ClientData clientData, char *buf,
int toRead, int *errorCodePtr);
static int ReflectOutput(ClientData clientData, const char *buf,
@@ -71,7 +73,7 @@ static const Tcl_ChannelType tclRChannelType = {
ReflectGetOption, /* Get options. NULL'able */
ReflectWatch, /* Initialize notifier */
NULL, /* Get OS handle from the channel. NULL'able */
- NULL, /* No close2 support. NULL'able */
+ ReflectClose2, /* No close2 support. NULL'able */
ReflectBlock, /* Set blocking/nonblocking. NULL'able */
NULL, /* Flush channel. Not used by core. NULL'able */
NULL, /* Handle events. NULL'able */
@@ -481,7 +483,7 @@ static const char *msg_dstlost = "-code 1 -level 0 -errorcode NONE -errorinfo
int
TclChanCreateObjCmd(
- ClientData clientData,
+ ClientData dummy,
Tcl_Interp *interp,
int objc,
Tcl_Obj *const *objv)
@@ -507,6 +509,7 @@ TclChanCreateObjCmd(
* this interp. */
Tcl_HashEntry *hPtr; /* Entry in the above map */
int isNew; /* Placeholder. */
+ (void)dummy;
/*
* Syntax: chan create MODE CMDPREFIX
@@ -670,7 +673,7 @@ TclChanCreateObjCmd(
* as the actual channel type.
*/
- Tcl_ChannelType *clonePtr = ckalloc(sizeof(Tcl_ChannelType));
+ Tcl_ChannelType *clonePtr = (Tcl_ChannelType *)ckalloc(sizeof(Tcl_ChannelType));
memcpy(clonePtr, &tclRChannelType, sizeof(Tcl_ChannelType));
@@ -770,6 +773,7 @@ ReflectEventRun(
*/
ReflectEvent *e = (ReflectEvent *) ev;
+ (void)flags;
Tcl_NotifyChannel(e->rcPtr->chan, e->events);
return 1;
@@ -798,7 +802,7 @@ ReflectEventDelete(
int
TclChanPostEventObjCmd(
- ClientData clientData,
+ ClientData dummy,
Tcl_Interp *interp,
int objc,
Tcl_Obj *const *objv)
@@ -827,6 +831,7 @@ TclChanPostEventObjCmd(
ReflectedChannelMap *rcmPtr;/* Map of reflected channels with handlers in
* this interp. */
Tcl_HashEntry *hPtr; /* Entry in the above map */
+ (void)dummy;
/*
* Number of arguments...
@@ -855,11 +860,12 @@ TclChanPostEventObjCmd(
}
/*
- * Note that the search above subsumes several of the older checks, namely:
+ * Note that the search above subsumes several of the older checks,
+ * namely:
*
- * (1) Does the channel handle refer to a reflected channel ?
+ * (1) Does the channel handle refer to a reflected channel?
* (2) Is the post event issued from the interpreter holding the handler
- * of the reflected channel ?
+ * of the reflected channel?
*
* A successful search answers yes to both. Because the map holds only
* handles of reflected channels, and only of such whose handler is
@@ -870,7 +876,7 @@ TclChanPostEventObjCmd(
* have gone seriously haywire.
*/
- chan = Tcl_GetHashValue(hPtr);
+ chan = (Tcl_Channel)Tcl_GetHashValue(hPtr);
chanTypePtr = Tcl_GetChannelType(chan);
/*
@@ -886,7 +892,7 @@ TclChanPostEventObjCmd(
Tcl_Panic("TclChanPostEventObjCmd: channel is not a reflected channel");
}
- rcPtr = Tcl_GetChannelInstanceData(chan);
+ rcPtr = (ReflectedChannel *)Tcl_GetChannelInstanceData(chan);
if (rcPtr->interp != interp) {
Tcl_Panic("TclChanPostEventObjCmd: postevent accepted for call from outside interpreter");
@@ -922,7 +928,7 @@ TclChanPostEventObjCmd(
Tcl_NotifyChannel(chan, events);
#ifdef TCL_THREADS
} else {
- ReflectEvent *ev = ckalloc(sizeof(ReflectEvent));
+ ReflectEvent *ev = (ReflectEvent *)ckalloc(sizeof(ReflectEvent));
ev->header.proc = ReflectEventRun;
ev->events = events;
@@ -943,7 +949,8 @@ TclChanPostEventObjCmd(
(void) GetThreadReflectedChannelMap();
- /* XXX Race condition !!
+ /*
+ * XXX Race condition !!
* XXX The destination thread may not exist anymore already.
* XXX (Delayed postevent executed after channel got removed).
* XXX Can we detect this ? (check the validity of the owner threadid ?)
@@ -1091,7 +1098,7 @@ TclChanCaughtErrorBypass(
/*
*----------------------------------------------------------------------
*
- * ReflectClose --
+ * ReflectClose/ReflectClose2 --
*
* This function is invoked when the channel is closed, to delete the
* driver specific instance data.
@@ -1110,7 +1117,7 @@ ReflectClose(
ClientData clientData,
Tcl_Interp *interp)
{
- ReflectedChannel *rcPtr = clientData;
+ ReflectedChannel *rcPtr = (ReflectedChannel *)clientData;
int result; /* Result code for 'close' */
Tcl_Obj *resObj; /* Result data for 'close' */
ReflectedChannelMap *rcmPtr;/* Map of reflected channels with handlers in
@@ -1231,6 +1238,18 @@ ReflectClose(
Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel);
return (result == TCL_OK) ? EOK : EINVAL;
}
+
+static int
+ReflectClose2(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ int flags)
+{
+ if ((flags & (TCL_CLOSE_READ | TCL_CLOSE_WRITE)) == 0) {
+ return ReflectClose(clientData, interp);
+ }
+ return EINVAL;
+}
/*
*----------------------------------------------------------------------
@@ -1255,7 +1274,7 @@ ReflectInput(
int toRead,
int *errorCodePtr)
{
- ReflectedChannel *rcPtr = clientData;
+ ReflectedChannel *rcPtr = (ReflectedChannel *)clientData;
Tcl_Obj *toReadObj;
int bytec; /* Number of returned bytes */
unsigned char *bytev; /* Array of returned bytes */
@@ -1276,7 +1295,10 @@ ReflectInput(
if (p.base.code != TCL_OK) {
if (p.base.code < 0) {
- /* No error message, this is an errno signal. */
+ /*
+ * No error message, this is an errno signal.
+ */
+
*errorCodePtr = -p.base.code;
} else {
PassReceivedError(rcPtr->chan, &p);
@@ -1321,7 +1343,7 @@ ReflectInput(
*errorCodePtr = EOK;
if (bytec > 0) {
- memcpy(buf, bytev, (size_t) bytec);
+ memcpy(buf, bytev, bytec);
}
stop:
@@ -1359,7 +1381,7 @@ ReflectOutput(
int toWrite,
int *errorCodePtr)
{
- ReflectedChannel *rcPtr = clientData;
+ ReflectedChannel *rcPtr = (ReflectedChannel *)clientData;
Tcl_Obj *bufObj;
Tcl_Obj *resObj; /* Result data for 'write' */
int written;
@@ -1379,7 +1401,10 @@ ReflectOutput(
if (p.base.code != TCL_OK) {
if (p.base.code < 0) {
- /* No error message, this is an errno signal. */
+ /*
+ * No error message, this is an errno signal.
+ */
+
*errorCodePtr = -p.base.code;
} else {
PassReceivedError(rcPtr->chan, &p);
@@ -1430,8 +1455,8 @@ ReflectOutput(
if ((written == 0) && (toWrite > 0)) {
/*
- * The handler claims to have written nothing of what it was
- * given. That is bad.
+ * The handler claims to have written nothing of what it was given.
+ * That is bad.
*/
SetChannelErrorStr(rcPtr->chan, msg_write_nothing);
@@ -1485,7 +1510,7 @@ ReflectSeekWide(
int seekMode,
int *errorCodePtr)
{
- ReflectedChannel *rcPtr = clientData;
+ ReflectedChannel *rcPtr = (ReflectedChannel *)clientData;
Tcl_Obj *offObj, *baseObj;
Tcl_Obj *resObj; /* Result for 'seek' */
Tcl_WideInt newLoc;
@@ -1536,7 +1561,7 @@ ReflectSeekWide(
goto invalid;
}
- if (newLoc < Tcl_LongAsWide(0)) {
+ if (newLoc < 0) {
SetChannelErrorStr(rcPtr->chan, msg_seek_beforestart);
goto invalid;
}
@@ -1594,7 +1619,7 @@ ReflectWatch(
ClientData clientData,
int mask)
{
- ReflectedChannel *rcPtr = clientData;
+ ReflectedChannel *rcPtr = (ReflectedChannel *)clientData;
Tcl_Obj *maskObj;
/*
@@ -1666,7 +1691,7 @@ ReflectBlock(
ClientData clientData,
int nonblocking)
{
- ReflectedChannel *rcPtr = clientData;
+ ReflectedChannel *rcPtr = (ReflectedChannel *)clientData;
Tcl_Obj *blockObj;
int errorNum; /* EINVAL or EOK (success). */
Tcl_Obj *resObj; /* Result data for 'blocking' */
@@ -1733,7 +1758,7 @@ ReflectThread(
ClientData clientData,
int action)
{
- ReflectedChannel *rcPtr = clientData;
+ ReflectedChannel *rcPtr = (ReflectedChannel *)clientData;
switch (action) {
case TCL_CHANNEL_THREAD_INSERT:
@@ -1772,7 +1797,7 @@ ReflectSetOption(
const char *optionName, /* Name of requested option */
const char *newValue) /* The new value */
{
- ReflectedChannel *rcPtr = clientData;
+ ReflectedChannel *rcPtr = (ReflectedChannel *)clientData;
Tcl_Obj *optionObj, *valueObj;
int result; /* Result code for 'configure' */
Tcl_Obj *resObj; /* Result data for 'configure' */
@@ -1849,7 +1874,7 @@ ReflectGetOption(
* The bypass functions are not required.
*/
- ReflectedChannel *rcPtr = clientData;
+ ReflectedChannel *rcPtr = (ReflectedChannel *)clientData;
Tcl_Obj *optionObj;
Tcl_Obj *resObj; /* Result data for 'configure' */
int listc, result = TCL_OK;
@@ -2065,7 +2090,7 @@ static Tcl_Obj *
DecodeEventMask(
int mask)
{
- register const char *eventStr;
+ const char *eventStr;
Tcl_Obj *evObj;
switch (mask & RANDW) {
@@ -2116,7 +2141,7 @@ NewReflectedChannel(
ReflectedChannel *rcPtr;
MethodName mn = METH_BLOCKING;
- rcPtr = ckalloc(sizeof(ReflectedChannel));
+ rcPtr = (ReflectedChannel *)ckalloc(sizeof(ReflectedChannel));
/* rcPtr->chan: Assigned by caller. Dummy data here. */
@@ -2377,8 +2402,8 @@ InvokeTclMethod(
* None.
*
* Users:
- * ReflectInput/Output(), to enable the signaling of EAGAIN
- * on 0-sized short reads/writes.
+ * ReflectInput/Output(), to enable the signaling of EAGAIN on 0-sized
+ * short reads/writes.
*
*----------------------------------------------------------------------
*/
@@ -2434,10 +2459,10 @@ static ReflectedChannelMap *
GetReflectedChannelMap(
Tcl_Interp *interp)
{
- ReflectedChannelMap *rcmPtr = Tcl_GetAssocData(interp, RCMKEY, NULL);
+ ReflectedChannelMap *rcmPtr = (ReflectedChannelMap *)Tcl_GetAssocData(interp, RCMKEY, NULL);
if (rcmPtr == NULL) {
- rcmPtr = ckalloc(sizeof(ReflectedChannelMap));
+ rcmPtr = (ReflectedChannelMap *)ckalloc(sizeof(ReflectedChannelMap));
Tcl_InitHashTable(&rcmPtr->map, TCL_STRING_KEYS);
Tcl_SetAssocData(interp, RCMKEY,
(Tcl_InterpDeleteProc *) DeleteReflectedChannelMap, rcmPtr);
@@ -2492,7 +2517,7 @@ DeleteReflectedChannelMap(
ClientData clientData, /* The per-interpreter data structure. */
Tcl_Interp *interp) /* The interpreter being deleted. */
{
- ReflectedChannelMap *rcmPtr = clientData;
+ ReflectedChannelMap *rcmPtr = (ReflectedChannelMap *)clientData;
/* The map */
Tcl_HashSearch hSearch; /* Search variable. */
Tcl_HashEntry *hPtr; /* Search variable. */
@@ -2519,8 +2544,8 @@ DeleteReflectedChannelMap(
for (hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch);
hPtr != NULL;
hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch)) {
- chan = Tcl_GetHashValue(hPtr);
- rcPtr = Tcl_GetChannelInstanceData(chan);
+ chan = (Tcl_Channel)Tcl_GetHashValue(hPtr);
+ rcPtr = (ReflectedChannel *)Tcl_GetChannelInstanceData(chan);
MarkDead(rcPtr);
Tcl_DeleteHashEntry(hPtr);
@@ -2564,7 +2589,10 @@ DeleteReflectedChannelMap(
evPtr = resultPtr->evPtr;
- /* Basic crash safety until this routine can get revised [3411310] */
+ /*
+ * Basic crash safety until this routine can get revised [3411310]
+ */
+
if (evPtr == NULL) {
continue;
}
@@ -2594,8 +2622,8 @@ DeleteReflectedChannelMap(
for (hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch);
hPtr != NULL;
hPtr = Tcl_NextHashEntry(&hSearch)) {
- chan = Tcl_GetHashValue(hPtr);
- rcPtr = Tcl_GetChannelInstanceData(chan);
+ chan = (Tcl_Channel)Tcl_GetHashValue(hPtr);
+ rcPtr = (ReflectedChannel *)Tcl_GetChannelInstanceData(chan);
if (rcPtr->interp != interp) {
/*
@@ -2635,7 +2663,7 @@ GetThreadReflectedChannelMap(void)
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if (!tsdPtr->rcmPtr) {
- tsdPtr->rcmPtr = ckalloc(sizeof(ReflectedChannelMap));
+ tsdPtr->rcmPtr = (ReflectedChannelMap *)ckalloc(sizeof(ReflectedChannelMap));
Tcl_InitHashTable(&tsdPtr->rcmPtr->map, TCL_STRING_KEYS);
Tcl_CreateThreadExitHandler(DeleteThreadReflectedChannelMap, NULL);
}
@@ -2663,13 +2691,14 @@ GetThreadReflectedChannelMap(void)
static void
DeleteThreadReflectedChannelMap(
- ClientData clientData) /* The per-thread data structure. */
+ ClientData dummy) /* The per-thread data structure. */
{
Tcl_HashSearch hSearch; /* Search variable. */
Tcl_HashEntry *hPtr; /* Search variable. */
Tcl_ThreadId self = Tcl_GetCurrentThread();
ReflectedChannelMap *rcmPtr; /* The map */
ForwardingResult *resultPtr;
+ (void)dummy;
/*
* The origin thread for one or more reflected channels is gone.
@@ -2679,8 +2708,8 @@ DeleteThreadReflectedChannelMap(
/*
* Go through the list of pending results and cancel all whose events were
- * destined for this thread. While this is in progress we block any
- * other access to the list of pending results.
+ * destined for this thread. While this is in progress we block any other
+ * access to the list of pending results.
*/
Tcl_MutexLock(&rcForwardMutex);
@@ -2711,7 +2740,10 @@ DeleteThreadReflectedChannelMap(
evPtr = resultPtr->evPtr;
- /* Basic crash safety until this routine can get revised [3411310] */
+ /*
+ * Basic crash safety until this routine can get revised [3411310]
+ */
+
if (evPtr == NULL ) {
continue;
}
@@ -2749,8 +2781,8 @@ DeleteThreadReflectedChannelMap(
for (hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch);
hPtr != NULL;
hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch)) {
- Tcl_Channel chan = Tcl_GetHashValue(hPtr);
- ReflectedChannel *rcPtr = Tcl_GetChannelInstanceData(chan);
+ Tcl_Channel chan = (Tcl_Channel)Tcl_GetHashValue(hPtr);
+ ReflectedChannel *rcPtr = (ReflectedChannel *)Tcl_GetChannelInstanceData(chan);
MarkDead(rcPtr);
Tcl_DeleteHashEntry(hPtr);
@@ -2765,8 +2797,8 @@ ForwardOpToHandlerThread(
const void *param) /* Arguments */
{
/*
- * Core of the communication from OWNER to HANDLER thread.
- * The receiver is ForwardProc() below.
+ * Core of the communication from OWNER to HANDLER thread. The receiver is
+ * ForwardProc() below.
*/
Tcl_ThreadId dst = rcPtr->thread;
@@ -2795,8 +2827,8 @@ ForwardOpToHandlerThread(
* Create and initialize the event and data structures.
*/
- evPtr = ckalloc(sizeof(ForwardingEvent));
- resultPtr = ckalloc(sizeof(ForwardingResult));
+ evPtr = (ForwardingEvent *)ckalloc(sizeof(ForwardingEvent));
+ resultPtr = (ForwardingResult *)ckalloc(sizeof(ForwardingResult));
evPtr->event.proc = ForwardProc;
evPtr->resultPtr = resultPtr;
@@ -2816,7 +2848,10 @@ ForwardOpToHandlerThread(
*/
TclSpliceIn(resultPtr, forwardList);
- /* Do not unlock here. That is done by the ConditionWait */
+
+ /*
+ * Do not unlock here. That is done by the ConditionWait.
+ */
/*
* Ensure cleanup of the event if the origin thread exits while this event
@@ -2892,7 +2927,7 @@ ForwardProc(
* Notes regarding access to the referenced data.
*
* In principle the data belongs to the originating thread (see
- * evPtr->src), however this thread is currently blocked at (*), i.e.
+ * evPtr->src), however this thread is currently blocked at (*), i.e.,
* quiescent. Because of this we can treat the data as belonging to us,
* without fear of race conditions. I.e. we can read and write as we like.
*
@@ -2910,6 +2945,7 @@ ForwardProc(
ReflectedChannelMap *rcmPtr;/* Map of reflected channels with handlers in
* this interp. */
Tcl_HashEntry *hPtr; /* Entry in the above map */
+ (void)mask;
/*
* Ignore the event if no one is waiting for its result anymore.
@@ -2991,7 +3027,7 @@ ForwardProc(
paramPtr->input.toRead = -1;
} else {
if (bytec > 0) {
- memcpy(paramPtr->input.buf, bytev, (size_t) bytec);
+ memcpy(paramPtr->input.buf, bytev, bytec);
}
paramPtr->input.toRead = bytec;
}
@@ -3062,7 +3098,7 @@ ForwardProc(
Tcl_WideInt newLoc;
if (Tcl_GetWideIntFromObj(interp, resObj, &newLoc) == TCL_OK) {
- if (newLoc < Tcl_LongAsWide(0)) {
+ if (newLoc < 0) {
ForwardSetStaticError(paramPtr, msg_seek_beforestart);
paramPtr->seek.offset = -1;
} else {
@@ -3170,7 +3206,7 @@ ForwardProc(
* Odd number of elements is wrong. [x].
*/
- char *buf = ckalloc(200);
+ char *buf = (char *)ckalloc(200);
sprintf(buf,
"{Expected list with even number of elements, got %d %s instead}",
listc, (listc == 1 ? "element" : "elements"));
@@ -3227,7 +3263,7 @@ static void
SrcExitProc(
ClientData clientData)
{
- ForwardingEvent *evPtr = clientData;
+ ForwardingEvent *evPtr = (ForwardingEvent *)clientData;
ForwardingResult *resultPtr;
ForwardParam *paramPtr;
@@ -3281,7 +3317,7 @@ ForwardSetObjError(
len++;
ForwardSetDynamicError(paramPtr, ckalloc(len));
- memcpy(paramPtr->base.msgStr, msgStr, (unsigned) len);
+ memcpy(paramPtr->base.msgStr, msgStr, len);
}
#endif