Beispiel #1
0
void main( int argc, char *argv[] )
{
    APIRET      rc;
    HFILE       h;
    unsigned long       actiontaken;
    unsigned long       sent;
    char        done;

    if( argc > 1 && (argv[1][0] == 'q' || argv[1][0] == 'Q') ) {
        rc = DosOpen( PREFIX DEFAULT_NAME, &h, &actiontaken, 0ul,
                        0, 0x01, 0x41, 0ul );
        if( rc == 0 ) {
            done = LNK_SHUTDOWN;
            DosWrite( h, &done, sizeof( done ), &sent );
            DosClose( h );
        }
        exit( 0 );
    }
    CmdProc = getenv( "COMSPEC" );
    if( CmdProc == NULL ) {
        fprintf( stderr, "Unable to find command processor\n" );
        exit( 1 );
    }
    //NYI: need to accept name for link pipe
    rc = DosCreateNPipe( PREFIX DEFAULT_NAME, &LnkHdl,
        NP_NOINHERIT | NP_NOWRITEBEHIND | NP_ACCESS_DUPLEX,
        NP_WAIT | NP_READMODE_MESSAGE | NP_TYPE_MESSAGE | 1,
        MAX_TRANS, MAX_TRANS, 0 );
    if( rc != 0 ) {
        fprintf( stderr, "Unable to create link pipe\n" );
        exit( 1 );
    }
    sprintf( RedirName, PREFIX "%d", getpid() );
    rc = DosCreateNPipe( RedirName, &RedirHdl,
        NP_NOINHERIT | NP_WRITEBEHIND | NP_ACCESS_INBOUND,
        NP_WAIT | NP_READMODE_BYTE | NP_TYPE_BYTE | 1,
        MAX_TRANS, MAX_TRANS, 0 );
    if( rc != 0 ) {
        fprintf( stderr, "Unable to create redirection pipe\n" );
        exit( 1 );
    }
    DosSetFHState( LnkHdl, OPEN_FLAGS_NOINHERIT );
    DosSetFHState( RedirHdl, OPEN_FLAGS_NOINHERIT );
    for( ;; ) {
        rc = DosConnectNPipe( LnkHdl );
        if( rc == 0 ) {
            ProcessConnection();
            DosDisConnectNPipe( LnkHdl );
        }
    }
}
Beispiel #2
0
int main(void)
{
    APIRET apiret;
    HPIPE hpipe;
    PSZ pipeName = "\\pipe\\testpipe";
    PSZ semName = "\\sem32\\pipesem";
    HEV hev;
    CHAR objname[50];
    RESULTCODES rc;
    ULONG bytesread;
    CHAR buf[50];

    printf(__FILE__ " main function invoked\n");
    printf("Test named pipe functions\n");

    apiret = DosCreateNPipe(pipeName, &hpipe, 0, NP_WAIT, 0, 0, 0);
    printf("DosCreateNPipe function returned %d\n", (int)apiret);

    apiret = DosCreateEventSem(semName, &hev, DC_SEM_SHARED, FALSE);
    printf("DosCreateEventSem function returned %d\n", (int)apiret);

    apiret = DosExecPgm(objname, 50, EXEC_ASYNC, NULL, NULL, &rc, "./test11a");
    printf("DosExecPgm function returned %d\n", (int)apiret);

    apiret = DosWaitEventSem(hev, 5000);
    printf("DosWaitEventSem function returned %d\n", (int)apiret);

    apiret = DosRead((HFILE)hpipe, buf, sizeof(buf) - 1, &bytesread);
    printf("DosRead function returned %d\n", (int)apiret);
    buf[bytesread] = '\0';
    printf("Message was \"%s\"\n", buf);

    apiret = DosWaitEventSem(hev, 5000);
    printf("DosWaitEventSem function returned %d\n", (int)apiret);

    apiret = DosRead((HFILE)hpipe, buf, sizeof(buf) - 1, &bytesread);
    printf("DosRead function returned %d\n", (int)apiret);
    buf[bytesread] = '\0';
    printf("Message was \"%s\"\n", buf);

    apiret = DosWaitEventSem(hev, 5000);
    printf("DosWaitEventSem function returned %d\n", (int)apiret);

    apiret = DosRead((HFILE)hpipe, buf, sizeof(buf) - 1, &bytesread);
    printf("DosRead function returned %d\n", (int)apiret);
    buf[bytesread] = '\0';
    printf("Message was \"%s\"\n", buf);

    /* wait for test11a to catch up with us */
    DosSleep(2000);

    apiret = DosCloseEventSem(hev);
    printf("DosCloseEventSem function returned %d\n", (int)apiret);

    apiret = DosClose((HFILE)hpipe);
    printf("DosClose function returned %d\n", (int)apiret);

    return 0;
}
/*@ XNamedPipeServer::Open(char *name, ULONG openMode, ULONG pipeMode, char pipeCount, LONG outSize, long inSize, ULONG timeOut)
@group open/close
@remarks Open a pipe, after you have opened it call Connect()
@parameters <t 'ø' c=2>
            øchar *     øpipename, without leading '\\PIPE\\'
            øULONG   ømode to open (see OS/2 docs):<BR>
XNPIPE_ACCESS_INBOUND<BR>
XNPIPE_ACCESS_OUTBOUND<BR>
XNPIPE_ACCESS_DUPLEX<BR>
XNPIPE_INHERIT<BR>
XNPIPE_NOINHERIT<BR>
XNPIPE_WRITEBEHIND<BR>
XNPIPE_NOWRITEBEHIND<BR>
            øULONG   ømode of data-transfer:<BR>
XNPIPE_READMODE_BYTE<BR>
XNPIPE_READMODE_MESSAGE<BR>
XNPIPE_TYPE_BYTE<BR>
XNPIPE_TYPE_MESSAGE<BR>
XNPIPE_WAIT<BR>
XNPIPE_NOWAIT<BR>
            øchar   ømaximum instances of pipe-servers, -1 = unlimited (default is 1)
            øULONG   øsize of write-buffer
            øULONG   øsize of read-buffer
            øULONG   øtime to wait for clients
         </t>
*/
LONG XNamedPipeServer::Open(char *name, ULONG openMode, ULONG pipeMode, char pipeCount, LONG outSize, long inSize, ULONG timeOut)
{
   XString n = "\\PIPE\\";
   n += name;
   pipeMode |= pipeCount;
   ULONG rc = DosCreateNPipe((PSZ) (char*) n, &handle, openMode, pipeMode, outSize, inSize, timeOut);

   if (rc == 0)
      isOpen = TRUE;
   else
      handle = -1;
   return rc;
}
Beispiel #4
0
/* open_subprocess_connection acts like the unix-known function pipe and sets
 * ep->RedirectedFile if necessary. Just in the latter case ep->data
 * is set to the filename.
 * Close the handles with __regina_close later.
 * Do IO by using Os2_read() and Os2_write().
 */
