Use AC_USE_SYSTEM_EXTENSIONS
[openafs.git] / src / lwp / iomgr.c
index e55d7ba..fcdba04 100644 (file)
        IO Manager routines & server process for VICE server.
 */
 
-#include <afs/param.h>
+/* This controls the size of an fd_set; it must be defined early before
+ * the system headers define that type and the macros that operate on it.
+ * Its value should be as large as the maximum file descriptor limit we
+ * are likely to run into on any platform.  Right now, that is 65536
+ * which is the default hard fd limit on Solaris 9 */
+/* We don't do this on Windows because on that platform there is code
+ * which allocates fd_set's on the stack (IOMGR_Sleep on Win9x, and
+ * FDSetAnd on WinNT) */
+#ifndef _WIN32
+#define FD_SETSIZE 65536
+#endif
+
 #include <afsconfig.h>
+#include <afs/param.h>
 
-RCSID("$Header$");
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -49,16 +60,6 @@ extern void lwp_abort(void);
 #ifdef AFS_SUN5_ENV
 #include <fcntl.h>
 #endif
-#ifdef AFS_DJGPP_ENV
-#include "dosdefs95.h"
-#include "netbios95.h"
-#include <sys/socket.h>
-#include <sys/farptr.h>
-#include <dpmi.h>
-#include <go32.h>
-#include <crt0.h>
-int _crt0_startup_flags = _CRT0_FLAG_LOCK_MEMORY;
-#endif /* AFS_DJGPP_ENV */
 
 #if    defined(USE_PTHREADS) || defined(USE_SOLARIS_THREADS)
 
@@ -88,14 +89,14 @@ typedef unsigned char bool;
 #define TRUE   1
 
 #ifndef MIN
-#define MIN(a,b) ((a)>(b)) ? b : a
+#define MIN(a,b) (((a)>(b)) ? (b) : (a))
 #endif
 
 #ifndef NSIG
 #define NSIG 8*sizeof(sigset_t)
 #endif
 
-static int SignalSignals();
+static int SignalSignals(void);
 \f
 /********************************\
 *                               *
@@ -117,15 +118,12 @@ struct IoRequest {
     struct TM_Elem     timeout;
 
     /* Result of select call */
-    long                       result;
+    int                        result;
 
-#ifdef AFS_DJGPP_ENV
-    NCB                  *ncbp;
-    dos_ptr              dos_ncb;
-#endif /* AFS_DJGPP_ENV */
+    struct IoRequest    *next; /* for iorFreeList */
 
 };
-\f
+
 /********************************\
 *                               *
 *  Stuff for managing signals    *
@@ -149,8 +147,8 @@ static int sigDelivered[NSIG];              /* True for signals delivered so far.
                                           to write it */
 /* software 'signals' */
 #define NSOFTSIG               4
-static int (*sigProc[NSOFTSIG])();
-static char *sigRock[NSOFTSIG];
+static void *(*sigProc[NSOFTSIG])(void *);
+static void *sigRock[NSOFTSIG];
 
 \f
 static struct IoRequest *iorFreeList = 0;
@@ -166,18 +164,9 @@ static void SignalIO(int fds, fd_set *rfds, fd_set *wfds, fd_set *efs,
                    int code);
 static void SignalTimeout(int code, struct timeval *timeout);
 
-#ifdef AFS_DJGPP_ENV
-/* handle Netbios NCB completion */
-static int NCB_fd;
-int anyNCBComplete = FALSE;
-int handler_seg, handler_off;  /* seg:off of NCB completion handler */
-static __dpmi_regs        callback_regs;
-static _go32_dpmi_seginfo callback_info;
-#endif /* AFS_DJGPP_ENV */
-
 /* fd_set pool managment. 
  * Use the pool instead of creating fd_set's on the stack. fd_set's can be
- * 2K in size, so making three could put 6K in the limited space of an LWP
+ * 8K in size, so making three could put 24K in the limited space of an LWP
  * stack.
  */
 struct IOMGR_fd_set {
@@ -216,14 +205,14 @@ fd_set *IOMGR_AllocFDSet(void)
     }
 }
 
-#define FreeRequest(x) ((x)->result = (long) iorFreeList, iorFreeList = (x))
+#define FreeRequest(x) ((x)->next = iorFreeList, iorFreeList = (x))
 
