Exemplo n.º 1
0
static int SysRunCommandPipe( const char *cmd, HFILE *readpipe )
{
    HFILE       pipe_input;
    HFILE       pipe_output;
    HFILE       std_output;
    HFILE       std_error;
    char        *cmdnam;
    char        *sp;
    int         rc;

    cmdnam = strdup( cmd );
    if( cmdnam == NULL )
        return( -1 );
    sp = strchr( cmdnam, ' ' );
    if( sp != NULL ) {
        *sp = '\0';
        sp++;
    }
    rc = -1;
    std_output = 1;
    std_error  = 2;
    if( DosCreatePipe( readpipe, &pipe_output, BUFSIZE ) == 0 ) {
        if( DosDupHandle( pipe_output, &std_output ) == 0 ) {
            if( DosDupHandle( pipe_output, &std_error ) == 0 ) {
                DosClose( pipe_output );
                rc = spawnl( P_NOWAIT, cmdnam, cmdnam, sp, NULL );
                DosClose( std_output );
                DosClose( std_error );
            }
        }
    }
    free( cmdnam );
    return( rc );
}
Exemplo n.º 2
0
static void Test(void *arg)
{
#ifdef XP_OS2
    HFILE pipefd[2];
#else
    int pipefd[2];
#endif
    int rv;
    char c = '\0';

#ifdef XP_OS2
    if (DosCreatePipe(&pipefd[0], &pipefd[1], 4096) != 0) {
#else
    if (pipe(pipefd) == -1) {
#endif
        fprintf(stderr, "cannot create pipe: %d\n", errno);
        exit(1);
    }
    close(pipefd[0]);

    rv = write(pipefd[1], &c, 1);
    if (rv != -1) {
        fprintf(stderr, "write to broken pipe should have failed with EPIPE but returned %d\n", rv);
        exit(1);
    }
#ifdef SYMBIAN
    /* Have mercy on the unknown 142 errno, it seems ok */
    if (errno != EPIPE && errno != 142) {
#else
    if (errno != EPIPE) {
#endif
        fprintf(stderr, "write to broken pipe failed but with wrong errno: %d\n", errno);
        exit(1);
    }
    close(pipefd[1]);
    printf("write to broken pipe failed with EPIPE, as expected\n");
}

int main(int argc, char **argv)
{
    PRThread *thread;

    /* This initializes NSPR. */
    PR_SetError(0, 0);

    thread = PR_CreateThread(PR_USER_THREAD, Test, NULL, PR_PRIORITY_NORMAL,
            PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
    if (thread == NULL) {
        fprintf(stderr, "PR_CreateThread failed\n");
        exit(1);
    }
    if (PR_JoinThread(thread) == PR_FAILURE) {
        fprintf(stderr, "PR_JoinThread failed\n");
        exit(1);
    }
    Test(NULL);

    printf("PASSED\n");
    return 0;
}
Buffer* launcher(char* command, char* expr, int type, int* prc)
{
	int rc = 0;

	if(!command || !command[0])
		return 0;

	HFILE hPipe[2] = {(HFILE)-1, (HFILE)-1};

	Buffer* buf = 0;

	do
	{
		rc = DosCreatePipe(&hPipe[0], &hPipe[1], 4096);

		if(rc)
			break;

//		noinherit(hPipe[0]);
//		noinherit(hPipe[1]);

		rc = redirect_and_run(hPipe[0], hPipe[1], (type) ? STDERR:STDOUT, command);

		if(rc)
			break;

		buf = filter_pipe(hPipe[0], expr);
	}
	while(0);

	DosClose(hPipe[0]);
	DosClose(hPipe[1]);

	if(prc)
		*prc = rc;

	return buf;
}
Exemplo n.º 4
0
_WCRTLINK int _pipe( int *phandles, unsigned psize, int textmode )
/****************************************************************/
{
#if defined(__NT__)
    HANDLE              hRead, hWrite;
//  HANDLE              osHandle;               // removed by JBS
    BOOL                rc;
    SECURITY_ATTRIBUTES sa;
#elif defined(__OS2__) && defined(__386__)
    HFILE               hRead, hWrite;
    APIRET              rc;
#elif defined(__OS2__) && !defined(__386__)
    HFILE               hRead, hWrite;
    USHORT              rc;
#endif
    int                 hReadPosix, hWritePosix;

// removed by JBS - allow O_NOINHERIT
//  /*** Sanity check ***/
//  if( textmode != 0  &&  textmode != _O_TEXT  &&  textmode != _O_BINARY ) {
//      return( -1 );
//  }

    /*** Create the pipes (note that psize==0 ==> use default size) ***/
    #if defined(__NT__)
        sa.nLength = sizeof( SECURITY_ATTRIBUTES );
        sa.lpSecurityDescriptor = NULL;
        sa.bInheritHandle = (((textmode & O_NOINHERIT)==O_NOINHERIT)?FALSE:TRUE);
        rc = CreatePipe( &hRead, &hWrite, &sa, psize );
        if( rc == FALSE ) {
            return( __set_errno_nt() );
        }
    #elif defined(__OS2__)
        if( psize == 0 )  psize = 4096;
        #ifdef __386__
            rc = DosCreatePipe( &hRead, &hWrite, psize );
        #else
            rc = DosMakePipe( &hRead, &hWrite, psize );
        #endif
        if( rc != NO_ERROR ) {
            __set_errno( ENOMEM );
            return( -1 );
        }
    #endif

// removed by JBS - used sa struct instead
//    /*** Make read handle inheritable ***/
//    #ifdef __NT__
//        rc = DuplicateHandle( GetCurrentProcess(), hRead, GetCurrentProcess(),
//                              &osHandle, 0, TRUE, DUPLICATE_SAME_ACCESS );
//        if( rc == FALSE ) {
//            CloseHandle( hRead );
//            CloseHandle( hWrite );
//            return( -1 );
//        }
//        CloseHandle( hRead );
//        hRead = osHandle;
//    #elif defined(__OS2__)
//        /* Handle is inheritable by default */
//    #endif
//
//    /*** Make write handle inheritable ***/
//    #ifdef __NT__
//        rc = DuplicateHandle( GetCurrentProcess(), hWrite, GetCurrentProcess(),
//                              &osHandle, 0, TRUE, DUPLICATE_SAME_ACCESS );
//        if( rc == FALSE ) {
//            CloseHandle( hRead );
//            CloseHandle( hWrite );
//            return( -1 );
//        }
//        CloseHandle( hWrite );
//        hWrite = osHandle;
//    #elif defined(__OS2__)
//        /* Handle is inheritable by default */
//    #endif

    /*** Initialize the POSIX-level handles ***/
    hReadPosix = _hdopen( (int)hRead, textmode|_O_RDONLY );
    hWritePosix = _hdopen( (int)hWrite, textmode|_O_WRONLY );
    if( hReadPosix == -1  ||  hWritePosix == -1 ) {
        if( hReadPosix != -1 ) {
            close( hReadPosix );
        } else {
            #if defined(__NT__)
                CloseHandle( hRead );
            #elif defined(__OS2__)
                DosClose( hRead );
            #endif
        }
        if( hWritePosix != -1 ) {
            close( hWritePosix );
        } else {
            #if defined(__NT__)
                CloseHandle( hWrite );
            #elif defined(__OS2__)
                DosClose( hWrite );
            #endif
        }
        return( -1 );
    }

    /*** Store the new POSIX handles in return buffer ***/
    phandles[0] = hReadPosix;
    phandles[1] = hWritePosix;
    return( 0 );
}
int main(int argc, char * argv[])
{
	int i;
	char cmdLine[CCHMAXPATH*4]={0};
	char * chrPtr;	
    char * chrPtr2;
	HWND hwndNotify;
	char exeName[CCHMAXPATH];//="g:\\projects_working\\audiocpy\\cdrecord.exe";
	char chrError[CCHMAXPATH];
	RESULTCODES resultCodes;
	ULONG rc,ulAction;
    int a;

    char puffer[1024];

    LONG lValue1=0;
    LONG lValue2=0;

    /* Vars for check size */
  int iLeadin;
  int iLeadout;
  int size;
  HFILE hfNew;
  HFILE hfSave;
  HPIPE hpR, hpW;
  ULONG cbRead, cbWritten;
  BOOL bBreak=TRUE;
  char *text,*text2;
  CHAR achBuf[PIPESIZE]={0};
  CHAR szFailName[CCHMAXPATH];
  RESULTCODES ChildRC= {0};
  PID pidChild;
  /*
    argv[0]: progname
    argv[1]: hwnd
    argv[2]: cdrecord path
    argv[3]: dev=x,y,z
   */

    /* Have to check if argc is really 4 */
    if(argc<4) {
      message();
      exit(-1);
    }

    /* Print the parameters in VIO window */
    printf("argc:%d\n",argc);  
    for(a=0;a<argc;a++)
      {
        printf("%d: %s\n",a,argv[a]);
      }
    printf("\n");

    hwndNotify=atol(argv[1]);
    /* Error: no cdrecord options given */
    if(argc<4) {
      WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(lValue1),MPFROMLONG(lValue2));
      return;
    }

	/* Get input */
    sprintf(exeName,"%s",argv[2]);// cdrecord/2 path

    for(i=3;i<argc;i++) {
      /* Find 'dev=' in option string */
      chrPtr=strstr(argv[i],"dev=");
      if(chrPtr!=NULL)i=argc;
    }


    /* Build cdrecord/2 cmd-line */
    sprintf(cmdLine,"%s",exeName);
    if((chrPtr=strrchr(cmdLine, 0))==NULL) {
      WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(0),MPFROMLONG(0));
      return;
    }
	chrPtr++;
	sprintf(chrPtr,"%s -msinfo", argv[3]);

	if(DosCreatePipe(&hpR,&hpW,1024)) {
      WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(0),MPFROMLONG(0));
      return;
    }
    if((chrPtr=strrchr(cmdLine, 0))==NULL) {
      WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(0),MPFROMLONG(0));
      return;
    }

    /* Save stdout */
    hfSave=-1;
    if(!DosDupHandle(HF_STDOUT,&hfSave)){/* Saves standard  handle      *//* Saves standard  handle      */
      
      /* Redirect stdout */
      hfNew=HF_STDOUT;
      if(!DosDupHandle(hpW,&hfNew)) {
        
        /* start cdrecord/2 */
        rc=DosExecPgm(chrError,sizeof(chrError),EXEC_ASYNC,cmdLine,0,&resultCodes,exeName);
        fprintf(stderr,"DosExecPgm() for CDRecord/2 returned: %d\n",rc);

        DosClose(hpW);                       /* Closes write handle to ensure     */
        /* Notification at child termination */
        DosDupHandle(hfSave, &hfNew);        /* Brings stdout back                */

        /*
         * Read from the pipe and write to the screen
         * as long as there are bytes to read.
         */

        do {
          /* Retrieve output */
          rc=DosRead(hpR,puffer,sizeof(puffer),&cbRead);
          DosWrite(HF_STDERR, puffer, cbRead, &cbWritten);

          if(cbRead>2) {
            lValue1=atol(puffer);// Previous session start sector
            puffer[1023]=0; //Make sure we have a terminating zero!
            chrPtr=strchr(puffer,',');
            chrPtr++;
            lValue2=atol(chrPtr);
          }
        } while(cbRead);

        DosClose(hpR);
        bBreak=FALSE;
      }/* if(!DosDupHandle(hpW,&hfNew)) */
    }/* if(!DosDupHandle(HF_STDOUT,&hfSave)) */
    /* Get leadin and leadout */

    if(!bBreak) {
      /* Now query size */
      sprintf(achBuf,"%s",argv[2]);/* cdrecord path */
      text=strchr(achBuf,0);
      if(!text) {
        WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(0),MPFROMLONG(0));    
      }
      text++;
      sprintf(text,"%s -toc -v", argv[3]);
      printf("Parameters for size query: %s\n",text);
      text=achBuf; 
      printf("Cdrecord path is: %s\n",text);

      /* Redirect stdout */ 
      hfSave = -1;// Get new handle
      hfNew = HF_STDOUT;
      
      if(!DosDupHandle(HF_STDOUT, &hfSave)){    /* Saves standard  handle      */
        if(!DosCreatePipe(&hpR, &hpW, PIPESIZE)){ /* Creates pipe            */
          
          /* If the pipe size is smaller than the output of the child the system() call blocks.
             So create the pipe big enough. */
          
          if(!DosDupHandle(hpW, &hfNew)){           /* Duplicates standard output handle */
            
            /* start CDRecord/2 */
            rc=DosExecPgm(szFailName,sizeof(szFailName),EXEC_ASYNCRESULT, text,NULL,&ChildRC, text);
            fprintf(stderr,"DosExecPgm() for CDRecord/2 returned: %d\n",rc);
            /*
              rc=system(text);
              */
            
            DosClose(hpW);                       /* Closes write handle to ensure     */
            /* Notification at child termination */
            DosDupHandle(hfSave, &hfNew);        /* Brings stdout back                */
            
            /*
             * Read from the pipe and write to the screen
             * as long as there are bytes to read.
             */
            
            do {
              DosRead(hpR, achBuf, sizeof(achBuf), &cbRead);
              DosWrite(HF_STDERR, achBuf, cbRead, &cbWritten);
              
              text=strstr(achBuf,"ATIP");
              
              if(text){
                /* Check if we have a lead in section */
                text2=strstr(text,"in:");
                if(text2) {
                  /* Yes, we have a lead in. Seems to be a blank disk. Find lead out now */
                  iLeadin=0;
                  text2++;
                  text=strstr(text2,"ATIP");/* Second ATIP shows lead out of blank disk */
                  if(text)
                    sscanf(text,"%[^:]: %ld",szFailName,&iLeadout);
                }/* if(text2) */
                else {
                  /* No lead in section. It seems to be a disk with some tracks already written */
                  sscanf(text,"%[^:]: %ld",szFailName,&iLeadout); /* ATIP shows disk lead out */
                  text2=strstr(text,"lout");
                  if(!text2){/* Error */
                    iLeadin=iLeadout;/* Set disk size to zero as error */
                    break;
                  }
                  /* Lead out of track is lead in of next track */
                  sscanf(text2,"%[^:]: %ld",szFailName,&iLeadin);
                }
              }
            } while(cbRead);          
            printf("Leadin is  %d \n",iLeadin); /* We use stdout because stderr is redirected */
            printf("Leadout is  %d \n",iLeadout);
            DosClose(hpR);
          }
        }
      }/* if(!DosDupHandle(HF_STDERR, &hfSave)) */      

      DosWaitChild(DCWA_PROCESS, DCWW_WAIT,&ChildRC, &pidChild, ChildRC.codeTerminate);
      if(ChildRC.codeResult!=0) {
        WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(0),MPFROMLONG(0));
        exit(0);
      }

      /* Calculate free space */
      size=iLeadout-iLeadin;
      if(iLeadin) {
        /* Because iLeadin isn't zero, the disk seems to be a disk with already written session.
           11400 sectors must be substracted from the size as lead in for the next session */
        if(size<11400)
          size=0;
        else
          size-=11400;
      }
    }
    printf("1. sector: %d\n2. sector: %d\n", lValue1, lValue2);

    /* The following kombinations of leadin, out, 1. sector and 2. sector are possible:
       Open CD with previous session:  xxx,  xxx,  ???,  xxx
       Empty CD:                       0  ,  xxx,  0  ,  0
       Closed CD:                      0  ,  0  ,  0  ,  0 (???)
       Closed CD:                      xxx,  xxxx,  0  ,  0
       No CD:                          0  ,  0  ,  0  ,  0
       */
    /* Full or no CD -> Error */
    if(!lValue1 && !lValue2 && !iLeadin && !iLeadout) {
      WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(0),MPFROMLONG(0));
      exit(0);
    }
    if(!lValue1 && !lValue2 && iLeadin && iLeadout) {
      WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(0),MPFROMLONG(0));
      exit(0);
    }

    /* Empty CD. Mark it by sending 1 for the sectors */
    if(!lValue1 && !lValue2  && iLeadout) {
      WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(1),MPFROMLONG(1));
      exit(0);
    }

	/* Send the two values to our notification window */
    WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(lValue1),MPFROMLONG(lValue2));
    exit(0);
}
Exemplo n.º 6
0
/*
 * Marks the end of writing.  Returns ElvTrue if all is okay, or ElvFalse if
 * error.
 *
 * For UNIX, the temp file is closed, and the program is forked.
 * (Since this function is only called when willwrite, the program
 * wasn't forked when prgopen() was called.)  Returns ElvTrue if the
 * fork was successful, or ElvFalse if it failed.
 */
