commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mt...@apache.org
Subject svn commit: r882894 - in /commons/sandbox/runtime/trunk/src/main: java/org/apache/commons/runtime/io/Pipe.java native/include/acr_pipe.h native/os/unix/pipe.c
Date Sat, 21 Nov 2009 13:11:33 GMT
Author: mturk
Date: Sat Nov 21 13:11:32 2009
New Revision: 882894

URL: http://svn.apache.org/viewvc?rev=882894&view=rev
Log:
Implement posix pipe creation

Modified:
    commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Pipe.java
    commons/sandbox/runtime/trunk/src/main/native/include/acr_pipe.h
    commons/sandbox/runtime/trunk/src/main/native/os/unix/pipe.c

Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Pipe.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Pipe.java?rev=882894&r1=882893&r2=882894&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Pipe.java (original)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Pipe.java Sat
Nov 21 13:11:32 2009
@@ -39,7 +39,7 @@
  * <p>
  * </p>
  */
-public final class Pipe
+public final class Pipe implements Device, Syncable
 {
 
     private Descriptor fd;
@@ -64,6 +64,11 @@
         mode = PipeIoMode.valueOf(type & 0xff);
     }
 
+    PipeIoMode getMode()
+    {
+        return mode;
+    }
+
     /**
      * Return the {@link Descriptor} accosicated with this pipe.
      *
@@ -74,4 +79,107 @@
         return fd;
     }
 
+    public static native Pipe[] create0(int mode)
+        throws IOException;
+    /**
+     * Creates a pipe, a unidirectional data channel that can be used
+     * for interprocess communication.
+     * <p>
+     * The returned array is used to return two file descriptors
+     * referring to the ends of the pipe.<br/>
+     * Pipe[0] refers to the read end of the pipe.<br/>
+     * Pipe[1] refers to the write end of the pipe.<br/>
+     * Data written to the write end of the
+     * pipe is buffered by the kernel until it is read from the
+     * read end of the pipe.
+     * </p>
+     */
+    public Pipe[] create(PipeIoMode mode)
+        throws IOException
+    {
+        return create0(mode.valueOf());
+    }
+
+    /**
+     * Test the pipe blocking mode.
+     *
+     * @return {@code true} if pipe operations are blocking.
+     *
+     * @throws ClosedDescriptorException
+     *          If this pipe is closed.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    @Override
+    public boolean isBlocking()
+        throws IOException
+    {
+        if (!valid())
+            throw new ClosedDescriptorException();
+        return mode != PipeIoMode.FULL_NONBLOCK;
+    }
+
+    @Override
+    public boolean valid()
+    {
+        if (fd != null)
+            return fd.valid();
+        else
+            return false;
+    }
+
+    /**
+     * Close this pipe.
+     * @see java.io.Closeable#close()
+     * @throws IOException if an I/O error occurs.
+     */
+    @Override
+    public final void close()
+        throws IOException
+    {
+        fd.close();
+    }
+
+    /**
+     * Flush the underlying pipe metadata.
+     * <p>
+     * {@code flush} transfers  all modified metadata of the file object
+     * referred to by {@code this} file to the disk device
+     * (or other permanent storage device)  where  that  object resides.
+     * The call blocks until the device reports that the transfer has
+     * completed.  It also flushes  metadata information associated with
+     * {@code this} Descriptor.
+     * </p>
+     *
+     * @throws SyncFailedException when the object cannot be flushed.
+     * @throws IOException if an I/O error occurs.
+     */
+    @Override
+    public final void flush()
+        throws SyncFailedException, IOException
+    {
+        fd.flush();
+    }
+
+    /**
+     * Sync the underlying pipe by writing any buffered data.
+     * <p>
+     * {@code sync} transfers  all  modified in-core data of the file object
+     * referred to by {@code this} file to the disk device
+     * (or other permanent storage device)  where  that  object resides.
+     * The call blocks until the device reports that the transfer has
+     * completed.  It also flushes  metadata information associated with
+     * {@code this} Descriptor.
+     * </p>
+     *
+     * @throws SyncFailedException when the object cannot be flushed.
+     * @throws IOException if an I/O error occurs.
+     */
+    @Override
+    public final void sync()
+        throws SyncFailedException, IOException
+    {
+        fd.sync();
+    }
+
 }

Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr_pipe.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr_pipe.h?rev=882894&r1=882893&r2=882894&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr_pipe.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr_pipe.h Sat Nov 21 13:11:32 2009
@@ -31,6 +31,16 @@
  *
  */
 
