/* Run a child process, redirecting its standard file handles to a socket descriptor. Return the child's PID or -1 on error. */ int netrun(struct fdinfo *fdn, char *cmdexec) { struct subprocess_info *info; HANDLE thread; int pid; info = (struct subprocess_info *) safe_malloc(sizeof(*info)); info->fdn = *fdn; pid = start_subprocess(cmdexec, info); if (pid == -1) { free(info); close(info->fdn.fd); return -1; } /* Start up the thread to handle process I/O. */ thread = CreateThread(NULL, 0, subprocess_thread_func, info, 0, NULL); if (thread == NULL) { if (o.verbose) logdebug("Error in CreateThread: %d\n", GetLastError()); free(info); return -1; } CloseHandle(thread); return pid; }
/* Run the given command line as if by exec. Doesn't return. */ void netexec(struct fdinfo *fdn, char *cmdexec) { struct subprocess_info *info; int pid; DWORD ret; info = (struct subprocess_info *) safe_malloc(sizeof(*info)); info->fdn = *fdn; pid = start_subprocess(cmdexec, info); if (pid == -1) ExitProcess(2); /* Run the subprocess thread function, but don't put it in a thread. Just run it and exit with its return value because we're simulating exec. */ ExitProcess(subprocess_thread_func(info)); }
int main(int argc, char *argv[]) { OutputAdapter *oadp; int vpfd, apfd; pid_t child; Pipe<AudioPacket *> *apipe; int aplay_pipe; static struct option options[] = { { "aplay", 0, 0, 'a' }, { "card", 1, 0, 'c' }, { 0, 0, 0, 0 } }; int card = 0; int aplay = 0; int opt; /* argument processing */ while ((opt = getopt_long(argc, argv, "ac:", options, NULL)) != -1) { switch (opt) { case 'c': card = atoi(optarg); break; case 'a': aplay = 1; break; default: usage(argv[0]); exit(1); } } if (argc - optind != 1) { usage(argv[0]); exit(1); } child = start_subprocess(argv[optind], vpfd, apfd); if (child == -1) { return 1; } if (aplay) { oadp = create_decklink_output_adapter(card, 0, RawFrame::CbYCrY8422); apipe = new Pipe<AudioPacket *>(16); run_subshell("aplay -c 2 -r 48000 -f s16_le", aplay_pipe); } else { oadp = create_decklink_output_adapter_with_audio(card, 0, RawFrame::CbYCrY8422); apipe = oadp->audio_input_pipe( ); } /* start video and audio sender threads */ Thread *video_th = new SenderThread<RawFrame, RawFrame1080Allocator> (&(oadp->input_pipe( )), vpfd); if (aplay) { Thread *audio_th = new SenderThread<AudioPacket, NTSCSyncAudioAllocator> (apipe, apfd); Thread *audio_writer_thread = new WriterThread<AudioPacket>(apipe, aplay_pipe); while (waitpid(child, NULL, 0) == EINTR) { /* busy wait */ } delete audio_th; delete audio_writer_thread; } else { Thread *audio_th = new SenderThread<AudioPacket, NTSCSyncAudioAllocator> (apipe, apfd); /* wait on child process */ while (waitpid(child, NULL, 0) == EINTR) { /* busy wait */ } delete audio_th; } /* done! */ delete video_th; }