コード例 #1
0
ファイル: socket.c プロジェクト: zaiah-dj/lite
/* This definition is stupid.  Think of something better */
SOCKET *
NEW(socket) (SOCKET *sk, int type, int domain, int proto, char sr, unsigned int port, const char *hostname, void *ssl_ctx)
{
	/* Object allocation */
	iiprintf(SOCKET);
	SOCKET *s;
	socket_t *sock;

	/* Check memory */
	if (!sk) {
		if (!(s = nalloc(sizeof(SOCKET), "socket.object")))
			return NULL;

		if (!(sock = (socket_t *)nalloc(sizeof(socket_t), "socket.socket")))
		{
			free(s);
			return NULL;
		}
		memset(sock, 0, sizeof(socket_t));
	}
	else {
		s = sk;
		sock = sk->data;
		memset(sock, 0, sizeof(socket_t));
	}

	/* All of this can be done with a macro */
	sock->buffer = NULL;
	sock->connection_type = type;
	sock->domain = domain;
	sock->protocol = proto;
	sock->addrsize = sizeof(struct sockaddr);
	sock->bufsz = 1024;
	sock->opened = 0;
	sock->backlog = 500;
	sock->waittime = 5000;  // 3000 microseconds
	sock->hostname = !hostname ? NULL : (char *)hostname;

	/* Check port number (clients are zero until a request is made) */
	if (port < 0 || port > 65536) {
		/* Free allocated socket */
		vvprintf("Invalid port specified.");
		return errnull("Invalid port specified.");
	}
	else if (!port)
		sock->port = 0;
	else
		sock->port = port;

#if 0	
	/* Service check (part of struct in the future) */
	fprintf(stderr, "Checking that port binds to a real service...");
	if (!services[port])
		sock->service = "UNKNOWN";
	else
		sock->service = (char *)services[port];
#endif

	/* Set up the address data structure for use as either client or server */	
	sock->_class = sr;
	if (sock->_class == 's')
	{
		if ((sock->srvaddrinfo = (struct sockaddr_in *)nalloc(sizeof(struct sockaddr_in), "sockaddr.info")) == NULL)
			return errnull("Could not allocate structure specified.");

		/* Some type of gethosting must be done */
		memset(sock->srvaddrinfo, 0, sizeof(struct sockaddr_in));
		struct sockaddr_in *saa = sock->srvaddrinfo; 
		saa->sin_family = AF_INET;
		saa->sin_port = htons(sock->port);
		/* A smart string function can decide whether or not this is IPv6 */
		(&saa->sin_addr)->s_addr = htonl(INADDR_ANY);
	}
	else if (sock->_class == 'c') 
	{
		/* Set up the addrinfo structure for a future client request. */
		struct addrinfo *h; 
		memset(&sock->hints, 0, sizeof(sock->hints));
		h = &sock->hints;
		h->ai_family = sock->domain;
		h->ai_socktype = sock->connection_type;
	}

	#if 0
	/* Show the buffer pointer... */
	fprintf(stderr, "tcp socket buffer: %p (%s)\n", sock->buffer,
		sock->_class == 'c' ? "client" : \
			sock->_class == 'd' ? "child" : "server");
	#endif


	/* Set up an SSL context if asked. */
	if (!ssl_ctx)
		sock->ssl_ctx = NULL;
	else
		sock->ssl_ctx = ssl_ctx;


	/* Finally, create a socket. */
	sock->fd = socket(sock->domain, sock->connection_type, sock->protocol);
	sock->opened = 1;


	/* Set timeout, reusable bit and any other options */
	struct timeval to;
	to.tv_sec = 2;
	to.tv_usec = 0;
	if (setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, &to, sizeof(to)) == -1) {
		// sock->free(sock);
		errsys("Could not reopen socket.");
		return NULL;
	}


	/* Set private data */
	s->data = sock;        /* Set the socket info as part of the object. */
	s->data->urn = NULL;   /* Set the URN to NULL */

	/* The standard */
	s->free = &__free;
	s->info = &__printf;

	/* The rest */
	s->connect = &__connect;
	s->bind = &__bind;
	s->listen = &__listen;
	s->accept = &__accept;
	s->shutdown = &__shutdown;
	s->close = &__close;
	s->send = &__send;
	s->recv = &__recv;
	s->addrinfo = &__addrinfo;
	s->recvd = &recvd;
	s->parsed = &parsed;
	s->release = &__release;
	return INITIALIZED(s);
}
コード例 #2
0
ファイル: digamma.c プロジェクト: epowers/mpfr
/* Put in s an approximation of digamma(x).
   Assumes x >= 2.
   Assumes s does not overlap with x.
   Returns an integer e such that the error is bounded by 2^e ulps
   of the result s.
*/
static mpfr_exp_t
mpfr_digamma_approx (mpfr_ptr s, mpfr_srcptr x)
{
  mpfr_prec_t p = MPFR_PREC (s);
  mpfr_t t, u, invxx;
  mpfr_exp_t e, exps, f, expu;
  mpz_t *INITIALIZED(B);  /* variable B declared as initialized */
  unsigned long n0, n; /* number of allocated B[] */

  MPFR_ASSERTN(MPFR_IS_POS(x) && (MPFR_EXP(x) >= 2));

  mpfr_init2 (t, p);
  mpfr_init2 (u, p);
  mpfr_init2 (invxx, p);

  mpfr_log (s, x, MPFR_RNDN);         /* error <= 1/2 ulp */
  mpfr_ui_div (t, 1, x, MPFR_RNDN);   /* error <= 1/2 ulp */
  mpfr_div_2exp (t, t, 1, MPFR_RNDN); /* exact */
  mpfr_sub (s, s, t, MPFR_RNDN);
  /* error <= 1/2 + 1/2*2^(EXP(olds)-EXP(s)) + 1/2*2^(EXP(t)-EXP(s)).
     For x >= 2, log(x) >= 2*(1/(2x)), thus olds >= 2t, and olds - t >= olds/2,
     thus 0 <= EXP(olds)-EXP(s) <= 1, and EXP(t)-EXP(s) <= 0, thus
     error <= 1/2 + 1/2*2 + 1/2 <= 2 ulps. */
  e = 2; /* initial error */
  mpfr_mul (invxx, x, x, MPFR_RNDZ);     /* invxx = x^2 * (1 + theta)
                                            for |theta| <= 2^(-p) */
  mpfr_ui_div (invxx, 1, invxx, MPFR_RNDU); /* invxx = 1/x^2 * (1 + theta)^2 */

  /* in the following we note err=xxx when the ratio between the approximation
     and the exact result can be written (1 + theta)^xxx for |theta| <= 2^(-p),
     following Higham's method */
  B = mpfr_bernoulli_internal ((mpz_t *) 0, 0);
  mpfr_set_ui (t, 1, MPFR_RNDN); /* err = 0 */
  for (n = 1;; n++)
    {
      /* compute next Bernoulli number */
      B = mpfr_bernoulli_internal (B, n);
      /* The main term is Bernoulli[2n]/(2n)/x^(2n) = B[n]/(2n+1)!(2n)/x^(2n)
         = B[n]*t[n]/(2n) where t[n]/t[n-1] = 1/(2n)/(2n+1)/x^2. */
      mpfr_mul (t, t, invxx, MPFR_RNDU);        /* err = err + 3 */
      mpfr_div_ui (t, t, 2 * n, MPFR_RNDU);     /* err = err + 1 */
      mpfr_div_ui (t, t, 2 * n + 1, MPFR_RNDU); /* err = err + 1 */
      /* we thus have err = 5n here */
      mpfr_div_ui (u, t, 2 * n, MPFR_RNDU);     /* err = 5n+1 */
      mpfr_mul_z (u, u, B[n], MPFR_RNDU);       /* err = 5n+2, and the
                                                   absolute error is bounded
                                                   by 10n+4 ulp(u) [Rule 11] */
      /* if the terms 'u' are decreasing by a factor two at least,
         then the error coming from those is bounded by
         sum((10n+4)/2^n, n=1..infinity) = 24 */
      exps = mpfr_get_exp (s);
      expu = mpfr_get_exp (u);
      if (expu < exps - (mpfr_exp_t) p)
        break;
      mpfr_sub (s, s, u, MPFR_RNDN); /* error <= 24 + n/2 */
      if (mpfr_get_exp (s) < exps)
        e <<= exps - mpfr_get_exp (s);
      e ++; /* error in mpfr_sub */
      f = 10 * n + 4;
      while (expu < exps)
        {
          f = (1 + f) / 2;
          expu ++;
        }
      e += f; /* total rouding error coming from 'u' term */
    }

  n0 = ++n;
  while (n--)
    mpz_clear (B[n]);
  (*__gmp_free_func) (B, n0 * sizeof (mpz_t));

  mpfr_clear (t);
  mpfr_clear (u);
  mpfr_clear (invxx);

  f = 0;
  while (e > 1)
    {
      f++;
      e = (e + 1) / 2;
      /* Invariant: 2^f * e does not decrease */
    }
  return f;
}