1f08c3bdfSopenharmony_ci/* 2f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2001 3f08c3bdfSopenharmony_ci * 4f08c3bdfSopenharmony_ci * This program is free software; you can redistribute it and/or modify 5f08c3bdfSopenharmony_ci * it under the terms of the GNU General Public License as published by 6f08c3bdfSopenharmony_ci * the Free Software Foundation; either version 2 of the License, or 7f08c3bdfSopenharmony_ci * (at your option) any later version. 8f08c3bdfSopenharmony_ci * 9f08c3bdfSopenharmony_ci * This program is distributed in the hope that it will be useful, 10f08c3bdfSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 11f08c3bdfSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 12f08c3bdfSopenharmony_ci * the GNU General Public License for more details. 13f08c3bdfSopenharmony_ci * 14f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License 15f08c3bdfSopenharmony_ci * along with this program; if not, write to the Free Software 16f08c3bdfSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17f08c3bdfSopenharmony_ci */ 18f08c3bdfSopenharmony_ci/* 19f08c3bdfSopenharmony_ci* File: pthserv.c Version: 1.3 Last update: 5/19/94 08:55:35 20f08c3bdfSopenharmony_ci*/ 21f08c3bdfSopenharmony_ci/******************************************************************************/ 22f08c3bdfSopenharmony_ci/* File: pthserv.c */ 23f08c3bdfSopenharmony_ci/* */ 24f08c3bdfSopenharmony_ci/* Description: Read a stream socket one line at a time and write each line */ 25f08c3bdfSopenharmony_ci/* back to the sender. */ 26f08c3bdfSopenharmony_ci/* */ 27f08c3bdfSopenharmony_ci/* History: Contact - 06/21/2001 - Manoj Iyeri, IBM Austin */ 28f08c3bdfSopenharmony_ci/* */ 29f08c3bdfSopenharmony_ci/* Usage: pthcli [port number] */ 30f08c3bdfSopenharmony_ci/* */ 31f08c3bdfSopenharmony_ci/******************************************************************************/ 32f08c3bdfSopenharmony_ci 33f08c3bdfSopenharmony_ci/* 34f08c3bdfSopenharmony_ci TCP server 35f08c3bdfSopenharmony_ci*/ 36f08c3bdfSopenharmony_ci 37f08c3bdfSopenharmony_ci#include <pthread.h> 38f08c3bdfSopenharmony_ci#include <string.h> 39f08c3bdfSopenharmony_ci#include "inet.h" 40f08c3bdfSopenharmony_ci#include <stdlib.h> 41f08c3bdfSopenharmony_ci#include <unistd.h> 42f08c3bdfSopenharmony_ci#include <stdint.h> 43f08c3bdfSopenharmony_ci 44f08c3bdfSopenharmony_ci#define MAXLINE 1024 45f08c3bdfSopenharmony_civoid noprintf(char *string, ...) 46f08c3bdfSopenharmony_ci{ 47f08c3bdfSopenharmony_ci} 48f08c3bdfSopenharmony_ci 49f08c3bdfSopenharmony_cipthread_t th; 50f08c3bdfSopenharmony_cipthread_mutex_t current_mutex; 51f08c3bdfSopenharmony_ciint sockfd; 52f08c3bdfSopenharmony_ci 53f08c3bdfSopenharmony_ci/* Read a stream socket one line at a time and write each line back 54f08c3bdfSopenharmony_ci to sender. Return when connection is terminated */ 55f08c3bdfSopenharmony_ci 56f08c3bdfSopenharmony_ciint str_echo(int sockfd) 57f08c3bdfSopenharmony_ci{ 58f08c3bdfSopenharmony_ci int n, testint; 59f08c3bdfSopenharmony_ci char line[MAXLINE]; 60f08c3bdfSopenharmony_ci 61f08c3bdfSopenharmony_ci printf("sockfd = %d\n", sockfd); 62f08c3bdfSopenharmony_ci for (;;) { 63f08c3bdfSopenharmony_ci prtln(); 64f08c3bdfSopenharmony_ci dprt2(("%s: str_echo(): reading from sockfd %d\n", __FILE__, 65f08c3bdfSopenharmony_ci sockfd)); 66f08c3bdfSopenharmony_ci n = readline(sockfd, line, MAXLINE); 67f08c3bdfSopenharmony_ci printf("str_echo: n = %d\n", n); 68f08c3bdfSopenharmony_ci if (n == 0) { 69f08c3bdfSopenharmony_ci dprt2(("%s: str_echo(): connection terminated\n", 70f08c3bdfSopenharmony_ci __FILE__)); 71f08c3bdfSopenharmony_ci return 0; /* connection terminated */ 72f08c3bdfSopenharmony_ci } else if (n < 0) { 73f08c3bdfSopenharmony_ci perror("str_echo: readline error"); 74f08c3bdfSopenharmony_ci return (-1); 75f08c3bdfSopenharmony_ci } 76f08c3bdfSopenharmony_ci dprt2(("%s: str_echo(): writing to sockfd = %d\n", __FILE__, 77f08c3bdfSopenharmony_ci sockfd)); 78f08c3bdfSopenharmony_ci testint = writen(sockfd, line, n); 79f08c3bdfSopenharmony_ci prtln(); 80f08c3bdfSopenharmony_ci if (testint != n) { 81f08c3bdfSopenharmony_ci perror("str_echo: writen error"); 82f08c3bdfSopenharmony_ci return (-1); 83f08c3bdfSopenharmony_ci } 84f08c3bdfSopenharmony_ci prtln(); 85f08c3bdfSopenharmony_ci } 86f08c3bdfSopenharmony_ci} 87f08c3bdfSopenharmony_ci 88f08c3bdfSopenharmony_ciint main(int argc, char *argv[]) 89f08c3bdfSopenharmony_ci{ 90f08c3bdfSopenharmony_ci void *new_thread(void *); 91f08c3bdfSopenharmony_ci pthread_attr_t newattr; 92f08c3bdfSopenharmony_ci int newsockfd; 93f08c3bdfSopenharmony_ci socklen_t clilen; 94f08c3bdfSopenharmony_ci struct sockaddr_in cli_addr, serv_addr; 95f08c3bdfSopenharmony_ci pname = argv[0]; 96f08c3bdfSopenharmony_ci 97f08c3bdfSopenharmony_ci (void) argc; 98f08c3bdfSopenharmony_ci prtln(); 99f08c3bdfSopenharmony_ci /* Open inet stream socket */ 100f08c3bdfSopenharmony_ci if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 101f08c3bdfSopenharmony_ci printf("server: socket failure:"); 102f08c3bdfSopenharmony_ci exit(1); 103f08c3bdfSopenharmony_ci } 104f08c3bdfSopenharmony_ci prtln(); 105f08c3bdfSopenharmony_ci dprt2(("%s: main(): Open inet stream socket sockfd = %d\n", __FILE__, 106f08c3bdfSopenharmony_ci sockfd)); 107f08c3bdfSopenharmony_ci 108f08c3bdfSopenharmony_ci /* Bind local address for client to use */ 109f08c3bdfSopenharmony_ci memset((char *)&serv_addr, 0x00, sizeof(serv_addr)); 110f08c3bdfSopenharmony_ci serv_addr.sin_family = AF_INET; 111f08c3bdfSopenharmony_ci serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); 112f08c3bdfSopenharmony_ci serv_addr.sin_port = htons(SERV_TCP_PORT); 113f08c3bdfSopenharmony_ci prtln(); 114f08c3bdfSopenharmony_ci dprt2(("%s: main(): Binding local address for client to use\n" 115f08c3bdfSopenharmony_ci "serv_addr.sin_family = %d\n serv_addr.sin_addr.s_addr = %#x\n" 116f08c3bdfSopenharmony_ci "serv_addr.sin_port = %d\n", __FILE__, serv_addr.sin_family, 117f08c3bdfSopenharmony_ci serv_addr.sin_addr.s_addr, serv_addr.sin_port)); 118f08c3bdfSopenharmony_ci 119f08c3bdfSopenharmony_ci prtln(); 120f08c3bdfSopenharmony_ci if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { 121f08c3bdfSopenharmony_ci printf("server bind failure:\n"); 122f08c3bdfSopenharmony_ci fflush(NULL); 123f08c3bdfSopenharmony_ci exit(1); 124f08c3bdfSopenharmony_ci } 125f08c3bdfSopenharmony_ci 126f08c3bdfSopenharmony_ci prtln(); 127f08c3bdfSopenharmony_ci if (pthread_mutex_init(¤t_mutex, NULL) != 0) 128f08c3bdfSopenharmony_ci printf("current_mutex_init() failure"); 129f08c3bdfSopenharmony_ci prtln(); 130f08c3bdfSopenharmony_ci 131f08c3bdfSopenharmony_ci /* attr init, detached state create thread */ 132f08c3bdfSopenharmony_ci if (pthread_attr_init(&newattr)) 133f08c3bdfSopenharmony_ci printf("failure to init attributes\n"); 134f08c3bdfSopenharmony_ci if (pthread_attr_setdetachstate(&newattr, PTHREAD_CREATE_DETACHED)) 135f08c3bdfSopenharmony_ci printf("failure to set detached state\n"); 136f08c3bdfSopenharmony_ci prtln(); 137f08c3bdfSopenharmony_ci listen(sockfd, 5); 138f08c3bdfSopenharmony_ci 139f08c3bdfSopenharmony_ci prtln(); 140f08c3bdfSopenharmony_ci for (;;) { 141f08c3bdfSopenharmony_ci /* Wait for connection from a client process */ 142f08c3bdfSopenharmony_ci clilen = sizeof(cli_addr); 143f08c3bdfSopenharmony_ci 144f08c3bdfSopenharmony_ci newsockfd = 145f08c3bdfSopenharmony_ci accept(sockfd, (struct sockaddr *)&cli_addr, &clilen); 146f08c3bdfSopenharmony_ci prtln(); 147f08c3bdfSopenharmony_ci if (newsockfd < 0) { 148f08c3bdfSopenharmony_ci perror("server: accept"); 149f08c3bdfSopenharmony_ci printf("server: accept error"); 150f08c3bdfSopenharmony_ci exit(1); 151f08c3bdfSopenharmony_ci } else { /* create thread to handle client request */ 152f08c3bdfSopenharmony_ci 153f08c3bdfSopenharmony_ci if (pthread_create(&th, &newattr, new_thread, 154f08c3bdfSopenharmony_ci (void *)(uintptr_t) newsockfd)) 155f08c3bdfSopenharmony_ci printf("failure to create thread\n"); 156f08c3bdfSopenharmony_ci#ifndef _LINUX 157f08c3bdfSopenharmony_ci yield(); 158f08c3bdfSopenharmony_ci#else 159f08c3bdfSopenharmony_ci sched_yield(); 160f08c3bdfSopenharmony_ci#endif 161f08c3bdfSopenharmony_ci } 162f08c3bdfSopenharmony_ci prtln(); 163f08c3bdfSopenharmony_ci } 164f08c3bdfSopenharmony_ci close(sockfd); 165f08c3bdfSopenharmony_ci} 166f08c3bdfSopenharmony_ci 167f08c3bdfSopenharmony_civoid *new_thread(void *arg_) 168f08c3bdfSopenharmony_ci{ 169f08c3bdfSopenharmony_ci int arg = (uintptr_t) arg_; 170f08c3bdfSopenharmony_ci if (pthread_mutex_lock(¤t_mutex)) 171f08c3bdfSopenharmony_ci printf("mutex_lock failed"); 172f08c3bdfSopenharmony_ci if (str_echo(arg) < 0) /* process the request */ 173f08c3bdfSopenharmony_ci printf("new_thread: str_echo returned error"); 174f08c3bdfSopenharmony_ci close(arg); /* i.e. newsockfd */ 175f08c3bdfSopenharmony_ci if (pthread_mutex_unlock(¤t_mutex)) 176f08c3bdfSopenharmony_ci printf("mutex_unlock failed"); 177f08c3bdfSopenharmony_ci#ifndef _LINUX 178f08c3bdfSopenharmony_ci yield(); 179f08c3bdfSopenharmony_ci#else 180f08c3bdfSopenharmony_ci sched_yield(); 181f08c3bdfSopenharmony_ci#endif 182f08c3bdfSopenharmony_ci pthread_exit(NULL); 183f08c3bdfSopenharmony_ci} 184