Súbor: [Platon] / libplaton / utils / server-backend / server-backend-fast.c (stiahnutie)
Revízia 1.1, Wed Oct 16 21:04:54 2002 UTC (20 years, 11 months ago) by nepto
Interactive communication implemented. Use -i switch.
Code split into several parts and redunand added into utils.c file.
server-backend2.[ch] removed, server-backed-fast.c added, they both use
the same header server-backend.h file.
README added with description and compilation notes.
|
/*
* server_backend.c - network server socketing backend
*
* (c) 2001 Ondrej Jombik <nepto@pobox.sk>
*
* History
* - 19/9/2001 - initial release
* - 20/9/2001 - minor bugfixes
* - waitpid() used as substitute of wait()
* - 24/9/2001 - fork() after accept() change (parent <-> child)
* - fnctl() removed
*
* TODO
* - write debug infomations to STDERR
* - ability to enter fake command on command line
*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
/* wait() */
#include <sys/wait.h>
/* struct timeval */
#include <sys/time.h>
/* signal() */
#include <signal.h>
#include "utils.h"
#include "server-backend.h"
int main(int argc, char *argv[])
{
register int cur_arg;
int port, f_interactive = 0;
int listen_sock;
char **process;
if (argc < 3) {
fprintf(stderr, "Usage:\n"
" %s <port> <process> <arg1> ... <argN>\n"
" %s -i <port>\n",
PROG_NAME, PROG_NAME);
return 1;
}
cur_arg = 1;
if (! strcmp(argv[cur_arg], "-i")) {
f_interactive = 1;
cur_arg++;
}
port = get_port(argv[cur_arg]);
cur_arg++;
if (f_interactive && 0) {
process = NULL;
} else {
if ((process = create_process_array(argc, argv, cur_arg)) == NULL) {
perror(PROG_NAME);
return 32;
}
}
fake_command_line(argc, argv);
if ((listen_sock = bind_to_port(port)) == -1) {
perror(PROG_NAME);
return 16;
}
if (1) {
(void) setpgrp();
signal(SIGHUP, SIG_IGN);
}
if (0)
fcntl(listen_sock,F_SETFL,O_NDELAY);
switch (f_interactive ? 1 : fork()) {
case -1:
perror(PROG_NAME);
return errno;
break;
case 0:
break;
default:
fprintf(stderr, "%s: accepting connections on port %d\n",
PROG_NAME, port);
if (f_interactive)
fprintf(stderr, "%s: interactive mode enabled,"
" waiting for first client\n", PROG_NAME);
else
return 0;
break;
}
while (1) {
struct sockaddr_in acc_addr;
unsigned int size;
int accept_sock;
sleep(1);
size = sizeof(struct sockaddr_in);
accept_sock = accept(listen_sock, (struct sockaddr*) &acc_addr, &size);
if (accept_sock < 0) {
perror(PROG_NAME);
return errno;
}
if (f_interactive) {
fprintf(stderr, "%s: new client connected from %s\n",
PROG_NAME, (char*)inet_ntoa(acc_addr.sin_addr));
fprintf(stderr, "%s: you can now communicate via socket no. %d\n",
PROG_NAME, accept_sock);
}
if (accept_sock > 0) {
switch (f_interactive ? 1 : fork()) {
case -1:
perror(PROG_NAME);
return errno;
break;
case 0: /* child */
close(accept_sock);
break;
default: /* parent */
if (! f_interactive) {
dup2(accept_sock, 0);
dup2(accept_sock, 1);
dup2(accept_sock, 2);
close(listen_sock);
close(accept_sock);
execvp(process[0], process);
write(accept_sock, "execlp() failure\n\r", 18);
return 8;
}
if (do_interactive(accept_sock) < 0) {
perror(PROG_NAME);
return 8;
}
return 0;
}
}
} /* while (1) */
return 0;
}
Platon Group <platon@platon.sk> http://platon.sk/
|