Logo Search packages:      
Sourcecode: hexec version File versions  Download package

shm.c

/***************************************************************************
 *   Copyright (C) 2008 by Alexander Block                                 *
 *   ablock@blocksoftware.net                                              *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "config.h"

#include "shm.h"
#include "buf.h"
#include "error.h"

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>

#include <sys/mman.h>
#include <sys/stat.h>

00035 struct shm_header
{
    int buf_size;
};

/////////////

int hexec_shm_create(struct hexec_shm* shm, const char* shm_name, struct hexec_buf* buf)
{
    int fd = shm_open(shm_name, O_CREAT | O_EXCL | O_RDWR, S_IRWXU | S_IRWXG);
    if(fd == -1)
    {
        hexec_error("failed to create shared memory object %s\n", shm_name);
        return -1;
    }

    int mmap_size = sizeof(struct shm_header) + buf->buf_size;

    if(ftruncate(fd, mmap_size))
    {
        close(fd);
        shm_unlink(shm_name);
        hexec_error("failed to resize shared memory object %s\n", shm_name);
        return -1;
    }

    char* mmap_buf = mmap(NULL, mmap_size, PROT_WRITE, MAP_SHARED, fd, 0);
    if(mmap_buf == MAP_FAILED)
    {
        close(fd);
        shm_unlink(shm_name);
        hexec_error("failed to map shared memory object %s\n", shm_name);
        return -1;
    }

    struct shm_header header;
    header.buf_size = buf->buf_size;

    memcpy(mmap_buf, &header, sizeof(struct shm_header));
    hexec_buf_copy_to(buf, mmap_buf + sizeof(struct shm_header), buf->buf_size);
    close(fd);

    shm->owner = true;
    shm->name = strdup(shm_name);
    shm->mmap = mmap_buf;
    shm->mmap_size = mmap_size;
    shm->buf = mmap_buf + sizeof(struct shm_header);
    shm->buf_size = buf->buf_size;

    return 0;
}

int hexec_shm_open(struct hexec_shm* shm,  const char* shm_name)
{
    int fd = shm_open(shm_name, O_RDONLY, 0);
    if(fd == -1)
    {
        hexec_error("failed to open shared memory object %s\n", shm_name);
        return -1;
    }

    char* mmap_buf = mmap(NULL, sizeof(struct shm_header), PROT_READ, MAP_SHARED, fd, 0);
    if(mmap_buf == MAP_FAILED)
    {
        close(fd);
        hexec_error("failed to map shared memory object %s\n", shm_name);
        return -1;
    }
    struct shm_header header;
    memcpy(&header, mmap_buf, sizeof(struct shm_header));
    munmap(mmap_buf, sizeof(struct shm_header));

    int mmap_size = sizeof(struct shm_header) + header.buf_size;

    mmap_buf = mmap(NULL, mmap_size, PROT_READ, MAP_SHARED, fd, 0);
    if(mmap_buf == MAP_FAILED)
    {
        close(fd);
        hexec_error("failed to map shared memory object %s\n", shm_name);
        return -1;
    }
 
    close(fd);

    shm->owner = false;
    shm->name = strdup(shm_name);
    shm->mmap = mmap_buf;
    shm->mmap_size = mmap_size;
    shm->buf = mmap_buf + sizeof(struct shm_header); 
    shm->buf_size = header.buf_size;

    return 0;
}

int hexec_shm_close(struct hexec_shm* shm)
{
    if(munmap(shm->mmap, shm->mmap_size))
        hexec_fatal("failed to unmap shared memory object %s\n", shm->name);
    if(shm->owner && shm_unlink(shm->name))
        hexec_fatal("failed to unlink shared memory object %s\n", shm->name);
    free(shm->name);
    return 0;
}

int hexec_shm_to_buf(struct hexec_shm* shm, struct hexec_buf* buf)
{
    return hexec_buf_create_from(buf, shm->buf, shm->buf_size, false);
}



Generated by  Doxygen 1.6.0   Back to index