ELVBOOL 
prggo (void)
{
  HFILE r_pipe, w_pipe;  /* two ends of a pipe */
  SAVE_IO save_io;
  HFILE fd, tmp_fd;
  APIRET rc;

  /* If we weren't writing, then there's nothing to be done here */
  if (writefd < 0)
    {
      return ElvTrue;
    }

  /*
   * If we're using a temp file, close it for writing, then spawn
   * the program with its stdin redirected to come from the file.
   */
  if (command)
    {
      /* Close the temp file for writing. */
      close (writefd);
      writefd = -1;

      /* Make a pipe to use for reading stdout/stderr. */
      rc = DosCreatePipe (&r_pipe, &w_pipe, 4096);
      if (rc != NO_ERROR)
        {
          msg (MSG_ERROR, "can't create pipe");
          goto Error;
        }

      /* Save all of the standard I/O handles. */
      if (!SaveStdIOHandles (save_io, 
                             SAVE_STDIN | SAVE_STDOUT | SAVE_STDERR))
        {
          goto Error;
        }

      /*
       * Redirect standard file handles for the CHILD PROCESS.
       */

      /* Get stdin from the temporary file. */
      tmp_fd = open (tempfname, O_RDONLY);
      fd = 0;
      if (DosDupHandle (tmp_fd, &fd) != NO_ERROR)
        {
          goto DupError;
        }
      close(tmp_fd);

      /* Connect the write end of the pipe to stdout/stderr. */
      fd = 1;
      if (DosDupHandle (w_pipe, &fd) != NO_ERROR)
        {
          goto DupError;
        }
      fd = 2;
      if (DosDupHandle (w_pipe, &fd) != NO_ERROR)
        {
          goto DupError;
        }

      /*
       * Prevent the child process from inheriting the read end
       * of the pipe.  This will ensure that the pipe closes
       * cleanly when the parent process (elvis) is done with it.
       */
      if (DosSetFHState (r_pipe, OPEN_FLAGS_NOINHERIT) != NO_ERROR)
        {
          msg (MSG_ERROR, "can't set file inheritance");
          goto Error;
        }

      /* Launch the command. */
      if ((pid = RunCommand (command)) < 0)
        {
          msg (MSG_ERROR, "can't spawn");
          goto Error;
        }

      /* Restore standard file handles for the PARENT PROCESS. */
      RestoreStdIOHandles (save_io);

      /*
       * Close the write end of the pipe; the read end becomes 
       * 'readfd'.
       */
      DosClose (w_pipe);
      w_pipe = NULLHANDLE;
      readfd = r_pipe;

      /* We don't need the command string any more. */
      free (command);
    }
  else /* writing but not reading */
    {
      /* close the writefd */
      close (writefd);
      writefd = -1;
    }

  return ElvTrue;

DupError:
  msg (MSG_ERROR, "can't dup file handle");

Error:
  /* Restore standard I/O handles if necessary. */
  RestoreStdIOHandles (save_io);
  return ElvFalse;
}
Exemplo n.º 7
0
/*
 * Declares which program we'll run, and what we'll be doing with it.
 * This function should return ElvTrue if successful.  If there is an error,
 * it should issue an error message via msg(), and return ElvFalse.
 *
 * For UNIX, the behavior of this function depends on willwrite.
 * If willwrite, then the command is saved and a temporary file is
 * is created to store the data that will become the program's stdin,
 * and the function succeeds if the temp file was created successfully.
 * Else the program is forked (with stdout/stderr redirected to a pipe
 * if willread) and the function succedes if pipe() and fork()
 * succeed.
 */