static int Os2_open_subprocess_connection(const tsd_t *TSD, environpart *ep)
{
#define MAGIC_MAX 2000000 /* Much beyond maximum, see below */
   static volatile unsigned BaseIndex = MAGIC_MAX;
   char buf[40];
   unsigned i;
   unsigned start,run;
   ULONG rc, openmode, dummy;
   HPIPE in = (HPIPE) -1, out;

   /* We have to use named pipes for various reasons. */
   openmode = (ep->flags.isinput) ? NP_ACCESS_OUTBOUND : NP_ACCESS_INBOUND;
   openmode |= NP_NOINHERIT | NP_WRITEBEHIND;

   /* algorithm:
    * select a random number, e.g. a mixture of pid, tid and time.
    * increment this number by a fixed amount until we reach the starting
    * value again. Do a wrap around and an increment which is a unique prime.
    * The number 1000000 has the primes 2 and 5. We may use all primes
    * except 2 and 5; 9901 (which is prime) will give a good distribution.
    *
    * We want to be able to create several temporary files at once without
    * more OS calls than needed. Thus, we have a program wide runner to
    * ensure a simple distribution without strength.
    */
   if (BaseIndex == MAGIC_MAX)
   {
      /*
       * We have to create (nearly) reentrant code.
       */
      i = (unsigned) getpid() * (unsigned) time(NULL);
      i %= 1000000;
      if (!i)
         i = 1;
      BaseIndex = i;
   }
   if (++BaseIndex >= 1000000)
      BaseIndex = 1;

   start = TSD->thread_id;
   if (start == 0)
      start = 999999;
   start *= (unsigned) (clock() + 1);
   start *= BaseIndex;
   start %= 1000000;

   run = start;
   for (i = 0;i <= 1000000;i++)
   {
      sprintf(buf,"%s%06u._rx", "\\pipe\\tmp\\", run );
      rc = DosCreateNPipe(buf,
                          &in,
                          openmode,
                          NP_TYPE_BYTE | NP_READMODE_BYTE | NP_NOWAIT | 1,
                          4096,
                          4096,
                          0); /* msec timeout */
      if (rc == NO_ERROR)
         break;

      if (rc != ERROR_PIPE_BUSY)
      {
         errno = EPIPE;
         return(-1);
      }

      /* Check the next possible candidate */
      run += 9901;
      run %= 1000000;
      if (run == start) /* paranoia check. i <= 1000000 should hit exactly */
         break;         /* here */
   }

   if (in == (HPIPE) -1)
   {
      errno = EPIPE;
      return(-1);
   }

   DosConnectNPipe(in); /* ignore the return */

   openmode = (ep->flags.isinput) ? OPEN_ACCESS_READONLY :
                                    OPEN_ACCESS_WRITEONLY;
   openmode |= OPEN_FLAGS_SEQUENTIAL | OPEN_SHARE_DENYREADWRITE;
   rc = DosOpen(buf,
                &out,
                &dummy, /* action */
                0ul, /* initial size */
                FILE_NORMAL,
                OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
                openmode,
                NULL); /* peaop2 */
   if (rc != NO_ERROR)
   {
      DosClose(in);
      errno = EPIPE; /* guess */
      return(-1);
   }

   /* Now do the final checking, the server end must be connected */
   if (DosConnectNPipe(in) != NO_ERROR)
   {
      DosClose(out);
      DosClose(in);
      errno = EPIPE; /* guess */
      return(-1);
   }

   /* We always want to have the server's end of the named pipe: */
   if (ep->flags.isinput)
   {
      ep->hdls[0] = (int) out;
      ep->hdls[1] = (int) in;
   }
   else
   {
      ep->hdls[0] = (int) in;
      ep->hdls[1] = (int) out;
   }
   return(0);
#undef MAGIC_MAX
}
Beispiel #5
0
void connectthread( void * parameters ) {

    struct connectthreadparameters * ctp;
    unsigned long curmax;
    HPIPE hpipe;
    struct messagequeue * msgq;
    unsigned char maxpipes;
    char pipename[CCHMAXPATH];
    APIRET rc;
    long req;
    HEV shutdown;
    HEV terminated;

    /*  Grab data from parameter block, and signal when done.  */

    ctp = ( struct connectthreadparameters * ) parameters;

    maxpipes = ctp->maxpipes;
    strcpy(pipename,ctp->pipename);
    shutdown = ctp->shutdown;
    msgq = ctp->msgq;
    terminated = ctp->terminated;

    DosPostEventSem(ctp->initialized);

    /*  Clear the pipe handle ( this is checked for a non-NULLHANDLE     **
    **  value on thread exit ).                                          */

    hpipe = NULLHANDLE;

    create:    /*  Create a new instance of the pipe.  */

    rc =
            DosCreateNPipe( pipename, &hpipe,
                NP_NOINHERIT|NP_ACCESS_DUPLEX,
                NP_NOWAIT|NP_TYPE_BYTE|NP_READMODE_BYTE|maxpipes,
                inbuffersize, outbuffersize, 0 );

    if (
            rc != NO_ERROR && rc != ERROR_PIPE_BUSY &&
                rc != ERROR_TOO_MANY_OPEN_FILES ) {
        /*  Some unexpected error has occurred.  Notify the              **
        **  application.                                                 */
        DosRequestMutexSem(msgq->access,SEM_INDEFINITE_WAIT);
        *msgq->qtail = malloc( sizeof( struct message ) );
        (*msgq->qtail)->id = cterror;
        (*msgq->qtail)->data.cterrordata.ec = apiret2ec(rc);
        (*msgq->qtail)->next = NULL;
        DosPostEventSem(msgq->available);
        DosReleaseMutexSem(msgq->access);
        goto completed;
        }

    if ( rc == ERROR_PIPE_BUSY )
        /*  Max pipes created.  */
        goto busy;

    if ( rc == ERROR_TOO_MANY_OPEN_FILES ) {
        req = 1;
        rc = DosSetRelMaxFH(&req,&curmax);
        if ( rc  == NO_ERROR )
            goto create;
        /*  Can trigger a 'max connections reached' message here ...  */
        goto busy;
        }

    connect:    /*  Connect pipe ( allows client to connect ).  */

    rc = DosConnectNPipe(hpipe);

    if (
            rc != NO_ERROR && rc != ERROR_PIPE_NOT_CONNECTED &&
                rc != ERROR_BROKEN_PIPE ) {
        /*  Unexpected error ...  */
        DosRequestMutexSem(msgq->access,SEM_INDEFINITE_WAIT);
        *msgq->qtail = malloc( sizeof( struct message ) );
        (*msgq->qtail)->id = cterror;
        (*msgq->qtail)->data.cterrordata.ec = apiret2ec(rc);
        (*msgq->qtail)->next = NULL;
        DosPostEventSem(msgq->available);
        DosReleaseMutexSem(msgq->access);
        DosClose(hpipe);
        hpipe = NULLHANDLE;
        goto completed;
        }

    if ( rc == ERROR_PIPE_NOT_CONNECTED )
        /*  No client connected, so wait a while ...  */
        goto waiting;

    if ( rc == ERROR_BROKEN_PIPE ) {
        /*  Client connected, but probably immediately closed.  */
        DosClose(hpipe);
        hpipe = NULLHANDLE;
        goto create;
        }

    /*  Send handle of the newly connected pipe to the application.  */

    DosRequestMutexSem(msgq->access,SEM_INDEFINITE_WAIT);
    *msgq->qtail = malloc( sizeof( struct message ) );
    (*msgq->qtail)->id = connected;
    (*msgq->qtail)->data.connecteddata.hpipe = hpipe;
    (*msgq->qtail)->next = NULL;
    DosPostEventSem(msgq->available);
    DosReleaseMutexSem(msgq->access);

    /*  Create a new instance of the pipe for the next client.  */

    goto create;

    waiting:    /*  Wait to see if the application is ready to exit.  */

    rc = DosWaitEventSem(shutdown,connectpolltimeout);
    if ( rc != ERROR_TIMEOUT )
        goto completed;

    /*  Not shutting down, so wait for a client to connect.  */

    goto connect;

    busy:    /*  Pipe is busy.  */

    rc = DosWaitEventSem(shutdown,connectpolltimeout);
    if ( rc != ERROR_TIMEOUT )
        goto completed;

    /*  Not shutting down, but in this case, unlike waiting above, go    **
    **  and create a new pipe.                                           */

    goto create;

    completed:    /*  Processing completed.  */

    /*  Close pipe if no client had connected.  */

    if ( hpipe != NULLHANDLE )
        DosClose(hpipe);

    /*  Notify application that the thread will not accept more          **
    **  connections.                                                     */

    DosRequestMutexSem(msgq->access,SEM_INDEFINITE_WAIT);
    *msgq->qtail = malloc( sizeof( struct message ) );
    (*msgq->qtail)->id = ctclosed;
    (*msgq->qtail)->next = NULL;
    DosPostEventSem(msgq->available);
    DosReleaseMutexSem(msgq->access);

    /*  Shutdown processing completed.  Signal owner.  */

    DosEnterCritSec();
    DosPostEventSem(terminated);

    }
