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 2011/04/27 11:48:54 UTC
svn commit: r1097056 - in /commons/sandbox/runtime/trunk/src/main:
java/org/apache/commons/runtime/
java/org/apache/commons/runtime/platform/unix/
java/org/apache/commons/runtime/platform/windows/ native/
native/include/acr/ native/os/unix/ native/shared/
Author: mturk
Date: Wed Apr 27 09:48:53 2011
New Revision: 1097056
URL: http://svn.apache.org/viewvc?rev=1097056&view=rev
Log:
Add Exec stub
Added:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Exec.java (with props)
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/ExecImpl.java (with props)
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/unix/PosixExec.java (with props)
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/unix/PosixExecImpl.java (with props)
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/WindowsExec.java (with props)
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/WindowsExecImpl.java (with props)
commons/sandbox/runtime/trunk/src/main/native/os/unix/exec.c (with props)
Modified:
commons/sandbox/runtime/trunk/src/main/native/Makefile.unx.in
commons/sandbox/runtime/trunk/src/main/native/include/acr/sbuf.h
commons/sandbox/runtime/trunk/src/main/native/include/acr/stdtypes.h
commons/sandbox/runtime/trunk/src/main/native/include/acr/string.h
commons/sandbox/runtime/trunk/src/main/native/os/unix/arch_opts.h
commons/sandbox/runtime/trunk/src/main/native/os/unix/util.c
commons/sandbox/runtime/trunk/src/main/native/shared/string.c
Added: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Exec.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Exec.java?rev=1097056&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Exec.java (added)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Exec.java Wed Apr 27 09:48:53 2011
@@ -0,0 +1,51 @@
+/* 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.
+ */
+package org.apache.commons.runtime;
+
+/**
+ * Exec class.
+ * <p>
+ * </p>
+ *
+ * @since Runtime 1.0
+ */
+public abstract class Exec
+{
+
+ protected Exec()
+ {
+ // No Instance
+ }
+
+ private static final ExecImpl impl;
+
+ static {
+ impl = ExecImpl.get();
+ }
+
+ protected String name;
+ protected boolean owner;
+
+ public static Exec create()
+ throws OperationNotImplementedException,
+ SystemException
+ {
+ if (impl == null)
+ throw new OperationNotImplementedException();
+ return impl.create();
+ }
+
+}
Propchange: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Exec.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/ExecImpl.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/ExecImpl.java?rev=1097056&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/ExecImpl.java (added)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/ExecImpl.java Wed Apr 27 09:48:53 2011
@@ -0,0 +1,51 @@
+/* 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.
+ */
+package org.apache.commons.runtime;
+
+/**
+ * ExecImpl class.
+ * <p>
+ * </p>
+ *
+ * @since Runtime 1.0
+ */
+public abstract class ExecImpl
+{
+ private static final ExecImpl impl;
+ private static native ExecImpl init0()
+ throws OutOfMemoryError;
+
+ static {
+ impl = init0();
+ }
+
+ protected ExecImpl()
+ {
+ // No Instance
+ }
+
+ public static final ExecImpl get()
+ throws OperationNotImplementedException
+ {
+ if (impl == null)
+ throw new OperationNotImplementedException();
+ return impl;
+ }
+
+ public abstract Exec create();
+
+}
+
Propchange: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/ExecImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/unix/PosixExec.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/unix/PosixExec.java?rev=1097056&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/unix/PosixExec.java (added)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/unix/PosixExec.java Wed Apr 27 09:48:53 2011
@@ -0,0 +1,39 @@
+/* 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.
+ */
+package org.apache.commons.runtime.platform.unix;
+
+import org.apache.commons.runtime.Exec;
+import org.apache.commons.runtime.Errno;
+import org.apache.commons.runtime.Status;
+import org.apache.commons.runtime.InvalidArgumentException;
+import org.apache.commons.runtime.SystemException;
+
+/**
+ * PosixExec class.
+ * <p>
+ * </p>
+ *
+ * @since Runtime 1.0
+ */
+final class PosixExec extends Exec
+{
+
+ public PosixExec()
+ {
+
+ }
+
+}
Propchange: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/unix/PosixExec.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/unix/PosixExecImpl.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/unix/PosixExecImpl.java?rev=1097056&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/unix/PosixExecImpl.java (added)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/unix/PosixExecImpl.java Wed Apr 27 09:48:53 2011
@@ -0,0 +1,41 @@
+/* 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.
+ */
+package org.apache.commons.runtime.platform.unix;
+
+import org.apache.commons.runtime.Exec;
+import org.apache.commons.runtime.ExecImpl;
+
+/**
+ * PosixExecImpl class.
+ * <p>
+ * </p>
+ *
+ * @since Runtime 1.0
+ */
+final class PosixExecImpl extends ExecImpl
+{
+
+ public PosixExecImpl()
+ {
+ // No Instance
+ }
+
+ public Exec create()
+ {
+ return new PosixExec();
+ }
+
+}
Propchange: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/unix/PosixExecImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/WindowsExec.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/WindowsExec.java?rev=1097056&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/WindowsExec.java (added)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/WindowsExec.java Wed Apr 27 09:48:53 2011
@@ -0,0 +1,39 @@
+/* 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.
+ */
+package org.apache.commons.runtime.platform.windows;
+
+import org.apache.commons.runtime.Exec;
+import org.apache.commons.runtime.Errno;
+import org.apache.commons.runtime.Status;
+import org.apache.commons.runtime.InvalidArgumentException;
+import org.apache.commons.runtime.SystemException;
+
+/**
+ * WindowsExec class.
+ * <p>
+ * </p>
+ *
+ * @since Runtime 1.0
+ */
+final class WindowsExec extends Exec
+{
+
+ public WindowsExec()
+ {
+
+ }
+
+}
Propchange: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/WindowsExec.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/WindowsExecImpl.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/WindowsExecImpl.java?rev=1097056&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/WindowsExecImpl.java (added)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/WindowsExecImpl.java Wed Apr 27 09:48:53 2011
@@ -0,0 +1,41 @@
+/* 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.
+ */
+package org.apache.commons.runtime.platform.windows;
+
+import org.apache.commons.runtime.Exec;
+import org.apache.commons.runtime.ExecImpl;
+
+/**
+ * WindowsExecImpl class.
+ * <p>
+ * </p>
+ *
+ * @since Runtime 1.0
+ */
+final class WindowsExecImpl extends ExecImpl
+{
+
+ public WindowsExecImpl()
+ {
+ // No Instance
+ }
+
+ public Exec create()
+ {
+ return new WindowsExec();
+ }
+
+}
Propchange: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/WindowsExecImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: commons/sandbox/runtime/trunk/src/main/native/Makefile.unx.in
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/Makefile.unx.in?rev=1097056&r1=1097055&r2=1097056&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/Makefile.unx.in (original)
+++ commons/sandbox/runtime/trunk/src/main/native/Makefile.unx.in Wed Apr 27 09:48:53 2011
@@ -61,6 +61,7 @@ ASMSOURCES=\
UNIX_SOURCES=\
$(TOPDIR)/os/unix/dso.c \
+ $(TOPDIR)/os/unix/exec.c \
$(TOPDIR)/os/unix/execmem.c \
$(TOPDIR)/os/unix/init.c \
$(TOPDIR)/os/unix/platform.c \
Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr/sbuf.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr/sbuf.h?rev=1097056&r1=1097055&r2=1097056&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr/sbuf.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr/sbuf.h Wed Apr 27 09:48:53 2011
@@ -68,7 +68,7 @@ char *AcrSbTrim(acr_sb_t *);
int AcrSbOverflowed(acr_sb_t *);
void AcrSbFinish(acr_sb_t *);
void AcrSbFlush(acr_sb_t *);
-char *AcrSbFetach(acr_sb_t *);
+char *AcrSbDetach(acr_sb_t *);
int AcrSbLen(acr_sb_t *);
int AcrSbCapacity(acr_sb_t *);
int AcrSbDone(acr_sb_t *);
Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr/stdtypes.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr/stdtypes.h?rev=1097056&r1=1097055&r2=1097056&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr/stdtypes.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr/stdtypes.h Wed Apr 27 09:48:53 2011
@@ -164,4 +164,12 @@ struct rlimit {
# define IOV_MAX 1024
#endif
+/** Generic buffer structure */
+typedef struct acr_buf_t {
+ char *buf;
+ acr_size_t len;
+ acr_size_t pos;
+ acr_size_t use;
+} acr_buf_t;
+
#endif /* _ACR_STDTYPES_H_ */
Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr/string.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr/string.h?rev=1097056&r1=1097055&r2=1097056&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr/string.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr/string.h Wed Apr 27 09:48:53 2011
@@ -169,6 +169,16 @@ AcrMszStrToStringArrayA(JNI_STDENV, cons
jobjectArray
AcrMszStrToStringArrayW(JNI_STDENV, const wchar_t *s);
+void
+AcrFreeStringArray(void **arr);
+
+char **
+AcrGetJavaStringArrayA(JNI_STDENV, jobjectArray arr);
+
+wchar_t **
+AcrGetJavaStringArrayW(JNI_STDENV, jobjectArray arr);
+
+
#ifdef __cplusplus
}
#endif
Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/arch_opts.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/arch_opts.h?rev=1097056&r1=1097055&r2=1097056&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/arch_opts.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/arch_opts.h Wed Apr 27 09:48:53 2011
@@ -41,6 +41,19 @@ ACR_INLINE(int) s_close(int fd)
return r_close(fd);
}
+ACR_INLINE(int) i_close(int *fd)
+{
+ if (fd != 0) {
+ int fc = *fd;
+ *fd = -1;
+ return s_close(fc);
+ }
+ else {
+ errno = EINVAL;
+ return -1;
+ }
+}
+
/* restartable dup2() */
ACR_INLINE(int) r_dup2(int oldfd, int newfd)
{
@@ -74,11 +87,70 @@ ACR_INLINE(ssize_t) r_write(int fd, cons
return w;
}
+/* restartable pread() */
+ACR_INLINE(ssize_t) r_pread(int fd, void *buf, size_t count, off_t offset)
+{
+ ssize_t r;
+ do {
+ r = pread(fd, buf, count, offset);
+ } while (r == -1 && errno == EINTR);
+
+ return r;
+}
+
+/* restartable pwrite() */
+ACR_INLINE(ssize_t) r_pwrite(int fd, const void *buf, size_t count, off_t offset)
+{
+ ssize_t w;
+ do {
+ w = pwrite(fd, buf, count, offset);
+ } while (w == -1 && errno == EINTR);
+
+ return w;
+}
+
+ACR_INLINE(ssize_t) f_write(int fd, const void *buf, size_t count)
+{
+ ssize_t t = 0;
+ ssize_t w;
+ ssize_t c = (ssize_t)count;
+ const char *p = (const char *)buf;
+ do {
+ w = r_write(fd, p, c);
+ if (w > 0) {
+ p += w;
+ c -= w;
+ t += w;
+ }
+ } while (w >= 0 && c > 0);
+ return t;
+}
+
+ACR_INLINE(ssize_t) f_read(int fd, void *buf, size_t count)
+{
+ ssize_t t = 0;
+ ssize_t r;
+ ssize_t c = (ssize_t)count;
+ char *p = (char *)buf;
+ do {
+ r = r_read(fd, p, c);
+ if (r > 0) {
+ p += r;
+ c -= r;
+ t += r;
+ }
+ } while (r >= 0 && c > 0);
+ return t;
+}
+
+int AcrFdwalk(int (*func)(void *data , int fd), void *cd);
int AcrNonblock(int fd, int on);
int AcrCloseOnExec(int fd, int on);
int AcrWaitIO(int fd, int timeout, int events);
int AcrNullPipe(int flags, int fd);
int AcrPipePair(int pd[2], int flags);
+int AcrSigIgnore(int signo);
+int AcrSigDefault(int signo);
#endif /* _ACR_ARCH_OPTS_H_ */
Added: commons/sandbox/runtime/trunk/src/main/native/os/unix/exec.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/exec.c?rev=1097056&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/exec.c (added)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/exec.c Wed Apr 27 09:48:53 2011
@@ -0,0 +1,650 @@
+/* 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/error.h"
+#include "acr/clazz.h"
+#include "acr/memory.h"
+#include "acr/iodefs.h"
+#include "acr/port.h"
+#include "acr/sbuf.h"
+#include "acr/time.h"
+#include "arch_opts.h"
+#include <poll.h>
+
+#define PROC_TIMEOUT_STEP 100
+#define PROC_BUFFER_SIZE 512
+
+#define PIPE_STDINP 0
+#define PIPE_STDINP_RDS 0
+#define PIPE_STDINP_WRS 1
+#define PIPE_STDOUT 2
+#define PIPE_STDOUT_RDS 2
+#define PIPE_STDOUT_WRS 3
+#define PIPE_STDERR 4
+#define PIPE_STDERR_RDS 4
+#define PIPE_STDERR_WRS 5
+#define PIPE_SIGERR 6
+#define PIPE_SIGERR_RDS 6
+#define PIPE_SIGERR_WRS 7
+#define PIPE_SIGPID 8
+#define PIPE_SIGPID_RDS 8
+#define PIPE_SIGPID_WRS 9
+#define PIPE_COUNT 10
+
+typedef struct acr_limit_t {
+ /** Process timeout in miliseconds
+ */
+ int timeout;
+ struct rlimit *cpu;
+ struct rlimit *mem;
+ struct rlimit *nproc;
+ struct rlimit *nfile;
+} acr_limit_t;
+
+typedef struct acr_proc_t {
+ /** Process timeout in miliseconds
+ */
+ acr_limit_t limit;
+ pid_t pid;
+ int flags;
+ int exitwhy;
+ int exitval;
+ uid_t uid;
+ gid_t gid;
+ mode_t mask;
+ acr_buf_t out;
+ acr_buf_t err;
+} acr_proc_t;
+
+J_DECLARE_CLAZZ = {
+ INVALID_FIELD_OFFSET,
+ 0,
+ 0,
+ 0,
+ ACR_UNX_CP "PosixExecImpl"
+};
+
+J_DECLARE_M_ID(0000) = {
+ 0,
+ "<init>",
+ "()V"
+};
+
+static int _setplimit(acr_limit_t *limit)
+{
+ if (limit == 0)
+ return 0;
+#if HAVE_SETRLIMIT
+#ifdef RLIMIT_CPU
+ if (limit->cpu != 0 &&
+ setrlimit(RLIMIT_CPU, limit->cpu) != 0)
+ return errno;
+#endif
+#ifdef RLIMIT_NPROC
+ if (limit->nproc != 0 &&
+ setrlimit(RLIMIT_NPROC, limit->nproc) != 0)
+ return errno;
+#endif
+#ifdef RLIMIT_NOFILE
+ if (limit->nfile != 0 &&
+ setrlimit(RLIMIT_NOFILE,limit->nfile) != 0)
+ return errno;
+#endif
+#if defined(RLIMIT_AS)
+ if (limit->mem != 0 &&
+ setrlimit(RLIMIT_AS, limit->mem) != 0)
+ return errno;
+#elif defined(RLIMIT_DATA)
+ if (limit->mem != 0 &&
+ setrlimit(RLIMIT_DATA, limit->mem) != 0)
+ return errno;
+#elif defined(RLIMIT_VMEM)
+ if (limit->mem != 0 &&
+ setrlimit(RLIMIT_VMEM, limit->mem) != 0)
+ return errno;
+#endif
+#endif
+ return 0;
+}
+
+static int _fdwalker(void *data , int fd)
+{
+ int i;
+ int *pipes = (int *)data;
+
+ if (fd < 3) {
+ /* Do not close std file descriptors
+ */
+ return 0;
+ }
+ for (i = 0; i < PIPE_COUNT; i++) {
+ if (pipes[i] == fd) {
+ /* This is one of our own's.
+ */
+ return 0;
+ }
+ }
+ /* Close the file
+ */
+ return r_close(fd);
+}
+
+static int _run_exec(const char *executable,
+ char *const *argv,
+ char *const *envp,
+ const char *workdir,
+ acr_buf_t *out,
+ acr_buf_t *err,
+ acr_buf_t *inp,
+ acr_limit_t *limit,
+ int *retval)
+{
+ int i, rc = 0;
+ int exitwhy = 0;
+ int exitval = 0;
+ int pipes[PIPE_COUNT] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
+ int sigerr = 0;
+ int detach = 0;
+ pid_t pid;
+ pid_t sigpid = 0;
+ acr_sb_t obuf_s;
+ acr_sb_t ebuf_s;
+ acr_sb_t *obuf = 0;
+ acr_sb_t *ebuf = 0;
+ acr_buf_t ibuf = { 0, 0, 0, 0};
+
+ /* By default process terminates when writting to a
+ * pipe with no readers.
+ * Ignore SIGPIPE
+ */
+ AcrSigIgnore(SIGPIPE);
+ if (limit != 0 && limit->timeout == 0)
+ detach = 1;
+ /* Create signaling pipe that is used both for reporting the
+ * failed exec and syncing with exec.
+ */
+ if ((rc = AcrPipePair(&pipes[PIPE_SIGERR], ACR_PIPE_FULL_BLOCK)))
+ goto cleanup;
+ if (detach) {
+ /* In case of daemon process, create a signaling pipe that is used
+ * for reporting the granchild's pid to the parent.
+ */
+ if ((rc = AcrPipePair(&pipes[PIPE_SIGPID], ACR_PIPE_FULL_BLOCK)))
+ goto cleanup;
+ }
+ else {
+ if (inp != 0 && inp->buf != 0 && inp->len != 0) {
+ if ((rc = AcrPipePair(&pipes[PIPE_STDINP], ACR_PIPE_READ_BLOCK)))
+ goto cleanup;
+ ibuf.buf = inp->buf;
+ ibuf.len = inp->len;
+ }
+ if (out != 0) {
+ if ((rc = AcrPipePair(&pipes[PIPE_STDOUT], ACR_PIPE_WRITE_BLOCK)))
+ goto cleanup;
+ if ((rc = AcrSbInitAuto(&obuf_s, PROC_BUFFER_SIZE)))
+ goto cleanup;
+ obuf = &obuf_s;
+ }
+ if (err != 0 && err != out) {
+ if ((rc = AcrPipePair(&pipes[PIPE_STDERR], ACR_PIPE_WRITE_BLOCK)))
+ goto cleanup;
+ if ((rc = AcrSbInitAuto(&ebuf_s, PROC_BUFFER_SIZE)))
+ goto cleanup;
+ ebuf = &ebuf_s;
+ }
+ }
+ pid = fork();
+ if (pid < 0) {
+ rc = ACR_GET_OS_ERROR();
+ goto cleanup;
+ }
+ else if (pid == 0) {
+ /* Child process */
+
+ /* Close child side of pipes
+ */
+ i_close(&pipes[PIPE_STDINP_WRS]);
+ i_close(&pipes[PIPE_STDOUT_RDS]);
+ i_close(&pipes[PIPE_STDERR_RDS]);
+ i_close(&pipes[PIPE_SIGERR_RDS]);
+ i_close(&pipes[PIPE_SIGPID_RDS]);
+
+ /* Make sure the signaling pipes are closed on exec.
+ * This forces parent to wait until actual
+ * exec is performed or until the error is
+ * written to the signal pipe.
+ * In case of detached process the close
+ */
+ if (!detach) {
+ AcrCloseOnExec(pipes[PIPE_SIGERR_WRS], 1);
+ AcrCloseOnExec(pipes[PIPE_SIGPID_WRS], 1);
+ }
+
+ if (IS_VALID_STR(workdir) && chdir(workdir) == -1) {
+ /* Failed changing the current directoty */
+ rc = ACR_GET_OS_ERROR();
+ goto child_cleanup;
+ }
+ /* Set the real os SIGCHLD child handler.
+ */
+ AcrSigDefault(SIGCHLD);
+
+ close(STDIN_FILENO);
+ if (pipes[PIPE_STDINP_RDS] == -1) {
+ /* Redirect stdin to /dev/null
+ */
+ pipes[PIPE_STDINP_RDS] = AcrNullPipe(O_RDONLY, -1);
+ if (pipes[PIPE_STDINP_RDS] == -1) {
+ rc = ACR_GET_OS_ERROR();
+ goto child_cleanup;
+ }
+ }
+ if (dup2(pipes[PIPE_STDINP_RDS], STDIN_FILENO) == -1) {
+ rc = ACR_GET_OS_ERROR();
+ goto child_cleanup;
+ }
+ i_close(&pipes[PIPE_STDINP_RDS]);
+
+ close(STDOUT_FILENO);
+ close(STDERR_FILENO);
+ if (pipes[PIPE_STDOUT_WRS] == -1) {
+ /* Redirect stdout to /dev/null
+ */
+ pipes[PIPE_STDOUT_WRS] = AcrNullPipe(O_WRONLY, -1);
+ if (pipes[PIPE_STDOUT_WRS] == -1) {
+ rc = ACR_GET_OS_ERROR();
+ goto child_cleanup;
+ }
+ }
+ if (dup2(pipes[PIPE_STDOUT_WRS], STDOUT_FILENO) == -1) {
+ rc = ACR_GET_OS_ERROR();
+ goto child_cleanup;
+ }
+ if (pipes[PIPE_STDERR_WRS] == -1) {
+ if (out == 0) {
+ pipes[PIPE_STDERR_WRS] = AcrNullPipe(O_WRONLY, -1);
+ if (pipes[PIPE_STDERR_WRS] == -1) {
+ rc = ACR_GET_OS_ERROR();
+ goto child_cleanup;
+ }
+ }
+ else
+ pipes[PIPE_STDERR_WRS] = pipes[PIPE_STDOUT_WRS];
+ }
+ if (dup2(pipes[PIPE_STDERR_WRS], STDERR_FILENO) == -1) {
+ rc = ACR_GET_OS_ERROR();
+ goto child_cleanup;
+ }
+ if (pipes[PIPE_STDERR_WRS] != pipes[PIPE_STDOUT_WRS])
+ i_close(&pipes[PIPE_STDERR_WRS]);
+ i_close(&pipes[PIPE_STDOUT_WRS]);
+ /* Close all descriptors except our pipes
+ * using fdwalk
+ */
+ AcrFdwalk(_fdwalker, pipes);
+
+ if ((rc = _setplimit(limit)) != 0)
+ goto child_cleanup;
+ if (detach) {
+ /* Time to do detach the process.
+ */
+
+ /* Should this be configurable ?
+ */
+ umask(0077);
+
+ if (IS_EMPTY_STR(workdir) && chdir("/") == -1) {
+ rc = ACR_GET_OS_ERROR();
+ goto child_cleanup;
+ }
+ /* Second fork
+ */
+ pid = fork();
+ if (pid < 0) {
+ /* Second fork failed.
+ * Time to bail out
+ */
+ rc = ACR_GET_OS_ERROR();
+ goto child_cleanup;
+ }
+ else if (pid == 0) {
+ /* We are inside grand child process
+ */
+ AcrCloseOnExec(pipes[PIPE_SIGERR_WRS], 1);
+ AcrCloseOnExec(pipes[PIPE_SIGPID_WRS], 1);
+
+ if (setsid() == -1) {
+ rc = ACR_GET_OS_ERROR();
+ goto child_cleanup;
+ }
+ /* Setup daemon signaling.
+ */
+ AcrSigIgnore(SIGPIPE);
+ AcrSigIgnore(SIGTTOU);
+ AcrSigIgnore(SIGTTIN);
+ AcrSigIgnore(SIGTSTP);
+
+ /* Report our pid to the parent
+ */
+ pid = getpid();
+ f_write(pipes[PIPE_SIGPID_WRS], &pid, sizeof(pid_t));
+ }
+ else {
+ /* We are done with the master child.
+ */
+ exit(0);
+ }
+ }
+ if (envp != 0)
+ execve(executable, argv, envp);
+ else
+ execv(executable, argv);
+ rc = ACR_GET_OS_ERROR();
+
+child_cleanup:
+ /* Still here?
+ */
+ f_write(pipes[PIPE_SIGERR_WRS], &rc, sizeof(int));
+ /* Alternative to exit() could be
+ * kill(info.pid, 9);
+ */
+ exit(0x80 + rc);
+ }
+ else {
+ /* Parent process */
+ struct pollfd ps[3];
+ char buf[PROC_BUFFER_SIZE];
+ int npipes = 0;
+ int pipelining = 1;
+ pid_t child = pid;
+ int polltime = -1;
+ acr_time_t endat = 0;
+ ssize_t rd, wr;
+ /* Close parent side of pipes
+ */
+ i_close(&pipes[PIPE_STDINP_RDS]);
+ i_close(&pipes[PIPE_STDOUT_WRS]);
+ i_close(&pipes[PIPE_STDERR_WRS]);
+ i_close(&pipes[PIPE_SIGERR_WRS]);
+ i_close(&pipes[PIPE_SIGPID_WRS]);
+/*
+ if (limit != 0 && limit->timeout > 0) {
+ endat = AcrTimeNow() + AcrTimeFromMsec(limit->timeout);
+ polltime = PROC_TIMEOUT_STEP;
+ }
+*/
+ if (pipes[PIPE_STDINP_WRS] == -1 &&
+ pipes[PIPE_STDOUT_RDS] == -1 &&
+ pipes[PIPE_STDERR_RDS] == -1)
+ pipelining = 0;
+ /* Handshake with the child process.
+ * If the read is sucessful it means that
+ * either init or execv inside child failed.
+ * However in case of detached proces this
+ * is valid struct informing about grandchild pid.
+ */
+ rd = r_read(pipes[PIPE_SIGERR_RDS], &sigerr, sizeof(int));
+ i_close(&pipes[PIPE_SIGERR_RDS]);
+ if (rd == sizeof(int)) {
+ /* We have received error status
+ * from the child
+ */
+ pipelining = 0;
+ }
+ else {
+ /* Guard againts partial reads */
+ sigerr = 0;
+ }
+ if (detach) {
+ rd = r_read(pipes[PIPE_SIGPID_RDS], &sigpid, sizeof(pid_t));
+ i_close(&pipes[PIPE_SIGPID_RDS]);
+ if (rd == sizeof(pid_t)) {
+ /* We have received the grand child's pid.
+ */
+ pipelining = 0;
+ }
+ else {
+ /* Guard againts partial reads */
+ sigpid = 0;
+ }
+ }
+ while (pipelining) {
+ npipes = 0;
+ if (pipes[PIPE_STDINP_WRS] != -1) {
+ ps[npipes].fd = pipes[PIPE_STDINP_WRS];
+ ps[npipes].events = POLLOUT;
+ ps[npipes].revents = 0;
+ npipes++;
+ }
+ if (pipes[PIPE_STDOUT_RDS] != -1) {
+ ps[npipes].fd = pipes[PIPE_STDOUT_RDS];
+ ps[npipes].events = POLLIN;
+ ps[npipes].revents = 0;
+ npipes++;
+ }
+ if (pipes[PIPE_STDERR_RDS] != -1) {
+ ps[npipes].fd = pipes[PIPE_STDERR_RDS];
+ ps[npipes].events = POLLIN;
+ ps[npipes].revents = 0;
+ npipes++;
+ }
+ if (npipes) {
+ do {
+ rc = poll(ps, npipes, polltime);
+ } while (rc == -1 && errno == EINTR);
+ if (rc < 1) {
+ if (polltime == -1 || rc == -1)
+ break;
+ /* No events fired within PROC_TIMEOUT_STEP.
+ * Check if we reached the abolute
+ */
+ if (AcrTimeNow() < endat)
+ continue;
+ /* Send SIGTERM to the child
+ */
+ kill(pid, SIGTERM);
+ break;
+ }
+ for (i = 0; i < npipes; i++) {
+ /* Loop trough every pollfd and check for the
+ * returned events.
+ */
+ if (pipes[PIPE_STDINP_WRS] == ps[i].fd && ps[i].revents) {
+ wr = 0;
+ if (ps[i].revents & POLLOUT) {
+ wr = r_write(pipes[PIPE_STDINP_WRS],
+ ibuf.buf + ibuf.use,
+ ibuf.len - ibuf.use);
+ }
+ if (wr > 0) {
+ ibuf.use += (int)wr;
+ if (ibuf.len == ibuf.use) {
+ /* Closing the stdin should cause
+ * EOF in the child.
+ */
+ i_close(&pipes[PIPE_STDINP_WRS]);
+ }
+ }
+ else {
+ if (wr != -1 || !ACR_STATUS_IS_EAGAIN(errno))
+ i_close(&pipes[PIPE_STDINP_WRS]);
+ }
+ }
+ if (pipes[PIPE_STDOUT_RDS] == ps[i].fd && ps[i].revents) {
+ rd = 0;
+ if (ps[i].revents & POLLIN) {
+ rd = r_read(pipes[PIPE_STDOUT_RDS],
+ buf, PROC_BUFFER_SIZE);
+ }
+ if (rd > 0) {
+ if (AcrSbCatb(obuf, buf, rd)) {
+ /* Error appending to the buffer.
+ * We have probably reach the limit or ENOMEM
+ */
+ pipelining = 0;
+ break;
+ }
+ if (ps[i].revents & POLLHUP)
+ i_close(&pipes[PIPE_STDERR_RDS]);
+ }
+ else {
+ if (rd != -1 || !ACR_STATUS_IS_EAGAIN(errno))
+ i_close(&pipes[PIPE_STDOUT_RDS]);
+ }
+ }
+ if (pipes[PIPE_STDERR_RDS] == ps[i].fd && ps[i].revents) {
+ rd = 0;
+ if (ps[i].revents & POLLIN) {
+ rd = r_read(pipes[PIPE_STDERR_RDS],
+ buf, PROC_BUFFER_SIZE);
+ }
+ if (rd > 0) {
+ if (AcrSbCatb(ebuf, buf, rd)) {
+ /* Error appending to the buffer.
+ * We have probably reach the limit or ENOMEM
+ */
+ pipelining = 0;
+ break;
+ }
+ if (ps[i].revents & POLLHUP)
+ i_close(&pipes[PIPE_STDERR_RDS]);
+ }
+ else {
+ if (rd != -1 || !ACR_STATUS_IS_EAGAIN(errno))
+ i_close(&pipes[PIPE_STDERR_RDS]);
+ }
+ }
+ }
+ }
+ else {
+ /* All pipes are closed
+ */
+ pipelining = 0;
+ }
+ }
+
+ /* Finished child stream processing.
+ * Cleanup pipes.
+ */
+ i_close(&pipes[PIPE_STDINP_WRS]);
+ i_close(&pipes[PIPE_STDOUT_RDS]);
+ i_close(&pipes[PIPE_STDERR_RDS]);
+
+ do {
+ /* TODO: We should consider using timeout here as well
+ * if set, instead infinite wait.
+ */
+ child = waitpid(pid, &exitval, WUNTRACED);
+ } while (child == -1 && errno == EINTR);
+
+ if (sigerr) {
+ /* Error reported from child
+ */
+ exitwhy = ACR_CHILD_ERROR;
+ exitval = sigerr;
+ goto finished;
+ }
+ if (detach) {
+ if (sigpid) {
+ /* We have a pid from the grand child
+ */
+ exitwhy = ACR_CHILD_DONE;
+ exitval = sigpid;
+ }
+ else {
+ /* We didn't recive the valid grandchild's pid
+ * XXX: Check for a valid return value
+ */
+ exitwhy = ACR_CHILD_ERROR;
+ exitval = child;
+ }
+ goto finished;
+ }
+ switch (child) {
+ case 0:
+ /* Unexpected condition
+ */
+ exitwhy = ACR_CHILD_NOTDONE;
+ exitval = 0;
+ break;
+ case -1:
+ /* unexpected condition */
+ exitwhy = ACR_CHILD_NOTDONE;
+ exitval = ACR_GET_OS_ERROR();
+ break;
+ default:
+ if (WIFEXITED(exitval)) {
+ exitwhy = ACR_CHILD_DONE;
+ exitval = WEXITSTATUS(exitval);
+ }
+ else if (WIFSIGNALED(exitval)) {
+ exitwhy = ACR_CHILD_SIGNAL;
+#ifdef WCOREDUMP
+ if (WCOREDUMP(exitval))
+ exitwhy = ACR_CHILD_SIGNAL_CORE;
+#endif
+ exitval = WTERMSIG(exitval);
+ }
+ else {
+ /* unexpected condition */
+ exitwhy = ACR_CHILD_ERROR;
+ exitval = child;
+ }
+ break;
+ }
+ }
+
+finished:
+ AcrSigDefault(SIGPIPE);
+ if (obuf != 0) {
+ AcrSbPutb(obuf, 0);
+ AcrSbPutb(obuf, 0);
+ out->len = AcrSbLen(obuf);
+ out->buf = AcrSbDetach(obuf);
+ }
+ if (ebuf != 0) {
+ AcrSbPutb(ebuf, 0);
+ AcrSbPutb(ebuf, 0);
+ err->len = AcrSbLen(ebuf);
+ err->buf = AcrSbDetach(ebuf);
+ }
+ if (inp != 0)
+ inp->use = ibuf.use;
+ *retval = exitval;
+ return exitwhy;
+
+cleanup:
+ AcrSbFree(obuf);
+ AcrSbFree(ebuf);
+ for (i = 0; i < PIPE_COUNT; i++)
+ s_close(pipes[i]);
+ AcrSigDefault(SIGPIPE);
+ *retval = rc;
+ return ACR_PARENT_ERROR;
+}
+
+ACR_JNI_EXPORT(jobject, ExecImpl, init0)(JNI_STDARGS)
+{
+ if (_clazzn.u == 1)
+ return (*env)->NewObject(env, _clazzn.i, J4MID(0000));
+ if (AcrLoadClass(env, &_clazzn, 0) != 0)
+ return 0;
+ R_LOAD_METHOD(0000, 0);
+ _clazzn.u = 1;
+ return (*env)->NewObject(env, _clazzn.i, J4MID(0000));
+}
+
Propchange: commons/sandbox/runtime/trunk/src/main/native/os/unix/exec.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/util.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/util.c?rev=1097056&r1=1097055&r2=1097056&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/util.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/util.c Wed Apr 27 09:48:53 2011
@@ -21,6 +21,91 @@
#include "arch_opts.h"
#include <poll.h>
+#if HAVE_FDWALK
+int AcrFdwalk(int (*func)(void *data , int fd), void *cd)
+{
+ return fdwalk(func, cd);
+}
+
+#else
+# if defined(_LINUX)
+# include <dirent.h>
+# define PROCFS_SELF_FD "/proc/self/fd"
+
+int AcrFdwalk(int (*func)(void *data , int fd), void *cd)
+{
+ DIR *pd;
+ struct dirent *pe;
+ int rc = 0;
+ int se;
+ if (!(pd = opendir(PROCFS_SELF_FD)))
+ return -1;
+
+ while ((pe = readdir(pd))) {
+ int fd;
+ long fv;
+ char *ep;
+ if (*pe->d_name == '.')
+ continue;
+ /* To distinguish success/failure after strtol call
+ */
+ errno = 0;
+ fv = strtol(pe->d_name, &ep, 10);
+ /* Check for various possible errors */
+ if ((errno == ERANGE && (fv == LONG_MAX || fv == LONG_MIN)) ||
+ (errno != 0 && fv == 0) ||
+ (errno != 0 || !ep || *ep)) {
+ /* Not an numbered entry.
+ */
+ continue;
+ }
+ if (fv < 0 || fv > INT_MAX)
+ continue;
+ else
+ fd = (int)fv;
+ if (fd == dirfd(pd))
+ continue;
+ if ((rc = (*func)(cd, fd)))
+ break;
+ }
+ if (rc)
+ se = errno;
+ closedir(pd);
+ if (rc)
+ errno = se;
+ return rc;
+}
+
+# else
+# if HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+# endif
+int AcrFdwalk(int (*func)(void *, int), void *cd)
+{
+ int rc = 0;
+ int fd;
+ int fm = 1024;
+# if HAVE_SYS_RESOURCE_H
+ struct rlimit rl;
+
+ if (getrlimit(RLIMIT_NOFILE, &rl) == 0 && rl.rlim_max != RLIM_INFINITY)
+ fm = (int)rl.rlim_max;
+ else
+# else
+ fm = sysconf(_SC_OPEN_MAX);
+# endif
+
+ for (fd = 0; fd < fm; fd++) {
+ errno = 0;
+ rc = (*func)(cd, fd);
+ if (rc && errno != ENOENT && errno != EBADF)
+ break;
+ }
+ return rc;
+}
+# endif /* _LINUX */
+#endif /* HAVE_FDWALK */
+
int
AcrNonblock(int fd, int on)
{
@@ -211,3 +296,89 @@ finally:
return rc;
}
+
+#if defined(__NETBSD) || defined(__DARWIN)
+static void avoid_zombies(int signo)
+{
+ int exit_status;
+
+ while (waitpid(-1, &exit_status, WNOHANG) > 0) {
+ /* do nothing */
+ }
+}
+#endif /* DARWIN */
+
+int AcrSigIgnore(int signo)
+{
+ int rc = -1;
+ struct sigaction act, oact;
+
+ if (signo <= 0 || signo >= NSIG) {
+ return EINVAL;
+ }
+ memset(&act, 0, sizeof(struct sigaction));
+
+ sigemptyset(&act.sa_mask);
+ act.sa_handler = SIG_IGN;
+ act.sa_flags = 0;
+#ifdef SA_INTERRUPT /* SunOS */
+ act.sa_flags |= SA_INTERRUPT;
+#endif
+ if (signo != SIGALRM)
+ act.sa_flags |= SA_RESTART;
+#ifdef SA_NOCLDSTOP
+ if (signo == SIGCHLD)
+ act.sa_flags |= SA_NOCLDSTOP;
+#endif
+#ifdef SA_NOCLDWAIT
+ if (signo == SIGCHLD)
+ act.sa_flags |= SA_NOCLDWAIT;
+#endif
+#if defined(__NETBSD) || defined(__DARWIN)
+ /* ignoring SIGCHLD or leaving the default disposition doesn't avoid zombies,
+ * and there is no SA_NOCLDWAIT flag, so catch the signal and reap status in
+ * the handler to avoid zombies
+ */
+ if (signo == SIGCHLD) {
+ act.sa_handler = avoid_zombies;
+ }
+#endif
+ rc = sigaction(signo, &act, &oact);
+ if (rc < 0)
+ return errno;
+ else
+ return 0;
+}
+
+int AcrSigDefault(int signo)
+{
+ int rc = -1;
+ struct sigaction act, oact;
+
+ if (signo <= 0 || signo >= NSIG) {
+ return EINVAL;
+ }
+ memset(&act, 0, sizeof(struct sigaction));
+
+ sigemptyset(&act.sa_mask);
+ act.sa_handler = SIG_DFL;
+ act.sa_flags = 0;
+#ifdef SA_INTERRUPT /* SunOS */
+ act.sa_flags |= SA_INTERRUPT;
+#endif
+ if (signo != SIGALRM)
+ act.sa_flags |= SA_RESTART;
+#ifdef SA_NOCLDSTOP
+ if (signo == SIGCHLD)
+ act.sa_flags |= SA_NOCLDSTOP;
+#endif
+#ifdef SA_NOCLDWAIT
+ if (signo == SIGCHLD)
+ act.sa_flags |= SA_NOCLDWAIT;
+#endif
+ rc = sigaction(signo, &act, &oact);
+ if (rc < 0)
+ return errno;
+ else
+ return 0;
+}
Modified: commons/sandbox/runtime/trunk/src/main/native/shared/string.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/string.c?rev=1097056&r1=1097055&r2=1097056&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/shared/string.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/shared/string.c Wed Apr 27 09:48:53 2011
@@ -1055,6 +1055,72 @@ AcrNewJavaStringU(JNIEnv *env, const cha
return new_string_utf_8(env, str);
}
+void AcrFreeStringArray(void **arr)
+{
+ if (arr != 0) {
+ void **ap = arr;
+ while (*ap != 0) {
+ AcrFree(*ap);
+ ap++;
+ }
+ AcrFree(arr);
+ }
+}
+
+char **
+AcrGetJavaStringArrayA(JNI_STDENV, jobjectArray arr)
+{
+ char **ret = NULL;
+ jsize cnt;
+ jsize i;
+
+ if (arr == 0)
+ return 0;
+
+ cnt = (*env)->GetArrayLength(env, arr);
+ ret = ACR_MALLOC(char *, cnt + 1);
+ if (ret == 0)
+ return 0;
+ for (i = 0; i < cnt; i++) {
+ jstring str = (*env)->GetObjectArrayElement(env, arr, i);
+ if (str != 0) {
+ ret[i] = AcrGetJavaStringA(env, str, 0);
+ (*env)->DeleteLocalRef(env, str);
+ }
+ else
+ break;
+ }
+ ret[i] = 0;
+ return ret;
+}
+
+wchar_t **
+AcrGetJavaStringArrayW(JNI_STDENV, jobjectArray arr)
+{
+ wchar_t **ret = NULL;
+ jsize cnt;
+ jsize i;
+
+ if (arr == 0)
+ return 0;
+
+ cnt = (*env)->GetArrayLength(env, arr);
+ ret = (wchar_t **)ACR_MALLOC(wchar_t *, cnt + 1);
+ if (ret == 0)
+ return 0;
+ for (i = 0; i < cnt; i++) {
+ jstring str = (*env)->GetObjectArrayElement(env, arr, i);
+ if (str) {
+ ret[i] = AcrGetJavaStringW(env, str, 0);
+ (*env)->DeleteLocalRef(env, str);
+ }
+ else
+ break;
+ }
+ ret[i] = 0;
+ return ret;
+}
+
#if defined(ENABLE_TEST_PRIVATE)
ACR_JNI_EXPORT(jint, TestString, test0)(JNI_STDARGS, jstring s)