ELVBOOL 
prgopen (char  *cmd,    /* command string */
         ELVBOOL  willwrite,  /* if ElvTrue, redirect command's stdin */
         ELVBOOL  willread)  /* if ElvTrue, redirect command's stdout */
{
  HFILE r_pipe, w_pipe;  /* two ends of a pipe */
  SAVE_IO save_io;
  HFILE fd;
  APIRET rc;

  /* Mark both fd's as being unused */
  writefd = readfd = -1;

  /* Next step depends on what I/O we expect to do with this program */
  if (willwrite && willread)
    {
      /* save the command */
      command = strdup (cmd);

      /* create a temporary file for feeding the program's stdin */
      sprintf (tempfname, "%s/elvis%d.tmp", TMPDIR, (int)getpid ());
      writefd = open (tempfname, O_WRONLY|O_CREAT|O_EXCL, S_IREAD|S_IWRITE);
      if (writefd < 0)
        {
          msg (MSG_ERROR, "can't make temporary file");
          free (command);
          return ElvFalse;
        }
    }
  else if (willwrite || willread) /* but not both */
    {
      /* Create a pipe. */
      rc = DosCreatePipe (&r_pipe, &w_pipe, 4096);
      if (rc != NO_ERROR)
        {
          msg(MSG_ERROR, "can't create pipe");
          goto Error;
        }

      /*
       * Redirect standard file handles for the CHILD PROCESS.
       */

      if (willwrite)
        {
          /* Save the standard input handle. */
          if (!SaveStdIOHandles (save_io, SAVE_STDIN))
            goto Error;

          /* Get standard input from the read end of the pipe. */
          fd = 0;
          if (DosDupHandle (r_pipe, &fd) != NO_ERROR)
            goto DupError;

          /*
           * Prevent the child process from inheriting the write end
           * of the pipe.  This will ensure that the pipe closes
           * cleanly when the parent process (elvis) is done with it.
           */
          if (DosSetFHState (w_pipe, OPEN_FLAGS_NOINHERIT) != NO_ERROR)
            {
              msg (MSG_ERROR, "can't set file inheritance");
              goto Error;
            }
        }
      else
        {
          /* Save the standard output and error handles. */
          if (!SaveStdIOHandles (save_io, SAVE_STDOUT | SAVE_STDERR))
            {
              goto Error;
            }

          /* Send standard output to the write end of the pipe. */
          fd = 1;
          if (DosDupHandle (w_pipe, &fd) != NO_ERROR)
            {
              goto DupError;
            }

          /* Send error output to the write end of the pipe. */
          fd = 2;
          if (DosDupHandle (w_pipe, &fd) != NO_ERROR)
            {
              goto DupError;
            }
        }

      /* Launch the command. */
      if ((pid = RunCommand (cmd)) < 0)
        {
          msg (MSG_ERROR, "can't spawn");
          goto Error;
        }

      if (willwrite)
        {
          /*
           * Close the read end of the pipe and remember the fd 
           * of the write end.
           */
          DosClose (r_pipe);
          r_pipe = NULLHANDLE;
          writefd = w_pipe;
        }
      else
        {
          /*
           * Close the write end of the pipe and remember the fd 
           * of the read end.
           */
          DosClose (w_pipe);
          w_pipe = NULLHANDLE;
          readfd = r_pipe;
        }

      /* Restore standard file handles for the PARENT PROCESS. */
      RestoreStdIOHandles (save_io);
    }
  else /* no redirection */
    {
      /* Launch the command. */
      if ((pid = RunCommand (cmd)) < 0)
        {
          msg(MSG_ERROR, "can't spawn");
          goto Error;
        }
    }

  /* if we get here, we must have succeeded */
  return ElvTrue;

DupError:
  msg(MSG_ERROR, "can't dup file handle");

Error:
  /* Restore standard I/O handles if necessary. */
  RestoreStdIOHandles (save_io);
  return ElvFalse;
}
Exemplo n.º 8
0
int main(VOID) {



HFILE    ReadHandle     = NULLHANDLE; /* Read handle of pipe */

HFILE    WriteHandle    = NULLHANDLE; /* Write handle of pipe */

HFILE    NewReadHandle  = (HFILE) -1; /* Duplicate read handle */

HFILE    NewWriteHandle = (HFILE) 10; /* Duplicate write handle */

ULONG    PipeSize       = 42;         /* Size of pipe */

APIRET   rc             = NO_ERROR;   /* API return code */



rc = DosCreatePipe ( &ReadHandle, &WriteHandle, PipeSize );

if (rc != NO_ERROR) {

   printf("DosCreatePipe error: return code = %u\n", rc);

   return 1;

}

      /* Duplicate Read Handle of Pipe - use next available handle */



rc = DosDupHandle ( ReadHandle, &NewReadHandle );

if (rc != NO_ERROR) {

   printf("DosDupHandle error: return code = %u\n", rc);

   return 1;

}

      /* Duplicate Write Handle of Pipe - use handle 10 */



rc = DosDupHandle ( ReadHandle, &NewWriteHandle );

if (rc != NO_ERROR) {

   printf("DosDupHandle error: return code = %u\n", rc);

   return 1;

}



printf("Handles are: Read:%u  Write:%u  NewRead:%u  NewWrite:%u\n",

            ReadHandle, WriteHandle, NewReadHandle, NewWriteHandle);



return NO_ERROR;

}
int main(int argc, char * argv[])
{
  char achBuf[PIPESIZE];
  char achBuf2[PIPESIZE];
  char szFailName[CCHMAXPATH];

  int rc;
  HFILE hfNew;
  HFILE hfSave;
  HPIPE hpR, hpW;

  HFILE hfNew2;
  HFILE hfSaveOutput;
  HPIPE hpR2, hpW2;


  ULONG cbRead, cbRead2, cbWritten;
  HWND hwndNotify;
  char *text;
  char *mem;
  char *ptrLocalMem;
  int a;


  UCHAR LoadError[CCHMAXPATH]= {0};
  RESULTCODES ChildRC= {0};
  PID pidChild;
  FILE* fh;
  char* pipePtr;
  char* fifoPtr;
  FILE * pipe;
  LONG writtenB=0;
  LONG delta=0;
  LONG lNoFix=0;
  int iFifo=0;
  BOOL bPriority=FALSE;
  FILE *file;

  rc=-1;

  /*
    argv[0]=progname
    argv[1]=HWND 
    argv[2]=cdrecord path
    argv[3]=installation dir
    argv[4]=Parameter filename
    argv[5]=logfilename
   */

  for(a=0;a<argc;a++)
    printf("%d:  %s\n", a, argv[a]);
    
  if(argc<6) {
    message();
    exit(-1);
  }  

  hwndNotify=atol(argv[1]);

  if((ptrLocalMem=malloc(SHAREDMEM_SIZE))==NULL){
    WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(ACKEY_PRINTSIZE),MPFROMLONG(0));
    exit(255);
  }
  /* Open file with parameters */
  if((file=fopen(argv[4],"rb"))==NULL){
    WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(ACKEY_PRINTSIZE),MPFROMLONG(0));
    exit(255);
  }
  
  /* Copy command line to local memory */
  fread(ptrLocalMem, sizeof(char), SHAREDMEM_SIZE, file);
  fclose(file);

  /* Open log file */
  snprintf(LoadError, sizeof(LoadError), "%s\\%s",argv[3], argv[5]);
  fh=fopen(LoadError,"a");

  /* Get cmd line */
  text=ptrLocalMem;
  
  /* find pipe char */
  pipePtr=strchr(text,'|');
  
  mem=strstr(text,"-print-size");
  for(a=0;a<strlen("-print-size");a++) {
    *mem=' ';
    mem++;
  }
  
  if(fh) {
    fputs("\n---------------------------------------------------------------\n",fh);
    fputs("Starting the helper \"",fh);
    fputs(argv[0],fh);
    fputs("\" with the following parameters:\n",fh);
    fputs(text,fh);
    fputs("\n\n",fh);
  }
  
  /* Find end of mkisofs path */
  mem=strchr(text,'"');
  *mem=0;
  
  if(pipePtr) {
    *pipePtr=0;
    pipePtr++;
    *pipePtr=0;
    pipePtr++;
  }
  /* pipePtr points to begin of cdrecord path */
  if(strstr(pipePtr,"-nofix"))
    lNoFix=1;
  
  /* FIFO size. Needing it to know when FIFO is filled. We raise the priority of the mkisofs
     process then.
     */
  if((fifoPtr=strstr(pipePtr,"fs="))!=NULLHANDLE) {
    fifoPtr+=3;
    iFifo=atoi(fifoPtr);
    iFifo*=1024*1024;
  }        
  