Beispiel #6
0
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;
}
Beispiel #7
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;
}
Beispiel #8
0
void system_Configure( libvlc_int_t *p_this, int i_argc, const char *const ppsz_argv[] )
{
    if( var_InheritBool( p_this, "high-priority" ) )
    {
        if( !DosSetPriority( PRTYS_PROCESS, PRTYC_REGULAR, PRTYD_MAXIMUM, 0 ) )
        {
            msg_Dbg( p_this, "raised process priority" );
        }
        else
        {
            msg_Dbg( p_this, "could not raise process priority" );
        }
    }

    if( var_InheritBool( p_this, "one-instance" )
        || ( var_InheritBool( p_this, "one-instance-when-started-from-file" )
             && var_InheritBool( p_this, "started-from-file" ) ) )
    {
        HPIPE hpipe;
        ULONG ulAction;
        ULONG rc;

        msg_Info( p_this, "one instance mode ENABLED");

        /* Use a named pipe to check if another instance is already running */
        for(;;)
        {
            rc = DosOpen( VLC_IPC_PIPE, &hpipe, &ulAction, 0, 0,
                          OPEN_ACTION_OPEN_IF_EXISTS,
                          OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYREADWRITE |
                          OPEN_FLAGS_FAIL_ON_ERROR,
                          NULL );

            if( rc == ERROR_PIPE_BUSY )
                DosWaitNPipe( VLC_IPC_PIPE, -1 );
            else
                break;
        }

        if( rc )
        {
            rc = DosCreateNPipe( VLC_IPC_PIPE,  &hpipeIPC,
                                 NP_ACCESS_DUPLEX,
                                 NP_WAIT | NP_TYPE_MESSAGE |
                                 NP_READMODE_MESSAGE | 0x01,
                                 32768, 32768, 0 );
            if( rc )
            {
                /* Failed to create a named pipe. Just ignore the option and
                 * go on as normal. */
                msg_Err( p_this, "one instance mode DISABLED "
                         "(a named pipe couldn't be created)" );
                return;
            }

            /* We are the 1st instance. */

            /* Save the tid of the first instance */
            tidIPCFirst = _gettid();

            /* Run the helper thread */
            tidIPCHelper = _beginthread( IPCHelperThread, NULL, 1024 * 1024,
                                         p_this );
            if( tidIPCHelper == -1 )
            {
                msg_Err( p_this, "one instance mode DISABLED "
                         "(IPC helper thread couldn't be created)");

                tidIPCFirst = -1;
            }
        }
        else
        {
            /* Another instance is running */
            ULONG ulCmd = var_InheritBool( p_this, "playlist-enqueue") ?
                              IPC_CMD_ENQUEUE : IPC_CMD_GO;
            ULONG cbActual;

            /* Write a command */
            DosWrite( hpipe, &ulCmd, sizeof( ulCmd ), &cbActual );

            /* We assume that the remaining parameters are filenames
             * and their input options */

            /* Write a count of arguments */
            DosWrite( hpipe, &i_argc, sizeof( i_argc ), &cbActual );

            for( int i_opt = 0; i_opt < i_argc; i_opt++ )
            {
                /* We need to resolve relative paths in this instance */
                char *mrl;
                if( strstr( ppsz_argv[ i_opt ], "://" ))
                    mrl = strdup( ppsz_argv[ i_opt ] );
                else
                    mrl = vlc_path2uri( ppsz_argv[ i_opt ], NULL );

                if( !mrl )
                    mrl = ( char * )ppsz_argv[ i_opt ];

                size_t i_len = strlen( mrl ) + 1;

                /* Write a length of an argument */
                DosWrite( hpipe, &i_len, sizeof( i_len ), &cbActual );

                /* Write an argument */
                DosWrite( hpipe, mrl, i_len, &cbActual );

                if( mrl != ppsz_argv[ i_opt ])
                    free( mrl );
            }

            /* Close a named pipe of a client side */
            DosClose( hpipe );

            /* Bye bye */
            system_End();
            exit( 0 );
        }
    }
}
Beispiel #9
0
int main(int argc, char **argv)
{
	int c, end = 0, lines = 25;
	int x, y, h, n, v;

	FILE *in=NULL;
	char a;
	char buf[160];
	HPIPE pipe;
	APIRET rc;
	char *target;

	/* Check command line */
	if (argc!=2 && argc!=3)
	{
		printf("Usage: %s Mirror|Recall|Choice|Term-4|...|Term-7 [number of lines]\n"
		       "Start this before angband.exe\n", argv[0]);
		exit(1);
	}

	if (argc==3) lines = atoi(argv[2]);
	if (lines <= 0) lines = 25;

	printf("Looking for Angband... press ^C to abort\n");

	target=strdup(argv[1]);
	for (c=0; c<strlen(target); c++) target[c]=tolower(target[c]);

	strnfmt(buf, 160, "\\pipe\\angband\\%s", target);

	do
	{
		rc=DosCreateNPipe((PSZ)buf,          /* Create pipe */
		                  &pipe,
		                  NP_ACCESS_INBOUND,
		                  NP_WAIT|NP_TYPE_BYTE|NP_READMODE_BYTE|1,
		                  1,                 /* No output buffer */
		                  1,                 /* No input buffer */
		                  -1);

		if (rc)                              /* Pipe not created */
		{
			printf("DosCreateNPipe: rc=%ld, pipe=%ld\n", (long)rc, (long)pipe);
			break;
		}

		do
		{
			rc=DosConnectNPipe(pipe);        /* Wait for angband to connect */
			if (!rc) break;
			_sleep2(500);                    /* Sleep for 0.5s  */
		} while (_read_kbd(0, 0, 0)==-1);      /* Until key pressed */

		if (rc) break;

		h=_imphandle(pipe);                  /* Register handle with io */
		setmode(h, O_BINARY);                 /* Make it binary */
		in=fdopen(h, "rb");                   /* Register handle with stdio */

	} while (0);           /* We don't need no stinking exception handling <g> */

	if (!in)
	{
		printf("Sorry, the pipe connection to Angband could not be established.\n");
		exit(1);
	}

	printf("Connected.\n");

	strnfmt(buf, 160, "mode co80,%d", lines);
	system(buf);

	/* Infinite loop */
	while (!end)
	{
		/* Get command */
		c = fgetc(in);

		switch (c)
		{
			case PIP_XTRA:
			if (!fread(&n, sizeof(x), 1, in) ||
			    !fread(&v, sizeof(y), 1, in))
				abort();

			/* This hack prevents another hack */
			printf("Sorry, angband.exe and aclient.exe don't fit together.\n");
			exit(1);

			break;

			case PIP_CURS:
			if (!fread(&x, sizeof(x), 1, in) ||
			    !fread(&y, sizeof(y), 1, in))
				abort();
			Term_curs_emx(x, y);
			break;

			case PIP_WIPE:
			if (!fread(&x, sizeof(x), 1, in) ||
			    !fread(&y, sizeof(y), 1, in) ||
			    !fread(&n, sizeof(n), 1, in))
				abort();
			Term_wipe_emx(x, y, n);
			break;

			case PIP_TEXT:
			if (!fread(&x, sizeof(x), 1, in) ||
			    !fread(&y, sizeof(y), 1, in) ||
			    !fread(&n, sizeof(n), 1, in) ||
			    !fread(&a, sizeof(a), 1, in) || (n > 160) ||
			    !fread(buf, n, 1, in))
				abort();
			Term_text_emx(x, y, n, a, buf);
			break;

			case PIP_INIT:
			Term_init_emx(NULL);
			break;

			case PIP_NUKE:
			case EOF:
			default:
			Term_nuke_emx(NULL);
			end=1;
			break;
		}
	}

	return 0;
}
Beispiel #10
0
static XtransConnInfo
TRANS(Os2OpenClient)(Xtransport *thistrans, char *protocol,
		     char *host, char *port)
{
	APIRET rc;
	HFILE hfd,hServer;
	ULONG action,byteWritten,State;
	char pipename[256],clientname[256];
        char server_string[256];
        struct sockaddr *addr_name;
        unsigned char pipe_len;
	XtransConnInfo ciptr;
        static int unique_id=0;
        int i,namelen,try;

	PRMSG(2,"Os2OpenClient(%s,%s,%s)\n",protocol,host,port);

	/* test, whether the host is really local, i.e. either
	 * "os2" or "local"
	 */
	if (strcmp(protocol,"os2") && strcmp(protocol,"local")) {
		PRMSG (1,
			"Os2OpenClient: Cannot connect to non-local host %s\n",
			host, 0, 0);
		return NULL;
	}

   /* make the pipename */

    if (port && *port ) {
	if( *port == '/' ) { /* A full pathname */
		(void) sprintf(pipename, "\\PIPE\\X\\%s,", port);
	    } else {
		(void) sprintf(pipename, "%s%s", "\\PIPE\\X\\xf86.", port);
	    }
    } else {
	(void) sprintf(pipename, "\\PIPE\\X\\xfree86"); }

    PRMSG(5, "Os2OpenClient: Creating pipe %s\n",pipename, 0,0 );

	/* make a connection entry */	
	if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL ) {
		PRMSG(1,"Os2OpenClient: calloc(1,%d) failed\n",
			sizeof(struct _XtransConnInfo),0,0 );
		return NULL;
	}

	/* open the pipe. Try ten times before giving up at 500ms intervals*/
    try = 0;
    do {
	rc = DosOpen(pipename,&hServer, &action, 0,
		FILE_NORMAL, FILE_OPEN,
		OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYWRITE,
		(PEAOP2)NULL);
        if(rc == 0) break;
	if (try >=10) {
		PRMSG(1,"Os2OpenClient: Open server pipe %s failed, rc=%d\n",
			pipename,rc,0 );
		PRMSG(1,"\tProbable causes: either the XServer is not running, or has not started properly,\n",
			0,0,0 );
		PRMSG(1,"\tor the DISPLAY variable is set incorrectly.\n",
			0,0,0 );
		xfree(ciptr);
		return NULL;
	    }
       try ++;
       DosSleep(500);
       } while (rc != 0);

