Well, here i am one more time.

In previos post I asked here about read files. All of those problem were fixed, but now, i really have a problem that I don't know why is happing.

In the first , i need to explain what my system will do:

My system will listen connections on port 8587, and when accept a new connection he will make 2 forks.

Each fork has a purpose, the first will receive the data send for the client, and the last will read the buffer file and send to the client.

Here all the code of main:

int main(int argc, char** argv) {

    /*=========== Variaveis Globais para Main =============================*/

    struct sockaddr_in localaddress; //Estrutura para endereçamento local
    struct sockaddr_in remoteaddress; //Estrutura para endereçamento remoto(cliente)

    int socksvr; //Descritor para socket do servidor
    int lenghtlocaladd; //Tamanho da estrutura de endereçamento local para setar na memoria
    int lenghtremoteadd; //Tamanho da estrutura de endereçamento remoto para setar na memoria


    /*===========Fim Variaveis Globais para Main===========================*/


    /*=========== Flags ====================================*/

    int client = 0; //Descritor de conexao do cliente
    int fbind = -1; //Validador de bind do servidor
    pid_t chield; // Pid do processo filho
    pid_t grandson; //Pid do processo neto

    /*============Fim Flags=================================*/

    /*============ Inicio =====================================*/


    /*Cria descritor de socket para o servidor
     * PF_INET = Tipo de socket para internet
     * SOCK_STREAM = Socket para stream de dados
     * IPPROTO_IP = Flag que determina que o Kernel ira escolher o protocolo */
    socksvr = socket(PF_INET, SOCK_STREAM, IPPROTO_IP);

    //Checa criacao do socket
    if (socksvr < 0) {
        //Exibe mensagem de erro de criacao
        perror("Erro ao gerar server socket.");
        //Finaliza aplicativo com codigo de erro
        exit(ERR_SOCKSVR);
    }

    //Obtem o tamanho da estrutura de endereçamento local
    lenghtlocaladd = sizeof (localaddress);

    //Seta na memoria a estrutura de endereco local
    memset((struct sockaddr_in *) &(localaddress), 0, lenghtlocaladd);

    /*Configura a estrutura local
     * Necessita ser da mesma forma que o socket
     * PF_INET = Familia para internet
     * htons() = Transforma a porta para byte-order
     * inet_addr() = Transforma o endereco para o tipo familia inet
     */
    localaddress.sin_family = PF_INET;
    localaddress.sin_port = htons(SVR_PORT);
    localaddress.sin_addr.s_addr = inet_addr("192.168.1.30");

    //Realiza bind de endereçamento
    fbind = bind(socksvr, (struct sockaddr *) & localaddress, lenghtlocaladd);

    //Checa bind
    if (fbind < 0) {
        //Exibe mensagem de erro
        perror("Erro ao realizar bind.");
        //Finaliza sistema com codigo de erro
        exit(ERR_BIND);
    }

    //Configura quantidade de conexoes que podem ficar na fila de espera
    listen(socksvr, WAIT_LINE);

    //Configura sinal para finalização do servidor
    signal(SIGTERM, endsystem);
    signal(SIGINT, endsystem);

    //Configura sinal para finalização do filho
    signal(SIGCHLD, endchield);

    /*Loop de escuta do servidor
     * Escuta até fsignal virar 0, tratado quando endsystem for
     * chamado pelo signal SIGTERM*/
    while (fsignal) {

        //Aguarda conexao de cliente
        client = accept(socksvr, (struct sockaddr *) & remoteaddress, &lenghtremoteadd);

        //Recebeu uma conexão, verifica se foi bem sucedida
        if (client < 0) {
            //Exibe mensagem de erro
            perror("Erro ao aceitar cliente.");
            //Força retorno do loop ao inicio
            continue;
        }

        /*Conexao bem sucedida
         * Atenção pode haver falha se vier para essa parte com
         * conexao de cliente mal sucedida.
         */

        //Cria processo filho de leitura de cotacoes
        chield = fork();

        //Verifica autenticidade do filho
        if (chield < 0) {
            //Exibe mensagem de erro
            perror("Erro ao criar filho para cliente.");
            //Fecha cliente
            close(client);
            //Forca retorno ao loop
            continue;
        }

        //Se for filho, sai do loop do servidor
        if (chield == 0) {
            //Muda flag para execução do servidor
            fsignal = 0;
            //Quebra loop
            break;
        }


    }


    /*========== Parte da execução do Filho ================*/
    /*======== Filho é responsável por receber comandos do cliente===*/

    //Msg de boas vindas
    send(client, WELCOME_MSG, strlen(WELCOME_MSG), 0);

    //Cria processo neto
    grandson = fork();

    //Verifica autenticidade do neto
    if (grandson < 0) {
        //Emite mensagem de erro
        perror("Não foi possivel criar neto.");
        //Fecha conexao
        shutdown(client, SHUT_RDWR);
        //Fecha processo
        exit(ERR_GDSON);
    }

    //Se for filho, entra em seu loop
    if ((chield == 0) && grandson > 0) {

        printf("Filho\n");

        //Flag de execução de filho
        int fchiled = 1;
        //Flag de leitura de buffer
        int rchield;
        //Buffer de leitura
        char *bchield;
        //Aloca buffer
        bchield = malloc(MAXSIZECMD);

        //Manipulação de comados
        char *cmd;
        char *param1;
        char *param2;
        cmd = malloc(5);
        param1 = malloc(10);
        param2 = malloc(10);

        //Loop de leitura
        while (fchiled) {

            //Aguarda recebimento de dados
            rchield = recv(client, bchield, MAXSIZECMD, 0);

            //Verifica validade do recebimento
            if (rchield > 0) {

                //Quebra comando e seus parametros
                sscanf(bchield, "%s %s %s ", cmd, param1, param2);

                //Verifica se comando de saida
                if (!strcmp(cmd, "quit")) {
                    printf("Cliente solicitou saida.\n");
                    fchiled = 0;
                }

                //Verifica sqt
                if (!strcmp(cmd, "sqt")) {
                    printf("Solicitou ativo %s\n", param1);

                    //Escreve na lista de ativos do DDC Crystal
                    bwrite("/home/donda/ddc/symbols.cal", param1);

                    //Concatena extensao sqt para o ativo
                    strcat(param1, ".sqt");

                    //Cria arquivo de solicitacao
                    bwrite(param1, "called");


                }

                //Limpa o buffer de leitura
                //bzero(bchield, MAXSIZECMD);

                //Limpa manipuladores
                bzero(cmd, 5);
                bzero(param1, 10);
                bzero(param2, 10);

            } else {

                printf("%s\n", bchield);

                //NULL representa erro de leitura, finaliza cliente
                close(client);

                printf("Filho finalizado.\n");

                fchiled = 0;

                //Finaliza processo
                exit(EXIT_CLI);
            }

        }

    }


    /*==========Fim da parte do filho===================*/


    /*==========Parte da execução para neto===============*/
    /* =======Neto é responsável pela leitura do buffer de cotações===*/

    if (grandson == 0) {

        printf("Neto\n");

        //Flag para leitura de buffer
        int gfread = 1;

        //Caminho padrão do buffer
        char *bfpath;

        //Aloca caminho
        bfpath = malloc(BUFFER_PATHSIZE + 10);

        //Descritor para arquivo de buffer
        FILE *fbuffer;

        //Flag de leitura no buffer
        int readbf = 1;

        //Buffer do dado lido
        char *bdata;

        //Aloca Buffer do dado lido
        bdata = malloc(BUFFER_DATASIZE);

        //Flag para leitura de dados
        int fdata;

        //Auxiliares
        char *p1;
        p1 = malloc(10);
        char *p2;           // <<-------- HERE IS THE PROBLEM
        p2 = malloc(10);

        //Loop de leitura de buffer
        while (gfread) {

            //Zera caminho do buffer por segurancao
            bzero(bfpath, BUFFER_PATHSIZE + 10);

            //Recebe o caminho padrão
            strcpy(bfpath, BUFFER_PATH);

            //Concatena com o nome do arquivo
            strcat(bfpath, btfile());

            //Abre o arquivo
            fbuffer = fopen(bfpath, "r");

            //Verifica se realmente abriu arquivo
            if (!fbuffer) {
                //Dorme 1/10 de segundo
                usleep(1000);
                //Forca retorno ao loop
                continue;
            }

            //Ativa flag de leitura de dados
            readbf = 1;

            //Loop para leitura dos dados
            while (readbf) {


                //Limpa o buffer lido
                //bzero(bdata, BUFFER_DATASIZE);

                //Lê linha
                fdata = fgets(bdata, BUFFER_DATASIZE, fbuffer);

                //Verifica se foi lido algo
                if (fdata > 0) {

                    //Verifica se foi final de arquivo de buffer
                    if (!strcmp(bdata, "EndOfBuffer")) {
                        //Altera flag de loop de leitura
                        readbf = 0;
                    } else {

                        //Separa os indices
                        sscanf(bdata, "%[^':']:%[^':']:%s", p1,p2);

                        printf("%s\n",p2);

                    }

                } else {
                    // 0 significa não a dados no arquivo, dorme 1/10 de segundo
                    usleep(1000);
                    //Força inicio do loop
                    continue;
                }
                 
            }

        }

    }

    /*=========== Fim da parte do neto====================*/

    //Fecha socket do servidor, liberando porta
    if (chield > 0) {
        close(socksvr);
        //Mensagem de fim de execução do servidor
        printf("Sistema finalizado.\n");
    } else {
        //Fecha socket do cliente
        shutdown(client, SHUT_RDWR);
        //Mensagem de fim de execução do filho
        printf("Filho finalizado.\n");
    }



    /*============Fim do neto=======================*/

    return (EXIT_SUCCESS);
}

