예제 #1
0
파일: pipe.c 프로젝트: cmjonze/apr
APR_DECLARE(apr_status_t) apr_file_pipe_timeout_set(apr_file_t *thepipe, apr_interval_time_t timeout)
{
    apr_status_t rv = APR_SUCCESS;

    if (thepipe->pipe == 1) {
        thepipe->timeout = timeout;

        if (thepipe->timeout >= 0) {
            if (thepipe->blocking != BLK_OFF) {
                thepipe->blocking = BLK_OFF;
                return APR_FROM_OS_ERROR(DosSetNPHState(thepipe->filedes, NP_NOWAIT));
            }
        }
        else if (thepipe->timeout == -1) {
            if (thepipe->blocking != BLK_ON) {
                thepipe->blocking = BLK_ON;
                return APR_FROM_OS_ERROR(DosSetNPHState(thepipe->filedes, NP_WAIT));
            }
        }
    }
    else {
        rv = APR_EINVAL;
    }

    return rv;
}
예제 #2
0
파일: pipe.c 프로젝트: cmjonze/apr
APR_DECLARE(apr_status_t) apr_file_pipe_create(apr_file_t **in, apr_file_t **out, apr_pool_t *pool)
{
    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, 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)->filedes = filedes[0];
    (*in)->fname = apr_pstrdup(pool, 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, apr_file_cleanup, apr_pool_cleanup_null);

    (*out) = (apr_file_t *)apr_palloc(pool, 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)->filedes = filedes[1];
    (*out)->fname = apr_pstrdup(pool, 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, apr_file_cleanup, apr_pool_cleanup_null);

    return APR_SUCCESS;
}
예제 #3
0
static void ProcessConnection( void )
{
    char                buff[MAX_TRANS];
    ULONG               bytes_read;
    unsigned long       max;
    struct _AVAILDATA   BytesAvail;
    ULONG               PipeState;
    APIRET              rc;
    RESULTCODES         res;
    PID                 dummy;
    char                *dir;

    for( ;; ) {
        DosRead( LnkHdl, buff, sizeof( buff ), &bytes_read );
        if( bytes_read == 0 ) break;
        buff[bytes_read] = '\0';
        switch( buff[0] ) {
        case LNK_CWD:
            rc = 0;
            dir = &buff[1];
            if( isalpha( dir[0] ) && dir[1] == ':' ) {
                rc = DosSetDefaultDisk( toupper( dir[0] ) - ('A' - 1) );
                dir += 2;
            }
            if( rc == 0 && dir[0] != '\0' ) {
                rc = DosSetCurrentDir( dir );
            }
            SendStatus( rc );
            break;
        case LNK_RUN:
            DosSetNPHState( RedirHdl, NP_NOWAIT | NP_READMODE_BYTE );
            DosConnectNPipe( RedirHdl );
            DosSetNPHState( RedirHdl, NP_WAIT | NP_READMODE_BYTE );
            RunCmd( &buff[1] );
            break;
        case LNK_QUERY:
            max = *(unsigned long *)&buff[1];
            if( max > sizeof( buff ) ) max = sizeof( buff );
            --max;
            rc = DosPeekNPipe(RedirHdl, buff, 0, &bytes_read,
                        &BytesAvail, &PipeState );
            if( rc == 0 && BytesAvail.cbpipe != 0 ) {
                DosRead( RedirHdl, &buff[1], max, &bytes_read );
                buff[0] = LNK_OUTPUT;
                DosWrite( LnkHdl, buff, bytes_read + 1, &bytes_read );
            } else {
                rc = DosWaitChild( DCWA_PROCESS, DCWW_NOWAIT, &res,
                                        &dummy, ProcId );
                if( rc != ERROR_CHILD_NOT_COMPLETE ) {
                    DosDisConnectNPipe( RedirHdl );
                    SendStatus( res.codeResult );
                    ProcId = 0;
                } else {
                    /* let someone else run */
                    DosSleep( 1 );
                    buff[0] = LNK_NOP;
                    DosWrite( LnkHdl, buff, 1, &bytes_read );
                }
            }
            break;
        case LNK_CANCEL:
            DosSendSignalException( ProcId, XCPT_SIGNAL_INTR );
            break;
        case LNK_ABORT:
            DosKillProcess( DKP_PROCESSTREE, ProcId );
            break;
        case LNK_DONE:
            return;
        case LNK_SHUTDOWN:
            exit( 0 );
            break;
        }
    }
}
예제 #4
0
static int CreatePipeChild(PID& pid, HPIPE& hfPipe, char *Command) {
  static int PCount = 0;
  char  szPipe[32];
  char  FailBuf[256];
  char *Args;
  int   arglen = 0;
  char *Prog;
  RESULTCODES rc_code;
  ULONG ulAction;

  // ULONG ulNew;
  HPIPE hfChildPipe;
  HFILE hfNewStdOut = (HFILE)-1, hfNewStdErr = (HFILE)-1;
  HFILE hfStdOut    = 1, hfStdErr = 2;
  int   rc;

  sprintf(szPipe, "\\PIPE\\eFTE%d\\CHILD%d", getpid(), PCount);
  PCount++;

  rc = DosCreateNPipe(szPipe, &hfPipe,
                      NP_NOINHERIT | NP_ACCESS_INBOUND,
                      NP_NOWAIT | NP_TYPE_BYTE | NP_READMODE_BYTE | 1,
                      0, 4096, 0);

  if (rc != 0) return -1;

  rc = DosConnectNPipe(hfPipe);

  if ((rc != 0) && (rc != ERROR_PIPE_NOT_CONNECTED)) {
    DosClose(hfPipe);
    return -1;
  }

  rc = DosSetNPHState(hfPipe, NP_WAIT | NP_READMODE_BYTE);

  if (rc != 0) {
    DosClose(hfPipe);
    return -1;
  }

  rc = DosOpen(szPipe, &hfChildPipe, &ulAction, 0,
               FILE_NORMAL,
               OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW,
               OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYREADWRITE,
               NULL);

  if (rc != 0) {
    DosClose(hfPipe);
    return -1;
  }

  // Duplicate handles
  DosDupHandle(hfStdOut, &hfNewStdOut);
  DosDupHandle(hfStdErr, &hfNewStdErr);

  // Close existing handles for current process
  DosClose(hfStdOut);
  DosClose(hfStdErr);

  // Redirect existing handles to new file
  DosDupHandle(hfChildPipe, &hfStdOut);
  DosDupHandle(hfChildPipe, &hfStdErr);

  // Let started program inherit handles from parent

  Prog = getenv("COMSPEC");

  Args = (char *)malloc(strlen(Prog) + 1
                        + 3 + strlen(Command) + 1
                        + 1);

  if (Args == NULL) {
    DosClose(hfPipe);
    return -1;
  }

  strcpy(Args,          Prog);
  arglen = strlen(Args) + 1;
  strcpy(Args + arglen, "/c ");
  arglen += 3;
  strcpy(Args + arglen, Command);
  arglen      += strlen(Command) + 1;
  Args[arglen] = '\0';

  rc = DosExecPgm(FailBuf, sizeof(FailBuf),
                  EXEC_ASYNCRESULT, // | EXEC_BACKGROUND,
                  Args,
                  0,
                  &rc_code,
                  Prog);

  free(Args);

  // Get back original handles
    DosDupHandle(hfNewStdOut, &hfStdOut);
    DosDupHandle(hfNewStdErr, &hfStdErr);

  // Close the duplicated handles - no longer needed
    DosClose(hfNewStdOut);
    DosClose(hfNewStdErr);

    DosClose(hfChildPipe); // pipe one way, close out write end

  if (rc != 0) {
    DosClose(hfPipe);
    return -1;
  }

  pid = rc_code.codeTerminate; // get pid when successful

  return 0;
}
예제 #5
0
static XtransConnInfo
TRANS(Os2Accept)(XtransConnInfo ciptr, int *status)
{
    XtransConnInfo	newciptr;
    HFILE hClient;
    unsigned char length;
    ULONG action;
    char clientname[256];
    struct sockaddr *addr_name;
    int in,namelen;
    APIRET rc;


    PRMSG(2,"Os2Accept(%x->%d)\n", ciptr, ciptr->fd,0);
    if( (newciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo)))==NULL )
    {
	PRMSG(1,"Os2Accept: xcalloc(1,%d) failed\n",
	      sizeof(struct _XtransConnInfo),0,0 );
	*status = TRANS_ACCEPT_BAD_MALLOC;
	return NULL;
    }

