From 93066d1ab1c21f0ffbc9ddbe86416951bf3e1681 Mon Sep 17 00:00:00 2001 From: surles Date: Mon, 3 Aug 1998 18:25:11 +0000 Subject: Fixed EINTR bug FossilOrigin-Name: 78adaaa9a3ae373b76c1264d14e3052f235c6a72 --- unix/tclUnixChan.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++ unix/tclUnixPort.h | 16 +++++++++ 2 files changed, 116 insertions(+) diff --git a/unix/tclUnixChan.c b/unix/tclUnixChan.c index 28e62e5..52af100 100644 --- a/unix/tclUnixChan.c +++ b/unix/tclUnixChan.c @@ -2571,3 +2571,103 @@ TclUnixWaitForFile(fd, mask, timeout) } return result; } + +/* + *---------------------------------------------------------------------- + * + * TclOpen, etc. -- + * + * Below are a bunch of procedures that are used by Tcl instead + * of system calls. Each of the procedures executes the + * corresponding system call and retries automatically + * if the system call was interrupted by a signal. + * + * Results: + * Whatever the system call would normally return. + * + * Side effects: + * Whatever the system call would normally do. + * + * NOTE: + * This should be the last page of this file, since it undefines + * the macros that redirect read etc. to the procedures below. + * + *---------------------------------------------------------------------- + */ + +#undef open +int +TclOpen(path, oflag, mode) + char *path; + int oflag; + int mode; +{ + int result; + while (1) { + result = open(path, oflag, mode); + if ((result != -1) || (errno != EINTR)) { + return result; + } + } +} + +#undef read +int +TclRead(fd, buf, numBytes) + int fd; + VOID *buf; + size_t numBytes; +{ + int result; + while (1) { + result = read(fd, buf, (size_t) numBytes); + if ((result != -1) || (errno != EINTR)) { + return result; + } + } +} + +#undef waitpid +extern pid_t waitpid _ANSI_ARGS_((pid_t pid, int *stat_loc, int options)); + +/* + * Note: the #ifdef below is needed to avoid compiler errors on systems + * that have ANSI compilers and also define pid_t to be short. The + * problem is a complex one having to do with argument type promotion. + */ + +#ifdef _USING_PROTOTYPES_ +int +TclWaitpid _ANSI_ARGS_((pid_t pid, int *statPtr, int options)) +#else +int +TclWaitpid(pid, statPtr, options) + pid_t pid; + int *statPtr; + int options; +#endif /* _USING_PROTOTYPES_ */ +{ + int result; + while (1) { + result = (int) waitpid((pid_t) pid, statPtr, options); + if ((result != -1) || (errno != EINTR)) { + return result; + } + } +} + +#undef write +int +TclWrite(fd, buf, numBytes) + int fd; + VOID *buf; + size_t numBytes; +{ + int result; + while (1) { + result = write(fd, buf, (size_t) numBytes); + if ((result != -1) || (errno != EINTR)) { + return result; + } + } +} diff --git a/unix/tclUnixPort.h b/unix/tclUnixPort.h index f99910f..3b0eb62 100644 --- a/unix/tclUnixPort.h +++ b/unix/tclUnixPort.h @@ -492,4 +492,20 @@ extern double strtod(); EXTERN int TclUnixWaitForFile _ANSI_ARGS_((int fd, int mask, int timeout)); +/* + * Substitute Tcl's own versions for several system calls. The + * Tcl versions retry automatically if interrupted by signals. + * (see tclUnixUtil.c). + */ + +#define open(a,b,c) TclOpen(a,b,c) +#define read(a,b,c) TclRead(a,b,c) +#define waitpid(a,b,c) TclWaitpid(a,b,c) +#define write(a,b,c) TclWrite(a,b,c) +EXTERN int TclOpen _ANSI_ARGS_((char *path, int oflag, int mode)); +EXTERN int TclRead _ANSI_ARGS_((int fd, VOID *buf, size_t numBytes)); +EXTERN int TclWaitpid _ANSI_ARGS_((pid_t pid, int *statPtr, int options)); +EXTERN int TclWrite _ANSI_ARGS_((int fd, VOID *buf, size_t numBytes)); + + #endif /* _TCLUNIXPORT */ -- cgit v0.12