You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mt...@apache.org on 2009/08/14 13:56:17 UTC
svn commit: r804172 - in /commons/sandbox/runtime/trunk/src/main/native:
Makefile.in include/arch/hpux/acr_arch_private.h os/hpux/shm.c
Author: mturk
Date: Fri Aug 14 11:56:16 2009
New Revision: 804172
URL: http://svn.apache.org/viewvc?rev=804172&view=rev
Log:
HP-UX doesn't have MAP_ANON
Added:
commons/sandbox/runtime/trunk/src/main/native/os/hpux/shm.c (with props)
Modified:
commons/sandbox/runtime/trunk/src/main/native/Makefile.in
commons/sandbox/runtime/trunk/src/main/native/include/arch/hpux/acr_arch_private.h
Modified: commons/sandbox/runtime/trunk/src/main/native/Makefile.in
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/Makefile.in?rev=804172&r1=804171&r2=804172&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/Makefile.in (original)
+++ commons/sandbox/runtime/trunk/src/main/native/Makefile.in Fri Aug 14 11:56:16 2009
@@ -174,7 +174,6 @@
$(SRCDIR)/os/unix/group.$(OBJ) \
$(SRCDIR)/os/unix/user.$(OBJ) \
$(SRCDIR)/os/unix/pmutex.$(OBJ) \
- $(SRCDIR)/os/unix/shm.$(OBJ) \
$(SRCDIR)/os/unix/signals.$(OBJ) \
$(SRCDIR)/os/unix/syslog.$(OBJ) \
$(SRCDIR)/os/unix/time.$(OBJ) \
@@ -184,6 +183,7 @@
$(SRCDIR)/os/hpux/platform.$(OBJ) \
$(SRCDIR)/os/hpux/pgroup.$(OBJ) \
$(SRCDIR)/os/hpux/puser.$(OBJ) \
+ $(SRCDIR)/os/hpux/shm.$(OBJ) \
$(SRCDIR)/os/hpux/os.$(OBJ)
ZLIB_OBJS=\
Modified: commons/sandbox/runtime/trunk/src/main/native/include/arch/hpux/acr_arch_private.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/arch/hpux/acr_arch_private.h?rev=804172&r1=804171&r2=804172&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/arch/hpux/acr_arch_private.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/arch/hpux/acr_arch_private.h Fri Aug 14 11:56:16 2009
@@ -41,8 +41,8 @@
/**
* Temporary APR flags
*/
-#define APR_USE_SHMEM_SHMGET 0
-#define APR_USE_SHMEM_MMAP_ANON 1
+#define APR_USE_SHMEM_SHMGET 1
+#define APR_USE_SHMEM_SHMGET_ANON 1
#define APR_USE_SYSVSEM_SERIALIZE 1
#define APR_USE_PTHREAD_SERIALIZE 1
#define APR_PROCESS_LOCK_IS_GLOBAL 0
@@ -56,9 +56,9 @@
#define APR_HAS_XTHREAD_FILES 0
#define APR_HAS_OS_UUID 0
#define APR_TCP_NOPUSH_FLAG 0
-#define APR_TCP_NODELAY_INHERITED 0
+#define APR_TCP_NODELAY_INHERITED 1
#define APR_O_NONBLOCK_INHERITED 0
-#define APR_HAS_LARGE_FILES 0
+#define APR_HAS_LARGE_FILES 1
/**
* Temporary APR private flags
Added: commons/sandbox/runtime/trunk/src/main/native/os/hpux/shm.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/hpux/shm.c?rev=804172&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/hpux/shm.c (added)
+++ commons/sandbox/runtime/trunk/src/main/native/os/hpux/shm.c Fri Aug 14 11:56:16 2009
@@ -0,0 +1,492 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "acr.h"
+#include "acr_private.h"
+#include "acr_arch.h"
+#include "acr_error.h"
+#include "acr_memory.h"
+#include "acr_string.h"
+#include "acr_descriptor.h"
+#include "acr_shm.h"
+
+#include <sys/mman.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/file.h>
+
+#if !defined(SHM_R)
+#define SHM_R 0400
+#endif
+#if !defined(SHM_W)
+#define SHM_W 0200
+#endif
+
+#define ACR_SHM_OWNER 0
+#define ACR_SHM_CHILD 1
+
+typedef struct memblock_t {
+ acr_uint32_t magic; /* Is this our memeory */
+ pid_t creator; /* Creator's process ID */
+ acr_size_t size;
+ acr_size_t length;
+} memblock_t;
+
+struct acr_shm_t {
+ void *base; /* base real address */
+ void *usable; /* base usable address */
+ acr_size_t reqsize; /* requested segment size */
+ acr_size_t realsize; /* actual segment size */
+ const char *filename; /* NULL if anonymous */
+ int shmid; /* shmem ID returned from shmget() */
+ key_t shmkey;
+};
+
+static int shm_owner_cleanup(void *shm, int type, unsigned int flags)
+{
+ int rc = 0;
+ acr_shm_t *m = (acr_shm_t *)shm;
+
+ if (type != ACR_DT_SHM) {
+ return ACR_EINVAL;
+ }
+ /* anonymous shared memory */
+ if (m->filename == NULL) {
+ if (shmdt(m->base) == -1) {
+ rc = ACR_GET_OS_ERROR();
+ }
+ }
+ /* name-based shared memory */
+ else {
+ /* Indicate that the segment is to be destroyed as soon
+ * as all processes have detached. This also disallows any
+ * new attachments to the segment.
+ */
+ if (shmctl(m->shmid, IPC_RMID, NULL) == -1 && errno != EINVAL) {
+ rc = ACR_GET_OS_ERROR();
+ goto cleanup;
+ }
+ if (shmdt(m->base) == -1) {
+ rc = ACR_GET_OS_ERROR();
+ goto cleanup;
+ }
+ if (access(m->filename, F_OK)) {
+ rc = ACR_SUCCESS;
+ }
+ else {
+ if (unlink(m->filename))
+ rc = ACR_GET_OS_ERROR();
+ }
+ }
+cleanup:
+ if (m->filename)
+ free((void *)(m->filename));
+ free(m);
+ return rc;
+}
+
+static int shm_child_cleanup(void *shm, int type, unsigned int flags)
+{
+ int rc = 0;
+ acr_shm_t *m = (acr_shm_t *)shm;
+
+ if (type != ACR_DT_SHM) {
+ return ACR_EINVAL;
+ }
+
+ if (m->filename == NULL) {
+ /* It doesn't make sense to detach from an
+ * anonymous memory segment.
+ */
+ rc = ACR_EINVAL;
+ }
+ else {
+ if (shmdt(m->base) == -1) {
+ rc = ACR_GET_OS_ERROR();
+ }
+ }
+ if (m->filename)
+ free((void *)(m->filename));
+ free(m);
+ return rc;
+}
+
+ACR_DECLARE(int) ACR_ShmClose(JNIEnv *_E, int shm)
+{
+ int rv;
+
+ rv = acr_ioh_close(shm);
+ if (rv && !IS_INVALID_HANDLE(_E)) {
+ if (rv == EACCES)
+ ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ESECURITY, 0);
+ else
+ ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EIO, rv);
+ }
+ return rv;
+}
+
+ACR_DECLARE(int) ACR_ShmRemove(JNIEnv *_E, const acr_pchar_t *filename)
+{
+ int rc = 0;
+ int file;
+ key_t shmkey;
+ int shmid;
+
+ /* Presume that the file already exists; just open for writing.
+ * Mode is not needed cause we don't use O_CREAT flag.
+ */
+ file = open(filename, O_WRONLY);
+ if (file < 0) {
+ rc = ACR_GET_OS_ERROR();
+ goto cleanup;
+ }
+
+ /* ftok() (on solaris at least) requires that the file actually
+ * exist before calling ftok().
+ */
+ shmkey = ftok(filename, 1);
+ if (shmkey == (key_t)-1) {
+ rc = ACR_GET_OS_ERROR();
+ close(file);
+ goto cleanup;
+ }
+ close(file);
+
+ if ((shmid = shmget(shmkey, 0, SHM_R | SHM_W)) < 0) {
+ rc = ACR_GET_OS_ERROR();
+ goto cleanup;
+ }
+
+ /* Indicate that the segment is to be destroyed as soon
+ * as all processes have detached. This also disallows any
+ * new attachments to the segment.
+ */
+ if (shmctl(shmid, IPC_RMID, NULL) == -1) {
+ rc = ACR_GET_OS_ERROR();
+ goto cleanup;
+ }
+
+cleanup:
+ unlink(filename);
+ if (rc && !IS_INVALID_HANDLE(_E)) {
+ if (rc == EACCES)
+ ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ESECURITY, 0);
+ else
+ ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EIO, rc);
+ }
+ return rc;
+}
+
+ACR_DECLARE(int) ACR_ShmCreate(JNIEnv *_E, acr_size_t reqsize,
+ const acr_pchar_t *filename)
+{
+ memblock_t hdr;
+ acr_shm_t *shm = NULL;
+ struct shmid_ds shmbuf;
+ int file; /* file where metadata is stored */
+ int rc = 0;
+ acr_size_t nbytes;
+
+ if (reqsize > ACR_SIZE_T_MAX) {
+ /* Guard against insane sizes */
+ if (!IS_INVALID_HANDLE(_E)) {
+ ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EINVAL, 0);
+ }
+ ACR_SET_OS_ERROR(ACR_EINVAL);
+ return -1;
+ }
+ shm = ACR_Calloc(_E, THROW_FMARK, sizeof(acr_shm_t));
+ if (!shm)
+ return -1;
+ /* Check if they want anonymous or name-based shared memory */
+ if (filename == NULL) {
+ shm->filename = NULL;
+ shm->reqsize = reqsize;
+ shm->realsize = reqsize;
+ shm->shmkey = IPC_PRIVATE
+ shm->shmid = shmget(shm->shmkey, shm->realsize,
+ SHM_R | SHM_W | IPC_CREAT);
+ if (shm->shmid < 0) {
+ rc = ACR_GET_OS_ERROR();
+ goto anonerr;
+ }
+ shm->base = shmat(shm->shmid, NULL, 0);
+ if (shm->base == (void *)-1) {
+ rc = ACR_GET_OS_ERROR();
+ goto anonerr;
+ }
+ shmbuf.shm_perm.uid = uid;
+ shmbuf.shm_perm.gid = gid;
+ if (shmctl(shm->shmid, IPC_SET, &shmbuf) == -1) {
+ rc = ACR_GET_OS_ERROR();
+ goto anonerr;
+ }
+ /* Remove the segment once use count hits zero.
+ * We will not attach to this segment again, since it is
+ * anonymous memory, so it is ok to mark it for deletion.
+ */
+ if (shmctl(shm->shmid, IPC_RMID, NULL) == -1) {
+ rc = ACR_GET_OS_ERROR();
+ goto anonerr;
+ }
+ shm->usable = shm->base;
+anonerr:
+ if (rc) {
+ free(shm);
+ if (!IS_INVALID_HANDLE(_E)) {
+ if (rc == EACCES)
+ ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ESECURITY, 0);
+ else
+ ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EIO, rc);
+ }
+ ACR_SET_OS_ERROR(rc);
+ return -1;
+ }
+ }
+ /* Name-based shared memory */
+ else {
+ shm->reqsize = reqsize;
+ shm->filename = ACR_StrdupA(_E, THROW_FMARK, filename);
+ if (!shm->filename) {
+ rc = ACR_GET_OS_ERROR();
+ free(shm);
+ ACR_SET_OS_ERROR(rc);
+ return -1;
+ }
+
+ shm->realsize = reqsize;
+
+ /* FIXME: APR_OS_DEFAULT is too permissive, switch to 600 I think.
+ * Unlike APR we use 0660 which is less permissive
+ */
+ file = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0660);
+ if (file < 0) {
+ rc = ACR_GET_OS_ERROR();
+ goto cleanup;
+ }
+
+ /* ftok() (on solaris at least) requires that the file actually
+ * exist before calling ftok(). */
+ shm->shmkey = ftok(filename, 1);
+ if (shm->shmkey == (key_t)-1) {
+ rc = ACR_GET_OS_ERROR();
+ goto cleanup;
+ }
+
+ if ((shm->shmid = shmget(shm->shmkey, shm->realsize,
+ SHM_R | SHM_W | IPC_CREAT | IPC_EXCL)) < 0) {
+ rc = ACR_GET_OS_ERROR();
+ goto cleanup;
+ }
+
+ if ((shm->base = shmat(shm->shmid, NULL, 0)) == (void *)-1) {
+ rc = ACR_GET_OS_ERROR();
+ goto cleanup;
+ }
+ shm->usable = shm->base;
+
+ if (shmctl(shm->shmid, IPC_STAT, &shmbuf) == -1) {
+ rc = ACR_GET_OS_ERROR();
+ goto cleanup;
+ }
+ shmbuf.shm_perm.uid = getuid();
+ shmbuf.shm_perm.gid = getgid();
+ if (shmctl(shm->shmid, IPC_SET, &shmbuf) == -1) {
+ rc = ACR_GET_OS_ERROR();
+ goto cleanup;
+ }
+
+ nbytes = sizeof(memblock_t);
+ hdr.creator = getpid();
+ hdr.magic = ACR_SHM_MAGIC;
+ hdr.size = shm->reqsize;
+ hdr.length = shm->realsize;
+ do {
+ rc = write(file,(const void *)&hdr, nbytes);
+ } while (rc == (acr_size_t)-1 && errno == EINTR);
+ if (rc == -1) {
+ rc = ACR_GET_OS_ERROR();
+ goto cleanup;
+ }
+cleanup:
+ if (file > 0)
+ rc = close(file);
+ if (rc) {
+ free((void *)(shm->filename));
+ free(shm);
+ if (!IS_INVALID_HANDLE(_E)) {
+ if (rc == EACCES)
+ ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ESECURITY, 0);
+ else
+ ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EIO, rc);
+ }
+ ACR_SET_OS_ERROR(rc);
+ shm = NULL;
+ }
+ }
+ if (shm) {
+ rc = acr_ioh_open(shm, ACR_DT_SHM, ACR_SHM_OWNER, shm_owner_cleanup);
+ return rc;
+ }
+ else
+ return -1;
+}
+
+ACR_DECLARE(int) ACR_ShmAttach(JNIEnv *_E,
+ const acr_pchar_t *filename)
+{
+ memblock_t hdr;
+ acr_shm_t *shm = NULL;
+ int file; /* file where metadata is stored */
+ int rc;
+ acr_size_t nbytes;
+
+ if (!filename) {
+ ACR_SET_OS_ERROR(ACR_EINVAL);
+ return -1;
+ }
+ shm = ACR_Calloc(_E, THROW_FMARK, sizeof(acr_shm_t));
+ if (!shm)
+ return -1;
+ shm->filename = ACR_StrdupA(_E, THROW_FMARK, filename);
+ if (!shm->filename) {
+ rc = ACR_GET_OS_ERROR();
+ free(shm);
+ ACR_SET_OS_ERROR(rc);
+ return -1;
+ }
+
+ file = open(filename, O_RDONLY);
+ if (file < 0) {
+ rc = ACR_GET_OS_ERROR();
+ goto cleanup;
+ }
+
+ nbytes = sizeof(memblock_t);
+
+ do {
+ rc = read(file, (void *)&hdr, nbytes);
+ } while (rc == -1 && errno == EINTR);
+ if (rc != nbytes) {
+ /* Wrong format */
+ rc = EBADF;
+ close(file);
+ goto cleanup;
+ }
+ rc = close(file);
+ if (rc) {
+ goto cleanup;
+ }
+ if (hdr.magic != ACR_SHM_MAGIC) {
+ /* Not created by us or corrupted */
+ rc = ACR_EBADF;
+ goto cleanup;
+ }
+ shm->reqsize = hdr.size;
+ shm->shmkey = ftok(filename, 1);
+ if (shm->shmkey == (key_t)-1) {
+ rc = ACR_GET_OS_ERROR();
+ goto cleanup;
+ }
+ if ((shm->shmid = shmget(shm->shmkey, 0, SHM_R | SHM_W)) == -1) {
+ rc = ACR_GET_OS_ERROR();
+ goto cleanup;
+ }
+ if ((shm->base = shmat(shm->shmid, NULL, 0)) == (void *)-1) {
+ rc = ACR_GET_OS_ERROR();
+ goto cleanup;
+ }
+ shm->usable = shm->base;
+ shm->realsize = shm->reqsize;
+
+cleanup:
+ if (rc) {
+ free((void *)(shm->filename));
+ free(shm);
+ if (!IS_INVALID_HANDLE(_E)) {
+ if (rc == EACCES)
+ ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ESECURITY, 0);
+ else
+ ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EIO, rc);
+ }
+ ACR_SET_OS_ERROR(rc);
+ shm = NULL;
+ }
+ if (shm) {
+ rc = acr_ioh_open(shm, ACR_DT_SHM, ACR_SHM_CHILD, shm_child_cleanup);
+ return rc;
+ }
+ else
+ return -1;
+}
+
+ACR_DECLARE(int) ACR_ShmPermSet(JNIEnv *_E, int shm, int perms,
+ acr_uid_t uid, acr_uid_t gid)
+{
+ int rc = 0;
+ struct shmid_ds shmbuf;
+ int shmid;
+ acr_shm_t *m = (acr_shm_t *)ACR_IOH(shm);
+
+ if (IS_INVALID_HANDLE(m) || ACR_IOH_TYPE(shm) != ACR_DT_SHM) {
+ rc = ACR_EINVAL;
+ goto cleanup;
+ }
+ if ((shmid = shmget(m->shmkey, 0, SHM_R | SHM_W)) == -1) {
+ rc = ACR_GET_OS_ERROR();
+ goto cleanup;
+ }
+ shmbuf.shm_perm.uid = uid;
+ shmbuf.shm_perm.gid = gid;
+ shmbuf.shm_perm.mode = ACR_UnixPermsToMode(perms);
+ if (shmctl(shmid, IPC_SET, &shmbuf) == -1) {
+ rc = ACR_GET_OS_ERROR();
+ goto cleanup;
+ }
+
+cleanup:
+ if (rc && !IS_INVALID_HANDLE(_E)) {
+ if (rc == EACCES)
+ ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ESECURITY, 0);
+ else
+ ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EIO, rc);
+ }
+ return rc;
+}
+
+ACR_DECLARE(void *) ACR_ShmGetBaseAddr(int shm)
+{
+ acr_shm_t *m = (acr_shm_t *)ACR_IOH(shm);
+
+ if (IS_INVALID_HANDLE(m) || ACR_IOH_TYPE(shm) != ACR_DT_SHM) {
+ ACR_SET_OS_ERROR(ACR_EINVAL);
+ return NULL;
+ }
+ else
+ return m->usable;
+}
+
+ACR_DECLARE(acr_size_t) ACR_ShmGetSize(int shm)
+{
+ acr_shm_t *m = (acr_shm_t *)ACR_IOH(shm);
+ if (IS_INVALID_HANDLE(m) || ACR_IOH_TYPE(shm) != ACR_DT_SHM) {
+ ACR_SET_OS_ERROR(ACR_EINVAL);
+ return 0;
+ }
+ else
+ return m->reqsize;
+}
+
Propchange: commons/sandbox/runtime/trunk/src/main/native/os/hpux/shm.c
------------------------------------------------------------------------------
svn:eol-style = native