#ifdef DEBUG    
  //      DosFreeMem(pvSharedMem);
  free(ptrLocalMem);
  WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(ACKEY_ONTHEFLY),MPFROMSHORT(rc));
  exit(0);
#endif

  fflush(stdout);
  fflush(stderr);
  
  hfSaveOutput = -1;// Get new handle
  hfNew2 = HF_STDOUT;
  
  if(!DosDupHandle(HF_STDOUT, &hfSaveOutput)) {
        if(!DosCreatePipe(&hpR2, &hpW2, PIPESIZE)) {
          if(!DosDupHandle(hpW2, &hfNew2)){/* Duplicates standard out handle */

            /* Start mkisofs */
            rc=DosExecPgm(LoadError,sizeof(LoadError),EXEC_ASYNCRESULT, text,NULL,&ChildRC,text);
            sprintf(achBuf,"DosExecPgm() for mkisofs returned: %d\n",rc);
            if(fh)
              fputs(achBuf,fh);
            
            DosClose(hpW2);                       /* Closes write handle to ensure     */
            /* Notification at child termination */
            
            DosDupHandle(hfSaveOutput, &hfNew2);        /* Brings stdout back                */   
            /* pipePtr points to begin of cdrecord path */
            pipe=popen(pipePtr,"wb");

            /*
             * Read from the pipe and write to the screen
             * as long as there are bytes to read.
             */          
            do {
              /* Read from mkisofs */
              DosRead(hpR2, achBuf2, sizeof(achBuf2), &cbRead2);

              /* Read output of cdrecord */
              //DosRead(hpR, achBuf, sizeof(achBuf), &cbRead);
              //DosWrite(HF_STDERR, achBuf, cbRead, &cbWritten);
              //   sscanf(achBuf,"%[^=]= %ld",szFailName,&size);       

              /* Write output of mkisofs */
              if(cbRead2)
                fwrite(achBuf2,sizeof(BYTE),cbRead2,pipe);
              
              delta+=cbRead2;
              writtenB+=cbRead2;
              if(delta>=PIPESIZE*200) {
                delta=0;
                WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(ACKEY_MBWRITTEN),MPFROMLONG(writtenB));
              }
              if(writtenB>=iFifo && !bPriority) {
                fputs("FIFO filled, increasing priority of mkisofs process.\n", fh);
                bPriority=TRUE;
                rc=DosSetPriority(PRTYS_PROCESS,PRTYC_TIMECRITICAL,30,ChildRC.codeTerminate);
                sprintf(LoadError,"DosSetPriority() returned: %d (should be 0)\n", rc);
                fputs(LoadError,fh);
                fputs("Increasing priority of the on-the-fly helper process.\n",fh);
                // rc=DosSetPriority(PRTYS_PROCESS,PRTYC_TIMECRITICAL,20,0);
                /* Is this kind of priority setting ok? */
                rc=DosSetPriority(PRTYS_PROCESS,PRTYC_TIMECRITICAL,30,0);
                sprintf(LoadError,"DosSetPriority() returned: %d (should be 0)\n", rc);
                fputs(LoadError,fh);
              }

            } while(cbRead2);

            WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(ACKEY_MBWRITTEN),MPFROMLONG(writtenB));
            /*  mark EOF in pipe */        
            ungetc(EOF,pipe);
            /* Tell the PM wrapper that all the data is transfered to cdrecord */
            WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(ACKEY_FIXATING),MPFROMLONG(lNoFix));            
            /* Wait for cdrecord process to end */
            rc=pclose(pipe);
          
            DosClose(hpR2);
        
          }
        }
      }/* if(!DosDupHandle(HF_STDERR, &hfSave)) */
      DosWaitChild(0,DCWW_WAIT,&ChildRC,&pidChild,0);

      free(ptrLocalMem);
      //  DosFreeMem(pvSharedMem);
      if(fh) {
        sprintf(achBuf,"CDRecord returned: %d\n",rc);
        fputs(achBuf,fh);
        fclose(fh);
      }
   
  /* Send msg. to the notification window */
  WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(ACKEY_ONTHEFLY),MPFROMSHORT(rc));
}
int main(int argc, char * argv[])
{
  int rc;
  HFILE hfNew;
  HWND hwndNotify;
  char *text;
  HPIPE hpR, hpW;
  ULONG cbRead, cbWritten;
  CHAR achBuf[PIPESIZE]={0};
  CHAR szFailName[CCHMAXPATH];
  HFILE hfSave;
  RESULTCODES ChildRC= {0};
  int a;
  int iBlocks;

  rc=-1;

  if(argc<4) {
    message();
    exit(-1);
  }  

  hwndNotify=atol(argv[1]);

  /* Print the parameters in VIO window */
  printf("argc:%d\n",argc);  
  for(a=0;a<argc;a++)
    {
      printf("%d: %s\n",a,argv[a]);
    }
  printf("\n");
  memset(achBuf, 0, sizeof(achBuf));

  /*  sprintf(achBuf,"%s %s -toc -v",argv[2],argv[3]); */
  sprintf(achBuf,"%s",argv[3]);
  text=strchr(achBuf,0);
  if(!text) {
    WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(4),MPFROMLONG(0));    
  }
  text++;
  sprintf(text,"%s", argv[4]);
  printf("Parameters for size query: %s\n",text);
  text=achBuf; 
  printf("Path is: %s\n",text);

  /**** start  ****/
  
  /* Redirect stdout */ 
  hfSave = -1;// Get new handle
  hfNew = HF_STDOUT;
 
  if(!DosDupHandle(HF_STDOUT, &hfSave)){    /* Saves standard  handle      */
    if(!DosCreatePipe(&hpR, &hpW, PIPESIZE)){ /* Creates pipe            */

      /* If the pipe size is smaller than the output of the child the system() call blocks.
         So create the pipe big enough. */
      
      if(!DosDupHandle(hpW, &hfNew)){           /* Duplicates standard output handle */
  
        /* start CDRecord/2 */
        rc=DosExecPgm(szFailName,sizeof(szFailName),EXEC_ASYNC, text,NULL,&ChildRC, text);
        fprintf(stderr,"DosExecPgm() for dvddao returned: %d\n",rc);
        /*
          rc=system(text);
        */

        DosClose(hpW);                       /* Closes write handle to ensure     */
        /* Notification at child termination */
        DosDupHandle(hfSave, &hfNew);        /* Brings stdout back                */

        /*
         * Read from the pipe and write to the screen
         * as long as there are bytes to read.
         */
          
        do {
          BOOL bNoMedia=FALSE;

          DosRead(hpR, achBuf, sizeof(achBuf), &cbRead);
          DosWrite(HF_STDERR, achBuf, cbRead, &cbWritten);

          /* Uppercase string */
          strupr(achBuf);
          text=strstr(achBuf,"NO MEDIA");
          if(text){
            /* No DVD/CD inserted */
            iBlocks=0;
            //WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(4),MPFROMLONG(0));
            bNoMedia=TRUE;
            break;
          }

          text=strstr(achBuf,"MEDIA SIZE");
          if(text){
            char dummy[200];
            /* We have the size */
            sscanf(text, "%s %s %d", dummy, dummy, &iBlocks);
            break;
          }

        } while(cbRead);          
        printf("Num blocks found %d \n",iBlocks);
        DosClose(hpR);
      }
    }
  }/* if(!DosDupHandle(HF_STDERR, &hfSave)) */      

  printf("Errorcode from dvddao is: %d\n",rc);
  /* Send msg. to the notification window */
  WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(4),MPFROMLONG(iBlocks));
  exit(0);
}