static apr_status_t file_pipe_create()

in file_io/os2/pipe.c [27:141]


static apr_status_t file_pipe_create(apr_file_t **in, apr_file_t **out,
        apr_pool_t *pool_in, apr_pool_t *pool_out)
{
    ULONG filedes[2];
    ULONG rc, action;
    static int id = 0;
    char pipename[50];

    sprintf(pipename, "/pipe/%d.%d", getpid(), id++);
    rc = DosCreateNPipe(pipename, filedes, NP_ACCESS_INBOUND, NP_NOWAIT|1, 4096, 4096, 0);

    if (rc)
        return APR_FROM_OS_ERROR(rc);

    rc = DosConnectNPipe(filedes[0]);

    if (rc && rc != ERROR_PIPE_NOT_CONNECTED) {
        DosClose(filedes[0]);
        return APR_FROM_OS_ERROR(rc);
    }

    rc = DosOpen (pipename, filedes+1, &action, 0, FILE_NORMAL,
                  OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW,
                  OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYREADWRITE,
                  NULL);

    if (rc) {
        DosClose(filedes[0]);
        return APR_FROM_OS_ERROR(rc);
    }

    (*in) = (apr_file_t *)apr_palloc(pool_in, sizeof(apr_file_t));
    rc = DosCreateEventSem(NULL, &(*in)->pipeSem, DC_SEM_SHARED, FALSE);

    if (rc) {
        DosClose(filedes[0]);
        DosClose(filedes[1]);
        return APR_FROM_OS_ERROR(rc);
    }

    rc = DosSetNPipeSem(filedes[0], (HSEM)(*in)->pipeSem, 1);

    if (!rc) {
        rc = DosSetNPHState(filedes[0], NP_WAIT);
    }

    if (rc) {
        DosClose(filedes[0]);
        DosClose(filedes[1]);
        DosCloseEventSem((*in)->pipeSem);
        return APR_FROM_OS_ERROR(rc);
    }

    (*in)->pool = pool_in;
    (*in)->filedes = filedes[0];
    (*in)->fname = apr_pstrdup(pool_in, pipename);
    (*in)->isopen = TRUE;
    (*in)->buffered = FALSE;
    (*in)->flags = APR_FOPEN_READ;
    (*in)->pipe = 1;
    (*in)->timeout = -1;
    (*in)->blocking = BLK_ON;
    (*in)->ungetchar = -1;
    apr_pool_cleanup_register(pool_in, *in, apr_file_cleanup,
            apr_pool_cleanup_null);

    (*out) = (apr_file_t *)apr_palloc(pool_out, sizeof(apr_file_t));
    rc = DosCreateEventSem(NULL, &(*out)->pipeSem, DC_SEM_SHARED, FALSE);

    if (rc) {
        DosClose(filedes[0]);
        DosClose(filedes[1]);
        DosCloseEventSem((*in)->pipeSem);
        return APR_FROM_OS_ERROR(rc);
    }

    rc = DosSetNPipeSem(filedes[1], (HSEM)(*out)->pipeSem, 1);

    if (rc) {
        DosClose(filedes[0]);
        DosClose(filedes[1]);
        DosCloseEventSem((*in)->pipeSem);
        DosCloseEventSem((*out)->pipeSem);
        return APR_FROM_OS_ERROR(rc);
    }

    (*out)->pool = pool_out;
    (*out)->filedes = filedes[1];
    (*out)->fname = apr_pstrdup(pool_out, pipename);
    (*out)->isopen = TRUE;
    (*out)->buffered = FALSE;
    (*out)->flags = APR_FOPEN_WRITE;
    (*out)->pipe = 1;
    (*out)->timeout = -1;
    (*out)->blocking = BLK_ON;
    (*out)->ungetchar = -1;
    apr_pool_cleanup_register(pool_out, *out, apr_file_cleanup,
            apr_pool_cleanup_null);

    switch (blocking) {
    case APR_FULL_BLOCK:
        break;
    case APR_READ_BLOCK:
        apr_file_pipe_timeout_set(*out, 0);
        break;
    case APR_WRITE_BLOCK:
        apr_file_pipe_timeout_set(*in, 0);
        break;
    default:
        apr_file_pipe_timeout_set(*out, 0);
        apr_file_pipe_timeout_set(*in, 0);
        break;
    }
    return APR_SUCCESS;
}