2014-12-12 4 views
2

Любой может помочь мне решить проблему с файловым дескриптором в posix mqueue. Я пытаюсь прочитать RAW-пакеты сокетов и поместить их в mqueue.Плохой дескриптор файла в posix mqueue

#include<stdlib.h> 
#include<stdio.h> 
#include<string.h> 
#include<sys/stat.h> 
#include<sys/types.h> 
#include<mqueue.h> 
#include<netinet/ip_icmp.h> 
#include<netinet/udp.h> 
#include<netinet/tcp.h> 
#include<netinet/ip.h> 
#include<netinet/if_ether.h> 
#include<net/ethernet.h> 

#define QUEUE_NAME "/test_queue" 
#define MAX_SIZE 71680 



#define CHECK(x) \ 
    do { \ 
     if (!(x)) { \ 
      fprintf(stderr, "%s:%d: ", __func__, __LINE__); \ 
      perror(#x); \ 
      exit(-1); \ 
     } \ 
    } while (0) \ 


int main(int argc, char **argv) 
{ 
    mqd_t mq; 
    struct mq_attr attr; 
    char buff[MAX_SIZE + 1]; 
    unsigned char* buffer = (unsigned char*) malloc(sizeof(65536)); 
    int saddr_size , data_size,sock_raw; 
    struct sockaddr saddr; 

    /* initialize the queue attributes */ 
    attr.mq_flags = 0; 
    attr.mq_maxmsg = 10; 
    attr.mq_msgsize = MAX_SIZE; 
    attr.mq_curmsgs = 0; 

    /* create the message queue */ 
    mq = mq_open(QUEUE_NAME, O_CREAT | O_RDONLY, 0644, &attr); 
    CHECK((mqd_t)-1 != mq); 

    sock_raw = socket(AF_PACKET , SOCK_RAW , htons(ETH_P_ALL)) ; 
    if(sock_raw < 0) 
    { 
     perror("Socket Error\n"); 
     return 1; 
    } 
    saddr_size = sizeof saddr; 
    data_size = recvfrom(sock_raw , buffer ,65536 , 0 , &saddr , (socklen_t*)&saddr_size); 

    if(data_size <0) 
    { 
     printf("Recvfrom error , failed to get packets\n"); 
     return 1; 
    } 

    memcpy(buff,buffer,65536); 


    CHECK(0 <= mq_send(mq, buffer, MAX_SIZE, 0)); 

    printf("Msg sent"); 

    CHECK((mqd_t)-1 != mq_close(mq)); 

    return 0; 
} 

выход, который я получил,

главная: 64: 0 < = mq_send (MQ, буфер, MAX_SIZE, 0): Плохой дескриптор файла

+0

Вы работаете как root? – Martin

+0

fprintf может изменяться errno, и ваш perror является фиктивным. Вызовите perror перед printf или вызовите strerror в списке аргументов в fprintf. –

+0

@WilliamPursell, отличный совет. В этом случае, однако, EBADF является подлинным. – pilcrow

ответ

3

Вы пытаетесь написать (mq_send) в дескриптор очереди сообщений, который вы открыли только для чтения (O_RDONLY).

Измените свой аргумент O_CREAT | O_RDWR и отправьте заявку.

Страница руководства Linux не вызывает этого, но others do: EBADF может означать, что дескриптор fd или fd-like полностью недействителен или что он недействителен для запрошенной операции.