From e6a868c242fb7ad99bf71d9d57597761e1fec9ab Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 12 Oct 2023 15:11:10 +0000 Subject: Fix [ad5a57f2f2]: Functions passed to Tcl_CreateFileHandler() must be declared/defined as Tcl_FileProc. Also, add some type-casts --- unix/tclUnixChan.c | 73 ++++++++++++++++++++++++++++++++---------------------- unix/tclUnixPipe.c | 51 ++++++++++++++++++++++++-------------- 2 files changed, 76 insertions(+), 48 deletions(-) diff --git a/unix/tclUnixChan.c b/unix/tclUnixChan.c index 2f51226..5742e9a 100644 --- a/unix/tclUnixChan.c +++ b/unix/tclUnixChan.c @@ -5,7 +5,7 @@ * and TCP sockets. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. - * Copyright (c) 1998-1999 by Scriptics Corporation. + * Copyright (c) 1998-1999 Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. @@ -205,7 +205,7 @@ FileBlockModeProc( int mode) /* The mode to set. Can be TCL_MODE_BLOCKING * or TCL_MODE_NONBLOCKING. */ { - FileState *fsPtr = instanceData; + FileState *fsPtr = (FileState *)instanceData; if (TclUnixSetBlockingMode(fsPtr->fd, mode) < 0) { return errno; @@ -240,7 +240,7 @@ FileInputProc( * buffer? */ int *errorCodePtr) /* Where to store error code. */ { - FileState *fsPtr = instanceData; + FileState *fsPtr = (FileState *)instanceData; int bytesRead; /* How many bytes were actually read from the * input device? */ @@ -254,7 +254,7 @@ FileInputProc( */ do { - bytesRead = read(fsPtr->fd, buf, (size_t) toRead); + bytesRead = read(fsPtr->fd, buf, toRead); } while ((bytesRead < 0) && (errno == EINTR)); if (bytesRead < 0) { @@ -289,7 +289,7 @@ FileOutputProc( int toWrite, /* How many bytes to write? */ int *errorCodePtr) /* Where to store error code. */ { - FileState *fsPtr = instanceData; + FileState *fsPtr = (FileState *)instanceData; int written; *errorCodePtr = 0; @@ -303,8 +303,8 @@ FileOutputProc( return 0; } - written = write(fsPtr->fd, buf, (size_t) toWrite); - if (written > -1) { + written = write(fsPtr->fd, buf, toWrite); + if (written >= 0) { return written; } *errorCodePtr = errno; @@ -333,7 +333,7 @@ FileCloseProc( ClientData instanceData, /* File state. */ Tcl_Interp *interp) /* For error reporting - unused. */ { - FileState *fsPtr = instanceData; + FileState *fsPtr = (FileState *)instanceData; int errorCode = 0; Tcl_DeleteFileHandler(fsPtr->fd); @@ -451,7 +451,7 @@ FileWideSeekProc( * one of SEEK_START, SEEK_CUR or SEEK_END. */ int *errorCodePtr) /* To store error code. */ { - FileState *fsPtr = instanceData; + FileState *fsPtr = (FileState *)instanceData; Tcl_WideInt newLoc; newLoc = TclOSseek(fsPtr->fd, (Tcl_SeekOffset) offset, mode); @@ -477,6 +477,20 @@ FileWideSeekProc( *---------------------------------------------------------------------- */ +/* + * Bug ad5a57f2f271: Tcl_NotifyChannel is not a Tcl_FileProc, + * so do not pass it to directly to Tcl_CreateFileHandler. + * Instead, pass a wrapper which is a Tcl_FileProc. + */ +static void +FileWatchNotifyChannelWrapper( + ClientData clientData, + int mask) +{ + Tcl_Channel channel = clientData; + Tcl_NotifyChannel(channel, mask); +} + static void FileWatchProc( ClientData instanceData, /* The file state. */ @@ -484,18 +498,16 @@ FileWatchProc( * TCL_READABLE, TCL_WRITABLE and * TCL_EXCEPTION. */ { - FileState *fsPtr = instanceData; + FileState *fsPtr = (FileState *)instanceData; /* - * Make sure we only register for events that are valid on this file. Note - * that we are passing Tcl_NotifyChannel directly to Tcl_CreateFileHandler - * with the channel pointer as the client data. + * Make sure we only register for events that are valid on this file. */ mask &= fsPtr->validMask; if (mask) { Tcl_CreateFileHandler(fsPtr->fd, mask, - (Tcl_FileProc *) Tcl_NotifyChannel, fsPtr->channel); + FileWatchNotifyChannelWrapper, fsPtr->channel); } else { Tcl_DeleteFileHandler(fsPtr->fd); } @@ -525,7 +537,7 @@ FileGetHandleProc( int direction, /* TCL_READABLE or TCL_WRITABLE */ ClientData *handlePtr) /* Where to store the handle. */ { - FileState *fsPtr = instanceData; + FileState *fsPtr = (FileState *)instanceData; if (direction & fsPtr->validMask) { *handlePtr = INT2PTR(fsPtr->fd); @@ -593,7 +605,7 @@ TtySetOptionProc( const char *optionName, /* Which option to set? */ const char *value) /* New value for option. */ { - FileState *fsPtr = instanceData; + FileState *fsPtr = (FileState *)instanceData; unsigned int len, vlen; TtyAttrs tty; int argc; @@ -620,7 +632,6 @@ TtySetOptionProc( return TCL_OK; } - /* * Option -handshake none|xonxoff|rtscts|dtrdsr */ @@ -721,9 +732,11 @@ TtySetOptionProc( /* * Option -ttycontrol {DTR 1 RTS 0 BREAK 0} */ + if ((len > 4) && (strncmp(optionName, "-ttycontrol", len) == 0)) { #if defined(TIOCMGET) && defined(TIOCMSET) - int i, control, flag; + int control, flag; + int i; if (Tcl_SplitList(interp, value, &argc, &argv) == TCL_ERROR) { return TCL_ERROR; @@ -820,7 +833,7 @@ TtyGetOptionProc( const char *optionName, /* Option to get. */ Tcl_DString *dsPtr) /* Where to store value(s). */ { - FileState *fsPtr = instanceData; + FileState *fsPtr = (FileState *)instanceData; unsigned int len; char buf[3*TCL_INTEGER_SPACE + 16]; int valid = 0; /* Flag if valid option parsed. */ @@ -897,6 +910,7 @@ TtyGetOptionProc( * Option is readonly and returned by [fconfigure chan -ttystatus] but not * returned by unnamed [fconfigure chan]. */ + if ((len > 4) && (strncmp(optionName, "-ttystatus", len) == 0)) { int status; @@ -914,7 +928,6 @@ TtyGetOptionProc( ); } - static const struct {int baud; speed_t speed;} speeds[] = { #ifdef B0 {0, B0}, @@ -1038,7 +1051,7 @@ static const struct {int baud; speed_t speed;} speeds[] = { #endif {-1, 0} }; - + /* *--------------------------------------------------------------------------- * @@ -1330,7 +1343,8 @@ TtyParseMode( static void TtyInit( - int fd) /* Open file descriptor for serial port to be initialized. */ + int fd) /* Open file descriptor for serial port to be + * initialized. */ { struct termios iostate; tcgetattr(fd, &iostate); @@ -1340,8 +1354,7 @@ TtyInit( || iostate.c_lflag != 0 || iostate.c_cflag & CREAD || iostate.c_cc[VMIN] != 1 - || iostate.c_cc[VTIME] != 0) - { + || iostate.c_cc[VTIME] != 0) { iostate.c_iflag = IGNBRK; iostate.c_oflag = 0; iostate.c_lflag = 0; @@ -1407,7 +1420,7 @@ TclpOpenFileChannel( return NULL; } - native = Tcl_FSGetNativePath(pathPtr); + native = (const char *)Tcl_FSGetNativePath(pathPtr); if (native == NULL) { if (interp != (Tcl_Interp *) NULL) { Tcl_AppendResult(interp, "couldn't open \"", @@ -1467,7 +1480,7 @@ TclpOpenFileChannel( channelTypePtr = &fileChannelType; } - fsPtr = ckalloc(sizeof(FileState)); + fsPtr = (FileState *)ckalloc(sizeof(FileState)); fsPtr->validMask = channelPermissions | TCL_EXCEPTION; fsPtr->fd = fd; @@ -1483,8 +1496,8 @@ TclpOpenFileChannel( * reports that the serial port isn't working. */ - if (Tcl_SetChannelOption(interp, fsPtr->channel, "-translation", - translation) != TCL_OK) { + if (Tcl_SetChannelOption(interp, fsPtr->channel, + "-translation", translation) != TCL_OK) { Tcl_Close(NULL, fsPtr->channel); return NULL; } @@ -1543,7 +1556,7 @@ Tcl_MakeFileChannel( snprintf(channelName, sizeof(channelName), "file%d", fd); } - fsPtr = ckalloc(sizeof(FileState)); + fsPtr = (FileState *)ckalloc(sizeof(FileState)); fsPtr->fd = fd; fsPtr->validMask = mode | TCL_EXCEPTION; fsPtr->channel = Tcl_CreateChannel(channelTypePtr, channelName, @@ -1925,7 +1938,7 @@ FileTruncateProc( ClientData instanceData, Tcl_WideInt length) { - FileState *fsPtr = instanceData; + FileState *fsPtr = (FileState *)instanceData; int result; #ifdef HAVE_TYPE_OFF64_T diff --git a/unix/tclUnixPipe.c b/unix/tclUnixPipe.c index 96ca095..6e07a02 100644 --- a/unix/tclUnixPipe.c +++ b/unix/tclUnixPipe.c @@ -421,7 +421,8 @@ TclpCreateProcess( char errSpace[200 + TCL_INTEGER_SPACE]; Tcl_DString *dsArray; char **newArgv; - int pid, i; + int pid; + int i; #if defined(HAVE_POSIX_SPAWNP) int childErrno; static int use_spawn = -1; @@ -447,8 +448,8 @@ TclpCreateProcess( * deallocated later */ - dsArray = TclStackAlloc(interp, argc * sizeof(Tcl_DString)); - newArgv = TclStackAlloc(interp, (argc+1) * sizeof(char *)); + dsArray = (Tcl_DString *)TclStackAlloc(interp, argc * sizeof(Tcl_DString)); + newArgv = (char **)TclStackAlloc(interp, (argc+1) * sizeof(char *)); newArgv[argc] = NULL; for (i = 0; i < argc; i++) { newArgv[i] = Tcl_UtfToExternalDString(NULL, argv[i], -1, &dsArray[i]); @@ -608,7 +609,7 @@ TclpCreateProcess( errPipeOut = NULL; fd = GetFd(errPipeIn); - count = read(fd, errSpace, (size_t) (sizeof(errSpace) - 1)); + count = read(fd, errSpace, sizeof(errSpace) - 1); if (count > 0) { char *end; @@ -632,7 +633,7 @@ TclpCreateProcess( * here, since this is the error case. [Bug: 6148] */ - Tcl_WaitPid((Tcl_Pid) INT2PTR(pid), &status, 0); + Tcl_WaitPid((Tcl_Pid)INT2PTR(pid), &status, 0); } if (errPipeIn) { @@ -828,7 +829,7 @@ TclpCreateCommandChannel( { char channelName[16 + TCL_INTEGER_SPACE]; int channelId; - PipeState *statePtr = ckalloc(sizeof(PipeState)); + PipeState *statePtr = (PipeState *)ckalloc(sizeof(PipeState)); int mode; statePtr->inFile = readFile; @@ -953,7 +954,7 @@ TclGetAndDetachPids( return; } - pipePtr = Tcl_GetChannelInstanceData(chan); + pipePtr = (PipeState *)Tcl_GetChannelInstanceData(chan); TclNewObj(pidsObj); for (i = 0; i < pipePtr->numPids; i++) { Tcl_ListObjAppendElement(NULL, pidsObj, Tcl_NewIntObj( @@ -991,7 +992,7 @@ PipeBlockModeProc( * TCL_MODE_BLOCKING or * TCL_MODE_NONBLOCKING. */ { - PipeState *psPtr = instanceData; + PipeState *psPtr = (PipeState *)instanceData; if (psPtr->inFile && TclUnixSetBlockingMode(GetFd(psPtr->inFile), mode) < 0) { @@ -1030,7 +1031,7 @@ PipeClose2Proc( Tcl_Interp *interp, /* For error reporting. */ int flags) /* Flags that indicate which side to close. */ { - PipeState *pipePtr = instanceData; + PipeState *pipePtr = (PipeState *)instanceData; Tcl_Channel errChan; int errorCode, result; @@ -1127,7 +1128,7 @@ PipeInputProc( * buffer? */ int *errorCodePtr) /* Where to store error code. */ { - PipeState *psPtr = instanceData; + PipeState *psPtr = (PipeState *)instanceData; int bytesRead; /* How many bytes were actually read from the * input device? */ @@ -1142,7 +1143,7 @@ PipeInputProc( */ do { - bytesRead = read(GetFd(psPtr->inFile), buf, (size_t) toRead); + bytesRead = read(GetFd(psPtr->inFile), buf, toRead); } while ((bytesRead < 0) && (errno == EINTR)); if (bytesRead < 0) { @@ -1177,7 +1178,7 @@ PipeOutputProc( int toWrite, /* How many bytes to write? */ int *errorCodePtr) /* Where to store error code. */ { - PipeState *psPtr = instanceData; + PipeState *psPtr = (PipeState *)instanceData; int written; *errorCodePtr = 0; @@ -1188,7 +1189,7 @@ PipeOutputProc( */ do { - written = write(GetFd(psPtr->outFile), buf, (size_t) toWrite); + written = write(GetFd(psPtr->outFile), buf, toWrite); } while ((written < 0) && (errno == EINTR)); if (written < 0) { @@ -1215,6 +1216,20 @@ PipeOutputProc( *---------------------------------------------------------------------- */ +/* + * Bug ad5a57f2f271: Tcl_NotifyChannel is not a Tcl_FileProc, + * so do not pass it to directly to Tcl_CreateFileHandler. + * Instead, pass a wrapper which is a Tcl_FileProc. + */ +static void +PipeWatchNotifyChannelWrapper( + ClientData clientData, + int mask) +{ + Tcl_Channel channel = clientData; + Tcl_NotifyChannel(channel, mask); +} + static void PipeWatchProc( ClientData instanceData, /* The pipe state. */ @@ -1222,14 +1237,14 @@ PipeWatchProc( * TCL_READABLE, TCL_WRITABLE and * TCL_EXCEPTION. */ { - PipeState *psPtr = instanceData; + PipeState *psPtr = (PipeState *)instanceData; int newmask; if (psPtr->inFile) { newmask = mask & (TCL_READABLE | TCL_EXCEPTION); if (newmask) { Tcl_CreateFileHandler(GetFd(psPtr->inFile), newmask, - (Tcl_FileProc *) Tcl_NotifyChannel, psPtr->channel); + PipeWatchNotifyChannelWrapper, psPtr->channel); } else { Tcl_DeleteFileHandler(GetFd(psPtr->inFile)); } @@ -1238,7 +1253,7 @@ PipeWatchProc( newmask = mask & (TCL_WRITABLE | TCL_EXCEPTION); if (newmask) { Tcl_CreateFileHandler(GetFd(psPtr->outFile), newmask, - (Tcl_FileProc *) Tcl_NotifyChannel, psPtr->channel); + PipeWatchNotifyChannelWrapper, psPtr->channel); } else { Tcl_DeleteFileHandler(GetFd(psPtr->outFile)); } @@ -1269,7 +1284,7 @@ PipeGetHandleProc( int direction, /* TCL_READABLE or TCL_WRITABLE */ ClientData *handlePtr) /* Where to store the handle. */ { - PipeState *psPtr = instanceData; + PipeState *psPtr = (PipeState *)instanceData; if (direction == TCL_READABLE && psPtr->inFile) { *handlePtr = INT2PTR(GetFd(psPtr->inFile)); @@ -1368,7 +1383,7 @@ Tcl_PidObjCmd( * Extract the process IDs from the pipe structure. */ - pipePtr = Tcl_GetChannelInstanceData(chan); + pipePtr = (PipeState *)Tcl_GetChannelInstanceData(chan); TclNewObj(resultPtr); for (i = 0; i < pipePtr->numPids; i++) { Tcl_ListObjAppendElement(NULL, resultPtr, -- cgit v0.12