view lib-src/tcp.c @ 5602:c9e5612f5424

Support the MP library on recent FreeBSD, have it pass relevant tests. src/ChangeLog addition: 2011-11-26 Aidan Kehoe <kehoea@parhasard.net> * number-mp.c (bignum_to_string): Don't overwrite the accumulator we've just set up for this function. * number-mp.c (BIGNUM_TO_TYPE): mp_itom() doesn't necessarily do what this code used to think with negative numbers, it can treat them as unsigned ints. Subtract numbers from bignum_zero instead of multiplying them by -1 to convert them to their negative equivalents. * number-mp.c (bignum_to_int): * number-mp.c (bignum_to_uint): * number-mp.c (bignum_to_long): * number-mp.c (bignum_to_ulong): * number-mp.c (bignum_to_double): Use the changed BIGNUM_TO_TYPE() in these functions. * number-mp.c (bignum_ceil): * number-mp.c (bignum_floor): In these functions, be more careful about rounding to positive and negative infinity, respectively. Don't use the sign of QUOTIENT when working out out whether to add or subtract one, rather use the sign QUOTIENT would have if arbitrary-precision division were done. * number-mp.h: * number-mp.h (MP_GCD): Wrap #include <mp.h> in BEGIN_C_DECLS/END_C_DECLS. * number.c (Fbigfloat_get_precision): * number.c (Fbigfloat_set_precision): Don't attempt to call XBIGFLOAT_GET_PREC if this build doesn't support big floats.
author Aidan Kehoe <kehoea@parhasard.net>
date Sat, 26 Nov 2011 17:59:14 +0000
parents b9167d522a9a
children
line wrap: on
line source

/*
 * TCP/IP stream emulation for XEmacs.
 * Copyright (C) 1988, 1989, 1992, 1993 Free Software Foundation, Inc.

 * Author: Masanobu Umeda
 * Maintainer: umerin@mse.kyutech.ac.jp

This file is part of XEmacs.

XEmacs is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.

XEmacs is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with XEmacs.  If not, see <http://www.gnu.org/licenses/>.

 *
 * Yasunari, Itoh at PFU limited contributed for Fujitsu UTS and SX/A.
 *
 * Thu Apr  6 13:47:37 JST 1989
 * USG fixes by Sakaeda <saka@mickey.trad.pf.fujitsu.junet>
 *
 * For Fujitsu UTS compile with:
 *	cc -O -o tcp tcp.c -DFUJITSU_UTS -lu -lsocket
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/types.h>

#ifdef FUJITSU_UTS
#define USG
#include <sys/ucbtypes.h>
#include <sys/tisp/socket.h>
#include <netdb.h>
#include <sys/tisp/in.h>
#else
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#endif

#ifdef USG
#include <sys/stat.h>
#include "syssignal.h"
#endif

#ifdef USG
int selectable = 1;

sigout ()
{
  fcntl (fileno (stdin), F_SETFL, 0);
  exit (-1);
}
#endif

main (argc, argv)
     int argc;
     char *argv[];
{
  struct hostent	*host;
  struct sockaddr_in	sockin, sockme;
  struct servent	*serv;
  char	*hostname = NULL;
  char	*service = "nntp";
  int	port;
  int	readfds;
  int   writefds;
  int	server;			/* NNTP Server */
  int	emacsIn = fileno (stdin); /* Emacs intput */
  int	emacsOut = fileno (stdout); /* Emacs output */
  char	buffer[1024];
  int	nbuffer;		/* Number of bytes in buffer */
  int   wret;
  char  *retry;			/* retry bufferp */
  int   false = 0;		/* FALSE flag for setsockopt () */

  if (argc < 2)
    {
      fprintf (stderr, "Usage: %s HOST [SERVICE]\n", argv[0]);
      exit (1);
    }
  if (argc >= 2)
    hostname = argv[1];
  if (argc >= 3)
    service = argv[2];

  if ((host = gethostbyname (hostname)) == NULL)
    {
      perror ("gethostbyname");
      exit (1);
    }
  if (isdigit (service[0]))
    port = atoi (service);
  else
    {
      serv = getservbyname (service, "tcp");
      if (serv == NULL)
	{
	  perror ("getservbyname");
	  exit (1);
	}
      port = serv->s_port;
    }

  memset (&sockin, 0, sizeof (sockin));
  sockin.sin_family = host->h_addrtype;
  memcpy (&sockin.sin_addr, host->h_addr, host->h_length);
  sockin.sin_port = port;
  if ((server = socket (AF_INET, SOCK_STREAM, 0)) < 0)
    {
      perror ("socket");
      exit (1);
    }
  if (setsockopt (server, SOL_SOCKET, SO_REUSEADDR, &false, sizeof (false)))
    {
      perror ("setsockopt");
      exit (1);
    }
  memset (&sockme, 0, sizeof (sockme));
  sockme.sin_family = sockin.sin_family;
  sockme.sin_addr.s_addr = INADDR_ANY;
  if (bind (server, &sockme, sizeof (sockme)) < 0)
    {
      perror ("bind");
      exit (1);
    }
  if (connect (server, &sockin, sizeof (sockin)) < 0)
    {
      perror ("connect");
      close (server);
      exit (1);
    }

