<commit_before>/**
 * This file is part of libipsc library code.
 *
 * Copyright (C) 2014 <NAME> <<EMAIL>>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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 LICENCE.txt file for more details.
 */
#include "priv.h"

ipsc_t *ipsc_listen( int st, int proto, char *host, uint16_t port, int maxq )
{
	ipsc_t *ipsc = ipsc_init( st, proto, host, port );
	if ( !ipsc )
		return NULL;

	ipsc->maxq = maxq;
	if ( maxq > IPSC_MAX_QUEUE )
		ipsc->maxq = IPSC_MAX_QUEUE;
	if ( maxq < 1 )
		ipsc->maxq = IPSC_MAX_QUEUE_DEFAULT;

	if ( ipsc_bind( ipsc ) )
		goto exit;

	if ( st == SOCK_STREAM && listen( ipsc->sd, ipsc->maxq ) )
		goto exit;

	ipsc->flags |= IPSC_FLAG_SERVER;

	return ipsc;

exit:
	ipsc_close( ipsc );
	return NULL;
}

ipsc_t *ipsc_accept( ipsc_t *ipsc )
{
	if ( !ipsc )
		return NULL;

	ipsc_t *client = (ipsc_t *)malloc( sizeof(ipsc_t) );
	if ( !client )
		return NULL;

	client->sd      = -1;
	client->maxq    = 0;
	client->flags   = 0;
	client->alen    = ipsc->alen;
	client->addr    = (struct sockaddr *)malloc( client->alen );
	client->cb_args = ipsc->cb_args;

	if ( !client->addr )
		goto exit;

	client->sd = accept( ipsc->sd, client->addr,
			     (socklen_t *)&(client->alen) );
	if ( client->sd > 0 )
		return client;

exit:
	ipsc_close( client );
	return NULL;
}

ipsc_t *ipsc_connect( int st, int proto, char *host, uint16_t port )
{
	ipsc_t *ipsc = ipsc_init( st, proto, host, port );
	if ( !ipsc  )
		return NULL;

	if ( !connect( ipsc->sd, ipsc->addr, ipsc->alen ) )
		return ipsc;

	ipsc_close( ipsc );
	return NULL;
}

ssize_t ipsc_send( ipsc_t *ipsc, const void *buf, size_t buflen )
{
	ssize_t sent = 0;
	size_t sent_sum = 0;

	while ( sent_sum < buflen ) {
		sent = send( ipsc->sd, (const char *)buf + sent_sum,
				buflen - sent_sum, MSG_NOSIGNAL );
		if ( sent == -1 ) {
			if ( errno == EAGAIN ||
			     errno == EWOULDBLOCK ||
			     errno == EINTR )
				continue;
			return sent;
		}
		sent_sum += sent;
	}

	return sent_sum;
}

ssize_t ipsc_recv( ipsc_t *ipsc, void *buf,
		   size_t buflen, unsigned int timeout )
{
	ssize_t rb = 0;
	ssize_t recvd = 0;

	if ( ipsc_set_recv_timeout( ipsc, timeout ) )
		return -1;

	while ( !recvd ) {
		rb = recv( ipsc->sd, (char *)buf + recvd, buflen - recvd, 0 );
		if ( rb == -1 ) {
			if ( ( (errno == EAGAIN || errno == EWOULDBLOCK) &&
						timeout == 0 ) ||
						errno == EINTR )
				continue;
			return rb;
		}
		recvd += rb;
	}

	return recvd;
}

