diff options
| author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2020-03-04 13:42:42 (GMT) |
|---|---|---|
| committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2020-03-04 13:42:42 (GMT) |
| commit | 8defb7d10b69cdbe3219de6ae2dc169dc8df8bb9 (patch) | |
| tree | d2f706832df81f622d3246731bef82f25668218a /generic/tclIORChan.c | |
| parent | a4154b246b048a378dd83998031d103263856c8f (diff) | |
| download | tcl-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.c | 150 |
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 |