And then, what is my problem?

Look above and see that have a variable called *p2 ( i think is line 265), this variable when declared makes all the system does not works.

For example:

I let declared the *p2 and compile and run the system.

The system runs all good, and then I will connect a client. In this time, when a client connect, the system returns an error for the client because of the check:

//Verifica autenticidade do filho
        if (client < 0) {
            //Exibe mensagem de erro
            perror("Erro ao aceitar cliente.");
            //Força retorno do loop ao inicio
            continue;
        }

And the client does not complete the connection.

BUT, if remove the *p2, the system and the connection works all good, and the client connect to the system very well.

My question is: Why?

Why a variable which does not be on the same block of the check connection can bug all the system?

If anyone can help me, i will thanks.

My msn is [email]--snipped--[/email] if anyone wants add me for talk about this problem.

Recommended Answers

All 7 Replies

In my experience the most likely cause of that type of behaviour is another part of the program writing outside object boundaries. Or writing outside of the boundaries of the object that p2 points at

The second possibility clearly can happen if there is no p2.

For the first possibility when you introduce the variable it alters where a lot of things are stored and the order they are stored in (if only inserting 1 thing somewhere in the order). If a piece of code is writing to somewhere it shouldn't be then this movement of where variables are stored can be the difference between it writing somewhere critical to program operation and somewhere not critical to program operation.

