Bad File Descriptor with Linux Socket write() Bad File Descriptor C

135,698

Solution 1

In general, when "Bad File Descriptor" is encountered, it means that the socket file descriptor you passed into the API is not valid, which has multiple possible reasons:

  1. The fd is already closed somewhere.
  2. The fd has a wrong value, which is inconsistent with the value obtained from socket() api

Solution 2

The value you have passed as the file descriptor is not valid. It is either negative or does not represent a currently open file or socket.

So you have either closed the socket before calling write() or you have corrupted the value of 'sockfd' somewhere in your code.

It would be useful to trace all calls to close(), and the value of 'sockfd' prior to the write() calls.

Your technique of only printing error messages in debug mode seems to me complete madness, and in any case calling another function between a system call and perror() is invalid, as it may disturb the value of errno. Indeed it may have done so in this case, and the real underlying error may be different.

Solution 3

I had this error too, my problem was in some part of code I didn't close file descriptor and in other part, I tried to open that file!! use close(fd) system call after you finished working on a file.

Share:
135,698
user1336117
Author by

user1336117

Updated on July 28, 2022

Comments

  • user1336117
    user1336117 almost 2 years

    I have an interesting problem with write(2) function. PrepareResponseForSetCoordinates function causes bad file descriptor error on write.

    Here is the line of error: perror("ERROR writing to socket"); total output: ERROR writing to socket: Bad file descriptor

    I am sure that I have established the connection because PrepareResponseForConnectionTest works like a charm.

    Can you have any idea about the reason of the error?

    When I use gcc as compiler there was no problem. After that because of using multiple new cpp sources I am using g++ as compiler and I have this error.

    Regards

    Here below my code:

    #define MAX_PMS_MESSAGE_LEN (4096)
    unsigned char baCommBuffer[MAX_PMS_MESSAGE_LEN];
    unsigned char PrepareResponseForSetCoordinates(void)
    {
        unsigned char baTempBuff[255]={0};
        unsigned short bCnt=0,i=0,bCsum=0,bCnt2=0;
    time_t lEpochTime;
    time_t lSessionTime;
    
    memset(baTempBuff,0,sizeof(baTempBuff));
    memset(baCommBuffer,0,sizeof(baCommBuffer));
    bzero(baCommBuffer,MAX_PMS_MESSAGE_LEN);
    bzero(baTempBuff,sizeof(baTempBuff));
    
    
    lEpochTime = time(NULL);
    baCommBuffer[bCnt++]    =   START_CHAR;
    baCommBuffer[bCnt++]    =   START_CHAR;
    baCommBuffer[bCnt++]    =   PACKET_SEPERATOR;
    sprintf((char*)baTempBuff,"%ld",(unsigned long)lEpochTime);
    memcpy(baCommBuffer+bCnt,baTempBuff,10);
    
    bzero(baTempBuff,sizeof(baTempBuff));
    bCnt+=10;
    baCommBuffer[bCnt++]    =   PACKET_SEPERATOR;
    //  lSessionTime = time(NULL);
    if(SPMSMessage.lSessionID)
    lSessionTime = SPMSMessage.lSessionID; 
    else
    lSessionTime=lEpochTime;
    sprintf((char*)baTempBuff,"%ld",(unsigned long)lSessionTime);
    memcpy(baCommBuffer+bCnt,baTempBuff,10);
    bzero(baTempBuff,sizeof(baTempBuff));
    bCnt+=10;
    baCommBuffer[bCnt++]    =   PACKET_SEPERATOR;
    baCommBuffer[bCnt++]    =   PMC_ID;
    baCommBuffer[bCnt++]    =   PACKET_SEPERATOR;
    baCommBuffer[bCnt++]    =   PMS_ID;
    baCommBuffer[bCnt++]    =   PACKET_SEPERATOR;
    baCommBuffer[bCnt++]    =   'R';
    baCommBuffer[bCnt++]    =   'E';
    baCommBuffer[bCnt++]    =   'P';
    baCommBuffer[bCnt++]    =   PACKET_SEPERATOR;
    baCommBuffer[bCnt++]    =   'C';
    baCommBuffer[bCnt++]    =   'O';
    baCommBuffer[bCnt++]    =   'O';
    baCommBuffer[bCnt++]    =   'S';
    baCommBuffer[bCnt++]    =   PACKET_SEPERATOR;
    if(SPMSMessage.bParam== SET_COOR_CAM1_PARAM)
    {
    baCommBuffer[bCnt++]    =   '2';
    baCommBuffer[bCnt++]    =   PACKET_SEPERATOR;
    baCommBuffer[bCnt++]    =   'O';
    baCommBuffer[bCnt++]    =   'N';
    baCommBuffer[bCnt++]    =   'E';
    baCommBuffer[bCnt++]    =   PARAMETER_SEPERATOR;
    baCommBuffer[bCnt++]    =   'A';
    baCommBuffer[bCnt++]    =   'C';
    baCommBuffer[bCnt++]    =   'K';
    }
    else if(SPMSMessage.bParam== SET_COOR_CAM2_PARAM)
    {
    baCommBuffer[bCnt++]    =   '2';
    baCommBuffer[bCnt++]    =   PACKET_SEPERATOR;
    baCommBuffer[bCnt++]    =   'T';
    baCommBuffer[bCnt++]    =   'W';
    baCommBuffer[bCnt++]    =   'O';
    baCommBuffer[bCnt++]    =   PARAMETER_SEPERATOR;
    baCommBuffer[bCnt++]    =   'A';
    baCommBuffer[bCnt++]    =   'C';
    baCommBuffer[bCnt++]    =   'K';    
    }
    else
    {
    baCommBuffer[bCnt++]    =   '1';
    baCommBuffer[bCnt++]    =   PACKET_SEPERATOR;
    baCommBuffer[bCnt++]    =   'N';
    baCommBuffer[bCnt++]    =   'A';
    baCommBuffer[bCnt++]    =   'C';
    baCommBuffer[bCnt++]    =   'K';        
    }
    baCommBuffer[bCnt++]    =   PACKET_SEPERATOR;
    baCommBuffer[bCnt++]    =   '*';
    memset(baTempBuff,0,sizeof(baTempBuff));
    bCsum = CalculateCheckSum(baCommBuffer);
    sprintf((char*)baTempBuff,"%.2X",bCsum);
    memcpy(baCommBuffer+bCnt,baTempBuff,2);
    bzero(baTempBuff,sizeof(baTempBuff));
    bCnt+=2;
    baCommBuffer[bCnt++]    =   PACKET_SEPERATOR;
    baCommBuffer[bCnt++]    =   END_CHAR;
    baCommBuffer[bCnt++]    =   END_CHAR;
    
    #ifdef _DEBUG_DEEP_DETAILED
                if(EDebugDeepDetail<GetDebugLevelOfPMC())
                {
                        printf("WILL BE sent: %s uzunluk:%d\n", baCommBuffer,bCnt);
                        sprintf(caLogStr,"WILL BE sent: %s uzunluk:%d\n", baCommBuffer,bCnt);
                        PrintToLogFile(caLogStr);
                        memset(caLogStr,0,MAX_LOG_STRLEN);
                    }
    #endif
    
            if((ETcpConnectionState== ETcpStateConnected) || (ETcpConnectionState== ETcpStateConnectedAndWaitingToWrite) )
            {
    
                if (write(sockfd,baCommBuffer,bCnt) < 0)
                {
                    #ifdef _DEBUG_DETAILED
                    if(EDebugDetail<GetDebugLevelOfPMC())
                    {
                         perror("ERROR writing to socket"); 
                         PrintToLogFile("ERROR writing to socket");
    
                     }
                     #endif
                 return 0;
                }
                    #ifdef _DEBUG_DEEP_DETAILED
                    if(EDebugDeepDetail<GetDebugLevelOfPMC())
                    {
                        printf("sent: %s uzunluk:%d\n", baCommBuffer,bCnt);
                        sprintf(caLogStr,"sent: %s uzunluk:%d\n", baCommBuffer,bCnt);
                        PrintToLogFile(caLogStr);
                        memset(caLogStr,0,MAX_LOG_STRLEN);
                    }
                    #endif
            }
            else
            {
                    #ifdef _DEBUG_DETAILED
                        if(EDebugDetail<GetDebugLevelOfPMC())
                        {
                        PrintToLogFile("Henüz Bağlantı Yok\n");
                        }
                    #endif
                    return 0;
            }
    
    
    return (bCnt);  
    

    }

    Here below you can see the code which run without error:

    unsigned char PrepareResponseForConnectionTest(void)
    {
    
    unsigned char baTempBuff[20]={0};
    unsigned char bCnt=0,i=0,bCsum=0;
    time_t lEpochTime;
    time_t lSessionTime;
    
    memset(baTempBuff,0,sizeof(baTempBuff));
    memset(baCommBuffer,0,sizeof(baCommBuffer));
    bzero(baCommBuffer,MAX_PMS_MESSAGE_LEN);
    bzero(baTempBuff,sizeof(baTempBuff));
    
    
    lEpochTime = time(NULL);
    baCommBuffer[bCnt++]    =   START_CHAR;
    baCommBuffer[bCnt++]    =   START_CHAR;
    baCommBuffer[bCnt++]    =   PACKET_SEPERATOR;
    sprintf((char*)baTempBuff,"%ld",(unsigned long)lEpochTime);
    memcpy(baCommBuffer+bCnt,baTempBuff,10);
    
    bzero(baTempBuff,sizeof(baTempBuff));
    bCnt+=10;
    baCommBuffer[bCnt++]    =   PACKET_SEPERATOR;
    
    lSessionTime = SPMSMessage.lSessionID; 
    sprintf((char*)baTempBuff,"%ld",(unsigned long)lSessionTime);
    memcpy(baCommBuffer+bCnt,baTempBuff,10);
    bzero(baTempBuff,sizeof(baTempBuff));
    bCnt+=10;
    baCommBuffer[bCnt++]    =   PACKET_SEPERATOR;
    baCommBuffer[bCnt++]    =   PMC_ID;
    baCommBuffer[bCnt++]    =   PACKET_SEPERATOR;
    baCommBuffer[bCnt++]    =   PMS_ID;
    baCommBuffer[bCnt++]    =   PACKET_SEPERATOR;
    baCommBuffer[bCnt++]    =   'R';
    baCommBuffer[bCnt++]    =   'E';
    baCommBuffer[bCnt++]    =   'P';
    baCommBuffer[bCnt++]    =   PACKET_SEPERATOR;
    baCommBuffer[bCnt++]    =   'C';
    baCommBuffer[bCnt++]    =   'O';
    baCommBuffer[bCnt++]    =   'N';
    baCommBuffer[bCnt++]    =   'T';
    baCommBuffer[bCnt++]    =   PACKET_SEPERATOR;
    baCommBuffer[bCnt++]    =   '1';
    baCommBuffer[bCnt++]    =   PACKET_SEPERATOR;
    baCommBuffer[bCnt++]    =   'A';
    baCommBuffer[bCnt++]    =   'C';
    baCommBuffer[bCnt++]    =   'K';
    baCommBuffer[bCnt++]    =   PACKET_SEPERATOR;
    baCommBuffer[bCnt++]    =   '*';
    memset(baTempBuff,0,sizeof(baTempBuff));
    bCsum = CalculateCheckSum(baCommBuffer);
    sprintf((char*)baTempBuff,"%.2X",bCsum);
    memcpy(baCommBuffer+bCnt,baTempBuff,2);
    bzero(baTempBuff,sizeof(baTempBuff));
    bCnt+=2;
    baCommBuffer[bCnt++]    =   PACKET_SEPERATOR;
    baCommBuffer[bCnt++]    =   END_CHAR;
    baCommBuffer[bCnt++]    =   END_CHAR;
    
    
    
            if((ETcpConnectionState== ETcpStateConnected) || (ETcpConnectionState== ETcpStateConnectedAndWaitingToWrite) )
            {
    
                if (write(sockfd,baCommBuffer,bCnt) < 0)
                {
                 perror("ERROR writing to socket\n");
                 PrintToLogFile("ERROR writing to socket\n");
                }
                    #ifdef _DEBUG_DEEP_DETAILED
                    if(EDebugDeepDetail<GetDebugLevelOfPMC())
                    {
                        printf("sent: %s uzunluk:%d\n", baCommBuffer,bCnt);
                        sprintf(caLogStr,"sent: %s uzunluk:%d\n", baCommBuffer,bCnt);
                        PrintToLogFile(caLogStr);
                        memset(caLogStr,0,MAX_LOG_STRLEN);
                    }
                    #endif
                    return 0;
            }
            else
            {
                    #ifdef _DEBUG_DETAILED
                        if(EDebugDetail<GetDebugLevelOfPMC())
                        {
                        PrintToLogFile("There is no connection yet\n");
                        }
                    #endif
                    //return 0;
            }
    
            //printf("\n\n");
    return (bCnt);
    }
    

    Here is my InitializeConnection function and ConnectToServer function:

    void InitializeTcpConnection(int argc, char *argv[])
    {
       int optval;
       socklen_t optlen = sizeof(optval);
    ETcpConnectionState = ETcpStateNotConnected;
        if (argc < 3) 
        {
           fprintf(stderr,"usage: %s hostname_or_ip port\n", argv[0]);
           #ifdef _DEBUG_PROCESS
           if(EDebugProcess<GetDebugLevelOfPMC())
           {
            sprintf(caLogStr,"usage: %s hostname_or_ip port\n", argv[0]);
            PrintToLogFile(caLogStr);
            memset(caLogStr,0,MAX_LOG_STRLEN);
            }
           #endif
           exit(0);
        }
        portno = atoi(argv[2]);
        /* int socket(domain,type,protocol)
         * socket creates an endpoint for communication and returns a descriptor
         * AF_INET: ARPA Internet protocols
         * SOCK_STREAM: sequenced, two way connection based byte streams
         * 
         * return: Socket returns a non-negative descriptor on success.
         * On failure it returns -1 and sets errno to indicate the error
         * */
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd < 0) {
            #ifdef _DEBUG_PROCESS
            if(EDebugProcess<GetDebugLevelOfPMC())
            {
            perror("ERROR creating socket");
            PrintToLogFile("ERROR creating socket\n");
    
            }
            #endif
            exit(1);
        }
    
        /**/
    
    
       /* Set the option active */
       optval = 1;
       optlen = sizeof(optval);
       if(setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) 
       {
          #ifdef _DEBUG_PROCESS
          if(EDebugProcess<GetDebugLevelOfPMC())
            {
              perror("setsockopt()");
              PrintToLogFile("ERROR creating socket\n");
            }
          #endif
          close(sockfd);
          exit(EXIT_FAILURE);
       }
       #ifdef _DEBUG_PROCESS
       if(EDebugProcess<GetDebugLevelOfPMC())
       {
        printf("SO_KEEPALIVE set on socket\n");
        PrintToLogFile("SO_KEEPALIVE set on socket\n");
        }
          #endif
       /* Check the status again */
       if(getsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen) < 0) {
           #ifdef _DEBUG_PROCESS
           if(EDebugProcess<GetDebugLevelOfPMC())
           {
              perror("getsockopt()");
              PrintToLogFile("getsockopt()");
          }
          #endif
          close(sockfd);
          exit(EXIT_FAILURE);
       }
       #ifdef _DEBUG_PROCESS
       if(EDebugProcess<GetDebugLevelOfPMC())
       {
       printf("SO_KEEPALIVE is %s\n", (optval ? "ON" : "OFF"));
       }
       #endif
    
       #ifdef _DEBUG_PROCESS
    
        if(EDebugProcess<GetDebugLevelOfPMC())
        {
        PrintToLogFile("Setting socket for reusability\n");
        }
       #endif
    
       if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(int)) == -1) 
       {
           #ifdef _DEBUG_PROCESS
           if(EDebugProcess<GetDebugLevelOfPMC())
           {
                    perror("setsockopt");
                    PrintToLogFile("Setting socket option error\n");
           }
           #endif
                    exit(1);
       }
    
       /*********/
    
        //get the address info by either host name or IP address
        SetTcpServerIpAddress(argv[1]);
        server = gethostbyname(argv[1]);
        if (server == NULL) 
        {
            #ifdef _DEBUG_PROCESS
            if(EDebugProcess<GetDebugLevelOfPMC())
            {
            PrintToLogFile("ERROR, no such host\n");
            }
            #endif
            exit(1);
        }
    
        bzero((char *) &serv_addr, sizeof(serv_addr));
        serv_addr.sin_family = AF_INET;
        bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);
        //serv_addr.sin_port: unsigned short 
        //htons converts the unsigned short hostshort from host byte order to network byte order
        serv_addr.sin_port = htons(portno);
    
    
        ETcpConnectionState = ETcpStateWaitingForConnection;
    
    }
    
    int ConnectToServer(void)
    {
                        if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)  
                        {
                            #ifdef _DEBUG_DETAILED
                            if(EDebugDetail<GetDebugLevelOfPMC())
                            {
                            PrintToLogFile("ERROR connecting");
                            }
                            #endif
                            return 1; // connection error
                            //exit(1);
                        }
                        else
                        {
                            #ifdef _DEBUG_DETAILED
                            if(EDebugDetail<GetDebugLevelOfPMC())
                            {
                            PrintToLogFile("connection established\n");
                            }
                            #endif
                        #ifndef PMS_COMM_POLL_MODE
                            #ifdef _DEBUG_DETAILED
                            if(EDebugDetail<GetDebugLevelOfPMC())
                            {
                            PrintToLogFile("State is non poll mode\n");
                            }
                            #endif
                        ETcpConnectionState = ETcpStateConnected;
                        #endif
                        #ifdef PMS_COMM_POLL_MODE
                            #ifdef _DEBUG_DETAILED
                            if(EDebugDetail<GetDebugLevelOfPMC())
                            {
                            PrintToLogFile("State is poll mode\n"); 
                            }
                            #endif
                        ETcpConnectionState = ETcpStateConnectedAndWaitingToRead;
                        #endif
    
                        SendRequestToGetImageUploadInfo();
                        }
    return 0;   
    }
    
  • user207421
    user207421 about 4 years
    This problem is caused by prematurely closing it, not by not closing it.
  • Steven
    Steven almost 3 years
    Thanks for your analyze about possible reasons, those are helpful to find out where cause the bug.