-static struct IoRequest *NewRequest()
+static struct IoRequest *NewRequest(void)
 {
     struct IoRequest *request;
 
     if ((request=iorFreeList))
-       iorFreeList = (struct IoRequest *) (request->result);
+       iorFreeList = (struct IoRequest *) (request->next);
     else request = (struct IoRequest *) malloc(sizeof(struct IoRequest));
 
     memset((char*)request, 0, sizeof(struct IoRequest));
@@ -244,14 +233,15 @@ static struct IoRequest *NewRequest()
 #else
 #define FDS_P_POS (sizeof(int)*8)
 #define INTS_PER_FDS(x) (((x)+(FDS_P_POS-1)) / FDS_P_POS)
-#define FD_N_ZERO(nfds, x) bzero((char*)(x), (INTS_PER_FDS(nfds))*sizeof(int))
+#define FD_N_ZERO(nfds, x) memset((char*)(x), 0, (INTS_PER_FDS(nfds))*sizeof(int))
 #endif
 
-#if defined(AFS_LINUX22_ENV) && (__GLIBC_MINOR__ > 0)
-/* Build for both glibc 2.0.x and 2.1.x */
-#define FDS_BITS __fds_bits
+/* On Linux without __USE_XOPEN, we have __fds_bits. With __USE_XOPEN, or
+ * non-Linux, we have fds_bits. */
+#if defined(AFS_LINUX22_ENV) && (__GLIBC_MINOR__ > 0) && !defined(__USE_XOPEN)
+# define FDS_BITS __fds_bits
 #else
-#define FDS_BITS fds_bits
+# define FDS_BITS fds_bits
 #endif
 
 /* FDSetCmp - returns 1 if any bits in fd_set1 are also set in fd_set2.
@@ -292,7 +282,10 @@ static int FDSetCmp(int nfds, fd_set *fd_set1, fd_set *fd_set2)
  */
 static void FDSetSet(int nfds, fd_set *fd_set1, fd_set *fd_set2)
 {
-    unsigned int i, n;
+    unsigned int i;
+#ifndef AFS_NT40_ENV
+    unsigned int n;
+#endif
 
     if (fd_set1 == (fd_set*)0 || fd_set2 == (fd_set*)0)
        return;
@@ -307,8 +300,7 @@ static void FDSetSet(int nfds, fd_set *fd_set1, fd_set *fd_set2)
     if (nfds == 0)
        return;
 
-    n = INTS_PER_FDS(nfds);
-    for (i=0; i<n; i++) {
+    for (i = 0, n = INTS_PER_FDS(nfds); i < n; i++) {
        fd_set1->FDS_BITS[i] |= fd_set2->FDS_BITS[i];
     }
 #endif
@@ -399,7 +391,7 @@ static int FDSetEmpty(int nfds, fd_set *fds)
 static fd_set IOMGR_readfds, IOMGR_writefds, IOMGR_exceptfds;
 static int IOMGR_nfds = 0;
 
-static int IOMGR(void *dummy)
+static void *IOMGR(void *dummy)
 {
     for (;;) {
        int code;
@@ -421,9 +413,7 @@ static int IOMGR(void *dummy)
            /* Note: SignalSignals() may yield! */
            if (anySigsDelivered && SignalSignals ())
                woke_someone = TRUE;
-#ifndef AFS_DJGPP_ENV
            FT_GetTimeOfDay(&junk, 0);    /* force accurate time check */
-#endif
            TM_Rescan(Requests);
            for (;;) {
                register struct IoRequest *req;
@@ -450,11 +440,6 @@ static int IOMGR(void *dummy)
                req->pid->iomgrRequest = 0;
            }
 
-#ifdef AFS_DJGPP_ENV
-            if (IOMGR_CheckNCB())    /* check for completed netbios requests */
-              woke_someone = TRUE;
-#endif /* AFS_DJGPP_ENV */
-
            if (woke_someone) LWP_DispatchProcess();
        } while (woke_someone);
 
@@ -525,24 +510,17 @@ static int IOMGR(void *dummy)
                iomgr_timeout.tv_sec = 100000000;
                iomgr_timeout.tv_usec = 0;
            }
-#ifdef AFS_NT40_ENV
+#if defined(AFS_NT40_ENV) || defined(AFS_LINUX24_ENV)
            /* On NT, signals don't interrupt a select call. So this can potentially
             * lead to long wait times before a signal is honored. To avoid this we
             * dont do select() for longer than IOMGR_MAXWAITTIME (5 secs) */
+           /* Whereas Linux seems to sometimes "lose" signals */
            if (iomgr_timeout.tv_sec > (IOMGR_MAXWAITTIME - 1)) {
              iomgr_timeout.tv_sec = IOMGR_MAXWAITTIME;
              iomgr_timeout.tv_usec = 0;
            }
 #endif /* NT40 */
 
-#ifdef AFS_DJGPP_ENV
-            /* We do this also for the DOS-box Win95 client, since
-               NCB calls don't interrupt a select, but we want to catch them
-               in a reasonable amount of time (say, half a second). */
-            iomgr_timeout.tv_sec = 0;
-            iomgr_timeout.tv_usec = IOMGR_WIN95WAITTIME;
-#endif /* DJGPP */
-
            /* Check one last time for a signal delivery.  If one comes after
               this, the signal handler will set iomgr_timeout to zero, causing
               the select to return immediately.  The timer package won't return
@@ -553,11 +531,6 @@ static int IOMGR(void *dummy)
            if (anySigsDelivered)
                continue;       /* go to the top and handle them. */
 
-#ifdef AFS_DJGPP_ENV
-            if (IOMGR_CheckNCB())    /* check for completed netbios requests */
-              LWP_DispatchProcess();
-#endif /* AFS_DJGPP_ENV */
-
 #ifdef AFS_NT40_ENV
            if (IOMGR_readfds.fd_count == 0 && IOMGR_writefds.fd_count == 0
                && IOMGR_exceptfds.fd_count == 0) {
@@ -629,29 +602,25 @@ static int IOMGR(void *dummy)
                /* Real timeout only if signal handler hasn't set
                   iomgr_timeout to zero. */
 
-#ifdef AFS_NT40_ENV
+#if defined(AFS_NT40_ENV) || defined(AFS_LINUX24_ENV)
                /* On NT, real timeout only if above and if iomgr_timeout
                 * interval is equal to timeout interval (i.e., not adjusted
                 * to check for pseudo-signals).
                 */
+               /* And also for Linux as above */
                if (iomgr_timeout.tv_sec  != timeout.tv_sec ||
                    iomgr_timeout.tv_usec != timeout.tv_usec) {
                    /* signal check interval timed out; not real timeout */
                    continue;
                }
 #endif /* AFS_NT40_ENV */
-#ifndef AFS_DJGPP_ENV
                FT_GetTimeOfDay(&junk, 0);
-#endif
                SignalTimeout(code, &timeout);
            }
-#ifdef AFS_DJGPP_ENV
-            IOMGR_CheckNCB();
-#endif /* AFS_DJGPP_ENV */
        }
        LWP_DispatchProcess();
     }
-    return -1; /* keeps compilers happy. */
+    return (void *)-1; /* keeps compilers happy. */
 }
 \f
 /************************\
@@ -708,8 +677,7 @@ static void SignalTimeout(int code, struct timeval *timeout)
 *  signalling routines, above).                              *
 *                                                    *
 \*****************************************************/
