Ejemplo n.º 1
0
int ioctl_sem_open(struct ipc_driver *drv, unsigned long arg)
{
    int error = 0;
    struct ipc_create_t ipc_param;

    if(copy_from_user(&ipc_param, (void *)arg, sizeof(struct ipc_create_t))) {
        err_msg(err_trace, "%s(): Error in copy_from_user()\n", __FUNCTION__);
        error = -EFAULT;
        goto do_exit;
    }

    ipc_param.handle = ipc_sem_create( drv, &ipc_param );
    if(!ipc_param.handle) {
        err_msg(err_trace, "%s(): Error in ipc_sem_create()\n", __FUNCTION__);
        error = -EINVAL;
        goto do_exit;
    }

    if(copy_to_user((void*)arg, (void*)&ipc_param, sizeof(struct ipc_create_t))) {
        err_msg(err_trace, "%s(): Error in copy_to_user()\n", __FUNCTION__);
        error = -EFAULT;
        goto do_exit;
    }

do_exit:
    return error;
}
Ejemplo n.º 2
0
ipc_t ipc_create(const char* name, int owner) {

    int isInited = 0;
    struct Queue* queue;

    ipc_t conn = malloc(sizeof(struct ipc_t));

    sprintf(conn->name, "/arqvenger_%s", name);

    if ((conn->lock = sem_open(conn->name, O_CREAT | O_EXCL, 0666, 0)) == SEM_FAILED) {
        conn->lock = sem_open(conn->name, 0);
        if (conn->lock == SEM_FAILED) {
            print_errno("Failed adquiring named lock");
            return NULL;
        }

        sem_wait(conn->lock);
        isInited = 1;
    }

    conn->fd = shm_open(conn->name, O_CREAT | O_RDWR, 0666);
    if (conn->fd == -1) {
        print_errno("shm_open failed");

        sem_close(conn->lock);
        if (owner) {
            sem_unlink(conn->name);
        }
        free(conn);

        return NULL;
    }

    if (!isInited) {
        if (ftruncate(conn->fd, SHMEM_SIZE) == -1) {
            print_errno("Truncate failed");

            sem_close(conn->lock);
            if (owner) {
                sem_unlink(conn->name);
                shm_unlink(conn->name);
            }
            free(conn);
            return NULL;
        }
    }

    conn->queue = mmap(NULL, SHMEM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, conn->fd, 0);
    if (conn->queue == (void*) -1) {
        print_errno("mmap");

        sem_close(conn->lock);
        if (owner) {
            sem_unlink(conn->name);
            shm_unlink(conn->name);
        }

        free(conn);
        return NULL;
    }

    if (isInited) {
        sem_post(conn->lock);
        return conn;
    }

    queue = conn->queue;
    for (size_t i = 0; i < ENTRIES_PER_QUEUE; i++) {
        queue->index[i] = -1;
        queue->slots[i].len = 0;
    }

    queue->readWait = ipc_sem_create(0);
    queue->writeSem = ipc_sem_create(ENTRIES_PER_QUEUE);
    if (queue->readWait == -1 || queue->writeSem == -1) {
        print_errno("failed creating sems");
        sem_close(conn->lock);
        ipc_sem_destroy(queue->readWait);
        ipc_sem_destroy(queue->writeSem);

        munmap(conn->queue, SHMEM_SIZE);
        if (owner) {
            sem_unlink(conn->name);
            shm_unlink(conn->name);
        }
        free(conn);
        return NULL;
    }

    sem_post(conn->lock);

    return conn;
}