#ifdef O_NDELAY
  fcntl (server, F_SETFL, O_NDELAY);

#ifdef USG
  /* USG pipe cannot not select emacsIn */
  {
    struct stat statbuf;
    fstat (emacsIn, &statbuf);
    if (statbuf.st_mode & 010000)
      selectable = 0;
    if (!selectable)
      {
	signal (SIGINT, sigout);
	fcntl (emacsIn, F_SETFL, O_NDELAY);
      }
  }
#endif
#endif

  /* Connection established. */
  while (1)
    {
      readfds = (1 << server) | (1 << emacsIn);
      if (select (32, &readfds, NULL, NULL, (struct timeval *)NULL) == -1)
	{
	  perror ("select");
	  exit (1);
	}
      if (readfds & (1 << emacsIn))
	{
	  /* From Emacs */
	  nbuffer = read (emacsIn, buffer, sizeof buffer -1);

#ifdef USG
	  if (selectable && nbuffer == 0)
	    {
	      goto finish;
	    }
	  else if (!(readfds & (1 << server)) && nbuffer == 0)
	    {
	      sleep (1);
	    }
	  else 
#else
	    if (nbuffer == 0)
	      goto finish;
#endif
	  for (retry = buffer; nbuffer > 0; nbuffer -= wret, retry += wret)
	    {
	      writefds = 1 << server;
	      if (select (server+1, NULL, &writefds, NULL, (struct timeval*)NULL) == -1)
		{
		  perror ("select");
		  exit (1);
		}
	      wret = write (server, retry, nbuffer);
	      if (wret < 0) goto finish;
	    }
	}
      if (readfds & (1 << server))
	{
	  /* From NNTP server */
	  nbuffer = read (server, buffer, sizeof buffer -1);
	  if (nbuffer == 0)
	    goto finish;
	  for (retry = buffer; nbuffer > 0; nbuffer -= wret, retry += wret)
	    {
	      writefds = 1 << emacsOut;
#ifdef USG
	      if (selectable)
#endif
		if (select (emacsOut+1, NULL, &writefds, NULL, (struct timeval*)NULL) == -1)
		  {
		    perror ("select");
		    exit (1);
		  }
	      wret = write (emacsOut, retry, nbuffer);
	      if (wret < 0) goto finish;
	    }
	}
    }

  /* End of communication. */
 finish:
  close (server);
#ifdef USG
  if (!selectable) fcntl (emacsIn, F_SETFL, 0);
#endif
  close (emacsIn);
  close (emacsOut);
  exit (0);
}