Hello people,
 Here I was writing some code(just for testing purposes) which is supposed
to sit and listen to some certain port on machine, and when gets
connection, just pass some text file there. (in attached file, apache's
access_log file). Originally I was writing this on BSD machine(FreeBSD
2.2.5) and things worked just fine. I brought it to some linux(redhat 4.1
kernel 2.0.29,libc 5.3.*) and weird things happen:
 When I either compile it with loggin' mode (so file with fd=0 is opened)
or run the code with -d switch (so it doesn't close stdin/stdout/stderr at
all) things work just fine. (as on BSD), but when I compile it with no
LOGGING and DEBUG mode, and run with no -d switch (so all file descriptors
are closed). The code hangs up somewhere.(but port isn't listened). I run
gdb attach process, and gdb says that code sits in accept function. I
wonder if that's just Linux implementation of accept which would want
descriptor=0 being opened or something?.. I attached both pieces of code,
if anyone would want to play with it.

 Would be greateful for any hints
 Fyodor


#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <netinet/in.h>


#define LISTEN_PORT 2000
#define SHARE_FILE "/usr/local/etc/httpd/logs/access_log"
#define BUFF_SIZE   256

#ifndef LOGGING
int fopenlog(void)
{ 
        close(0);
        close(1);
        close(2);
        return 1;
}
int flogf(char *str, ... )
{
#ifdef DEBUG
        printf("%s\n",str);
#endif
        return 1;
} 
#else
#include "logging.c"
#endif


int process_connection(int sock_out);

int main(int argc, char **argv)

{
int sock_s,sock_a,sinlen;
int debug=0;
int portnum=LISTEN_PORT;

struct sockaddr_in hostin;
if (argc!=1 && !strncmp(argv[1],"-d",2))
{ printf("invoked in debugging mode\n");
  debug=1;
}
/* if not debugging, deattach from terminal, start our own session */
if (!debug)
{
        if (fork()) exit(1); // parent exits
        if(fopenlog()==-1) exit(-1); // if can't open log file
        setsid();
        chdir("/");
        umask(0x777);
}


sock_s=socket(AF_INET,SOCK_STREAM,0);

#ifdef DEBUG
printf("socket %i created\n",sock_s);
#endif

if (sock_s<0) 
{ 
        flogf("can't create socket\n");
        exit(-1);
}


bzero((char *)&hostin,sizeof(hostin));
hostin.sin_family=AF_INET;
hostin.sin_port=htons(portnum);
hostin.sin_addr.s_addr=INADDR_ANY;


if (bind(sock_s,(struct sockaddr *)&hostin,sizeof(hostin))<0)
        {
                flogf("can't bind socket to %i port\n",portnum);
                close(sock_s);
                exit(-1);
        }
        
#ifdef DEBUG
printf("socket %i binded\n",sock_s);
#endif

if (listen(sock_s,10)<0) 
        { 
                flogf("can't listen to port\n");
                close(sock_s);
                exit(-1);
        }


#ifdef DEBUG
printf("socket %i listened\n",sock_s);
#endif
while(1)
{
        close(sock_a);
        sinlen=sizeof(hostin);

#ifdef DEBUG
        printf("interation is on\n");
#endif
        
        
        sock_a=accept(sock_s,(struct sockaddr*)&hostin,&sinlen);
        if (sock_a<0)
        { flogf("error while accept.Continuing\n");
        continue;
        }
        switch(fork())
        {
                case -1:continue;
                case 0: /* child */
                        process_connection(sock_a);
                        exit(0);
        }
         while(waitpid(-1, NULL, (int) NULL) > 0); 
}
}


int process_connection(int sock_out)
{
        int sock_in;
        char buff[BUFF_SIZE];
        int count;
        sock_in=open(SHARE_FILE,O_RDONLY);
        if (sock_in<0) 
        { flogf("error while opening file\n");
                return -1;
        }
        while (1)
        {
                count=read(sock_in,buff,BUFF_SIZE);
                if (count<1) break; // eof?
                count=write(sock_out,buff,count);
                if (count<1) break; // network connection failed?
        }
        close(sock_in);
        close(sock_out);
        return 1;
}
#define LOG_FILE "server.log"

FILE *forlog;

int fopenlog(void)
{
close(0);
close(1);
close(2);
forlog=fopen(LOG_FILE,"wa");
return 1;
}
int flogf(char *strg, ...)
{

fprintf(forlog,"[server] %s\n",strg);
}

Reply via email to