int
CreateLocalChild(pid_t *pid,
                 Socket *parentToChild,
                 Socket *childToParent) {

  int childWrite[2];
  int parentWrite[2];
  int myEnd;

  if(parentToChild != NULL) {
    if(pipe(parentWrite) == -1) {
      FAIL1("CreateLocalChild: couldn't get pipe, errno: %d\n", errno);
    }
  }
  if(childToParent != NULL) {
    if(pipe(childWrite) == -1) {
      if(parentToChild != NULL) {
        close(parentWrite[0]);
        close(parentWrite[1]);
      }
      FAIL1("CreateLocalChild: couldn't get pipe, errno: %d\n", errno);
    }
  }

  *pid = fork();

  if(*pid == -1) {
    if(parentToChild != NULL) {
      close(parentWrite[0]);
      close(parentWrite[1]);
    }
    if(childToParent != NULL) {
      close(childWrite[0]);
      close(childWrite[1]);
    }
    FAIL2("CreateLocalChild: couldn't fork, errno: %d (%s)\n",
          errno, strerror(errno));
  }

  /* Close descriptors that this process won't be using. */
  if(parentToChild != NULL) {
    myEnd = (*pid == 0) ? READ_END : WRITE_END;
    close(parentWrite[1 - myEnd]);
    FD_SET(parentWrite[myEnd], &connectedPipes);
    *parentToChild = parentWrite[myEnd];
  }

  if(childToParent != NULL) {
    myEnd = (*pid == 0) ? WRITE_END : READ_END;
    close(childWrite[1 - myEnd]);
    FD_SET(childWrite[myEnd], &connectedPipes);
    *childToParent = childWrite[myEnd];
  }

  return(1);

}
int
EstablishAnEar(short startingPort,
               short endingPort,
               Socket *ear,
               short *earPort) {

  int k32 = 32 * 1024;
  int on = 1;
  short port;
  Socket sd = NO_SOCKET;
  struct sockaddr_in server;

  for(port = startingPort; port <= endingPort; port++) {
    server.sin_port = htons((u_short)port);
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_family = AF_INET;
    if((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
      FAIL("EstablishAnEar: socket allocation failed\n");
    }
    (void)setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
    /*
     * Set the socket buffer sizes to 32k, which just happens to correspond to
     * the most common option value for tcpMessageMonitor activities.  This
     * allows us to use a client connection to conduct the experiment, rather
     * than needing to configure and open a new connection.
     */
    (void)setsockopt(sd, SOL_SOCKET, SO_RCVBUF, (char *)&k32, sizeof(k32));
    (void)setsockopt(sd, SOL_SOCKET, SO_SNDBUF, (char *)&k32, sizeof(k32));
    if(bind(sd, (struct sockaddr *)&server, sizeof(server)) != -1 &&
       listen(sd, 5) != -1) {
      break;
    }
    close(sd);
  }

  if(port > endingPort) {
    FAIL2("EstablishAnEar: couldn't find a port between %d and %d\n",
          startingPort, endingPort);
  }

  if (debug > 0) {
      DDEBUG1("EstablistAnEar: connected socket %d\n", sd);
  }
  FD_SET(sd, &connectedEars);

  *ear = sd;
  *earPort = port;
  return(1);

}
int
CloseSocket(Socket *sock,
            int waitForPeer) {

  fd_set readFDs;
  Socket sd = *sock;
  struct timeval timeout;

  if (debug > 0) {
      DDEBUG1("CloseSocket: Closing connection %d\n", *sock);
  }

  if(*sock == NO_SOCKET) {
    return 1;  /* Already closed; nothing to do. */
  }

  if(waitForPeer > 0) {

    FD_ZERO(&readFDs);
    FD_SET(sd, &readFDs);
    timeout.tv_sec = waitForPeer;
    timeout.tv_usec = 0;

    if(select(FD_SETSIZE, &readFDs, NULL, NULL, &timeout) < 0) {
      FAIL2("CloseSocket: no response on select %d %d\n", sd, errno);
    }

  }

  if(!FD_ISSET(sd, &connectedPipes)) {
    if(shutdown(sd, 2) < 0) {
      /* The other side may have beaten us to the reset. */
      if ((errno != ENOTCONN) && (errno != ECONNRESET)) {
        WARN1("CloseSocket: shutdown error %d\n", errno);
      }
    }
  }

  if(close(sd) < 0) {
    WARN2("CloseSocket: close error %d (%s)\n", errno, strerror(errno));
  }
  ClearSocket(sd);
  DoDisconnectNotification(sd);
  *sock = NO_SOCKET;
  return(1);

}
Пример #4
0
int	sconnect(char *addr,int port,char *laddr,int doproc,PSHANDLER hf,void *ha) {
    int			idx,opt;
    struct sockaddr_in	rem,loc;

#define FAIL0(m) { clwarnx(m); return -1; }
#define	FAIL1(m) { sockerrmsg(m,0); return -1; }
#define	FAIL2(m) { sockerrmsg(m,0); goto free_sock; }
#define	FAIL3(m) { sockerrmsg(m,0); goto free_event; }
#define	FAILD(m) { sockerrmsg(m,1); return -1; }

#ifdef WIN32
    if (initsockets()<0)
	return -1;
#endif

    if (!hf)
	return -1;
    for (idx=0;idx<NSOCK;idx++)
	if (!sockets[idx].inuse)
	    break;
    if (idx==NSOCK) {
	clwarnx("too many open sockets");
	return -1;
    }
    sockets[idx].handler=hf;
    sockets[idx].data=ha;
    sockets[idx].ilen=sockets[idx].olen=0;
    sockets[idx].lp=1;
    sockets[idx].lpevent=-1;
    sockets[idx].state=sNORMAL;
    sockets[idx].attr=7;
    sockets[idx].mode=SM_NORM;
    sockets[idx].opmode=doproc ? SM_NORM : SM_HALF;
    sockets[idx].type=RT_SOCK;
    sockets[idx].zsp=NULL;
    sockets[idx].rawin=sockets[idx].rawout=sockets[idx].procin=0;
    window_flush(); /* flush output before a long blocking operation */
    memset(&rem,0,sizeof(rem));
    rem.sin_family=AF_INET;
    rem.sin_port=htons((short)port);
    if ((rem.sin_addr.s_addr=inet_addr(addr))==INADDR_NONE) {
	struct hostent	*hp=gethostbyname(addr);

	if (!hp)
	    FAILD("can't get remote address");
	memcpy(&rem.sin_addr,hp->h_addr,sizeof(rem.sin_addr));
    }
    memcpy(&sockets[idx].remote,&rem,sizeof(sockets[idx].remote));
    if (laddr) {
	int   slen;
	char  *cp,*buf;

	memset(&loc,0,sizeof(loc));
	loc.sin_family=AF_INET;
	slen=strlen(laddr);
	for (cp=laddr+slen;cp>laddr;--cp)
	  if (*cp==':')
	    break;
	if (*cp==':') {
	  buf=malloc(cp-laddr+1);
	  if (!buf)
	    FAIL0("out of memory");
	  memcpy(buf,laddr,cp-laddr);
	  buf[cp-laddr]='\0';
	  ++cp;
	  loc.sin_port=htons((short)atoi(cp));
	} else
	  buf=laddr;
	if ((loc.sin_addr.s_addr=inet_addr(buf))==INADDR_NONE) {
	    struct hostent  *hp=gethostbyname(buf);

	    if (!hp)
		FAILD("can't get local address");
	    memcpy(&loc.sin_addr,hp->h_addr,sizeof(loc.sin_addr));
	}
	if (buf!=laddr)
	  free(buf);
    }
    if ((sockets[idx].sock=socket(PF_INET,SOCK_STREAM,0))<0)
	FAIL1("can't create socket");
    if (laddr)
	if (bind(sockets[idx].sock,(struct sockaddr *)&loc,sizeof(loc))<0)
	    FAIL2("can't bind socket");
#ifdef WIN32
    if ((sockets[idx].event=CreateEvent(NULL,FALSE,FALSE,NULL))==NULL) {
	clwarn("can't create event");
	goto free_sock;
    }
    if (WSAEventSelect(sockets[idx].sock,sockets[idx].event,FD_READ|FD_CLOSE|FD_CONNECT))
	FAIL3("can't bind event to socket");
#endif
#ifndef WIN32
    {
      int flags=fcntl(sockets[idx].sock,F_GETFL,0);
      if (flags<0)
	FAIL3("can't get fd flags");
      if (fcntl(sockets[idx].sock,F_SETFL,flags|O_NONBLOCK)<0)
	FAIL3("can't set fd flags");
    }
#endif
    opt=KERN_SOCKBUFSIZE;
    setsockopt(sockets[idx].sock,SOL_SOCKET,SO_RCVBUF,(void*)&opt,sizeof(opt)); /* ignore result */
    if (connect(sockets[idx].sock,(struct sockaddr *)&rem,sizeof(rem))<0) {
#ifdef WIN32
      if (WSAGetLastError()!=WSAEWOULDBLOCK)
#else
      if (errno!=EINPROGRESS)
#endif
	FAIL3("can't connect to remote host");
      sockets[idx].mode=SM_CONN;
      sockets[idx].inuse=1;
    } else {
      sockets[idx].inuse=1;
      if (sockets[idx].handler)
	sockets[idx].handler(idx,SCONN,sockets[idx].data,NULL,0);
    }
    return idx;
free_event:
#ifdef WIN32
    CloseHandle(sockets[idx].event);
#endif
free_sock:
    closesocket(sockets[idx].sock);
    return -1;
#undef FAIL0
#undef FAIL1
#undef FAIL2
#undef FAIL3
}
/* compute the total ammount of physical memory used
   it's the sum of the resident size of each processes
   this function parse the output of "PS PS_ARGS" */
unsigned int 
ActiveMemoryGetUsed(void) {

  FILE * file;
  char command[128];
  char string[4096];
  char * token;
  unsigned int field_status, field_rss, memory_used;
  unsigned int index_token, status_valid, rss_value;
  
  strcpy(command, PS);
  strcat(command, " ");
  strcat(command, PS_ARGS);
  if ((file = popen(command, "r")) != NULL) {
    field_status = 0;
    field_rss = 0;
    memory_used = 0;
    while ((field_status == 0) || (field_rss == 0)) {
      if (fgets(string, sizeof(string), file) != NULL) {
	token = strtok(string, PS_DELIM);
	index_token = 1;
	while (token != NULL) {
	  if ((field_status ==0) && (strcmp(token, STATUS_FIELD) == 0))
	    field_status = index_token;
	  if ((field_rss ==0) && (strcmp(token, RSS_FIELD) == 0))
	    field_rss = index_token;
	  index_token++;
	  token = strtok(NULL, PS_DELIM);
	}
      } else
         break;
    }
    
    if ((field_status == 0) || (field_rss == 0))
      FAIL3("ActiveMemoryGetUsed: Error in reading (%s): "
	    "unable to find the fields %s and %s\n",
	    command, STATUS_FIELD, RSS_FIELD);
    
    memory_used = 0;
    
    while (fgets(string, sizeof(string), file) != NULL) {
      token = strtok(string, PS_DELIM);
      index_token = 1;
      status_valid = 0;
      while (token != NULL) {
	if (index_token == field_status) 
	  if (strpbrk(token, STATUS_VALID) != NULL)
	    status_valid = 1;
	if ((status_valid) && (index_token == field_rss)) {
	  if (sscanf(token, "%d", &rss_value) != 1) {
	    FAIL3("ActiveMemoryGetUsed: Error in reading (%s) from (%s):"
		  "no valid RSS value in (%s)\n",
		  command, string, token);
	  } else
	    memory_used += rss_value*MEMSOR_UNIT;
	}
	index_token++;
	token = strtok(NULL, PS_DELIM);
      }
    }
      
    pclose(file);
  } else
    FAIL2("ActiveMemoryGetUsed: execution of %s failed (error %d)\n",
          command, errno);

  return memory_used;
}
/* this code return the ammount of physical memory available 
   it's the base memory minus the memory used at this time */
int
ActiveMemoryGetFree(double *measure) {
 
#if MEMORY_SUPPORT
  unsigned int usedmem;
  int freemem;
  double current, available;

  if (debug > 0)
    DDEBUG3("MemoryGetFree: basemem = %d, count = %d, max = %d\n",
	    BaseMem,CountFromLastCalibration,CountBetweenCalibration);
  
  if (BaseMem == 0)
    ActiveMemoryMonitorCalibration();
  
  if (CountFromLastCalibration > CountBetweenCalibration) {
    if (cpu_monitor_on) {
      if (PassiveCpuGetLoad(0, 0, &available, &current)) {
	if (debug > 0)
	  DDEBUG1("MemoryGetFree: Passive cpu load=%f\n", current);
	if (current >= MIN_CPU_FOR_CALIBRATION) {
	  if (ActiveCpuGetLoad(19, 20, 500, &available)) {
	    if (debug > 0)
	      DDEBUG1("MemoryGetFree: Active cpu load=%f\n", available);
	    if (available >= MIN_CPU_FOR_CALIBRATION) {
	      if (PassiveCpuCloseMonitor())
		cpu_monitor_on = 0;
	      ActiveMemoryMonitorCalibration();
	      CountFromLastCalibration = 0;
	      if (CountBetweenCalibration < MAX_COUNT_BETWEEN_CALIBRATION)
		CountBetweenCalibration *= 2;
	    }
	  } else
	    LOG("MemoryGetFree: error getting an active cpu measurement\n");
	}
      } else
	LOG("MemoryGetFree: error getting a passive cpu measurement\n");  
    } else
      if (!PassiveCpuMonitorAvailable)
	CountFromLastCalibration = 0;
      else 
	if (PassiveCpuOpenMonitor(20))
	  cpu_monitor_on = 1;
	else
	  LOG("MemoryGetFree: problem starting passive CPU sensor\n");
  } else {
    if ((CountFromLastCalibration > CountBetweenCalibration - 16)
	&& (!cpu_monitor_on)
	&& (PassiveCpuMonitorAvailable))
      if (PassiveCpuOpenMonitor(20)) {
	cpu_monitor_on = 1;
      } else
	LOG("MemoryGetFree: problem starting passive CPU sensor\n");
  }
  usedmem = ActiveMemoryGetUsed();
  freemem = BaseMem - usedmem;
  if (freemem < 0)
    FAIL2("MemoryGetFree: Base memory size to small :"
	  "base=%d and memory in used=%d\n", BaseMem, usedmem);
  
  if (debug > 0) {
    DDEBUG2("MemoryGetFree: %d kB physical memory available (%d kB used)\n",
		  freemem, usedmem);
  }
  *measure = (freemem/1024.);
  CountFromLastCalibration++;
  
  return(1);
#else
  return 0;
#endif

}
/* Try to get a good rough estimate of the free memory
   to speed up the calibration process */
unsigned int
ActiveMemoryGetRoughlyFree(void) {

  FILE * file;
  char command[128];
  char string[4096];
  char * token;
  unsigned int field_free, memory_free;
  unsigned int index_token, free_value;

  strcpy(command, VMSTAT);
  if (strstr(command, "vmstat") == NULL)
    return 0;
  strcat(command, " 1 2");
  field_free = 0;
  if ((file = popen(command, "r")) != NULL) {
    while (field_free == 0) {
      if (fgets(string, sizeof(string), file) != NULL) {
        token = strtok(string, VMSTAT_DELIM);
        index_token = 1;
        while ((token != NULL) && (field_free == 0))  {
          if ((field_free ==0) && (strcmp(token, VMSTAT_FREE) == 0))
            field_free = index_token;
          index_token++;
          token = strtok(NULL, VMSTAT_DELIM);
        }
      } else
         break;
    }

    if (field_free == 0)
      FAIL2("ActiveMemoryGetRoughlyFree: Error in reading (%s): "
            "unable to find the field %s\n",
            command, VMSTAT_FREE);
 
    memory_free = 0;
    free_value = 0;
    sleep(1);
 
    while (fgets(string, sizeof(string), file) != NULL) {
      token = strtok(string, VMSTAT_DELIM);
      index_token = 1;
      while (token != NULL) {
        if (index_token == field_free) {
          if (sscanf(token, "%d", &free_value) != 1) {
            FAIL3("ActiveMemoryGetRoughlyFree: Error in reading (%s) from (%s):"
                  "no valid FREE value in (%s)\n",
                  command, string, token);
          } else
            memory_free = free_value*MEMSOR_UNIT;
        }
        index_token++;
        token = strtok(NULL, VMSTAT_DELIM);
      }
    }

    pclose(file);
  } else
    FAIL2("ActiveMemoryGetRoughlyFree: execution of %s failed (error %d)\n",
          command, errno);

  return memory_free;
}
int
RecvBytes(Socket sd,
          void *bytes,
          size_t byteSize,
          double timeOut) {

  double end;
  int isPipe;
  char *nextByte;
  fd_set readFds;
  int recvd;
  double start;
  int totalRecvd;
  struct timeval tout;
  void (*was)(int);

  isPipe = FD_ISSET(sd, &connectedPipes);
  FD_ZERO(&readFds);
  FD_SET(sd, &readFds);

  tout.tv_sec = (int)timeOut;
  tout.tv_usec = 0;

  start = CurrentTime();
  was = signal(SIGALRM, RecvTimeOut);
  nextByte = (char *)bytes;

  for(totalRecvd = 0; totalRecvd < byteSize; totalRecvd += recvd) {
    
    recvd = 0;
    switch (select(FD_SETSIZE, &readFds, NULL, NULL, &tout)) {

    case -1:
      if(errno == EINTR) {
        end = CurrentTime();
        if((int)(end - start) < timeOut) {
          tout.tv_sec = (int)(timeOut - (end - start));
          continue;
        }
      }
      signal(SIGALRM, was);
      FAIL2("RecvBytes: select %d failed %s\n", sd, strerror(errno));
      break;

    case 0:
      if(!isPipe) {
        end = CurrentTime();
        SetPktTimeOut(sd, end - start, 1);
      }
      signal(SIGALRM, was);
      FAIL3("RecvBytes: timed out socket %d after %d/%fs\n",
            sd, tout.tv_sec, timeOut);
      break;

    default:
      SetRealTimer((unsigned int)timeOut);

 	  recvd = read(sd, nextByte, (size_t)(byteSize - totalRecvd));

      RESETREALTIMER;

      if(recvd <= 0) {
		WARN3("RecvBytes: read() on descriptor %d returned %d (errno=%d).\n", sd, recvd, errno);
        if(!isPipe) {
          end = CurrentTime();
          SetPktTimeOut(sd, end - start, 0);
        }
        signal(SIGALRM, was);
        FAIL5("RecvBytes: sd %d (addr:%s) failed with %s after %d of %d\n",
              sd, PeerName(sd), strerror(errno), totalRecvd, byteSize);
      }
      break;

    }

    nextByte += recvd;

  }

  return(1);

}
Пример #9
0
int
main (int argc, char **argv)
{
  int i;
  int pass, reps = 400;
  mpz_t in1, in2, in3;
  unsigned long int in2i;
  mp_size_t size;
  mpz_t res1, res2, res3;
  mpz_t ref1, ref2, ref3;
  mpz_t t;
  unsigned long int r1, r2;
  gmp_randstate_ptr rands;
  mpz_t bs;
  unsigned long bsi, size_range;

  tests_start ();
  TESTS_REPS (reps, argv, argc);

  rands = RANDS;

  mpz_init (bs);

  mpz_init (in1);
  mpz_init (in2);
  mpz_init (in3);
  mpz_init (ref1);
  mpz_init (ref2);
  mpz_init (ref3);
  mpz_init (res1);
  mpz_init (res2);
  mpz_init (res3);
  mpz_init (t);

  for (pass = 1; pass <= reps; pass++)
    {
      if (isatty (fileno (stdout)))
	{
	  printf ("\r%d/%d passes", pass, reps);
	  fflush (stdout);
	}

      mpz_urandomb (bs, rands, 32);
      size_range = mpz_get_ui (bs) % 21 + 2;

      if ((pass & 1) == 0)
	{
	  /* Make all input operands have quite different sizes */
	  mpz_urandomb (bs, rands, 32);
	  size = mpz_get_ui (bs) % size_range;
	  mpz_rrandomb (in1, rands, size);

	  mpz_urandomb (bs, rands, 32);
	  size = mpz_get_ui (bs) % size_range;
	  mpz_rrandomb (in2, rands, size);

	  mpz_urandomb (bs, rands, 32);
	  size = mpz_get_ui (bs) % size_range;
	  mpz_rrandomb (in3, rands, size);
	}
      else
	{
	  /* Make all input operands have about the same size */
	  mpz_urandomb (bs, rands, size_range);
	  size = mpz_get_ui (bs);
	  mpz_rrandomb (in1, rands, size);

	  mpz_urandomb (bs, rands, size_range);
	  size = mpz_get_ui (bs);
	  mpz_rrandomb (in2, rands, size);

	  mpz_urandomb (bs, rands, size_range);
	  size = mpz_get_ui (bs);
	  mpz_rrandomb (in3, rands, size);
	}

      mpz_urandomb (bs, rands, 3);
      bsi = mpz_get_ui (bs);
      if ((bsi & 1) != 0)
	mpz_neg (in1, in1);
      if ((bsi & 2) != 0)
	mpz_neg (in2, in2);
      if ((bsi & 4) != 0)
	mpz_neg (in3, in3);

      for (i = 0; i < numberof (dss); i++)
	{
	  if (dss[i].isdivision && mpz_sgn (in2) == 0)
	    continue;
	  if (dss[i].isslow && size_range > 19)
	    continue;

	  (dss[i].fptr) (ref1, in1, in2);
	  MPZ_CHECK_FORMAT (ref1);

	  mpz_set (res1, in1);
	  INVOKE_RSS (dss[i], res1, res1, in2);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL (dss, i, in1, in2, NULL);

	  mpz_set (res1, in2);
	  INVOKE_RSS (dss[i], res1, in1, res1);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL (dss, i, in1, in2, NULL);
	}

      for (i = 0; i < numberof (ddss_div); i++)
	{
	  if (mpz_sgn (in2) == 0)
	    continue;

	  (ddss_div[i].fptr) (ref1, ref2, in1, in2);
	  MPZ_CHECK_FORMAT (ref1);
	  MPZ_CHECK_FORMAT (ref2);

	  mpz_set (res1, in1);
	  INVOKE_RRSS (ddss_div[i], res1, res2, res1, in2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
	    FAIL (ddss_div, i, in1, in2, NULL);

	  mpz_set (res2, in1);
	  INVOKE_RRSS (ddss_div[i], res1, res2, res2, in2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
	    FAIL (ddss_div, i, in1, in2, NULL);

	  mpz_set (res1, in2);
	  INVOKE_RRSS (ddss_div[i], res1, res2, in1, res1);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
	    FAIL (ddss_div, i, in1, in2, NULL);

	  mpz_set (res2, in2);
	  INVOKE_RRSS (ddss_div[i], res1, res2, in1, res2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
	    FAIL (ddss_div, i, in1, in2, NULL);
	}

      for (i = 0; i < numberof (ds); i++)
	{
	  if (ds[i].nonneg && mpz_sgn (in1) < 0)
	    continue;

	  (ds[i].fptr) (ref1, in1);
	  MPZ_CHECK_FORMAT (ref1);

	  mpz_set (res1, in1);
	  INVOKE_RS (ds[i], res1, res1);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL (ds, i, in1, in2, NULL);
	}

      in2i = mpz_get_ui (in2);

      for (i = 0; i < numberof (dsi); i++)
	{
	  if (dsi[i].mod != 0)
	    in2i = mpz_get_ui (in2) % dsi[i].mod;

	  (dsi[i].fptr) (ref1, in1, in2i);
	  MPZ_CHECK_FORMAT (ref1);

	  mpz_set (res1, in1);
	  INVOKE_RRS (dsi[i], res1, res1, in2i);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL (dsi, i, in1, in2, NULL);
	}

      if (in2i != 0)	  /* Don't divide by 0.  */
	{
	  for (i = 0; i < numberof (dsi_div); i++)
	    {
	      r1 = (dsi_div[i].fptr) (ref1, in1, in2i);
	      MPZ_CHECK_FORMAT (ref1);

	      mpz_set (res1, in1);
	      r2 = (dsi_div[i].fptr) (res1, res1, in2i);
	      MPZ_CHECK_FORMAT (res1);
	      if (mpz_cmp (ref1, res1) != 0 || r1 != r2)
		FAIL (dsi_div, i, in1, in2, NULL);
	    }

	  for (i = 0; i < numberof (ddsi_div); i++)
	    {
	      r1 = (ddsi_div[i].fptr) (ref1, ref2, in1, in2i);
	      MPZ_CHECK_FORMAT (ref1);

	      mpz_set (res1, in1);
	      r2 = (ddsi_div[i].fptr) (res1, res2, res1, in2i);
	      MPZ_CHECK_FORMAT (res1);
	      if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || r1 != r2)
		FAIL (ddsi_div, i, in1, in2, NULL);

	      mpz_set (res2, in1);
	      (ddsi_div[i].fptr) (res1, res2, res2, in2i);
	      MPZ_CHECK_FORMAT (res1);
	      if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || r1 != r2)
		FAIL (ddsi_div, i, in1, in2, NULL);
	    }
	}

      if (mpz_sgn (in1) >= 0)
	{
	  mpz_sqrtrem (ref1, ref2, in1);
	  MPZ_CHECK_FORMAT (ref1);
	  MPZ_CHECK_FORMAT (ref2);

	  mpz_set (res1, in1);
	  mpz_sqrtrem (res1, res2, res1);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
	    FAIL2 (mpz_sqrtrem, in1, NULL, NULL);

	  mpz_set (res2, in1);
	  mpz_sqrtrem (res1, res2, res2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
	    FAIL2 (mpz_sqrtrem, in1, NULL, NULL);

	  mpz_set (res1, in1);
	  mpz_sqrtrem (res1, res1, res1);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref2, res1) != 0)
	    FAIL2 (mpz_sqrtrem, in1, NULL, NULL);
	}

      if (mpz_sgn (in1) >= 0)
	{
	  mpz_root (ref1, in1, in2i % 0x100 + 1);
	  MPZ_CHECK_FORMAT (ref1);

	  mpz_set (res1, in1);
	  mpz_root (res1, res1, in2i % 0x100 + 1);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_root, in1, in2, NULL);
	}

      if (mpz_sgn (in1) >= 0)
	{
	  mpz_rootrem (ref1, ref2, in1, in2i % 0x100 + 1);
	  MPZ_CHECK_FORMAT (ref1);
	  MPZ_CHECK_FORMAT (ref2);

	  mpz_set (res1, in1);
	  mpz_rootrem (res1, res2, res1, in2i % 0x100 + 1);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
	    FAIL2 (mpz_rootrem, in1, in2, NULL);

	  mpz_set (res2, in1);
	  mpz_rootrem (res1, res2, res2, in2i % 0x100 + 1);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
	    FAIL2 (mpz_rootrem, in1, in2, NULL);
	}

      if (size_range < 18)	/* run fewer tests since gcdext lots of time */
	{
	  mpz_gcdext (ref1, ref2, ref3, in1, in2);
	  MPZ_CHECK_FORMAT (ref1);
	  MPZ_CHECK_FORMAT (ref2);
	  MPZ_CHECK_FORMAT (ref3);

	  mpz_set (res1, in1);
	  mpz_gcdext (res1, res2, res3, res1, in2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  MPZ_CHECK_FORMAT (res3);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);

	  mpz_set (res2, in1);
	  mpz_gcdext (res1, res2, res3, res2, in2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  MPZ_CHECK_FORMAT (res3);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);

	  mpz_set (res3, in1);
	  mpz_gcdext (res1, res2, res3, res3, in2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  MPZ_CHECK_FORMAT (res3);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);

	  mpz_set (res1, in2);
	  mpz_gcdext (res1, res2, res3, in1, res1);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  MPZ_CHECK_FORMAT (res3);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);

	  mpz_set (res2, in2);
	  mpz_gcdext (res1, res2, res3, in1, res2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  MPZ_CHECK_FORMAT (res3);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);

	  mpz_set (res3, in2);
	  mpz_gcdext (res1, res2, res3, in1, res3);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  MPZ_CHECK_FORMAT (res3);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);

	  mpz_set (res1, in1);
	  mpz_gcdext (res1, res2, NULL, res1, in2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);

	  mpz_set (res2, in1);
	  mpz_gcdext (res1, res2, NULL, res2, in2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);

	  mpz_set (res1, in2);
	  mpz_gcdext (res1, res2, NULL, in1, res1);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);

	  mpz_set (res2, in2);
	  mpz_gcdext (res1, res2, NULL, in1, res2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);
	}

      /* Don't run mpz_powm for huge exponents or when undefined.  */
      if (size_range < 17 && mpz_sizeinbase (in2, 2) < 250 && mpz_sgn (in3) != 0
	  && (mpz_sgn (in2) >= 0 || mpz_invert (t, in1, in3)))
	{
	  mpz_powm (ref1, in1, in2, in3);
	  MPZ_CHECK_FORMAT (ref1);

	  mpz_set (res1, in1);
	  mpz_powm (res1, res1, in2, in3);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_powm, in1, in2, in3);

	  mpz_set (res1, in2);
	  mpz_powm (res1, in1, res1, in3);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_powm, in1, in2, in3);

	  mpz_set (res1, in3);
	  mpz_powm (res1, in1, in2, res1);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_powm, in1, in2, in3);
	}

      /* Don't run mpz_powm_ui when undefined.  */
      if (size_range < 17 && mpz_sgn (in3) != 0)
	{
	  mpz_powm_ui (ref1, in1, in2i, in3);
	  MPZ_CHECK_FORMAT (ref1);

	  mpz_set (res1, in1);
	  mpz_powm_ui (res1, res1, in2i, in3);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_powm_ui, in1, in2, in3);

	  mpz_set (res1, in3);
	  mpz_powm_ui (res1, in1, in2i, res1);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_powm_ui, in1, in2, in3);
	}

      {
	r1 = mpz_gcd_ui (ref1, in1, in2i);
	MPZ_CHECK_FORMAT (ref1);

	mpz_set (res1, in1);
	r2 = mpz_gcd_ui (res1, res1, in2i);
	MPZ_CHECK_FORMAT (res1);
	if (mpz_cmp (ref1, res1) != 0)
	  FAIL2 (mpz_gcd_ui, in1, in2, NULL);
      }

      if (mpz_sgn (in2) != 0)
	{
	  /* Test mpz_remove */
	  mp_bitcnt_t refretval, retval;
	  refretval = mpz_remove (ref1, in1, in2);
	  MPZ_CHECK_FORMAT (ref1);

	  mpz_set (res1, in1);
	  retval = mpz_remove (res1, res1, in2);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0 || refretval != retval)
	    FAIL2 (mpz_remove, in1, in2, NULL);

	  mpz_set (res1, in2);
	  retval = mpz_remove (res1, in1, res1);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0 || refretval != retval)
	    FAIL2 (mpz_remove, in1, in2, NULL);
	}

      if (mpz_sgn (in2) != 0)
	{
	  /* Test mpz_divexact */
	  mpz_mul (t, in1, in2);
	  mpz_divexact (ref1, t, in2);
	  MPZ_CHECK_FORMAT (ref1);

	  mpz_set (res1, t);
	  mpz_divexact (res1, res1, in2);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_divexact, t, in2, NULL);

	  mpz_set (res1, in2);
	  mpz_divexact (res1, t, res1);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_divexact, t, in2, NULL);
	}

      if (mpz_sgn (in2) > 0)
	{
	  /* Test mpz_divexact_gcd, same as mpz_divexact */
	  mpz_mul (t, in1, in2);
	  mpz_divexact_gcd (ref1, t, in2);
	  MPZ_CHECK_FORMAT (ref1);

	  mpz_set (res1, t);
	  mpz_divexact_gcd (res1, res1, in2);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_divexact_gcd, t, in2, NULL);

	  mpz_set (res1, in2);
	  mpz_divexact_gcd (res1, t, res1);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_divexact_gcd, t, in2, NULL);
	}
    }

  if (isatty (fileno (stdout)))
    printf ("\r%20s", "");

  mpz_clear (bs);
  mpz_clear (in1);
  mpz_clear (in2);
  mpz_clear (in3);
  mpz_clear (ref1);
  mpz_clear (ref2);
  mpz_clear (ref3);
  mpz_clear (res1);
  mpz_clear (res2);
  mpz_clear (res3);
  mpz_clear (t);

  if (isatty (fileno (stdout)))
    printf ("\r");

  tests_end ();
  exit (0);
}