<commit_before>/*
 * (C)opyright MMIV-MMVI <NAME> <<EMAIL>>
 * See LICENSE file for license details.
 */

#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

#include "ixp.h"

static unsigned char *msg[IXP_MAX_MSG];

IXPConn *ixp_server_open_conn(IXPServer *s, int fd, void (*read)(IXPConn *c),
		void (*close)(IXPConn *c))
{
	IXPConn *c = cext_emallocz(sizeof(IXPConn));
	c->fd = fd;
	c->srv = s;
	c->read = read;
	c->close = close;
	c->next = s->conn;
	s->conn = c;
	return c;
}

void
ixp_server_close_conn(IXPConn *c)
{
	IXPServer *s = c->srv;
	IXPConn **tc;
	IXPMap *m;
	for(tc=&s->conn; *tc && *tc != c; tc=&(*tc)->next);
	cext_assert(*tc == c);
	*tc = c->next;
	while((m = c->map)) {
		c->map = m->next;
		free(m);
	}
	shutdown(c->fd, SHUT_RDWR);
	close(c->fd);
	free(c);
}

static void
prepare_select(IXPServer *s)
{
	IXPConn *c;
	FD_ZERO(&s->rd);
	for(c=s->conn; c; c=c->next) {
		if(s->maxfd < c->fd)
			s->maxfd = c->fd;
		if(c->read)
			FD_SET(c->fd, &s->rd);
	}
}

static void
handle_conns(IXPServer *s)
{
	IXPConn *c;
	for(c=s->conn; c; c=c->next)
		if(FD_ISSET(c->fd, &s->rd) && c->read)
			/* call read handler */
			c->read(c);
}

char *
ixp_server_loop(IXPServer *s)
{
	int r;
	s->running = 1;

	/* main loop */
	while(s->running) {
		prepare_select(s);

		r = select(s->maxfd + 1, &s->rd, 0, 0, 0);
		if(r == -1 && errno == EINTR)
			continue;
		if(r < 0)
			return "fatal select error";
		else if(r > 0)
			handle_conns(s);<commit_msg>fixed handle_conns to prevent the crashing bug<commit_after>/*
 * (C)opyright MMIV-MMVI <NAME> <<EMAIL> at <EMAIL>>
 * See LICENSE file for license details.
 */

#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

#include "ixp.h"

static unsigned char *msg[IXP_MAX_MSG];

IXPConn *ixp_server_open_conn(IXPServer *s, int fd, void (*read)(IXPConn *c),
		void (*close)(IXPConn *c))
{
	IXPConn *c = cext_emallocz(sizeof(IXPConn));
	c->fd = fd;
	c->srv = s;
	c->read = read;
	c->close = close;
	c->next = s->conn;
	s->conn = c;
	return c;
}

void
ixp_server_close_conn(IXPConn *c)
{
	IXPServer *s = c->srv;
	IXPConn **tc;
	IXPMap *m;
	for(tc=&s->conn; *tc && *tc != c; tc=&(*tc)->next);
	cext_assert(*tc == c);
	*tc = c->next;
	while((m = c->map)) {
		c->map = m->next;
		free(m);
	}
	shutdown(c->fd, SHUT_RDWR);
	close(c->fd);
	free(c);
}

static void
prepare_select(IXPServer *s)
{
	IXPConn *c;
	FD_ZERO(&s->rd);
	for(c=s->conn; c; c=c->next) {
		if(s->maxfd < c->fd)
			s->maxfd = c->fd;
		if(c->read)
			FD_SET(c->fd, &s->rd);
	}
}

static void
handle_conns(IXPServer *s)
{
	IXPConn *c = s->conn, *n;
	while(c) {
		n = c->next;
		if(FD_ISSET(c->fd, &s->rd) && c->read)
			/* call read handler */
			c->read(c);
		c = n;
	}
}

char *
ixp_server_loop(IXPServer *s)
{
	int r;
	s->running = 1;

	/* main loop */
	while(s->running) {
		prepare_select(s);

		r = select(s->maxfd + 1, &s->rd, 0, 0, 0);
		if(r == -1 && errno == EINTR)
			continue;
		if(r < 0)
			return "fatal select error";
		else if(r > 0)
			handle_conns(s);
{'fraction_non_alphanumeric': 0.21805428484293993, 'fraction_numerical': 0.004879536444037816, 'mean_word_length': 3.549237170596394, 'pattern_counts': {'":': 0, '<': 34, '<?xml version=': 0, '>': 104, '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': '3167161', 'n_tokens_mistral': 1633, 'n_tokens_neox': 1549, 'n_words': 329}