aboutsummaryrefslogtreecommitdiff
path: root/src/backend/port/qnx/shm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/port/qnx/shm.c')
-rw-r--r--src/backend/port/qnx/shm.c193
1 files changed, 193 insertions, 0 deletions
diff --git a/src/backend/port/qnx/shm.c b/src/backend/port/qnx/shm.c
new file mode 100644
index 00000000000..293c901ac69
--- /dev/null
+++ b/src/backend/port/qnx/shm.c
@@ -0,0 +1,193 @@
+/*-------------------------------------------------------------------------
+ *
+ * shm.c
+ * System V Shared Memory Emulation
+ *
+ * Copyright (c) 1999, repas AEG Automation GmbH
+ *
+ *
+ * IDENTIFICATION
+ * $Header: /cvsroot/pgsql/src/backend/port/qnx/Attic/shm.c,v 1.1 1999/12/16 01:25:06 momjian Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/shm.h>
+
+
+#define MODE 0777
+
+#define SHMMAX 1024
+
+
+struct shm_info {
+ int shmid;
+ key_t key;
+ size_t size;
+ void *addr;
+};
+
+static struct shm_info *ShmInfo;
+
+
+static int shm_putinfo( struct shm_info *info );
+static int shm_updinfo( int i, struct shm_info *info );
+static int shm_getinfo( int shmid, struct shm_info *info );
+static int shm_getinfobyaddr( const void *addr, struct shm_info *info );
+
+
+static int shm_putinfo( struct shm_info *info )
+{
+ int i;
+
+ if( ShmInfo == NULL ) {
+ ShmInfo = calloc( SHMMAX, sizeof( struct shm_info ) );
+ if( ShmInfo == NULL ) return -1;
+ /* initialize ShmInfo */
+ for( i = 0; i < SHMMAX; i++ ) {
+ ShmInfo[i].shmid = -1;
+ }
+ }
+
+ /* search first free element */
+ i = 0;
+ while( i < SHMMAX && ShmInfo[i].shmid != -1 ) i++;
+ if( i >= SHMMAX ) {
+ errno = ENOSPC;
+ return -1;
+ }
+
+ memcpy( &ShmInfo[i], info, sizeof( struct shm_info ) );
+
+ return i;
+}
+
+static int shm_updinfo( int i, struct shm_info *info )
+{
+ if( i >= SHMMAX ) return -1;
+ if( ShmInfo == NULL ) return -1;
+
+ memcpy( &ShmInfo[i], info, sizeof( struct shm_info ) );
+
+ return i;
+}
+
+static int shm_getinfo( int shmid, struct shm_info *info )
+{
+ int i;
+
+ if( ShmInfo == NULL ) return -1;
+
+ /* search element */
+ i = 0;
+ while( i < SHMMAX && ShmInfo[i].shmid != shmid ) i++;
+ if( i >= SHMMAX ) return -1;
+
+ memcpy( info, &ShmInfo[i], sizeof( struct shm_info ) );
+
+ return i;
+}
+
+static int shm_getinfobyaddr( const void *addr, struct shm_info *info )
+{
+ int i;
+
+ if( ShmInfo == ( struct shm_info * )-1 ) return -1;
+
+ /* search element */
+ i = 0;
+ while( i < SHMMAX && ShmInfo[i].addr != addr ) i++;
+ if( i >= SHMMAX ) return -1;
+
+ memcpy( info, &ShmInfo[i], sizeof( struct shm_info ) );
+
+ return i;
+}
+
+
+void *shmat( int shmid, const void *shmaddr, int shmflg )
+{
+ struct shm_info info;
+ int i;
+
+ i = shm_getinfo( shmid, &info );
+ if( i == -1 ) {
+ errno = EACCES;
+ return ( void * )-1;
+ }
+
+ info.addr = mmap( ( void * )shmaddr, info.size,
+ PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0 );
+ if( info.addr == MAP_FAILED ) return info.addr;
+
+ if( shm_updinfo( i, &info ) == -1 ) {
+ errno = EACCES;
+ return ( void * )-1;
+ }
+
+ return info.addr;
+}
+
+int shmdt( const void *addr )
+{
+ struct shm_info info;
+
+ if( shm_getinfobyaddr( addr, &info ) == -1 ) {
+ errno = EACCES;
+ return -1;
+ }
+
+ return munmap( ( void * )addr, info.size );
+}
+
+int shmctl( int shmid, int cmd, struct shmid_ds *buf )
+{
+ struct shm_info info;
+ char name[NAME_MAX+1];
+
+ /* IPC_RMID supported only */
+ if( cmd != IPC_RMID ) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if( shm_getinfo( shmid, &info ) == -1 ) {
+ errno = EACCES;
+ return -1;
+ }
+
+ return shm_unlink( itoa( info.key, name, 16 ) );
+}
+
+int shmget( key_t key, size_t size, int flags )
+{
+ char name[NAME_MAX+1];
+ int oflag = 0;
+ struct shm_info info;
+
+ if( flags & IPC_CREAT ) oflag |= O_CREAT;
+ if( flags & IPC_EXCL ) oflag |= O_EXCL;
+ if( flags & SHM_R ) {
+ if( flags & SHM_W ) oflag |= O_RDWR;
+ else oflag |= O_RDONLY;
+ }
+ info.shmid = shm_open( itoa( key, name, 16 ), oflag, MODE );
+
+ /* store shared memory information */
+ if( info.shmid != -1 ) {
+ info.key = key;
+ info.size = size;
+ info.addr = NULL;
+ if( shm_putinfo( &info ) == -1 ) return -1;
+ }
+
+ /* The size may only be set once. Ignore errors. */
+ ltrunc( info.shmid, size, SEEK_SET );
+
+ return info.shmid;
+}