508 lines
10 KiB
C
508 lines
10 KiB
C
/*
|
|
* tclUnixPort.h --
|
|
*
|
|
* This header file handles porting issues that occur because
|
|
* of differences between systems. It reads in UNIX-related
|
|
* header files and sets up UNIX-related macros for Tcl's UNIX
|
|
* core. It should be the only file that contains #ifdefs to
|
|
* handle different flavors of UNIX. This file sets up the
|
|
* union of all UNIX-related things needed by any of the Tcl
|
|
* core files. This file depends on configuration #defines such
|
|
* as NO_DIRENT_H that are set up by the "configure" script.
|
|
*
|
|
* Much of the material in this file was originally contributed
|
|
* by Karl Lehenbauer, Mark Diekhans and Peter da Silva.
|
|
*
|
|
* Copyright (c) 1991-1994 The Regents of the University of California.
|
|
* Copyright (c) 1994-1995 Sun Microsystems, Inc.
|
|
*
|
|
* See the file "license.terms" for information on usage and redistribution
|
|
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
*
|
|
* SCCS: @(#) tclUnixPort.h 1.49 97/07/30 14:11:59
|
|
*/
|
|
|
|
#ifndef _TCLUNIXPORT
|
|
#define _TCLUNIXPORT
|
|
|
|
#ifndef _TCLINT
|
|
# include "tclInt.h"
|
|
#endif
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#ifdef HAVE_NET_ERRNO_H
|
|
# include <net/errno.h>
|
|
#endif
|
|
#include <pwd.h>
|
|
#include <signal.h>
|
|
#include <sys/param.h>
|
|
#include <sys/types.h>
|
|
#ifdef USE_DIRENT2_H
|
|
# ifdef SCM_CODE
|
|
# include "compat/dirent2.h"
|
|
# else
|
|
# include "../compat/dirent2.h"
|
|
# endif
|
|
#else
|
|
# ifdef NO_DIRENT_H
|
|
# ifdef SCM_CODE
|
|
# include "compat/dirent.h"
|
|
# else
|
|
# include "../compat/dirent.h"
|
|
# endif
|
|
# else
|
|
# include <dirent.h>
|
|
# endif
|
|
#endif
|
|
#include <sys/file.h>
|
|
#ifdef HAVE_SYS_SELECT_H
|
|
# include <sys/select.h>
|
|
#endif
|
|
#include <sys/stat.h>
|
|
#if TIME_WITH_SYS_TIME
|
|
# include <sys/time.h>
|
|
# include <time.h>
|
|
#else
|
|
# if HAVE_SYS_TIME_H
|
|
# include <sys/time.h>
|
|
# else
|
|
# include <time.h>
|
|
# endif
|
|
#endif
|
|
#ifndef NO_SYS_WAIT_H
|
|
# include <sys/wait.h>
|
|
#endif
|
|
#ifdef HAVE_UNISTD_H
|
|
# include <unistd.h>
|
|
#else
|
|
# ifdef SCM_CODE
|
|
# include "compat/unistd.h"
|
|
# else
|
|
# include "../compat/unistd.h"
|
|
# endif
|
|
#endif
|
|
#ifdef USE_FIONBIO
|
|
|
|
/*
|
|
* Not using the Posix fcntl(...,O_NONBLOCK,...) interface, instead
|
|
* we are using ioctl(..,FIONBIO,..).
|
|
*/
|
|
|
|
# ifdef HAVE_SYS_FILIO_H
|
|
# include <sys/filio.h> /* For FIONBIO. */
|
|
# endif
|
|
|
|
# ifdef HAVE_SYS_IOCTL_H
|
|
# include <sys/ioctl.h> /* For FIONBIO. */
|
|
# endif
|
|
#endif /* USE_FIONBIO */
|
|
|
|
/*
|
|
* Socket support stuff: This likely needs more work to parameterize for
|
|
* each system.
|
|
*/
|
|
|
|
#include <sys/socket.h> /* struct sockaddr, SOCK_STREAM, ... */
|
|
#ifndef NO_UNAME
|
|
# include <sys/utsname.h> /* uname system call. */
|
|
#endif
|
|
#include <netinet/in.h> /* struct in_addr, struct sockaddr_in */
|
|
#include <arpa/inet.h> /* inet_ntoa() */
|
|
#include <netdb.h> /* gethostbyname() */
|
|
|
|
/*
|
|
* Some platforms (e.g. SunOS) don't define FLT_MAX and FLT_MIN, so we
|
|
* look for an alternative definition. If no other alternative is available
|
|
* we use a reasonable guess.
|
|
*/
|
|
|
|
#ifndef NO_FLOAT_H
|
|
#include <float.h>
|
|
#else
|
|
# ifndef NO_VALUES_H
|
|
# include <values.h>
|
|
# endif
|
|
#endif
|
|
|
|
#ifndef FLT_MAX
|
|
# ifdef MAXFLOAT
|
|
# define FLT_MAX MAXFLOAT
|
|
# else
|
|
# define FLT_MAX 3.402823466E+38F
|
|
# endif
|
|
#endif
|
|
#ifndef FLT_MIN
|
|
# ifdef MINFLOAT
|
|
# define FLT_MIN MINFLOAT
|
|
# else
|
|
# define FLT_MIN 1.175494351E-38F
|
|
# endif
|
|
#endif
|
|
|
|
/*
|
|
* NeXT doesn't define O_NONBLOCK, so #define it here if necessary.
|
|
*/
|
|
|
|
#ifndef O_NONBLOCK
|
|
# define O_NONBLOCK 0x80
|
|
#endif
|
|
|
|
/*
|
|
* HPUX needs the flag O_NONBLOCK to get the right non-blocking I/O
|
|
* semantics, while most other systems need O_NDELAY. Define the
|
|
* constant NBIO_FLAG to be one of these
|
|
*/
|
|
|
|
#ifdef HPUX
|
|
# define NBIO_FLAG O_NONBLOCK
|
|
#else
|
|
# define NBIO_FLAG O_NDELAY
|
|
#endif
|
|
|
|
/*
|
|
* The following defines denote malloc and free as the system calls
|
|
* used to allocate new memory. These defines are only used in the
|
|
* file tclCkalloc.c.
|
|
*/
|
|
|
|
#define TclpAlloc(size) malloc(size)
|
|
#define TclpFree(ptr) free(ptr)
|
|
#define TclpRealloc(ptr, size) realloc(ptr, size)
|
|
|
|
/*
|
|
* The default platform eol translation on Unix is TCL_TRANSLATE_LF:
|
|
*/
|
|
|
|
#define TCL_PLATFORM_TRANSLATION TCL_TRANSLATE_LF
|
|
|
|
/*
|
|
* Not all systems declare the errno variable in errno.h. so this
|
|
* file does it explicitly. The list of system error messages also
|
|
* isn't generally declared in a header file anywhere.
|
|
*/
|
|
|
|
extern int errno;
|
|
|
|
/*
|
|
* The type of the status returned by wait varies from UNIX system
|
|
* to UNIX system. The macro below defines it:
|
|
*/
|
|
|
|
#ifdef _AIX
|
|
# define WAIT_STATUS_TYPE pid_t
|
|
#else
|
|
#ifndef NO_UNION_WAIT
|
|
# define WAIT_STATUS_TYPE union wait
|
|
#else
|
|
# define WAIT_STATUS_TYPE int
|
|
#endif
|
|
#endif
|
|
|
|
/*
|
|
* Supply definitions for macros to query wait status, if not already
|
|
* defined in header files above.
|
|
*/
|
|
|
|
#ifndef WIFEXITED
|
|
# define WIFEXITED(stat) (((*((int *) &(stat))) & 0xff) == 0)
|
|
#endif
|
|
|
|
#ifndef WEXITSTATUS
|
|
# define WEXITSTATUS(stat) (((*((int *) &(stat))) >> 8) & 0xff)
|
|
#endif
|
|
|
|
#ifndef WIFSIGNALED
|
|
# define WIFSIGNALED(stat) (((*((int *) &(stat)))) && ((*((int *) &(stat))) == ((*((int *) &(stat))) & 0x00ff)))
|
|
#endif
|
|
|
|
#ifndef WTERMSIG
|
|
# define WTERMSIG(stat) ((*((int *) &(stat))) & 0x7f)
|
|
#endif
|
|
|
|
#ifndef WIFSTOPPED
|
|
# define WIFSTOPPED(stat) (((*((int *) &(stat))) & 0xff) == 0177)
|
|
#endif
|
|
|
|
#ifndef WSTOPSIG
|
|
# define WSTOPSIG(stat) (((*((int *) &(stat))) >> 8) & 0xff)
|
|
#endif
|
|
|
|
/*
|
|
* Define constants for waitpid() system call if they aren't defined
|
|
* by a system header file.
|
|
*/
|
|
|
|
#ifndef WNOHANG
|
|
# define WNOHANG 1
|
|
#endif
|
|
#ifndef WUNTRACED
|
|
# define WUNTRACED 2
|
|
#endif
|
|
|
|
/*
|
|
* Supply macros for seek offsets, if they're not already provided by
|
|
* an include file.
|
|
*/
|
|
|
|
#ifndef SEEK_SET
|
|
# define SEEK_SET 0
|
|
#endif
|
|
|
|
#ifndef SEEK_CUR
|
|
# define SEEK_CUR 1
|
|
#endif
|
|
|
|
#ifndef SEEK_END
|
|
# define SEEK_END 2
|
|
#endif
|
|
|
|
/*
|
|
* The stuff below is needed by the "time" command. If this
|
|
* system has no gettimeofday call, then must use times and the
|
|
* CLK_TCK #define (from sys/param.h) to compute elapsed time.
|
|
* Unfortunately, some systems only have HZ and no CLK_TCK, and
|
|
* some might not even have HZ.
|
|
*/
|
|
|
|
#ifdef NO_GETTOD
|
|
# include <sys/times.h>
|
|
# include <sys/param.h>
|
|
# ifndef CLK_TCK
|
|
# ifdef HZ
|
|
# define CLK_TCK HZ
|
|
# else
|
|
# define CLK_TCK 60
|
|
# endif
|
|
# endif
|
|
#else
|
|
# ifdef HAVE_BSDGETTIMEOFDAY
|
|
# define gettimeofday BSDgettimeofday
|
|
# endif
|
|
#endif
|
|
|
|
#ifdef GETTOD_NOT_DECLARED
|
|
EXTERN int gettimeofday _ANSI_ARGS_((struct timeval *tp,
|
|
struct timezone *tzp));
|
|
#endif
|
|
|
|
/*
|
|
* Define access mode constants if they aren't already defined.
|
|
*/
|
|
|
|
#ifndef F_OK
|
|
# define F_OK 00
|
|
#endif
|
|
#ifndef X_OK
|
|
# define X_OK 01
|
|
#endif
|
|
#ifndef W_OK
|
|
# define W_OK 02
|
|
#endif
|
|
#ifndef R_OK
|
|
# define R_OK 04
|
|
#endif
|
|
|
|
/*
|
|
* Define FD_CLOEEXEC (the close-on-exec flag bit) if it isn't
|
|
* already defined.
|
|
*/
|
|
|
|
#ifndef FD_CLOEXEC
|
|
# define FD_CLOEXEC 1
|
|
#endif
|
|
|
|
/*
|
|
* On UNIX, there's no platform specific implementation of "TclpStat(...)"
|
|
* or "TclpAccess(...)". Simply call "stat(...)' and "access(...)"
|
|
* respectively.
|
|
*/
|
|
|
|
#define TclpStat stat
|
|
#define TclpAccess access
|
|
|
|
/*
|
|
* On systems without symbolic links (i.e. S_IFLNK isn't defined)
|
|
* define "lstat" to use "stat" instead.
|
|
*/
|
|
|
|
#ifndef S_IFLNK
|
|
# define lstat stat
|
|
#endif
|
|
|
|
/*
|
|
* Define macros to query file type bits, if they're not already
|
|
* defined.
|
|
*/
|
|
|
|
#ifndef S_ISREG
|
|
# ifdef S_IFREG
|
|
# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
|
|
# else
|
|
# define S_ISREG(m) 0
|
|
# endif
|
|
# endif
|
|
#ifndef S_ISDIR
|
|
# ifdef S_IFDIR
|
|
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
|
# else
|
|
# define S_ISDIR(m) 0
|
|
# endif
|
|
# endif
|
|
#ifndef S_ISCHR
|
|
# ifdef S_IFCHR
|
|
# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
|
|
# else
|
|
# define S_ISCHR(m) 0
|
|
# endif
|
|
# endif
|
|
#ifndef S_ISBLK
|
|
# ifdef S_IFBLK
|
|
# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
|
|
# else
|
|
# define S_ISBLK(m) 0
|
|
# endif
|
|
# endif
|
|
#ifndef S_ISFIFO
|
|
# ifdef S_IFIFO
|
|
# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
|
|
# else
|
|
# define S_ISFIFO(m) 0
|
|
# endif
|
|
# endif
|
|
#ifndef S_ISLNK
|
|
# ifdef S_IFLNK
|
|
# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
|
|
# else
|
|
# define S_ISLNK(m) 0
|
|
# endif
|
|
# endif
|
|
#ifndef S_ISSOCK
|
|
# ifdef S_IFSOCK
|
|
# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
|
|
# else
|
|
# define S_ISSOCK(m) 0
|
|
# endif
|
|
# endif
|
|
|
|
/*
|
|
* Make sure that MAXPATHLEN is defined.
|
|
*/
|
|
|
|
#ifndef MAXPATHLEN
|
|
# ifdef PATH_MAX
|
|
# define MAXPATHLEN PATH_MAX
|
|
# else
|
|
# define MAXPATHLEN 2048
|
|
# endif
|
|
#endif
|
|
|
|
/*
|
|
* Make sure that L_tmpnam is defined.
|
|
*/
|
|
|
|
#ifndef L_tmpnam
|
|
# define L_tmpnam 100
|
|
#endif
|
|
|
|
/*
|
|
* The following macro defines the type of the mask arguments to
|
|
* select:
|
|
*/
|
|
|
|
#ifndef NO_FD_SET
|
|
# define SELECT_MASK fd_set
|
|
#else
|
|
# ifndef _AIX
|
|
typedef long fd_mask;
|
|
# endif
|
|
# if defined(_IBMR2)
|
|
# define SELECT_MASK void
|
|
# else
|
|
# define SELECT_MASK int
|
|
# endif
|
|
#endif
|
|
|
|
/*
|
|
* Define "NBBY" (number of bits per byte) if it's not already defined.
|
|
*/
|
|
|
|
#ifndef NBBY
|
|
# define NBBY 8
|
|
#endif
|
|
|
|
/*
|
|
* The following macro defines the number of fd_masks in an fd_set:
|
|
*/
|
|
|
|
#ifndef FD_SETSIZE
|
|
# ifdef OPEN_MAX
|
|
# define FD_SETSIZE OPEN_MAX
|
|
# else
|
|
# define FD_SETSIZE 256
|
|
# endif
|
|
#endif
|
|
#if !defined(howmany)
|
|
# define howmany(x, y) (((x)+((y)-1))/(y))
|
|
#endif
|
|
#ifndef NFDBITS
|
|
# define NFDBITS NBBY*sizeof(fd_mask)
|
|
#endif
|
|
#define MASK_SIZE howmany(FD_SETSIZE, NFDBITS)
|
|
|
|
/*
|
|
* The following implements the Unix method for exiting the process.
|
|
*/
|
|
#define TclPlatformExit(status) exit(status)
|
|
|
|
/*
|
|
* The following functions always succeeds under Unix.
|
|
*/
|
|
|
|
#define TclHasSockets(interp) (TCL_OK)
|
|
#define TclHasPipes() (1)
|
|
|
|
/*
|
|
* Variables provided by the C library:
|
|
*/
|
|
|
|
#if defined(_sgi) || defined(__sgi)
|
|
#define environ _environ
|
|
#endif
|
|
extern char **environ;
|
|
|
|
/*
|
|
* At present (12/91) not all stdlib.h implementations declare strtod.
|
|
* The declaration below is here to ensure that it's declared, so that
|
|
* the compiler won't take the default approach of assuming it returns
|
|
* an int. There's no ANSI prototype for it because there would end
|
|
* up being too many conflicts with slightly-different prototypes.
|
|
*/
|
|
|
|
extern double strtod();
|
|
|
|
/*
|
|
* The following macros define time related functions in terms of
|
|
* standard Unix routines.
|
|
*/
|
|
|
|
#define TclpGetDate(t,u) ((u) ? gmtime((t)) : localtime((t)))
|
|
#define TclStrftime(s,m,f,t) (strftime((s),(m),(f),(t)))
|
|
#define TclpGetPid(pid) ((unsigned long) (pid))
|
|
|
|
#define TclpReleaseFile(file)
|
|
|
|
/*
|
|
* TclpFinalize is a noop on Unix systems.
|
|
*/
|
|
|
|
#define TclpFinalize()
|
|
|
|
/*
|
|
* The following routine is only exported for testing purposes.
|
|
*/
|
|
|
|
EXTERN int TclUnixWaitForFile _ANSI_ARGS_((int fd, int mask,
|
|
int timeout));
|
|
|
|
#endif /* _TCLUNIXPORT */
|