/* OK, now we are talking to the server. Generate a unique pipe name and pass it to
 * the server. Make the pipe and wait for server to connect */

   sprintf(clientname,"\\PIPE\\X\\%d.%d",getpid(),unique_id++);

   rc = DosCreateNPipe (clientname, &hfd,
                       NP_NOINHERIT | NP_ACCESS_DUPLEX,
                       1 | NP_NOWAIT | NP_TYPE_BYTE | NP_READMODE_BYTE,
                       16384, 16384, 0);
   if (rc != 0){
        PRMSG(1, "Os2OpenClient: Unable to create pipe %s\n", pipename,0,0 );
	DosClose(hfd);
        pipe_len=0;
        DosWrite(hServer,&pipe_len,1,&byteWritten);
        DosClose(hServer);
        xfree(ciptr);
	return(NULL);
    }

 /* Connect to the pipe. */

  rc = DosConnectNPipe (hfd);
  if (rc != 0 && rc != ERROR_PIPE_NOT_CONNECTED)
    {
        PRMSG(1, "Os2OpenClient: Unable to connect to pipe %s\n", pipename,0,0 );
        DosClose (hfd);
        DosClose(hServer);
        xfree(ciptr);
        return (NULL);
    }

/* Now write name to server on hServer */
        server_string[0]=(char) strlen(clientname)+1;
        strcpy(&server_string[1],clientname);
        rc = DosWrite(hServer,server_string,(ULONG)server_string[0]+1,&byteWritten);
        if(rc != 0){  /* Could not write to server pipe? */
           PRMSG(1, "Os2OpenClient: Error writing to server pipe, handle=%d, rc=%d, w=%d\n",
                hServer,rc,byteWritten );
           DosClose(hServer);
           DosClose(hfd);
           xfree(ciptr);
           return(NULL);
           }

      PRMSG (5, "Os2OpenCLient: Wrote pipename %s to server; len %d written %d \n",
        &server_string[1],server_string[0]+1,byteWritten);


