/**---------------------------------------------------------------------------
* 版权 2004 啄木鸟基金会
* 保留一切权利。
* 
* 重新分发或者使用源代码格式和二进制格式，无论是否修改，必须在符合
* 以下许可条件的情况下进行：
* 1. 重新分发的源代码必须保留上述版权信息、本许可条件列表以及下列
*    否认声明。
* 2. 重新分发的二进制格式程序必须再次产生上述版权信息，本许可条件列
*    表以及在本分发中的文档或者其他材料中提供的否认声明。
*
* 本软件是由作者和参与者“照此”提供，并且任何显式或隐式的保证，只
* 包含在内但不被其限制，否认任何商业性和特殊目的适切性的隐式担保
* 之效力。本软件的作者或参与者不对由于本软件造成的任何直接地、
* 间接地、连带地、特殊地、惩戒性地，或者由此而产生地损害（还包括
* 以下的不被其限制的内容在内：替代品或服务地取得；使用过程、数据、
* 或由此产生的收益之损失；或商业行为的中断）发生在即使被告知可能
* 出现上述损害后，仍设法摆脱使用本软件的过程中，无论其起因和任何
* 责任地推测，其是否属于合同范畴、限定的义务、或者民事侵权行为
*（包括疏忽及其他）都否认其责任。
* 
* 
*
* Copyright (c) 2004 The Woodpecker Foundation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the
*    documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
**---------------------------------------------------------------------------
*/

#include "spshm.h"
#define _IN_SPSHM_C_


/* create & attach shared memory if not exist
 * attach shared memory if exist
 */
void *shminit(char *fn, size_t len)
{
    int shmid, oflag, fid;
    void *ptr;
    struct shmid_ds buff;

    oflag = SVSHM_MODE|IPC_CREAT;
    if ( (fid = ftok(fn, 0)) < 0)
        return NULL;
    if  ((shmid = shmget(fid, len, oflag)) < 0)
        return NULL;
    if ( (ptr = shmat(shmid, NULL, 0)) == (unsigned char *) -1)
        return NULL;
    
    /* retset to zero 
    if (shmctl(shmid, IPC_STAT, &buff))
        return NULL;

    memset(ptr, 0, buff.shm_segsz);
*/
    return ptr;
}

int shmrm(char *fn)
{
    int shmid, oflag, fid;

    oflag = SVSHM_MODE|IPC_CREAT;
    if ( (fid = ftok(fn, 0)) < 0)
        return -1;
    if  ((shmid = shmget(fid, 0, oflag)) < 0)
        return -2;
    return shmctl(shmid, IPC_RMID, NULL);
}

/* if exist return shmid
 * if noexist return 0
 * if exception return -1
 */
int shmgetid(char *fn)
{
    int shmid, oflag, fid;

    oflag = SVSHM_MODE;
    if ( (fid = ftok(fn, 0)) < 0)
        return NULL;
    shmid = shmget(fid, 0, oflag);
    if (shmid > 0)
        return shmid;
    else if (ENOENT == errno)
        return 0;
    else
        return -1;
}
    



 
int shmwrite(int id, void *val, size_t len)
{
    struct shmid_ds buff;
    unsigned char *pval = (unsigned char*)val;
    unsigned char *ptr;

    if ( (ptr = shmat(id, NULL, 0)) == (unsigned char *) -1)
        return -1;
    if (shmctl(id, IPC_STAT, &buff))
        return -1;

    memcpy(ptr, pval, buff.shm_segsz);
    shmdt(ptr);
    return 0;
}

int shmread(int id, void *val, size_t len)
{
    struct shmid_ds buff;
    unsigned char *pval = (unsigned char*)val;
    unsigned char *ptr;

    if ( (ptr = shmat(id, NULL, 0)) == (unsigned char *) -1)
        return -1;
    if (shmctl(id, IPC_STAT, &buff))
        return -1;

    memcpy(pval, ptr, buff.shm_segsz);
    shmdt(ptr);
    return 0;
}