You might want consider using valgrind if you are using Linux, or OS X it can help with detecting that sort of problem.

You might also want to consider splitting you code up into some functions just for readabilities sake if nothing else.

please just one more time help me

naw... you'll be back :)

yeah man.. i know i wrote wrong but i did not find how change the title.. sorry...

Banfa... I'll make functions and change the how i manipulate the forks, i think is the how i made made it that is wrong and making all my system bug.

Thanks for all

This sscanf() line looks dodgy to me. Test the return value it gives, and see if it's 2.

//Separa os indices
sscanf(bdata, "%[^':']:%[^':']:%s", p1,p2);
printf("%s\n",p2);

It has 3 % char's in it, and 1 s in it's formatting, but it's going into two variables??

If it's right, explain it to me, please. I am not a sscanf() expert, but I don't understand that formatting for p1 and p2.

The data on the buffer are writen line by line and the fields are
separate by the char ':' .

For example:

FIELD1:FIELD2:FIELD3:FIELDn

But, for this system, i just need the first and second field, the rest
can be ignored.

Then sscanf separte the first and second putting on p1 and p2 char, the
rest is ignored.

In the code above, I removed the code that make the check about the first and second data, because will be very long the post and the rules here does not allow codes very long.

Then sscanf separte the first and second putting on p1 and p2 char, the
rest is ignored.

GCC (hint) disagrees with you ..

warning: [I]too few arguments[/I] for format

To ignore the rest, you might use ..

sscanf(data, "%[^':']:%[^':']:%*s", p1, p2);

GCC (hint) disagrees with you ..

warning: [I]too few arguments[/I] for format

To ignore the rest, you might use ..

sscanf(data, "%[^':']:%[^':']:%*s", p1, p2);

Wow.. thanks for that..

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.