int ipsc_epoll_init( ipsc_t *ipsc )
{
	int epfd;

	if ( ipsc_set_nonblock(ipsc) )
		return -1;

	epfd = epoll_create( ipsc->maxq );
	if ( epfd == -1 )
		return -1;<commit_msg>handle remote end connection shutdown on receive<commit_after>/**
 * This file is part of libipsc library code.
 *
 * Copyright (C) 2014 <NAME> <<EMAIL>>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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 LICENCE.txt file for more details.
 */
#include "priv.h"

ipsc_t *ipsc_listen( int st, int proto, char *host, uint16_t port, int maxq )
{
	ipsc_t *ipsc = ipsc_init( st, proto, host, port );
	if ( !ipsc )
		return NULL;

	ipsc->maxq = maxq;
	if ( maxq > IPSC_MAX_QUEUE )
		ipsc->maxq = IPSC_MAX_QUEUE;
	if ( maxq < 1 )
		ipsc->maxq = IPSC_MAX_QUEUE_DEFAULT;

	if ( ipsc_bind( ipsc ) )
		goto exit;

	if ( st == SOCK_STREAM && listen( ipsc->sd, ipsc->maxq ) )
		goto exit;

	ipsc->flags |= IPSC_FLAG_SERVER;

	return ipsc;

exit:
	ipsc_close( ipsc );
	return NULL;
}

ipsc_t *ipsc_accept( ipsc_t *ipsc )
{
	if ( !ipsc )
		return NULL;

	ipsc_t *client = (ipsc_t *)malloc( sizeof(ipsc_t) );
	if ( !client )
		return NULL;

	client->sd      = -1;
	client->maxq    = 0;
	client->flags   = 0;
	client->alen    = ipsc->alen;
	client->addr    = (struct sockaddr *)malloc( client->alen );
	client->cb_args = ipsc->cb_args;

	if ( !client->addr )
		goto exit;

	client->sd = accept( ipsc->sd, client->addr,
			     (socklen_t *)&(client->alen) );
	if ( client->sd > 0 )
		return client;

exit:
	ipsc_close( client );
	return NULL;
}

ipsc_t *ipsc_connect( int st, int proto, char *host, uint16_t port )
{
	ipsc_t *ipsc = ipsc_init( st, proto, host, port );
	if ( !ipsc  )
		return NULL;

	if ( !connect( ipsc->sd, ipsc->addr, ipsc->alen ) )
		return ipsc;

	ipsc_close( ipsc );
	return NULL;
}

ssize_t ipsc_send( ipsc_t *ipsc, const void *buf, size_t buflen )
{
	ssize_t sent = 0;
	size_t sent_sum = 0;

	while ( sent_sum < buflen ) {
		sent = send( ipsc->sd, (const char *)buf + sent_sum,
				buflen - sent_sum, MSG_NOSIGNAL );
		if ( sent == -1 ) {
			if ( errno == EAGAIN ||
			     errno == EWOULDBLOCK ||
			     errno == EINTR )
				continue;
			return sent;
		}
		sent_sum += sent;
	}

	return sent_sum;
}

ssize_t ipsc_recv( ipsc_t *ipsc, void *buf,
		   size_t buflen, unsigned int timeout )
{
	ssize_t rb = 0;
	ssize_t recvd = 0;

	if ( ipsc_set_recv_timeout( ipsc, timeout ) )
		return -1;

	while ( !recvd ) {
		rb = recv( ipsc->sd, (char *)buf + recvd, buflen - recvd, 0 );
		if ( rb < 1 ) {
			if ( ( (errno == EAGAIN || errno == EWOULDBLOCK) &&
						timeout == 0 ) ||
						errno == EINTR )
				continue;
			return rb;
		}
		recvd += rb;
	}

	return recvd;
}

int ipsc_epoll_init( ipsc_t *ipsc )
{
	int epfd;

	if ( ipsc_set_nonblock(ipsc) )
		return -1;

	epfd = epoll_create( ipsc->maxq );
	if ( epfd == -1 )
		return -1;
{'fraction_non_alphanumeric': 0.1333113347632404, 'fraction_numerical': 0.008909420887642303, 'mean_word_length': 3.0252324037184595, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 67, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1288575', 'n_tokens_mistral': 2576, 'n_tokens_neox': 2362, 'n_words': 705}