/* Read in length of client pipe name. If fails, then reset server pipe */
    if((in=read(ciptr->fd,&length,1))<=0){
        PRMSG(2,"Os2Accept: Error reading incoming connection, in=%d, error=%d\n",
	      in,errno,0 );
	*status = TRANS_ACCEPT_MISC_ERROR;
        xfree(newciptr);
        rc = DosDisConnectNPipe(ciptr->fd);
        rc = DosConnectNPipe (ciptr->fd);
        if (rc != 0 && rc != ERROR_PIPE_NOT_CONNECTED)
        {
                PRMSG(1, "Os2Accept: Unable to reconnect server pipe %d\n", ciptr->fd,0,0 );
                }
	return NULL;
        }
	PRMSG(5, "Os2Accept: Bytes to read for name: %d\n",length,0,0 );


/* Check length for valid length ?? */

/* Now read in length bytes from pipe for client pipe name */
    if((in=read(ciptr->fd,clientname,length))<=0){
        PRMSG(2,"Os2Accept: Error reading incoming connection, in=%d, error=%d\n",
	      in,errno,0 );
	*status = TRANS_ACCEPT_MISC_ERROR;
        xfree(newciptr);
        rc = DosDisConnectNPipe(ciptr->fd);
        rc = DosConnectNPipe (ciptr->fd);
        if (rc != 0 && rc != ERROR_PIPE_NOT_CONNECTED)
        {
                PRMSG(1, "Os2Accept: Unable to reconnect server pipe %d\n", ciptr->fd,0,0 );
                }
	return NULL;
        }
    clientname[length]='\0';
    PRMSG(5, "Os2Accept: Server name %s length %d\n",clientname,length,0 );