-static void SigHandler (signo)
-    int signo;
+static void SigHandler (int signo)
 {
     if (badsig(signo) || (sigsHandled & mysigmask(signo)) == 0)
        return;         /* can't happen. */
@@ -722,11 +690,11 @@ static void SigHandler (signo)
 
 /* Alright, this is the signal signalling routine.  It delivers LWP signals
    to LWPs waiting on Unix signals. NOW ALSO CAN YIELD!! */
-static int SignalSignals ()
+static int SignalSignals (void)
 {
     bool gotone = FALSE;
     register int i;
-    register int (*p)();
+    register void *(*p)(void *);
     afs_int32 stackSize;
 
     anySigsDelivered = FALSE;
@@ -735,9 +703,9 @@ static int SignalSignals ()
     stackSize = (AFS_LWP_MINSTACKSIZE < lwp_MaxStackSeen? lwp_MaxStackSeen : AFS_LWP_MINSTACKSIZE);
     for (i=0; i < NSOFTSIG; i++) {
        PROCESS pid;
-       if (p=sigProc[i]) /* This yields!!! */
-           LWP_CreateProcess2(p, stackSize, LWP_NORMAL_PRIORITY, sigRock[i],
-               "SignalHandler", &pid);
+       if ((p=sigProc[i])) /* This yields!!! */
+           LWP_CreateProcess2(p, stackSize, LWP_NORMAL_PRIORITY, 
+                              sigRock[i], "SignalHandler", &pid);
        sigProc[i] = 0;
     }
 
@@ -761,9 +729,8 @@ static int SignalSignals ()
 /* Keep IOMGR process id */
 static PROCESS IOMGR_Id = NULL;
 
-int IOMGR_SoftSig(aproc, arock)
-int (*aproc)();
-char *arock; {
+int IOMGR_SoftSig(void *(*aproc)(void *), void *arock)
+{
     register int i;
     for (i=0;i<NSOFTSIG;i++) {
        if (sigProc[i] == 0) {
@@ -780,11 +747,8 @@ char *arock; {
 }
 
 
-unsigned char allOnes[100];
-
 int IOMGR_Initialize(void)
 {
-    extern int TM_Init();
     PROCESS pid;
 
     /* If lready initialized, just return */
@@ -801,17 +765,12 @@ int IOMGR_Initialize(void)
     sigsHandled = 0;
     anySigsDelivered = TRUE; /* A soft signal may have happened before
        IOMGR_Initialize:  so force a check for signals regardless */
-    memset(allOnes, 0xff, sizeof(allOnes));
-
-#ifdef AFS_DJGPP_ENV
-    install_ncb_handler();
-#endif /* AFS_DJGPP_ENV */
 
-    return LWP_CreateProcess(IOMGR, AFS_LWP_MINSTACKSIZE, 0, 0, "IO MANAGER",
-                            &IOMGR_Id);
+    return LWP_CreateProcess(IOMGR, AFS_LWP_MINSTACKSIZE, 0, (void *) 0, 
+                            "IO MANAGER", &IOMGR_Id);
 }
 
-int IOMGR_Finalize()
+int IOMGR_Finalize(void)
 {
     int status;
 
@@ -899,10 +858,8 @@ int IOMGR_Poll(void) {
     return 0;
 }
 
-int IOMGR_Select(fds, readfds, writefds, exceptfds, timeout)
-     int fds;
-     fd_set *readfds, *writefds, *exceptfds;
-     struct timeval *timeout;
+int IOMGR_Select(int fds, fd_set *readfds, fd_set *writefds, 
+                fd_set *exceptfds, struct timeval *timeout)
 {
     register struct IoRequest *request;
     int result;
@@ -923,7 +880,9 @@ int IOMGR_Select(fds, readfds, writefds, exceptfds, timeout)
 #ifdef DEBUG
            if (lwp_debug != 0) puts("[Polling SELECT]");
 #endif /* DEBUG */
+#if    defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV) || defined(AFS_AIX32_ENV) || defined(AFS_NT40_ENV)
 again:
+#endif
            code = select(fds, readfds, writefds, exceptfds, timeout);
 #if    defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV) || defined(AFS_AIX32_ENV)
            /*
@@ -1023,9 +982,7 @@ int IOMGR_Cancel(PROCESS pid)
 #ifndef AFS_NT40_ENV
 /* Cause delivery of signal signo to result in a LWP_SignalProcess of
    event. */
-IOMGR_Signal (signo, event)
-    int signo;
-    char *event;
+int IOMGR_Signal (int signo, char *event)
 {
     struct sigaction sa;
 
@@ -1034,7 +991,7 @@ IOMGR_Signal (signo, event)
     if (event == NULL)
        return LWP_EBADEVENT;
     sa.sa_handler = SigHandler;
-    sa.sa_mask = *((sigset_t *) allOnes);      /* mask all signals */
+    sigfillset(&sa.sa_mask);   /* mask all signals */
     sa.sa_flags = 0;
     sigsHandled |= mysigmask(signo);
     sigEvents[signo] = event;
@@ -1045,12 +1002,11 @@ IOMGR_Signal (signo, event)
 }
 
 /* Stop handling occurrences of signo. */
-IOMGR_CancelSignal (signo)
-    int signo;
+int IOMGR_CancelSignal (int signo)
 {
     if (badsig(signo) || (sigsHandled & mysigmask(signo)) == 0)
        return LWP_EBADSIG;
-    sigaction (signo, &oldActions[signo], (struct sigaction *)0);
+    sigaction (signo, &oldActions[signo], NULL);
     sigsHandled &= ~mysigmask(signo);
     return LWP_SUCCESS;
 }
@@ -1058,174 +1014,10 @@ IOMGR_CancelSignal (signo)
 /* This routine calls select is a fashion that simulates the standard sleep routine */
 void IOMGR_Sleep (int seconds)
 {
-#ifndef AFS_DJGPP_ENV
     struct timeval timeout;
 
     timeout.tv_sec = seconds;
     timeout.tv_usec = 0;
     IOMGR_Select(0, 0, 0, 0, &timeout);
-#else
-    struct timeval timeout;
-    int s;
-    fd_set set, empty;
-    FD_ZERO(&empty);
-    FD_ZERO(&set);
-    s = socket(AF_INET,SOCK_STREAM,0);
-    FD_SET(s,&set);
-
-    timeout.tv_sec = seconds;
-    timeout.tv_usec = 0;
-    IOMGR_Select(1,&set,&empty,&empty,&timeout);
-    close(s);
-#endif            /* DJGPP  */
 }
 #endif /* USE_PTHREADS */
-
-
-#ifdef AFS_DJGPP_ENV
-
-/* Netbios code for djgpp port */
-
-int IOMGR_NCBSelect(ncbp, dos_ncb, timeout)
-  NCB *ncbp;
-  dos_ptr dos_ncb;
-  struct timeval *timeout;
-{
-  struct IoRequest *request;
-  int result;
-  
-  if (timeout != NULL && timeout->tv_sec == 0 && timeout->tv_usec == 0)
-  {
-    /* Poll */
-    if (ncbp->ncb_event != NULL)
-    {
-      /* error */
-      return -1;
-    }
-    
-    if (get_dos_member_b(NCB, dos_ncb, ncb_cmd_cplt) != 0xff)
-    {
-      return 1;
-    }
-    else {
-      return 0;
-    }
-  }
-
-  /* Construct request block & insert */
-  request = NewRequest();
-  request->ncbp = ncbp;
-  request->dos_ncb = dos_ncb;
-  
-  if (timeout == NULL)
-  {
-    request->timeout.TotalTime.tv_sec = -1;
-    request->timeout.TotalTime.tv_usec = -1;
-  }
-  else
-  {
-    request -> timeout.TotalTime = *timeout;
-    /* check for bad request */
-    if (timeout->tv_sec < 0 || timeout->tv_usec < 0 || timeout->tv_usec > 999999)
-    {
-      /* invalid arg */
-      iomgr_badtv = *timeout;
-      iomgr_badpid = LWP_ActiveProcess;
-      /* now fixup request */
-      if(request->timeout.TotalTime.tv_sec < 0)
-        request->timeout.TotalTime.tv_sec = 1;
-      request->timeout.TotalTime.tv_usec = 100000;
-    }
-  }
-
-  request->timeout.BackPointer = (char *)request;
-
-  /* Insert my PID in case of IOMGR_Cancel */
-  request -> pid = LWP_ActiveProcess;
-  LWP_ActiveProcess -> iomgrRequest = request;
-  
-#ifdef DEBUG
-  request -> timeout.Next = (struct TM_Elem *) 1;
-  request -> timeout.Prev = (struct TM_Elem *) 1;
-#endif /* DEBUG */
-  TM_Insert(Requests, &request->timeout);
-
-  if (ncbp->ncb_event != NULL)
-  {
-    /* since we were given an event, we can return immediately and just
-       signal the event once the request completes. */
-    return 0;
-  }
-  else
-  {
-    /* Wait for action */
-    
-    LWP_QWait();
-    
-    /* Update parameters & return */
-    result = request -> result;
-
-    FreeRequest(request);
-    return (result > 1 ? 1 : result);
-  }
-}
-      
-int IOMGR_CheckNCB()
-{
-  int woke_someone = FALSE;
-  EVENT_HANDLE ev;
-  PROCESS pid;
-  
-  anyNCBComplete = FALSE;
-  FOR_ALL_ELTS(r, Requests, {
-    register struct IoRequest *req;
-    req = (struct IoRequest *) r -> BackPointer;
-
-    if (req->dos_ncb && get_dos_member_b(NCB, req->dos_ncb, ncb_cmd_cplt) != 0xff)
-    {
-      /* this NCB has completed */
-      TM_Remove(Requests, &req->timeout);
-
-      /* copy out NCB from DOS to virtual space */
-      dosmemget(req->dos_ncb, sizeof(NCB), (char *) req->ncbp);
-
-      if (ev = req->ncbp->ncb_event)
-      {
-        thrd_SetEvent(ev);
-      }
-      else
-      {
-        woke_someone = TRUE;
-        LWP_QSignal(pid=req->pid);
-        pid->iomgrRequest = 0;
-      }
-    }
-  })
-  return woke_someone;
-}
-
-int ncb_handler(__dpmi_regs *r)
-{
-  anyNCBComplete = TRUE;  /* NCB completed */
-  /* Make sure that the IOMGR process doesn't pause on the select. */
-  iomgr_timeout.tv_sec = 0;
-  iomgr_timeout.tv_usec = 0;
-  return;
-}
-
-int install_ncb_handler()
-{
-  callback_info.pm_offset = (long) ncb_handler;
-  if (_go32_dpmi_allocate_real_mode_callback_retf(&callback_info,
-                                                  &callback_regs))
- {
-      fprintf(stderr, "error, allocate_real_mode_callback_retf failed\n");
-      return -1;
- }
-
- handler_seg = callback_info.rm_segment;
- handler_off = callback_info.rm_offset;
- /*printf("NCB handler_seg=0x%x, off=0x%x\n", handler_seg, handler_off);*/
-}
-#endif /* AFS_DJGPP_ENV */