/* The server will respond by opening the pipe. Wait for that for 30 secs */

        i=0;
        DosSleep(50);  /* Give it time to catch up but minimize race condition*/
        rc = DosConnectNPipe(hfd);
        while((rc == ERROR_PIPE_NOT_CONNECTED)&&(i++<60)) {
                DosSleep(500);
                rc = DosConnectNPipe(hfd);
                }

        if(rc != 0){  /* Server has not responded! */
           PRMSG(1, "Os2OpenClient: Timeout on wait for server response, handle=%d, rc=%d\n",hServer,rc,0 );
           PRMSG(1, "\tProbable cause: the XServer has exited or crashed while the connection was being established\n",0,0,0 );
           PRMSG(1, "\tor the XServer is too busy to respond.\n",0,0,0 );
           DosClose(hServer);
           DosClose(hfd);
           xfree(ciptr);
           return(NULL);
           }

/* OK, the server has connected! Fill-in the info and return */

        DosClose(hServer);

/* Last check: make sure client is connected! */

        rc = DosQueryNPHState(hfd,&State);
        if(rc != 0){  /* Client is not connected! */
           PRMSG(1, "Os2OpenClient: Client pipe does not appear connected. rc=%d, h=%d\n",rc,hfd,0 );
           PRMSG(1, "\tProbable cause: the XServer has just exited.\n",0,0,0 );
           DosClose(hfd);
           xfree(ciptr);
           return(NULL);
           }

        namelen=sizeof(struct sockaddr);
        if ((ciptr->addr = (char *) xalloc (namelen)) == NULL)
          {
                PRMSG (1, "Os2OpenClient: Can't allocate space for the addr\n",
	        0, 0, 0);
                DosClose(hfd);
                xfree(ciptr);
                return(NULL);
           }
        ciptr->addrlen = namelen;
        ((struct sockaddr *)ciptr->addr)->sa_family = AF_UNIX;
        strcpy(((struct sockaddr *)ciptr->addr)->sa_data, "local");

        if ((ciptr->peeraddr = (char *) xalloc (namelen)) == NULL)
          {
                PRMSG (1, "Os2OpenCLient: Can't allocate space for the addr\n",
	        0, 0, 0);
                DosClose(hfd);
                xfree(ciptr->addr);
                xfree(ciptr);
                return(NULL);
           }
       ciptr->peeraddrlen = namelen;
       ((struct sockaddr *)ciptr->peeraddr)->sa_family = AF_UNIX;
       strcpy (((struct sockaddr *)ciptr->peeraddr)->sa_data,"local");

       PRMSG (5, "Os2OpenCLient: Filled in struct: len %d %d name %s\n",
                ciptr->addrlen,ciptr->peeraddrlen,((struct sockaddr *)ciptr->peeraddr)->sa_data);


        ciptr->index=hfd;
        ciptr->family=AF_UNIX;
        if((ciptr->fd=_imphandle(hfd))<0){
           PRMSG(1, "Os2OpenClient: Could not import the pipe handle into EMX\n",0,0,0 );
           PRMSG(1, "\tProbable cause: EMX has run out of free file handles.\n",0,0,0 );
           DosClose(hfd);
           xfree(ciptr->addr);
           xfree(ciptr->peeraddr);
           xfree(ciptr);
           return(NULL);
           }
    PRMSG(5, "Os2OpenClient: pipe handle %d EMX handle %d\n",ciptr->index,ciptr->fd,0 );
        fcntl(ciptr->fd,F_SETFL,O_NDELAY);
        fcntl(ciptr->fd,F_SETFD,FD_CLOEXEC);
	return ciptr;
}
#endif /* TRANS_CLIENT */

