mq_open возвращает 0 для четырех очередей

Я делаю простую программу с очередями сообщений POSIX. Я открываю четыре очереди, но ВСЕ возвращенные дескрипторы являются нулями (не -1, что означало бы ошибку при открытии). И затем, когда я пытаюсь получить или отправить, я получаю сообщение об ошибке: Неверный файловый дескриптор. Где может быть баг?

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <mqueue.h>
#define _GNU_SOURCE
#define ERR(source) (fprintf(stderr,"%s:%d\n",__FILE__,__LINE__),\
                     perror(source),kill(0,SIGKILL),\
                         exit(EXIT_FAILURE))


#define MSGSIZE 100

void usage(void){
    fprintf(stderr,"USAGE: niepoprawna ilosc argumentow\n");
    fprintf(stderr,"argumenty muszą być wieksze niz 0 \n");
    exit(EXIT_FAILURE);
}

int main(int argc, char *argv[])
{
    if (argc!=5)
    usage();

    int dz1 = atoi(argv[1]);
    int dz2 = atoi(argv[2]);
    int dz3 = atoi(argv[3]);
    int dz4 = atoi(argv[4]);

    char* name1 = malloc(50);
        if (!name1) ERR("MALLOC");

    char* name2 = malloc(50);
        if (!name2) ERR("MALLOC");

    char* name3 = malloc(50);
        if (!name3) ERR("MALLOC");

    char* name4 = malloc(50);
        if (!name4) ERR("MALLOC");

    int pid = getpid();     

    if (snprintf(name1, 50, "/%d_%d", pid, dz1)<0)
        ERR("snprintf");

    if (snprintf(name2, 50, "/%d_%d", pid, dz2)<0)
        ERR("snprintf");

    if (snprintf(name3, 50, "/%d_%d", pid, dz3)<0)
        ERR("snprintf");

    if (snprintf(name4, 50, "/%d_%d", pid, dz4)<0)
        ERR("snprintf");


    mqd_t des1, des2, des3, des4;

    struct mq_attr attr;
    attr.mq_maxmsg=10;
    attr.mq_msgsize=MSGSIZE -2;


    if (des1 = TEMP_FAILURE_RETRY(mq_open(name1, O_RDWR | O_CREAT | O_NONBLOCK, 0666, &attr)) < 0)
        ERR("MQOPEN");


    printf("dekryptor: %d ", des1); 

    if (des2 = TEMP_FAILURE_RETRY(mq_open(name2, O_RDWR | O_CREAT | O_NONBLOCK, 0666, &attr)) < 0)
        ERR("MQOPEN");


        printf("dekryptor: %d ", des2);

    if (des3 = TEMP_FAILURE_RETRY(mq_open(name3, O_RDWR | O_CREAT | O_NONBLOCK, 0666, &attr)) < 0)
        ERR("MQOPEN");


    printf("dekryptor: %d ", des3); 

    if (des4 = TEMP_FAILURE_RETRY(mq_open(name4,  O_RDWR | O_CREAT | O_NONBLOCK, 0666, &attr)) < 0)
        ERR("MQOPEN");

    printf("dekryptor: %d ", des4); 

    puts(name1);
    puts(name2);
    puts(name3);
    puts(name4);    


    struct timespec timeout;
    clock_gettime(CLOCK_REALTIME, &timeout);
    timeout.tv_sec=0;
    timeout.tv_nsec= 200000000;

    char* bufor = malloc(MSGSIZE);
    if (!bufor) ERR("malloc");


    printf("dekryptor: %d ", des1);

    if (mq_timedreceive(des1, bufor, MSGSIZE, NULL, &timeout) < 0)
        ERR("mq_timedreceive");

    if (mq_send(des1, bufor, MSGSIZE, NULL) < 0)
        ERR("mw_send");

    mq_close(des1);
    mq_close(des2);
    mq_close(des3);
    mq_close(des4);

    if(mq_unlink(name1))ERR("mq unlink");
    if(mq_unlink(name2))ERR("mq unlink");
    if(mq_unlink(name3))ERR("mq unlink");
    if(mq_unlink(name4))ERR("mq unlink");

}

person Piotr Bródka    schedule 27.05.2016    source источник


Ответы (1)


Вы не устанавливаете des# в значение, возвращаемое mq_open, вы устанавливаете его в значение, возвращаемое оператором <, потому что < имеет более высокий приоритет, чем =. Поскольку mq_open завершается успешно, < 0 возвращает false, что равно 0, и оно устанавливается для всех des# переменных.

Вам нужен еще один набор скобок.

if ((des1 = TEMP_FAILURE_RETRY(mq_open(name1, O_RDWR | O_CREAT | O_NONBLOCK, 0666, &attr))) < 0)

или сделать это в два этапа.

des1 = TEMP_FAILURE_RETRY(mq_open(name1, O_RDWR | O_CREAT | O_NONBLOCK, 0666, &attr));
if (des1 < 0)
person Barmar    schedule 27.05.2016