Victor Leite
Victor Leite

Reputation: 21

C stdin does not work

I trying to fix some bugs in a legacy code. This is the code:

#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <sys/msg.h>

#include "libSvr.h"

#define CONEC 3
#define CONFIG 4

typedef struct {
    long type;
    int cmd;
    int id;
    char data[7000];
} msg;

typedef struct {
    int id[100];
    unsigned long ip[100];
    int type[100];
    char name[100][20];
    int num;
} conec;

typedef struct {
    char ip;
    char svr;
} param_cfg;

typedef struct {
    unsigned long my_ip;
    unsigned long svr_ip;
} tcp_cfg;

msg client, server;
conec conec_tab;

param_cfg param;
tcp_cfg setup;

void *Receive_MSG(void *arg) {
    int i;
    while (1) {
        if ( msgrcv(msgkey,&client,7008,2,0) != -1 ) {
            switch (client.cmd) {
                case CONEC:
                    memmove((char*)&conec_tab,client.data,sizeof(conec_tab));
                    printf("\n%d\n",conec_tab.num);
                    break;
                case CONFIG:
                    switch (conec_tab.type[client.id]) {
                        case 0:
                            memmove((char*)&param,&client.data[sizeof(param_cfg)],sizeof(param_cfg));
                            printf("------------PARAM Config------------\n");
                            printf("%c\n%c\n\n",param.ip,param.svr);
                            break;
                        case 1:
                            memmove((char*)&setup,client.data,sizeof(tcp_cfg));
                            printf("\n------------Setup------------\n");
                            printf("%s\n",Inet_ntoa(setup.my_ip));
                            break;
                    }
            }
        }
    }
}

void send_msg() {
    msgsnd(msgkey,&(server.type),7008,0);
}

void Process(char *command) {
    server.type = 1;

    if ( !strncmp(command,"text",8) ) {
        server.cmd = 1;
        send_text();
        send_msg();
    }
    else if ( !strncmp(command,"image",9) ) {
        server.cmd = 2;
        send_image();
        send_msg();
    }
    else
        printf("\nCommand not found.\n");
}

int main()
{
    int i;
    char cmd[100];
    msgkey=msgget(100,0);

    if ( msgkey == -1) {
        printf("ERROR msgkey!!");
        exit(1);
    }

    pthread_t receive;
    pthread_create(&receive,NULL,Receive_MSG,NULL);

    do {
        printf("Enter a command -> ");

        if (fgets(cmd,100,stdin) == NULL) {
            printf("error");
            exit(1);
        }

        cmd[strlen(cmd)-1]='\0';
        if ( (strcmp(cmd,"exit")) && (strcmp(cmd,"")) )
            Process(cmd);

    } while (strcmp(cmd,"exit"));

    return 0; 
}

The libSvr.h code:

#ifndef LIBSVR_H
#define LIBSVR_H

#pragma pack(push,1)
#pragma pack(1)


extern "C" void send_text();

extern "C" void send_image();


#pragma pack(pop)

#endif

The thread receive just receive some messages from another application in the queue id msgkey and print some text.

The problem is when I get into the do while loop, where I need to get some user inputs, the fgets fails... When I printed the error (with errno) I saw that it is a bad file descriptor error (EBADF).

The Process function get the command a calls the appropriate function, that basically will send some data through a socket. And these functions called by Process are from a lib (libSvr) writen in C++ with functions C extern-ed.

I'm using an ubuntu 12.10 machine with gcc 4.7.2.

I tried to see the code after preprocessor (with gcc -E) and stdin is still showed as stdin. I tried to print the output of fileno(stdin) and it was 0 (I saw somewhere that it the right value) and then I tried to call fgets this way: fgets(cmd,100,0). But nothing works.

Anyone have any idea of what is happening?

Thanks!

Edit:

Included all the code.

I tried call gets(), scanf() and read() and also comment the thread creation (pthread_create) but nothing changed.

I ran the command strace -s2000 -etrace=open,close <MYPROGRAM> and this is the output:

open("/mnt/hgfs/projects/tls/i686/sse2/cmov/libSvr.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/mnt/hgfs/projects/tls/i686/sse2/libSvr.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/mnt/hgfs/projects/tls/i686/cmov/libSvr.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/mnt/hgfs/projects/tls/i686/libSvr.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/mnt/hgfs/projects/tls/sse2/cmov/libSvr.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/mnt/hgfs/projects/tls/sse2/libSvr.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/mnt/hgfs/projects/tls/cmov/libSvr.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/mnt/hgfs/projects/tls/libSvr.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/mnt/hgfs/projects/i686/sse2/cmov/libSvr.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/mnt/hgfs/projects/i686/sse2/libSvr.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/mnt/hgfs/projects/i686/cmov/libSvr.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/mnt/hgfs/projects/i686/libSvr.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/mnt/hgfs/projects/sse2/cmov/libSvr.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/mnt/hgfs/projects/sse2/libSvr.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/mnt/hgfs/projects/cmov/libSvr.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/mnt/hgfs/projects/libSvr.so.1", O_RDONLY|O_CLOEXEC) = 3
close(3)                                = 0
open("/mnt/hgfs/projects/libpthread.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
close(3)                                = 0
open("/lib/i386-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
close(3)                                = 0
open("/mnt/hgfs/projects/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
close(3)                                = 0
open("/mnt/hgfs/projects/libstdc++.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/i386-linux-gnu/libstdc++.so.6", O_RDONLY|O_CLOEXEC) = 3
close(3)                                = 0
open("/mnt/hgfs/projects/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3
close(3)                                = 0
open("/mnt/hgfs/projects/libm.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
close(3)                                = 0
close(0)                                = 0
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)
close(0)                                = -1 EBADF (Bad file descriptor)

Enter a command -> 
errorEnter a command -> 
errorEnter a command -> 
errorEnter a command -> 

So, the stdin file descriptor is beeing closed but and now I need to know where it is beeing closed.

I'm studying some howto's and the man page of strace now, because I never use it before.

Any help and tips will be welcome.

Thanks again!

Upvotes: 1

Views: 753

Answers (1)

Atle
Atle

Reputation: 1877

I got your code to run with a few changes. I did not manage to get the System V-stuff to work, but I got it to read commands without crashing.

I think the initialization of System V-stiff in your program is wrong, and creates undefined behavior.

All the close(0)-s is probably from the server-thread somewhere, which does not break from the while-loop on errors.

The initialization of System V (I have no clue how to use this, really, just read man-pages), I did like this:

    // msg_key is declared above the server-code (used by both) like `key_t msg_key`
    msg_key = ftok ("/home/atle/prog/test.c", 'A');
    if (msg_key == -1) {
            printf ("ftok error: %s\n", strerror(errno));
            exit(1);
    }
    msgkey = msgget(msg_key, IPC_CREAT);

    if ( msgkey == -1) {
            printf ("msgget error: %s\n", strerror(errno));
            exit(1);
    }

In the server, I did like this:

    int msgkey_server = msgget(msg_key, 0);
    if ( msgkey_server == -1) {
            printf ("Server msgget error: %s\n", strerror(errno));
            exit(1);
    }

    while (1) {
            printf ("Server loop\n");
            if ( msgrcv(msgkey_server,&client,sizeof(client),0,0) == -1 ) {
                    printf ("Server read error: %s\n", strerror(errno));
                    exit(1);
            }
            else {
                   // MSG READ OK
            }

BTW:

When you pass a struct to a command with its size attached, you should always user sizeof() like I did here, not writing the size manually (causes problems).

Extra BTW:

You need the errno-header:

#include <errno.h>

Upvotes: 1

Related Questions