+/** PipeIoMode flags
+ */
+#define ACR_PIPE_FULL_BLOCK     1
+#define ACR_PIPE_FULL_NONBLOCK  2
+#define ACR_PIPE_PARENT_BLOCK   3
+#define ACR_PIPE_CHILD_BLOCK    4
+
+#define ACR_PIPE_IN             0x0100
+#define ACR_PIPE_OUT            0x0200
+
 /**
  * Create new Pipe object.
  */

Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/pipe.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/pipe.c?rev=882894&r1=882893&r2=882894&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/pipe.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/pipe.c Sat Nov 21 13:11:32 2009
@@ -21,10 +21,15 @@
 #include "acr_error.h"
 #include "acr_clazz.h"
 #include "acr_string.h"
+#include "acr_memory.h"
 #include "acr_descriptor.h"
 #include "acr_file.h"
 #include "acr_pipe.h"
 
+/* Platform includes
+ */
+#include <sys/time.h>
+
 /**
  * Posix pipe functions
  *
@@ -75,3 +80,189 @@
     else
         return NULL;
 }
+
+static int file_cleanup(void *file, int type, unsigned int flags)
+{
+    int rc = ACR_EBADF;
+    acr_file_t *fp = (acr_file_t *)file;
+
+    if (type != ACR_DT_FILE) {
+        return ACR_EBADF;
+    }
+    if (fp->fd >= 0) {
+        if (close(fp->fd))
+            rc = ACR_GET_OS_ERROR();
+        else
+            rc = ACR_SUCCESS;
+    }
+    if (flags & ACR_IOH_CLEAR)
+        x_free(fp);
+    else
+        fp->fd = -1;
+    return rc;
+}
+
+static int descriptor_cleanup(ACR_JNISTDARGS,
+                              acr_descriptor_cb_type_e cm,
+                              acr_descriptor_cb_t *dp)
+{
+    int rc = ACR_SUCCESS;
+    switch (cm) {
+        case ACR_DESC_FINALIZE:
+            if (dp->di > 0) {
+                acr_file_t *fp = ACR_IOH_FDATA(dp->di);
+                if (fp->descriptor) {
+                    (*_E)->DeleteWeakGlobalRef(_E, fp->descriptor);
+                    fp->descriptor = NULL;
+                }
+                rc = acr_ioh_clear(dp->di);
+            }
+            else
+                rc = ACR_EBADF;
+        break;
+        case ACR_DESC_CLOSE:
+            if (dp->di > 0) {
+                acr_file_t *fp = ACR_IOH_FDATA(dp->di);
+                if (fp->descriptor) {
+                    (*_E)->DeleteWeakGlobalRef(_E, fp->descriptor);
+                    fp->descriptor = NULL;
+                }
+                rc = acr_ioh_close(dp->di);
+            }
+            else
+                rc = ACR_EBADF;
+        break;
+        case ACR_DESC_FLUSH:
+            if (dp->di > 0) {
+                acr_file_t *fp = ACR_IOH_FDATA(dp->di);
+                if (fdatasync(fp->fd) < 0)
+                    rc = ACR_GET_OS_ERROR();
+            }
+            else
+                rc = ACR_EBADF;
+        break;
+        case ACR_DESC_SYNC:
+            if (dp->di > 0) {
+                acr_file_t *fp = ACR_IOH_FDATA(dp->di);
+                if (fsync(fp->fd) < 0)
+                    rc = ACR_GET_OS_ERROR();
+            }
+            else
+                rc = ACR_EBADF;
+        break;
+        default:
+            rc = ACR_ENOTIMPL;
+        break;
+    }
+    return rc;
+}
+
+static int do_popen(JNIEnv *_E, int fd, int flags,
+                    jobject *fdo)
+{
+    int rc =  0;
+    int fo;
+    acr_file_t *fp = NULL;
+
+    if ((flags & 0xFF) == ACR_PIPE_FULL_NONBLOCK) {
+#ifdef O_NONBLOCK
+        /* Use non-blocking I/O
+         */
+        int mode;
+        if ((mode = fcntl(fd, F_GETFL, 0)) == -1) {
+            rc = ACR_GET_OS_ERROR();
+            goto finally;
+        }
+        mode |= O_NONBLOCK;
+        if (fcntl(fd, F_SETFL, mode) == -1) {
+            rc = ACR_GET_OS_ERROR();
+            goto finally;
+        }
+#else
+        /* Non blocking files are unsupported.
+         */
+        rc = ACR_ENOTIMPL;
+        goto finally;
+#endif
+    }
+    fp = ACR_CALLOC(acr_file_t, 1);
+    if (!fp) {
+        rc = ACR_ENOMEM;
+        goto finally;
+    }
+    fp->fd     = fd;
+    fp->name   = NULL;
+    fp->flags  = flags;
+    fp->type   = ACR_FT_PIPE;
+    if ((flags & 0xFF) == ACR_PIPE_FULL_NONBLOCK) {
+        fp->blocking = BLK_OFF;
+        fp->timeout  = 0;
+    }
+    else {
+        fp->blocking = BLK_ON;
+        fp->timeout  = -1;
+    }
+    fo = acr_ioh_open(fp, ACR_DT_FILE, 0, file_cleanup);
+    if (fo < 0) {
+        rc = ACR_GET_OS_ERROR();
+        goto finally;
+    }
+    /* Create File Descriptor Object */
+    *fdo = ACR_DescriptorCreate(_E, ACR_DT_FILE, fo, NULL,
+                                descriptor_cleanup);
+    if (!*fdo) {
+        rc = ACR_GET_OS_ERROR();
+        goto finally;
+    }
+    fp->descriptor = (*_E)->NewWeakGlobalRef(_E, *fdo);
+finally:
+    if (rc) {
+        if (fd >= 0)
+            close(fd);
+        x_free(fp);
+    }
+
+    return rc;
+}
+
+ACR_IO_EXPORT_DECLARE(jobjectArray, Pipe, create0)(ACR_JNISTDARGS,
+                                                   jint flags)
+{
+    int rc = 0;
+    jobjectArray pa = NULL;
+    jobject fd[2];
+    int     pd[2] = { -1, -1 };
+
+    if (pipe(pd) == -1) {
+        ACR_THROW_IO_ERRNO();
+        return NULL;
+    }
+    pa = ACR_NewPipeArray(_E, 2);
+    if (pa == NULL) {
+        close(pd[0]);
+        close(pd[1]);
+    }
+    rc = do_popen(_E, pd[0], flags & ACR_PIPE_IN,  &fd[0]);
+    if (rc) {
+        goto cleanup;
+    }
+    rc = do_popen(_E, pd[1], flags & ACR_PIPE_OUT, &fd[1]);
+    if (rc) {
+        /* ### fd[0] will be closed by GC ?
+         */
+        pd[0] = -1;
+        goto cleanup;
+    }
+    (*_E)->SetObjectArrayElement(_E, pa, 0, fd[0]);
+    (*_E)->SetObjectArrayElement(_E, pa, 1, fd[1]);
+    return pa;
+
+cleanup:
+    if (pd[0] != -1)
+        close(pd[0]);
+    if (pd[1] != -1)
+        close(pd[1]);
+
+    ACR_THROW_IO_IF_ERR(rc);
+    return NULL;
+}



Mime
View raw message