/*
* Copyright (c)2006-2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:  Implementation of semaphore (POSIX Standard).
*
*/


// INCLUDE FILES
#include <stdarg.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>
#include "sysreent.h"


// -----------------------------------------------------------------------------
// Funcation name: semget
// Description: Get semaphore identifier using the IPC key generated by ftok.
// Returns: None zero number (semaphore identifier): On success
//          -1              : On error.
// In case of error, errno value set to
//          EACCES - Semaphore exists but access denied.
//          EEXIST - A semaphore identifier exists for the argument key but
//                   ((semflg&IPC_CREAT)&&(semflg&IPC_EXCL)) is non-zero.
//          EINVAL - The value of nsems is either less than or equal to 0 or
//                   greater than the system-imposed limit, or a semaphore
//                   identifier exists for the argument key, but the number of
//                   semaphores in the set associated with it is less than nsems
//                   and nsems is not equal to 0.
//          ENOENT - A semaphore identifier does not exist for the argument key
//                   and (semflg&IPC_CREAT) is equal to 0.
//          ENOSPC - A semaphore identifier is to be created but the system-imposed
//                   limit on the maximum number of allowed semaphores system-wide
//                   would be exceeded.
// -----------------------------------------------------------------------------
//

extern "C" {

EXPORT_C int semget(key_t key, int nsems, int semflg)
    {
    return _semget_r( &errno, key, nsems, semflg);
    }

// -----------------------------------------------------------------------------
// Funcation name: semop
// Description: Perform atomically a user-defined array of semaphore operations
//              on the set of semaphores associated with the semaphore identifier
//              specified by the argument semid.
// Returns: 0  : On success
//          -1 : On error.
// In case of error, errno value set to
//          E2BIG - The value of nsops is greater than the system-imposed maximum.
//          EACCES - Operation permission is denied to the calling process, see IPC.
//          EAGAIN - The operation would result in suspension of the calling process
//                   but (sem_flg&IPC_NOWAIT) is non-zero.
//          EFBIG - The value of sem_num is less than 0 or greater than or equal to
//                   the number of semaphores in the set associated with semid.
//          EIDRM - The semaphore identifier semid is removed from the system.
//          EINTR - The semop() function was interrupted by a signal.
//          EINVAL - The value of semid is not a valid semaphore identifier, or the
//                   number of individual semaphores for which the calling process
//                   requests a SEM_UNDO would exceed the system-imposed limit.
//          ENOSPC - The limit on the number of individual processes requesting a
//                   SEM_UNDO would be exceeded.
//          ERANGE - An operation would cause a semval to overflow the system-imposed
//                   limit, or an operation would cause a semadj value to overflow the
//                   system-imposed limit
// -----------------------------------------------------------------------------
//
EXPORT_C int semop(int semid, struct sembuf *sops, unsigned nsops)
    {
    return _semop_r(&errno, semid, sops, nsops);
    }

// -----------------------------------------------------------------------------
// Funcation name: semctl
// Description: Provides a variety of semaphore control operations as specified by cmd.
// Returns:
//          If successful, the value returned by semctl() depends on cmd as follows:
//                 GETVAL - Value of semval.
//                 GETPID - Value of sempid.
//                 GETNCNT - Value of semncnt.
//                 GETZCNT - Value of semzcnt.
//                 All others, it returns 0.
//          -1 : On error.
// In case of error, errno value set to
//          EACCES - Operation permission is denied to the calling process.
//          EINVAL - The value of semid is not a valid semaphore identifier,
//                   or the value of semnum is less than 0 or greater than or
//                   equal to sem_nsems, or the value of cmd is not a valid command.
//          EPERM - The argument cmd is equal to IPC_RMID or IPC_SET and the
//                   effective user ID of the calling process is not equal to
//                   that of a process with appropriate privileges and it is not
//                   equal to the value of sem_perm.cuid or sem_perm.uid in the
//                   data structure associated with semid.
//          ERANGE - The argument cmd is equal to SETVAL or SETALL and the value
//                   to which semval is to be set is greater than the system-imposed maximum
// -----------------------------------------------------------------------------
//
EXPORT_C int semctl(int semid, int semnum, int cmd, ...)
    {
	va_list ap;
	union semun semun;


	if (cmd == IPC_SET || cmd == IPC_STAT || cmd == GETALL
	    || cmd == SETVAL || cmd == SETALL)
	    {
		va_start(ap, cmd);
		semun = va_arg(ap, union semun);
		va_end(ap);
		return _semctl_r(&errno, semid, semnum, cmd, semun);
	    }
	else
	    {
		return _semctl_r(&errno, semid, semnum, cmd);
	    }
    }

} // extern "C" {


//  End of File
