blob: 98dba079007cac83fccb3101baf25044147c123d [file] [log] [blame]
/*
* Copyright (c) International Business Machines Corp., 2001
*
* This program 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 2 of the License, or
* (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* File: pthserv.c Version: 1.3 Last update: 5/19/94 08:55:35
*/
/******************************************************************************/
/* File: pthserv.c */
/* */
/* Description: Read a stream socket one line at a time and write each line */
/* back to the sender. */
/* */
/* History: Contact - 06/21/2001 - Manoj Iyeri, IBM Austin */
/* */
/* Usage: pthcli [port number] */
/* */
/******************************************************************************/
/*
TCP server
*/
#include <pthread.h>
#include <string.h>
#include "inet.h"
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#define MAXLINE 1024
void noprintf(char* string, ...) {
}
pthread_t th;
pthread_mutex_t current_mutex;
int sockfd;
/* Read a stream socket one line at a time and write each line back
to sender. Return when connection is terminated */
int str_echo(sockfd)
int sockfd;
{
int n, testint;
char line[MAXLINE];
printf("sockfd = %d\n", sockfd);
for (; ;)
{
prtln();
dprt2(("%s: str_echo(): reading from sockfd %d\n", __FILE__, sockfd));
n = readline(sockfd, line, MAXLINE);
printf("str_echo: n = %d\n",n);
if (n == 0)
{
dprt2(("%s: str_echo(): connection terminated\n", __FILE__));
return 0; /* connection terminated */
}
else if (n < 0)
{
perror("str_echo: readline error");
return(-1);
}
dprt2(("%s: str_echo(): writing to sockfd = %d\n", __FILE__, sockfd));
testint = writen(sockfd, line, n);
prtln();
if (testint != n)
{
perror("str_echo: writen error");
return(-1);
}
prtln();
}
}
int
main(int argc, char *argv[])
{
void *new_thread(void*);
pthread_attr_t newattr;
int newsockfd;
socklen_t clilen;
struct sockaddr_in cli_addr, serv_addr;
pname = argv[0];
prtln();
/* Open inet stream socket */
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) <0)
{
printf("server: socket failure:");
exit(1);
}
prtln();
dprt2(("%s: main(): Open inet stream socket sockfd = %d\n", __FILE__, sockfd));
/* Bind local address for client to use */
memset((char *) &serv_addr, 0x00, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY) ;
serv_addr.sin_port = htons(SERV_TCP_PORT);
prtln();
dprt2(("%s: main(): Binding local address for client to use\n"
"serv_addr.sin_family = %d\n serv_addr.sin_addr.s_addr = %#x\n"
"serv_addr.sin_port = %d\n", __FILE__, serv_addr.sin_family,
serv_addr.sin_addr.s_addr, serv_addr.sin_port));
prtln();
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
{
printf("server bind failure:\n");
fflush(NULL);
exit(1);
}
prtln();
if (pthread_mutex_init(&current_mutex, NULL) != 0)
printf("current_mutex_init() failure");
prtln();
/* attr init, detached state create thread */
if (pthread_attr_init(&newattr))
printf("failure to init attributes\n");
if (pthread_attr_setdetachstate(&newattr,PTHREAD_CREATE_DETACHED))
printf("failure to set detached state\n");
prtln();
listen(sockfd, 5);
prtln();
for (; ;)
{
/* Wait for connection from a client process */
clilen = sizeof(cli_addr);
newsockfd = accept (sockfd, (struct sockaddr *) &cli_addr, &clilen);
prtln();
if (newsockfd < 0)
{
perror("server: accept");
printf("server: accept error");
exit(1);
}
else /* create thread to handle client request */
{
if (pthread_create(&th, &newattr, new_thread,
(void *)(uintptr_t)newsockfd))
printf("failure to create thread\n");
#ifndef _LINUX
yield();
#else
sched_yield();
#endif
}
prtln();
}
close(sockfd);
}
void *
new_thread(void* arg_)
{
int arg=(uintptr_t)arg_;
if (pthread_mutex_lock (&current_mutex))
printf("mutex_lock failed");
if (str_echo(arg) < 0) /* process the request */
printf("new_thread: str_echo returned error");
close(arg); /* i.e. newsockfd*/
if (pthread_mutex_unlock (&current_mutex))
printf("mutex_unlock failed");
#ifndef _LINUX
yield();
#else
sched_yield();
#endif
pthread_exit ( (void *) 0);
}