#ifdef TRANS_SERVER
static XtransConnInfo
TRANS(Os2OpenServer)(Xtransport *thistrans, char *protocol,
		     char *host, char *port)
{
   APIRET rc;
   HFILE hfd;
   ULONG action;
   char pipename[256];
   struct sockaddr *addr_name;
   XtransConnInfo ciptr;
   int namelen;

#ifdef XSERV_t
    if (! init_server_pipes()) return(NULL);
#endif

    PRMSG(2,"Os2OpenServer(%s,%s,%s)\n",protocol,host,port);

   if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL )
    {
	PRMSG(1,"Os2OpenServer: xcalloc(1,%d) failed\n",
	      sizeof(struct _XtransConnInfo),0,0 );
	return NULL;
    }


    if (port && *port ) {
	if( *port == '/' ) { /* A full pathname */
		(void) sprintf(pipename, "\\PIPE\\X\\%s", port);
	    } else {
		(void) sprintf(pipename, "%s%s", "\\PIPE\\X\\xf86.", port);
	    }
    } else {
	(void) sprintf(pipename, "\\PIPE\\X\\xfree86");
    }

    PRMSG(5, "Os2OpenServer: Creating pipe %s\n",pipename, 0,0 );

   rc = DosCreateNPipe (pipename, &hfd,
                       NP_NOINHERIT | NP_ACCESS_INBOUND,
                       1 | NP_NOWAIT | NP_TYPE_BYTE | NP_READMODE_BYTE,
                       0, 8192, 0);
   if (rc != 0){
        PRMSG(1, "Os2OpenServer: Unable to create pipe %s, rc=%d\n", pipename,rc,0 );
        PRMSG(1, "\tProbable cause: there is already another XServer running on display :%s\n",port,0,0 );
	DosClose(hfd);
        xfree(ciptr);
	return(NULL);
    }

 /* Connect to the pipe. */

  rc = DosConnectNPipe (hfd);
  if (rc != 0 && rc != ERROR_PIPE_NOT_CONNECTED)
    {
        PRMSG(1, "Os2OpenServer: Unable to connect to pipe %s\n", pipename,0,0 );
        DosClose (hfd);
        xfree(ciptr);
        return (NULL);
    }

