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 ); }
/* * Save standard I/O handles prior to redirection processing. 'select' * is a flag mask that specifies which of the standard handles are * marked for safekeeping. */ static ELVBOOL SaveStdIOHandles (SAVE_IO save, int select) { /* Establish default values for error recovery. */ save[0] = save[1] = save[2] = ~0; /* * Make copies of the selected standard I/O handles and mark the * copies so that child processes will not inherit them. */ if (select & SAVE_STDIN) { if (DosDupHandle (0, &save[0]) != NO_ERROR) { goto Error; } if (DosSetFHState (save[0], OPEN_FLAGS_NOINHERIT) != NO_ERROR) { goto Error; } } if (select & SAVE_STDOUT) { if (DosDupHandle (1, &save[1]) != NO_ERROR) { goto Error; } if (DosSetFHState (save[1], OPEN_FLAGS_NOINHERIT) != NO_ERROR) { goto Error; } } if (select & SAVE_STDERR) { if (DosDupHandle (2, &save[2]) != NO_ERROR) { goto Error; } if (DosSetFHState (save[2], OPEN_FLAGS_NOINHERIT) != NO_ERROR) { goto Error; } } /* Success. */ return ElvTrue; Error: /* Restore any handles we have managed to save. */ RestoreStdIOHandles (save); msg (MSG_ERROR, "can't save stdio handle"); return ElvFalse; }
static int redirect_and_run(HFILE local, HFILE remote, int stream, char* command) { int rc = 0; HFILE save_pipe = (HFILE)-1; set_inherit(local, 0); set_inherit(stream, 1); do { rc = DosDupHandle(stream, &save_pipe); if(rc) break; set_inherit(save_pipe, 0); HFILE hTmp = stream; rc = DosDupHandle(remote, &hTmp); if(rc) break; rc = DosClose(remote); if(rc) break; rc = run(command); if(rc) break; } while(0); if(save_pipe != -1) { int rc = 0; HFILE hTmp = stream; rc = DosDupHandle(save_pipe, &hTmp); rc = DosClose(save_pipe); } return rc; }
_WCRTLINK int dup2( int handle1, int handle2 ) { APIRET rc; __handle_check( handle1, -1 ); if( handle1 == handle2 ) { return( handle2 ); } rc = DosDupHandle( handle1, (PHFILE)&handle2 ); if( rc != 0 ) { return( __set_errno_dos( rc ) ); } __SetIOMode( handle2, __GetIOMode( handle1 ) ); return( 0 ); /* indicate success */ }
/* * Restore I/O handles saved by SaveStdIOHandles(). */ static void RestoreStdIOHandles (SAVE_IO save) { HFILE fd; int i; /* * Restore any saved I/O handles in 'save'. If the filesystem * calls fail, there's no easy way to recover. */ for (i = 0; i < 3; i++) { if (save[i] != ~0) { fd = i; DosDupHandle (save[i], &fd); DosClose (save[i]); save[i] = ~0; } } }
static apr_status_t file_dup(apr_file_t **new_file, apr_file_t *old_file, apr_pool_t *p) { int rv; apr_file_t *dup_file; if (*new_file == NULL) { dup_file = (apr_file_t *)apr_palloc(p, sizeof(apr_file_t)); if (dup_file == NULL) { return APR_ENOMEM; } dup_file->filedes = -1; } else { dup_file = *new_file; } dup_file->pool = p; rv = DosDupHandle(old_file->filedes, &dup_file->filedes); if (rv) { return APR_FROM_OS_ERROR(rv); } dup_file->fname = apr_pstrdup(dup_file->pool, old_file->fname); dup_file->buffered = old_file->buffered; dup_file->isopen = old_file->isopen; dup_file->flags = old_file->flags & ~APR_INHERIT; dup_file->ungetchar = old_file->ungetchar; /* TODO - dup pipes correctly */ dup_file->pipe = old_file->pipe; if (*new_file == NULL) { apr_pool_cleanup_register(dup_file->pool, dup_file, apr_file_cleanup, apr_pool_cleanup_null); *new_file = dup_file; } return APR_SUCCESS; }
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; }
int main(int argc, char * argv[]) { int i; char cmdLine[CCHMAXPATH*4]={0}; char cmdLineBuff[CCHMAXPATH*4]; char * chrPtr; HWND hwndNotify; char exeName[CCHMAXPATH];//"g:\\projects_working\\audiocpy\\show.exe"; char chrError[CCHMAXPATH]; char logName[CCHMAXPATH]; RESULTCODES resultCodes; ULONG rc,ulAction; HFILE hf,hfNew; if(argc<3) { message(); exit(-1); } hwndNotify=atol(argv[1]); sprintf(exeName,"%s",argv[2]); sprintf(logName,"%s\\Logfiles\\write.log",argv[3]); sprintf(cmdLine,exeName); chrPtr=strrchr(cmdLine,0); chrPtr++; /* Build parameters */ for(i=4;i<argc;i++) { sprintf(cmdLineBuff,"%s",chrPtr); sprintf(chrPtr,"%s %s",cmdLineBuff,argv[i]); } /* Replace ' with " */ changeChar(chrPtr,'\'','\"'); /* Replace ^ with space */ changeChar(chrPtr,'^',' '); printf("HWND: %ld",hwndNotify); printf("\n"); printf("cdrecord-executable: %s",exeName); printf("\n"); printf("Logname: %s\n",logName); printf("cdrecord parameter: %s",chrPtr); printf("\n"); /* Redirect stderr */ rc=DosOpen(logName,&hf,&ulAction,0,FILE_NORMAL,OPEN_ACTION_CREATE_IF_NEW|OPEN_ACTION_OPEN_IF_EXISTS, OPEN_ACCESS_WRITEONLY|OPEN_SHARE_DENYWRITE,0); if(!rc) { DosSetFilePtr(hf,0,FILE_END,&ulAction); hfNew=2; DosDupHandle(hf,&hfNew); sprintf(logName,"---------------------------------------------------------------------\n"); write(2,logName,strlen(logName)); sprintf(logName,"\n"); write(2,logName,strlen(logName)); /* time(<ime); sprintf(logName,"%s",ctime(<ime)); write(2,logName,strlen(logName)); sprintf(logName,"\n"); write(2,logName,strlen(logName)); */ sprintf(logName,"Starting to write using %s\n",exeName); write(2,logName,strlen(logName)); sprintf(logName,"with the following parameters: %s\n",chrPtr); write(2,logName,strlen(logName)); } DosExecPgm(chrError,sizeof(chrError),EXEC_SYNC,cmdLine,0,&resultCodes,exeName); sprintf(logName,"Return code is: %ld\n ",resultCodes.codeResult); write(2,logName,strlen(logName)); DosClose(hf); WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(ACKEY_WRITEONLY),MPFROMLONG(resultCodes.codeResult)); return 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; }
/* * 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; }
static void *get_log_instance() { if (gLogInstance || gLogInstanceState == 2 || gInFork) return gLogInstance; /* Set a flag that we're going to init a new log instance */ if (!__atomic_cmpxchg32(&gLogInstanceState, 1, 0)) { /* * Another thread was faster in starting instance creation, wait for it * to complete in a simple spin loop (completion should be really quick). */ while (gLogInstanceState == 1) DosSleep(1); return gLogInstance; } void *logInstance = NULL; __LIBC_LOGGROUPS *logGroups = NULL; #if defined(TRACE_ENABLED) logGroups = &gLogGroups; __libc_LogGroupInit(&gLogGroups, "LIBCX_TRACE"); #endif /* Check if we are asked to log to console */ { PSZ dummy; gLogToConsole = DosScanEnv("LIBCX_TRACE_TO_CONSOLE", &dummy) == NO_ERROR; } char buf[CCHMAXPATH + 128]; if (gLogToConsole) { logInstance = __libc_LogInit(0, logGroups, "NUL"); if (logInstance) { /* * This is a dirty hack to write logs to stdout, * LIBC isn't capable of it on its own (@todo fix LIBC). */ typedef struct __libc_logInstance { /** Write Semaphore. */ HMTX hmtx; /** Filehandle. */ HFILE hFile; /** Api groups. */ __LIBC_PLOGGROUPS pGroups; } __LIBC_LOGINST, *__LIBC_PLOGINST; /* Sanity check (note: we use LIBC assert here to avoid recursion) */ assert(((__LIBC_PLOGINST)logInstance)->pGroups == logGroups); /* Duplicate STDOUT */ DosDupHandle(1, &((__LIBC_PLOGINST)logInstance)->hFile); } } else { /* * We don't query QSV_TIME_HIGH as it will remain 0 until 19-Jan-2038 and for * our purposes (generate an unique log name sorted by date) it's fine. */ ULONG time; DosQuerySysInfo(QSV_TIME_LOW, QSV_TIME_LOW, &time, sizeof(time)); // Get log directory (boot drive if no UNIXROOT) const char *path = "/var/log/libcx"; PSZ unixroot; if (DosScanEnv("UNIXROOT", &unixroot) != NO_ERROR) { ULONG drv; DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, &drv, sizeof(drv)); unixroot = "C:"; unixroot[0] = '@' + drv; path = ""; } else { /* * Make sure the directory exists (no error checks here as a failure to * do so will pop up later in __libc_LogInit anyway). */ if (strlen(unixroot) >= CCHMAXPATH) return NULL; strcpy(buf, unixroot); strcat(buf, path); DosCreateDir(buf, NULL); } // Get program name char name[CCHMAXPATH]; PPIB ppib = NULL; DosGetInfoBlocks(NULL, &ppib); if (DosQueryModuleName(ppib->pib_hmte, sizeof(name), name) != NO_ERROR) return NULL; _remext(name); logInstance = __libc_LogInit(0, logGroups, "%s%s/%s-%08lx-%04x.log", unixroot, path, _getname(name), time, getpid()); } /* Bail out if we failed to create a log file at all */ if (!logInstance) { gLogInstanceState = 0; return NULL; } if (!gLogToConsole) { // Write out LIBCx info strcpy(buf, "LIBCx version : " VERSION_MAJ_MIN_BLD LIBCX_DEBUG_SUFFIX LIBCX_DEV_SUFFIX "\n"); strcat(buf, "LIBCx module : "); APIRET arc = DosQueryModuleName(ghModule, CCHMAXPATH, buf + strlen(buf)); if (arc == NO_ERROR) sprintf(buf + strlen(buf), " (hmod=%04lx)\n", ghModule); else sprintf(buf + strlen(buf), " <error %ld>\n", arc); __libc_LogRaw(logInstance, __LIBC_LOG_MSGF_FLUSH, buf, strlen(buf)); } /* * Finish initialization by storing the instance and setting the state to 2 * (this will unfreeze other threads that started instance creation, if any). */ gLogInstance = logInstance; gLogInstanceState = 2; return gLogInstance; }
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); }
/** * Implementation of VbglR3Init and VbglR3InitUser */ static int vbglR3Init(const char *pszDeviceName) { uint32_t cInits = ASMAtomicIncU32(&g_cInits); Assert(cInits > 0); if (cInits > 1) { /* * This will fail if two (or more) threads race each other calling VbglR3Init. * However it will work fine for single threaded or otherwise serialized * processed calling us more than once. */ #ifdef RT_OS_WINDOWS if (g_hFile == INVALID_HANDLE_VALUE) #elif !defined (VBOX_VBGLR3_XFREE86) if (g_File == NIL_RTFILE) #else if (g_File == -1) #endif return VERR_INTERNAL_ERROR; return VINF_SUCCESS; } #if defined(RT_OS_WINDOWS) if (g_hFile != INVALID_HANDLE_VALUE) #elif !defined(VBOX_VBGLR3_XFREE86) if (g_File != NIL_RTFILE) #else if (g_File != -1) #endif return VERR_INTERNAL_ERROR; #if defined(RT_OS_WINDOWS) /* * Have to use CreateFile here as we want to specify FILE_FLAG_OVERLAPPED * and possible some other bits not available thru iprt/file.h. */ HANDLE hFile = CreateFile(pszDeviceName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); if (hFile == INVALID_HANDLE_VALUE) return VERR_OPEN_FAILED; g_hFile = hFile; #elif defined(RT_OS_OS2) /* * We might wish to compile this with Watcom, so stick to * the OS/2 APIs all the way. And in any case we have to use * DosDevIOCtl for the requests, why not use Dos* for everything. */ HFILE hf = NULLHANDLE; ULONG ulAction = 0; APIRET rc = DosOpen((PCSZ)pszDeviceName, &hf, &ulAction, 0, FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS, OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NOINHERIT | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE, NULL); if (rc) return RTErrConvertFromOS2(rc); if (hf < 16) { HFILE ahfs[16]; unsigned i; for (i = 0; i < RT_ELEMENTS(ahfs); i++) { ahfs[i] = 0xffffffff; rc = DosDupHandle(hf, &ahfs[i]); if (rc) break; } if (i-- > 1) { ULONG fulState = 0; rc = DosQueryFHState(ahfs[i], &fulState); if (!rc) { fulState |= OPEN_FLAGS_NOINHERIT; fulState &= OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_NOINHERIT; /* Turn off non-participating bits. */ rc = DosSetFHState(ahfs[i], fulState); } if (!rc) { rc = DosClose(hf); AssertMsg(!rc, ("%ld\n", rc)); hf = ahfs[i]; } else i++; while (i-- > 0) DosClose(ahfs[i]); } } g_File = (RTFILE)hf; #elif defined(VBOX_VBGLR3_XFREE86) int File = xf86open(pszDeviceName, XF86_O_RDWR); if (File == -1) return VERR_OPEN_FAILED; g_File = File; #else /* The default implementation. (linux, solaris, freebsd) */ RTFILE File; int rc = RTFileOpen(&File, pszDeviceName, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE); if (RT_FAILURE(rc)) return rc; g_File = File; #endif #ifndef VBOX_VBGLR3_XFREE86 /* * Create release logger */ PRTLOGGER pReleaseLogger; static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES; int rc2 = RTLogCreate(&pReleaseLogger, 0, "all", "VBOX_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), &s_apszGroups[0], RTLOGDEST_USER, NULL); /* This may legitimately fail if we are using the mini-runtime. */ if (RT_SUCCESS(rc2)) RTLogRelSetDefaultInstance(pReleaseLogger); #endif return VINF_SUCCESS; }
HB_FHANDLE hb_fsProcessOpen( const char * pszFileName, HB_FHANDLE * phStdin, HB_FHANDLE * phStdout, HB_FHANDLE * phStderr, HB_BOOL fDetach, HB_ULONG * pulPID ) { HB_FHANDLE hPipeIn [ 2 ] = { FS_ERROR, FS_ERROR }, hPipeOut[ 2 ] = { FS_ERROR, FS_ERROR }, hPipeErr[ 2 ] = { FS_ERROR, FS_ERROR }; HB_FHANDLE hResult = FS_ERROR; HB_ERRCODE errCode; HB_BOOL fError = HB_FALSE; HB_TRACE( HB_TR_DEBUG, ( "hb_fsProcessOpen(%s, %p, %p, %p, %d, %p)", pszFileName, phStdin, phStdout, phStderr, fDetach, pulPID ) ); if( phStdin != NULL ) fError = ! hb_fsPipeCreate( hPipeIn ); if( ! fError && phStdout != NULL ) fError = ! hb_fsPipeCreate( hPipeOut ); if( ! fError && phStderr != NULL ) { if( phStdout == phStderr ) { hPipeErr[ 0 ] = hPipeOut[ 0 ]; hPipeErr[ 1 ] = hPipeOut[ 1 ]; } else fError = ! hb_fsPipeCreate( hPipeErr ); } if( ! fError ) { #if defined( HB_OS_WIN ) PROCESS_INFORMATION pi; STARTUPINFO si; DWORD dwFlags = 0; LPTSTR lpCommand = HB_CHARDUP( pszFileName ); # if ! defined( HB_OS_WIN_CE ) if( phStdin != NULL ) SetHandleInformation( ( HANDLE ) hb_fsGetOsHandle( hPipeIn [ 1 ] ), HANDLE_FLAG_INHERIT, 0 ); if( phStdout != NULL ) SetHandleInformation( ( HANDLE ) hb_fsGetOsHandle( hPipeOut[ 0 ] ), HANDLE_FLAG_INHERIT, 0 ); if( phStderr != NULL && phStdout != phStderr ) SetHandleInformation( ( HANDLE ) hb_fsGetOsHandle( hPipeErr[ 0 ] ), HANDLE_FLAG_INHERIT, 0 ); # endif memset( &pi, 0, sizeof( pi ) ); memset( &si, 0, sizeof( si ) ); si.cb = sizeof( si ); # ifdef STARTF_USESTDHANDLES si.dwFlags = STARTF_USESTDHANDLES; # endif if( fDetach ) { # ifdef STARTF_USESHOWWINDOW si.dwFlags |= STARTF_USESHOWWINDOW; # endif si.wShowWindow = SW_HIDE; si.hStdInput = ( HANDLE ) hb_fsGetOsHandle( hPipeIn [ 0 ] ); si.hStdOutput = ( HANDLE ) hb_fsGetOsHandle( hPipeOut[ 1 ] ); si.hStdError = ( HANDLE ) hb_fsGetOsHandle( hPipeErr[ 1 ] ); # ifdef DETACHED_PROCESS dwFlags |= DETACHED_PROCESS; # endif } else { si.hStdInput = phStdin ? ( HANDLE ) hb_fsGetOsHandle( hPipeIn [ 0 ] ) : GetStdHandle( STD_INPUT_HANDLE ); si.hStdOutput = phStdout ? ( HANDLE ) hb_fsGetOsHandle( hPipeOut[ 1 ] ) : GetStdHandle( STD_OUTPUT_HANDLE ); si.hStdError = phStderr ? ( HANDLE ) hb_fsGetOsHandle( hPipeErr[ 1 ] ) : GetStdHandle( STD_ERROR_HANDLE ); } fError = ! CreateProcess( NULL, /* lpAppName */ lpCommand, NULL, /* lpProcessAttr */ NULL, /* lpThreadAttr */ TRUE, /* bInheritHandles */ dwFlags, /* dwCreationFlags */ NULL, /* lpEnvironment */ NULL, /* lpCurrentDirectory */ &si, &pi ); hb_fsSetIOError( ! fError, 0 ); hb_xfree( lpCommand ); if( ! fError ) { if( phStdin != NULL ) { *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ]; hPipeIn[ 1 ] = FS_ERROR; } if( phStdout != NULL ) { *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ]; hPipeOut[ 0 ] = FS_ERROR; } if( phStderr != NULL ) { *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ]; hPipeErr[ 0 ] = FS_ERROR; } if( pulPID ) *pulPID = pi.dwProcessId; CloseHandle( pi.hThread ); hResult = ( HB_FHANDLE ) pi.hProcess; } #elif defined( HB_OS_OS2 ) HFILE hNull = ( HFILE ) FS_ERROR; ULONG ulState = 0; APIRET ret = NO_ERROR; PID pid = ( PID ) -1; PHB_GT pGT; if( fDetach && ( ! phStdin || ! phStdout || ! phStderr ) ) { HB_FHANDLE hFile; ret = hb_fsOS2DosOpen( "NUL:", &hFile, &ulState, 0, FILE_NORMAL, OPEN_ACCESS_READWRITE, OPEN_ACTION_OPEN_IF_EXISTS ); if( ret == NO_ERROR ) hNull = ( HFILE ) hFile; } if( ret == NO_ERROR && phStdin != NULL ) { ret = DosQueryFHState( hPipeIn[ 1 ], &ulState ); if( ret == NO_ERROR && ( ulState & OPEN_FLAGS_NOINHERIT ) == 0 ) ret = DosSetFHState( hPipeIn[ 1 ], ( ulState & 0xFF00 ) | OPEN_FLAGS_NOINHERIT ); } if( ret == NO_ERROR && phStdout != NULL ) { ret = DosQueryFHState( hPipeOut[ 0 ], &ulState ); if( ret == NO_ERROR && ( ulState & OPEN_FLAGS_NOINHERIT ) == 0 ) ret = DosSetFHState( hPipeOut[ 0 ], ( ulState & 0xFF00 ) | OPEN_FLAGS_NOINHERIT ); } if( ret == NO_ERROR && phStderr != NULL && phStdout != phStderr ) { ret = DosQueryFHState( hPipeErr[ 0 ], &ulState ); if( ret == NO_ERROR && ( ulState & OPEN_FLAGS_NOINHERIT ) == 0 ) ret = DosSetFHState( hPipeErr[ 0 ], ( ulState & 0xFF00 ) | OPEN_FLAGS_NOINHERIT ); } if( ret == NO_ERROR && ( pGT = hb_gt_Base() ) != NULL ) { ULONG ulStateIn, ulStateOut, ulStateErr; HFILE hStdIn, hStdErr, hStdOut, hDup; ulStateIn = ulStateOut = ulStateErr = OPEN_FLAGS_NOINHERIT; hStdIn = hStdErr = hStdOut = ( HFILE ) FS_ERROR; if( ret == NO_ERROR && ( phStdin != NULL || fDetach ) ) { hDup = 0; ret = DosDupHandle( hDup, &hStdIn ); if( ret == NO_ERROR ) { ret = DosQueryFHState( hStdIn, &ulStateIn ); if( ret == NO_ERROR && ( ulStateIn & OPEN_FLAGS_NOINHERIT ) == 0 ) ret = DosSetFHState( hStdIn, ( ulStateIn & 0xFF00 ) | OPEN_FLAGS_NOINHERIT ); if( ret == NO_ERROR ) ret = DosDupHandle( phStdin != NULL ? ( HFILE ) hPipeIn[ 0 ] : hNull, &hDup ); } } if( ret == NO_ERROR && ( phStdout != NULL || fDetach ) ) { hDup = 1; ret = DosDupHandle( hDup, &hStdOut ); if( ret == NO_ERROR ) { ret = DosQueryFHState( hStdOut, &ulStateOut ); if( ret == NO_ERROR && ( ulStateOut & OPEN_FLAGS_NOINHERIT ) == 0 ) ret = DosSetFHState( hStdOut, ( ulStateOut & 0xFF00 ) | OPEN_FLAGS_NOINHERIT ); if( ret == NO_ERROR ) ret = DosDupHandle( phStdout != NULL ? ( HFILE ) hPipeOut[ 1 ] : hNull, &hDup ); } } if( ret == NO_ERROR && ( phStderr != NULL || fDetach ) ) { hDup = 2; ret = DosDupHandle( hDup, &hStdErr ); if( ret == NO_ERROR ) { ret = DosQueryFHState( hStdErr, &ulStateErr ); if( ret == NO_ERROR && ( ulStateErr & OPEN_FLAGS_NOINHERIT ) == 0 ) ret = DosSetFHState( hStdErr, ( ulStateErr & 0xFF00 ) | OPEN_FLAGS_NOINHERIT ); if( ret == NO_ERROR ) ret = DosDupHandle( phStderr != NULL ? ( HFILE ) hPipeErr[ 1 ] : hNull, &hDup ); } } if( ret == NO_ERROR ) { char * pArgs = hb_buildArgsOS2( pszFileName, &ret ); char uchLoadError[ CCHMAXPATH ] = { 0 }; RESULTCODES ChildRC = { 0, 0 }; if( pArgs ) { ret = DosExecPgm( uchLoadError, sizeof( uchLoadError ), fDetach ? EXEC_BACKGROUND : EXEC_ASYNCRESULT, ( PCSZ ) pArgs, NULL /* env */, &ChildRC, ( PCSZ ) pArgs ); if( ret == NO_ERROR ) pid = ChildRC.codeTerminate; hb_freeArgsOS2( pArgs ); } } if( hNull != ( HFILE ) FS_ERROR ) DosClose( hNull ); if( hStdIn != ( HFILE ) FS_ERROR ) { hDup = 0; DosDupHandle( hStdIn, &hDup ); DosClose( hStdIn ); if( ( ulStateIn & OPEN_FLAGS_NOINHERIT ) == 0 ) DosSetFHState( hDup, ulStateIn & 0xFF00 ); } if( hStdOut != ( HFILE ) FS_ERROR ) { hDup = 1; DosDupHandle( hStdOut, &hDup ); DosClose( hStdOut ); if( ( ulStateOut & OPEN_FLAGS_NOINHERIT ) == 0 ) DosSetFHState( hDup, ulStateOut & 0xFF00 ); } if( hStdErr != ( HFILE ) FS_ERROR ) { hDup = 2; DosDupHandle( hStdErr, &hDup ); DosClose( hStdErr ); if( ( ulStateErr & OPEN_FLAGS_NOINHERIT ) == 0 ) DosSetFHState( hDup, ulStateErr & 0xFF00 ); } hb_gt_BaseFree( pGT ); } else { if( hNull != ( HFILE ) FS_ERROR ) DosClose( hNull ); if( ret == NO_ERROR ) ret = ( APIRET ) FS_ERROR; } fError = ret != NO_ERROR; if( ! fError ) { if( phStdin != NULL ) { *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ]; hPipeIn[ 1 ] = FS_ERROR; } if( phStdout != NULL ) { *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ]; hPipeOut[ 0 ] = FS_ERROR; } if( phStderr != NULL ) { *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ]; hPipeErr[ 0 ] = FS_ERROR; } if( pulPID ) *pulPID = pid; hResult = ( HB_FHANDLE ) pid; } hb_fsSetError( ( HB_ERRCODE ) ret ); #elif defined( HB_OS_UNIX ) && \ ! defined( HB_OS_VXWORKS ) && ! defined( HB_OS_SYMBIAN ) char ** argv = hb_buildArgs( pszFileName ); pid_t pid = fork(); if( pid == -1 ) fError = HB_TRUE; else if( pid != 0 ) /* parent process */ { if( phStdin != NULL ) { *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ]; hPipeIn[ 1 ] = FS_ERROR; } if( phStdout != NULL ) { *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ]; hPipeOut[ 0 ] = FS_ERROR; } if( phStderr != NULL ) { *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ]; hPipeErr[ 0 ] = FS_ERROR; } if( pulPID ) *pulPID = pid; hResult = ( HB_FHANDLE ) pid; } else /* child process */ { if( fDetach && ( ! phStdin || ! phStdout || ! phStderr ) ) { HB_FHANDLE hNull = open( "/dev/null", O_RDWR ); if( ! phStdin ) dup2( hNull, 0 ); if( ! phStdout ) dup2( hNull, 1 ); if( ! phStderr ) dup2( hNull, 2 ); if( hNull != FS_ERROR ) hb_fsClose( hNull ); } if( phStdin != NULL ) { dup2( hPipeIn[ 0 ], 0 ); hb_fsClose( hPipeIn[ 1 ] ); } if( phStdout != NULL ) { dup2( hPipeOut[ 1 ], 1 ); hb_fsClose( hPipeOut[ 0 ] ); } if( phStderr != NULL ) { dup2( hPipeErr[ 1 ], 2 ); if( phStdout != phStderr ) hb_fsClose( hPipeErr[ 0 ] ); } /* close all non std* handles */ { int iMaxFD, i; iMaxFD = sysconf( _SC_OPEN_MAX ); if( iMaxFD < 3 ) iMaxFD = 1024; for( i = 3; i < iMaxFD; ++i ) hb_fsClose( i ); } /* reset extended process attributes */ if( setuid( getuid() ) == -1 ) {} if( setgid( getgid() ) == -1 ) {} /* execute command */ { # if defined( __WATCOMC__ ) execvp( argv[ 0 ], ( const char ** ) argv ); # else execvp( argv[ 0 ], argv ); # endif exit( -1 ); } } hb_fsSetIOError( ! fError, 0 ); hb_freeArgs( argv ); #elif defined( HB_OS_OS2 ) || defined( HB_OS_WIN ) int hStdIn, hStdOut, hStdErr; char ** argv; int pid; hStdIn = dup( 0 ); hStdOut = dup( 1 ); hStdErr = dup( 2 ); if( fDetach && ( ! phStdin || ! phStdout || ! phStderr ) ) { HB_FHANDLE hNull = open( "NUL:", O_RDWR ); if( ! phStdin ) dup2( hNull, 0 ); if( ! phStdout ) dup2( hNull, 1 ); if( ! phStderr ) dup2( hNull, 2 ); if( hNull != FS_ERROR ) close( hNull ); } if( phStdin != NULL ) dup2( hPipeIn[ 0 ], 0 ); if( phStdout != NULL ) dup2( hPipeOut[ 1 ], 1 ); if( phStderr != NULL ) dup2( hPipeErr[ 1 ], 2 ); argv = hb_buildArgs( pszFileName ); #if defined( _MSC_VER ) || defined( __LCC__ ) || \ defined( __XCC__ ) || defined( __POCC__ ) pid = _spawnvp( _P_NOWAIT, argv[ 0 ], argv ); #elif defined( __MINGW32__ ) || defined( __WATCOMC__ ) pid = spawnvp( P_NOWAIT, argv[ 0 ], ( const char * const * ) argv ); #else pid = spawnvp( P_NOWAIT, argv[ 0 ], ( char * const * ) argv ); #endif hb_freeArgs( argv ); dup2( hStdIn, 0 ); close( hStdIn ); dup2( hStdOut, 1 ); close( hStdOut ); dup2( hStdErr, 2 ); close( hStdErr ); if( pid < 0 ) fError = HB_TRUE; else if( pid != 0 ) /* parent process */ { if( phStdin != NULL ) { *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ]; hPipeIn[ 1 ] = FS_ERROR; } if( phStdout != NULL ) { *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ]; hPipeOut[ 0 ] = FS_ERROR; } if( phStderr != NULL ) { *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ]; hPipeErr[ 0 ] = FS_ERROR; } if( pulPID ) *pulPID = pid; hResult = ( HB_FHANDLE ) pid; } hb_fsSetIOError( ! fError, 0 ); #else int iTODO; /* TODO: for given platform */ HB_SYMBOL_UNUSED( pszFileName ); HB_SYMBOL_UNUSED( fDetach ); HB_SYMBOL_UNUSED( pulPID ); hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); #endif } errCode = hb_fsError(); if( hPipeIn[ 0 ] != FS_ERROR ) hb_fsClose( hPipeIn[ 0 ] ); if( hPipeIn[ 1 ] != FS_ERROR ) hb_fsClose( hPipeIn[ 1 ] ); if( hPipeOut[ 0 ] != FS_ERROR ) hb_fsClose( hPipeOut[ 0 ] ); if( hPipeOut[ 1 ] != FS_ERROR ) hb_fsClose( hPipeOut[ 1 ] ); if( phStdout != phStderr ) { if( hPipeErr[ 0 ] != FS_ERROR ) hb_fsClose( hPipeErr[ 0 ] ); if( hPipeErr[ 1 ] != FS_ERROR ) hb_fsClose( hPipeErr[ 1 ] ); } hb_fsSetError( errCode ); return hResult; }
PRProcess * _PR_CreateOS2Process( const char *path, char *const *argv, char *const *envp, const PRProcessAttr *attr) { PRProcess *proc = NULL; char *cmdLine = NULL; char **newEnvp = NULL; char *envBlock = NULL; STARTDATA startData = {0}; APIRET rc; ULONG ulAppType = 0; PID pid = 0; char *pszComSpec; char pszEXEName[CCHMAXPATH] = ""; char pszFormatString[CCHMAXPATH]; char pszObjectBuffer[CCHMAXPATH]; char *pszFormatResult = NULL; /* * Variables for DosExecPgm */ char szFailed[CCHMAXPATH]; char *pszCmdLine = NULL; RESULTCODES procInfo; HFILE hStdIn = 0, hStdOut = 0, hStdErr = 0; HFILE hStdInSave = -1, hStdOutSave = -1, hStdErrSave = -1; proc = PR_NEW(PRProcess); if (!proc) { PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); goto errorExit; } if (assembleCmdLine(argv, &cmdLine) == -1) { PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); goto errorExit; } #ifdef MOZ_OS2_HIGH_MEMORY /* * DosQueryAppType() fails if path (the char* in the first argument) is in * high memory. If that is the case, the following moves it to low memory. */ if ((ULONG)path >= 0x20000000) { size_t len = strlen(path) + 1; char *copy = (char *)alloca(len); memcpy(copy, path, len); path = copy; } #endif if (envp == NULL) { newEnvp = NULL; } else { int i; int numEnv = 0; while (envp[numEnv]) { numEnv++; } newEnvp = (char **) PR_MALLOC((numEnv+1) * sizeof(char *)); for (i = 0; i <= numEnv; i++) { newEnvp[i] = envp[i]; } qsort((void *) newEnvp, (size_t) numEnv, sizeof(char *), compare); } if (assembleEnvBlock(newEnvp, &envBlock) == -1) { PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); goto errorExit; } rc = DosQueryAppType(path, &ulAppType); if (rc != NO_ERROR) { char *pszDot = strrchr(path, '.'); if (pszDot) { /* If it is a CMD file, launch the users command processor */ if (!stricmp(pszDot, ".cmd")) { rc = DosScanEnv("COMSPEC", (PSZ *)&pszComSpec); if (!rc) { strcpy(pszFormatString, "/C %s %s"); strcpy(pszEXEName, pszComSpec); ulAppType = FAPPTYP_WINDOWCOMPAT; } } } } if (ulAppType == 0) { PR_SetError(PR_UNKNOWN_ERROR, 0); goto errorExit; } if ((ulAppType & FAPPTYP_WINDOWAPI) == FAPPTYP_WINDOWAPI) { startData.SessionType = SSF_TYPE_PM; } else if (ulAppType & FAPPTYP_WINDOWCOMPAT) { startData.SessionType = SSF_TYPE_WINDOWABLEVIO; } else { startData.SessionType = SSF_TYPE_DEFAULT; } if (ulAppType & (FAPPTYP_WINDOWSPROT31 | FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSREAL)) { strcpy(pszEXEName, "WINOS2.COM"); startData.SessionType = PROG_31_STDSEAMLESSVDM; strcpy(pszFormatString, "/3 %s %s"); } startData.InheritOpt = SSF_INHERTOPT_SHELL; if (pszEXEName[0]) { pszFormatResult = PR_MALLOC(strlen(pszFormatString)+strlen(path)+strlen(cmdLine)); sprintf(pszFormatResult, pszFormatString, path, cmdLine); startData.PgmInputs = pszFormatResult; } else { strcpy(pszEXEName, path); startData.PgmInputs = cmdLine; } startData.PgmName = pszEXEName; startData.Length = sizeof(startData); startData.Related = SSF_RELATED_INDEPENDENT; startData.ObjectBuffer = pszObjectBuffer; startData.ObjectBuffLen = CCHMAXPATH; startData.Environment = envBlock; if (attr) { /* On OS/2, there is really no way to pass file handles for stdin, * stdout, and stderr to a new process. Instead, we can make it * a child process and make the given file handles a copy of our * stdin, stdout, and stderr. The child process then inherits * ours, and we set ours back. Twisted and gross I know. If you * know a better way, please use it. */ if (attr->stdinFd) { hStdIn = 0; DosDupHandle(hStdIn, &hStdInSave); DosDupHandle((HFILE) attr->stdinFd->secret->md.osfd, &hStdIn); } if (attr->stdoutFd) { hStdOut = 1; DosDupHandle(hStdOut, &hStdOutSave); DosDupHandle((HFILE) attr->stdoutFd->secret->md.osfd, &hStdOut); } if (attr->stderrFd) { hStdErr = 2; DosDupHandle(hStdErr, &hStdErrSave); DosDupHandle((HFILE) attr->stderrFd->secret->md.osfd, &hStdErr); } /* * Build up the Command Line for DosExecPgm */ pszCmdLine = PR_MALLOC(strlen(pszEXEName) + strlen(startData.PgmInputs) + 3); sprintf(pszCmdLine, "%s%c%s%c", pszEXEName, '\0', startData.PgmInputs, '\0'); rc = DosExecPgm(szFailed, CCHMAXPATH, EXEC_ASYNCRESULT, pszCmdLine, envBlock, &procInfo, pszEXEName); PR_DELETE(pszCmdLine); /* Restore our old values. Hope this works */ if (hStdInSave != -1) { DosDupHandle(hStdInSave, &hStdIn); DosClose(hStdInSave); } if (hStdOutSave != -1) { DosDupHandle(hStdOutSave, &hStdOut); DosClose(hStdOutSave); } if (hStdErrSave != -1) { DosDupHandle(hStdErrSave, &hStdErr); DosClose(hStdErrSave); } if (rc != NO_ERROR) { /* XXX what error code? */ PR_SetError(PR_UNKNOWN_ERROR, rc); goto errorExit; } proc->md.pid = procInfo.codeTerminate; } else { /* * If no STDIN/STDOUT redirection is not needed, use DosStartSession * to create a new, independent session */ rc = DosStartSession(&startData, &ulAppType, &pid); if ((rc != NO_ERROR) && (rc != ERROR_SMG_START_IN_BACKGROUND)) { PR_SetError(PR_UNKNOWN_ERROR, rc); goto errorExit; } proc->md.pid = pid; } if (pszFormatResult) { PR_DELETE(pszFormatResult); } PR_DELETE(cmdLine); if (newEnvp) { PR_DELETE(newEnvp); } if (envBlock) { PR_DELETE(envBlock); } return proc; errorExit: if (cmdLine) { PR_DELETE(cmdLine); } if (newEnvp) { PR_DELETE(newEnvp); } if (envBlock) { PR_DELETE(envBlock); } if (proc) { PR_DELETE(proc); } return NULL; } /* _PR_CreateOS2Process */
/** * Implementation of VbglR3Init and VbglR3InitUser */ static int vbglR3Init(const char *pszDeviceName) { uint32_t cInits = ASMAtomicIncU32(&g_cInits); Assert(cInits > 0); if (cInits > 1) { /* * This will fail if two (or more) threads race each other calling VbglR3Init. * However it will work fine for single threaded or otherwise serialized * processed calling us more than once. */ #ifdef RT_OS_WINDOWS if (g_hFile == INVALID_HANDLE_VALUE) #elif !defined (VBOX_VBGLR3_XSERVER) if (g_File == NIL_RTFILE) #else if (g_File == -1) #endif return VERR_INTERNAL_ERROR; return VINF_SUCCESS; } #if defined(RT_OS_WINDOWS) if (g_hFile != INVALID_HANDLE_VALUE) #elif !defined(VBOX_VBGLR3_XSERVER) if (g_File != NIL_RTFILE) #else if (g_File != -1) #endif return VERR_INTERNAL_ERROR; #if defined(RT_OS_WINDOWS) /* * Have to use CreateFile here as we want to specify FILE_FLAG_OVERLAPPED * and possible some other bits not available thru iprt/file.h. */ HANDLE hFile = CreateFile(pszDeviceName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); if (hFile == INVALID_HANDLE_VALUE) return VERR_OPEN_FAILED; g_hFile = hFile; #elif defined(RT_OS_OS2) /* * We might wish to compile this with Watcom, so stick to * the OS/2 APIs all the way. And in any case we have to use * DosDevIOCtl for the requests, why not use Dos* for everything. */ HFILE hf = NULLHANDLE; ULONG ulAction = 0; APIRET rc = DosOpen((PCSZ)pszDeviceName, &hf, &ulAction, 0, FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS, OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NOINHERIT | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE, NULL); if (rc) return RTErrConvertFromOS2(rc); if (hf < 16) { HFILE ahfs[16]; unsigned i; for (i = 0; i < RT_ELEMENTS(ahfs); i++) { ahfs[i] = 0xffffffff; rc = DosDupHandle(hf, &ahfs[i]); if (rc) break; } if (i-- > 1) { ULONG fulState = 0; rc = DosQueryFHState(ahfs[i], &fulState); if (!rc) { fulState |= OPEN_FLAGS_NOINHERIT; fulState &= OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_NOINHERIT; /* Turn off non-participating bits. */ rc = DosSetFHState(ahfs[i], fulState); } if (!rc) { rc = DosClose(hf); AssertMsg(!rc, ("%ld\n", rc)); hf = ahfs[i]; } else i++; while (i-- > 0) DosClose(ahfs[i]); } } g_File = (RTFILE)hf; #elif defined(RT_OS_DARWIN) /* * Darwin is kind of special we need to engage the device via I/O first * before we open it via the BSD device node. */ mach_port_t MasterPort; kern_return_t kr = IOMasterPort(MACH_PORT_NULL, &MasterPort); if (kr != kIOReturnSuccess) return VERR_GENERAL_FAILURE; CFDictionaryRef ClassToMatch = IOServiceMatching("org_virtualbox_VBoxGuest"); if (!ClassToMatch) return VERR_GENERAL_FAILURE; io_service_t ServiceObject = IOServiceGetMatchingService(kIOMasterPortDefault, ClassToMatch); if (!ServiceObject) return VERR_NOT_FOUND; io_connect_t uConnection; kr = IOServiceOpen(ServiceObject, mach_task_self(), VBOXGUEST_DARWIN_IOSERVICE_COOKIE, &uConnection); IOObjectRelease(ServiceObject); if (kr != kIOReturnSuccess) return VERR_OPEN_FAILED; RTFILE hFile; int rc = RTFileOpen(&hFile, pszDeviceName, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE); if (RT_FAILURE(rc)) { IOServiceClose(uConnection); return rc; } g_File = hFile; g_uConnection = uConnection; #elif defined(VBOX_VBGLR3_XSERVER) int File = xf86open(pszDeviceName, XF86_O_RDWR); if (File == -1) return VERR_OPEN_FAILED; g_File = File; #else /* The default implementation. (linux, solaris, freebsd, haiku) */ RTFILE File; int rc = RTFileOpen(&File, pszDeviceName, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE); if (RT_FAILURE(rc)) return rc; g_File = File; #endif #ifndef VBOX_VBGLR3_XSERVER /* * Create release logger */ PRTLOGGER pReleaseLogger; static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES; int rc2 = RTLogCreate(&pReleaseLogger, 0, "all", "VBOX_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), &s_apszGroups[0], RTLOGDEST_USER, NULL); /* This may legitimately fail if we are using the mini-runtime. */ if (RT_SUCCESS(rc2)) RTLogRelSetDefaultInstance(pReleaseLogger); #endif return VINF_SUCCESS; }
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)); }
static int connect_pipe( FILE *fp, const CHAR_TYPE *command, int *handles, int readOrWrite, int textOrBinary ) /************************************************************************/ { #if defined( __NT__ ) BOOL rc; HANDLE osHandle; HANDLE oldHandle; #elif defined( __WARP__ ) APIRET rc; HFILE osHandle; HFILE oldHandle; #elif defined( __OS2__ ) USHORT rc; HFILE osHandle; HFILE oldHandle; #endif if( readOrWrite == 'w' ) { /*** Change the standard input handle for process inheritance ***/ #if defined( __NT__ ) osHandle = GetStdHandle( STD_INPUT_HANDLE ); /* get old */ if( osHandle == INVALID_HANDLE_VALUE ) { return( 0 ); } oldHandle = osHandle; rc = SetStdHandle( STD_INPUT_HANDLE, /* set new */ (HANDLE)_os_handle(handles[0]) ); if( rc == FALSE ) { SetStdHandle( STD_INPUT_HANDLE, oldHandle ); return( 0 ); } #elif defined( __OS2__ ) oldHandle = (HFILE)0xFFFFFFFF; /* duplicate standard input */ rc = DosDupHandle( STDIN_HANDLE, &oldHandle ); if( rc != NO_ERROR ) return( 0 ); osHandle = STDIN_HANDLE; /* use new standard input */ rc = DosDupHandle( (HFILE)_os_handle(handles[0]), &osHandle ); if( rc != NO_ERROR ) { DosClose( oldHandle ); return( 0 ); } #endif /*** Spawn the process and go home ***/ if( spawn_it( fp, command ) == 0 ) { return( 0 ); } #if defined( __NT__ ) SetStdHandle( STD_INPUT_HANDLE, oldHandle ); #elif defined( __OS2__ ) osHandle = STDIN_HANDLE; rc = DosDupHandle( oldHandle, &osHandle ); #endif close( handles[0] ); /* parent process should close this */ } else { /*** Change the standard output handle for process inheritance ***/ #if defined( __NT__ ) osHandle = GetStdHandle( STD_OUTPUT_HANDLE ); /* get old */ if( osHandle == INVALID_HANDLE_VALUE ) { return( 0 ); } oldHandle = osHandle; rc = SetStdHandle( STD_OUTPUT_HANDLE, /* set new */ (HANDLE)_os_handle(handles[1]) ); if( rc == FALSE ) { SetStdHandle( STD_OUTPUT_HANDLE, oldHandle ); return( 0 ); } #elif defined( __OS2__ ) oldHandle = (HFILE)0xFFFFFFFF; /* duplicate standard input */ rc = DosDupHandle( STDOUT_HANDLE, &oldHandle ); if( rc != NO_ERROR ) { return( 0 ); } osHandle = STDOUT_HANDLE; /* use new standard input */ rc = DosDupHandle( (HFILE)_os_handle(handles[1]), &osHandle ); if( rc != NO_ERROR ) { DosClose( oldHandle ); return( 0 ); } #endif /*** Spawn the process and go home ***/ if( spawn_it( fp, command ) == 0 ) { return( 0 ); } #if defined( __NT__ ) SetStdHandle( STD_OUTPUT_HANDLE, oldHandle ); #elif defined( __OS2__ ) osHandle = STDOUT_HANDLE; rc = DosDupHandle( oldHandle, &osHandle ); #endif close( handles[1] ); /* parent process should close this */ } return( 1 ); }
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); }
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( void ) { unsigned long action; char buffer[32]; struct messagequeue chtmsgq; struct clienthandlerthreadparameters chtp; unsigned long count; struct connectthreadparameters ctp; HFILE hfcon; HFILE hfstdout; struct message * msg; APIRET rc; int running; /* Reopen file 1 in case the user has redirected output. */ DosOpen( "CON", &hfcon, &action, 0, FILE_NORMAL, OPEN_ACTION_FAIL_IF_NEW|OPEN_ACTION_OPEN_IF_EXISTS, OPEN_FLAGS_FAIL_ON_ERROR|OPEN_FLAGS_SEQUENTIAL| OPEN_SHARE_DENYNONE|OPEN_ACCESS_WRITEONLY, NULL ); hfstdout = HFILE_STDOUT; DosDupHandle(hfcon,&hfstdout); /* Unbuffer stdout. */ setbuf(stdout,NULL); /* Header stuff. */ printf("tserver v%d.%03d Client/Server Demonstration Server\n", TSERVER_VERSION,TSERVER_PATCHLEVEL); /* Install break handlers to catch ^C and Ctrl-Break. */ signal(SIGINT,sigbreak); signal(SIGBREAK,sigbreak); /* Begin application initialization ... */ printf("Server is initializing - please wait ... "); /* Initialize mainmsgq. */ DosCreateMutexSem(NULL,&mainmsgq.access,0,FALSE); mainmsgq.q = NULL; mainmsgq.qtail = &mainmsgq.q; DosCreateEventSem(NULL,&mainmsgq.available,0,FALSE); /* Start the connect thread. */ DosCreateEventSem(NULL,&ctp.initialized,0,FALSE); ctp.maxpipes = ( unsigned char ) NP_UNLIMITED_INSTANCES; ctp.pipename = "\\pipe\\time"; DosCreateEventSem(NULL,&ctp.shutdown,0,FALSE); ctp.msgq = &mainmsgq; DosCreateEventSem(NULL,&ctp.terminated,0,FALSE); _beginthread( connectthread, NULL, 8192, ( void * ) &ctp ); DosWaitEventSem(ctp.initialized,SEM_INDEFINITE_WAIT); DosCloseEventSem(ctp.initialized); /* Start the client handler thread. */ DosCreateMutexSem(NULL,&chtmsgq.access,0,FALSE); chtmsgq.q = NULL; chtmsgq.qtail = &chtmsgq.q; DosCreateEventSem(NULL,&chtmsgq.available,0,FALSE); DosCreateEventSem(NULL,&chtp.initialized,0,FALSE); chtp.inmsgq = &chtmsgq; chtp.outmsgq = &mainmsgq; DosCreateEventSem(NULL,&chtp.terminated,0,FALSE); _beginthread( clienthandlerthread, NULL, 8192, ( void * ) &chtp ); DosWaitEventSem(chtp.initialized,SEM_INDEFINITE_WAIT); DosCloseEventSem(chtp.initialized); printf("completed\n\n"); /* Initialization completed. */ printf( "%s Server is running.\n", timestamp(buffer) ); running = !0; while ( running ) { printf( "\r%s ", timestamp(buffer) ); /* Wait one second for a message to hit the queue. If one ** ** arrives, handle it, otherwise just update the timer. */ rc = DosWaitEventSem(mainmsgq.available,1000); if ( rc != ERROR_TIMEOUT ) /* Loop until message queue is empty ( break below ). */ while ( !0 ) { DosRequestMutexSem(mainmsgq.access,SEM_INDEFINITE_WAIT); msg = mainmsgq.q; if ( msg != NULL ) { mainmsgq.q = msg->next; /* If last message dequeued, reset tail pointer. */ if ( mainmsgq.q == NULL ) mainmsgq.qtail = &mainmsgq.q; } DosResetEventSem(mainmsgq.available,&count); DosReleaseMutexSem(mainmsgq.access); /* Break out of inner loop if last message pulled. */ if ( msg == NULL ) break; /* Update the timer ... */ printf( "\r%s ", timestamp(buffer) ); switch ( msg->id ) { case closed: /* Client disconnected. */ printf("Closed pipe %lu.\n", msg->data.closeddata.hpipe); break; case connected: /* Client connected. Display message, then ** ** pass the pipe handle to the client handler. */ printf("Connected pipe %lu.\n", msg->data.connecteddata.hpipe); DosRequestMutexSem(chtmsgq.access, SEM_INDEFINITE_WAIT); *chtmsgq.qtail = malloc( sizeof( struct message ) ); (*chtmsgq.qtail)->id = connected; (*chtmsgq.qtail)->data.connecteddata.hpipe = msg->data.connecteddata.hpipe; (*chtmsgq.qtail)->next = NULL; DosPostEventSem(chtmsgq.available); DosReleaseMutexSem(chtmsgq.access); break; case ctclosed: /* Connect thread has shut down prematurely. ** ** This will occur if there is an error in ** ** that thread. */ printf( "Connect thread died - NO NEW CLIENTS MAY " "CONNECT.\n"); break; case cterror: /* Display error message from the connect ** ** thread. */ if ( msg->data.cterrordata.ec == pipedisconnected ) printf("Disconnected from pipe %lu.\n", msg->data.cterrordata.hpipe); else printf("Error %d in connect thread.\n", msg->data.cterrordata.ec); break; case executing: /* Log informative message. */ printf("Pipe %d executing: %s.\n", msg->data.executingdata.hpipe, msg->data.executingdata.cmd); break; case shutdownreq: printf("Shutting down.\n"); running = 0; break; case breakhit: printf("**** break ****\n"); running = 0; break; } free(msg); } } /* Begin termination ... */ printf("\nServer is shutting down - please wait ... "); /* Post shutdown message to client handler thread. */ DosRequestMutexSem(chtmsgq.access,SEM_INDEFINITE_WAIT); *chtmsgq.qtail = malloc( sizeof( struct message ) ); (*chtmsgq.qtail)->id = shutdownreq; (*chtmsgq.qtail)->next = NULL; DosPostEventSem(chtmsgq.available); DosReleaseMutexSem(chtmsgq.access); DosWaitEventSem(chtp.terminated,SEM_INDEFINITE_WAIT); DosCloseEventSem(chtp.terminated); /* Clear out any messages remaining in the queue. */ while ( chtmsgq.q != NULL ) { msg = chtmsgq.q; chtmsgq.q = msg->next; free(msg); } DosCloseEventSem(chtmsgq.available); DosCloseMutexSem(chtmsgq.access); /* Post shutdown semaphore in connect thread. */ DosPostEventSem(ctp.shutdown); DosWaitEventSem(ctp.terminated,SEM_INDEFINITE_WAIT); DosCloseEventSem(ctp.shutdown); DosCloseEventSem(ctp.terminated); /* All threads shut down. Clear out the main message queue. */ while ( mainmsgq.q != NULL ) { msg = mainmsgq.q; mainmsgq.q = msg->next; free(msg); } DosCloseEventSem(mainmsgq.available); DosCloseMutexSem(mainmsgq.access); printf("completed\n"); /* Outta here ... */ return 0; }
BreakPoint( OpenFile( name, mode, flags ) ); } static void doClose( HFILE hdl ) { BreakPoint( DosClose( hdl ) ); } void DoDupFile( HFILE old, HFILE new ) { HFILE new_t; USHORT rc; new_t = new; rc = DosDupHandle( old, &new_t ); if( rc != 0 ) { BreakPoint( NIL_DOS_HANDLE ); } else { BreakPoint( new_t ); } } static char stack[1024]; long TaskExecute( excfn rtn ) { long retval;