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