/* Pipe is now connected and waiting for client connect */

/*** Put in info ***/

        namelen=sizeof(struct sockaddr);
        if ((ciptr->addr = (char *) xalloc (namelen)) == NULL)
          {
                PRMSG (1, "Os2OpenServer: Can't allocate space for the addr\n",
	        0, 0, 0);
                DosClose(hfd);
                xfree(ciptr);
                return(NULL);
           }
        ciptr->addrlen = namelen;
        ((struct sockaddr *)ciptr->addr)->sa_family = AF_UNIX;
        strcpy (((struct sockaddr *)ciptr->addr)->sa_data, "local");

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

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

      PRMSG (5, "Os2OpenServer: Filled in struct: len %d %d name %s\n",
                ciptr->addrlen,ciptr->peeraddrlen,((struct sockaddr *)ciptr->peeraddr)->sa_data);

    ciptr->index=hfd; /* Save this for later use in this unused member of struct */
    ciptr->flags=1;     /* Listener */
    ciptr->family=AF_UNIX;

    if((ciptr->fd=_imphandle(hfd))<0){
       DosClose(hfd);
       xfree(ciptr->addr);
       xfree(ciptr->peeraddr);
       xfree(ciptr);
       return(NULL);
       }
    PRMSG(5, "Os2OpenServer: Pipe handle %d EMX handle %d",ciptr->index,ciptr->fd,0 );

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

    fcntl(ciptr->fd,F_SETFL,O_NDELAY);
    fcntl(ciptr->fd,F_SETFD,FD_CLOEXEC);
    return(ciptr);
}