/* Now we have the client pipe name. Open it with DosOpen  */

     rc = DosOpen(clientname,&hClient, &action, 0,
	   FILE_NORMAL, FILE_OPEN,
	   OPEN_FLAGS_NOINHERIT | OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYREADWRITE,
	   (PEAOP2)NULL);

     PRMSG(5, "Os2Accept: Open pipe %s, handle = %d, rc=%d\n",clientname,hClient,rc );

       if (rc) {
	    PRMSG(1,"Os2Accept: Open pipe %s to client failed, rc=%d\n",
	    clientname,rc,0 );
            PRMSG(1, "\tProbable cause: the client has exited or timed-out.\n",0,0,0 );
            xfree(newciptr);
            rc = DosDisConnectNPipe(ciptr->fd);
            rc = DosConnectNPipe (ciptr->fd);
            if (rc != 0 && rc != ERROR_PIPE_NOT_CONNECTED)
               {
                   PRMSG(1, "Os2Accept: Unable to reconnect server pipe %d\n", ciptr->fd,0,0 );
                   }
     	    return NULL;
            }

        rc = DosSetNPHState (hClient, NP_NOWAIT | NP_READMODE_BYTE);
        if (rc != 0)
        {
            PRMSG(1,"Os2Accept: Could not set pipe %s to non-blocking mode, rc=%d\n",
	    hClient,rc,0 );
            xfree(newciptr);
            rc = DosDisConnectNPipe(ciptr->fd);
            rc = DosConnectNPipe (ciptr->fd);
            if (rc != 0 && rc != ERROR_PIPE_NOT_CONNECTED)
               {
                   PRMSG(1, "Os2Accept: Unable to reconnect server pipe %d\n", ciptr->fd,0,0 );
                   }
     	    return NULL;
            }

/* OK, we seem to be well connected to client. Now disconnect server pipe and put again in listen */

         rc = DosDisConnectNPipe(ciptr->fd);
         rc = DosConnectNPipe (ciptr->fd);
	PRMSG(5, "Os2Accept: Reconnecting server pipe %d, rc = %d\n",ciptr->fd,rc,0 );

         if (rc != 0 && rc != ERROR_PIPE_NOT_CONNECTED)
         {
              PRMSG(1, "Os2Accept: Unable to reconnect server pipe %d\n", ciptr->fd,0,0 );
              }  /* Consider this non-fatal for present connection */

/* And finally fill-in info in newciptr */

        namelen=sizeof(struct sockaddr);
        if ((newciptr->addr = (char *) xalloc (namelen)) == NULL)
          {
                PRMSG (1, "Os2Accept: Can't allocate space for the addr\n",
	        0, 0, 0);
                DosClose(hClient);
                xfree(newciptr);
                return(NULL);
           }

        newciptr->addrlen = namelen;
        ((struct sockaddr *)newciptr->addr)->sa_family = AF_UNIX;
        strcpy (((struct sockaddr *)newciptr->addr)->sa_data, "local");

        if ((newciptr->peeraddr = (char *) xalloc (namelen)) == NULL)
          {
                PRMSG (1, "Os2Accept: Can't allocate space for the addr\n",
	        0, 0, 0);
                DosClose(hClient);
                xfree(ciptr->addr);
                xfree(newciptr);
                return(NULL);
           }

       newciptr->peeraddrlen = namelen;
       ((struct sockaddr *)newciptr->peeraddr)->sa_family = AF_UNIX;
       strcpy (((struct sockaddr *)newciptr->peeraddr)->sa_data, "local");

      PRMSG (5, "Os2Accept: Filled in struct: len %d %d name %s\n",
                newciptr->addrlen,newciptr->peeraddrlen,newciptr->peeraddr);


        newciptr->index=hClient;
        newciptr->family=AF_UNIX;
        if((newciptr->fd=_imphandle(hClient))<0){
           PRMSG(1,"Os2Accept: Could not import pipe %d into EMX, errno=%d\n",
           hClient,errno,0 );
           PRMSG(1, "\tProbable cause: EMX has run out of file handles.\n",0,0,0 );
           DosClose(hClient);
           xfree(newciptr->addr);
           xfree(newciptr->peeraddr);
           xfree(newciptr);
           return(NULL);
           }
    PRMSG(5, "Os2Accept: Pipe handle %d EMX handle %d",newciptr->index,newciptr->fd,0 );

#ifdef XSERV_t
/* Attach the pipe sem to the pipe. Use handle index as key */
    rc = DosSetNPipeSem(newciptr->fd, (HSEM)hPipeSem, newciptr->fd);
    if (rc){
        PRMSG(1, "Os2OpenCOTSServer: Could not attach sem %d to pipe %d, rc=%d\n",
                 hPipeSem,newciptr->fd,rc);
        DosClose(newciptr->fd);
        xfree(newciptr->addr);
        xfree(newciptr->peeraddr);
        xfree(newciptr);
         return(NULL);
        }
#endif

    fcntl(ciptr->fd,F_SETFL,O_NDELAY);
    fcntl(ciptr->fd,F_SETFD,FD_CLOEXEC);
    *status=0;
    return newciptr;
}