|
|
1.1 ! root 1: /* ! 2: * DOSMAKEPIPE example (pp.c, needs related program pc.c). ! 3: * ! 4: * Pipes are a byte stream oriented IPC mechanism which uses ! 5: * standard DOSREAD and DOSWRITE file system calls. Since file ! 6: * handles are used to access the pipe, each process using the ! 7: * pipe needs to know the handles. There are two general ways ! 8: * this is done: ! 9: * ! 10: * 1. Have very closely cooperating processes which notify ! 11: * each other of the file handles via some private method ! 12: * such as shared memory or command line arguments. ! 13: * ! 14: * 2. With unrelated processes, a process which reads and writes ! 15: * from STDIN (handle 0) and STDOUT (handle 1) can be attached ! 16: * to a pipe without being aware of it. ! 17: * ! 18: * This example demonstrates case #2 since that is the harder of the ! 19: * two to set up. This process, pp.exe, creates a pipe and exec's a ! 20: * child process pc.exe whose stdin is attached to the pipe. The parent ! 21: * process writes a lower case message repeatedly into the pipe, and ! 22: * the child process translates it into upper case and prints it on ! 23: * the screen. ! 24: * ! 25: * Compile as: cl -AL -G2 -Lp pp.c (parent process) ! 26: * cl -AL -G2 -Lp pc.c (child process) ! 27: * ! 28: * Copyright (C) Microsoft Corp. 1986 ! 29: */ ! 30: #include <stdio.h> ! 31: #include <doscalls.h> ! 32: ! 33: #define PSIZE 256 /* pipe buffer size */ ! 34: ! 35: char msg[] = "hello there!\n"; /* message to write down pipe */ ! 36: char exec_buf[100]; /* buffer for DosExecPgm ObjName */ ! 37: char *pgmname = "pc.exe"; /* name of child program */ ! 38: ! 39: main() ! 40: { ! 41: unsigned pread; /* pipe read handle */ ! 42: unsigned pwrite; /* pipe write handle */ ! 43: unsigned newstdin, newstdout; /* stdin as a pipe handle */ ! 44: unsigned FileHandlState; /* Used to modify handle inheritance */ ! 45: int i; ! 46: int bytecount; /* bytes written result */ ! 47: struct ResultCodes rc2; /* double return codes for EXEC */ ! 48: ! 49: DOSMAKEPIPE(&pread, &pwrite, PSIZE); /* create the pipe */ ! 50: ! 51: /* ! 52: * Now close our stdin which is attached to the console, ! 53: * and make it refer to the pipe instead. ! 54: */ ! 55: DOSCLOSE(0); /* close stdin */ ! 56: newstdin = 0; ! 57: DOSDUPHANDLE(pread, &newstdin); /* make pipe = stdin */ ! 58: /* ! 59: * Since the child process will normaly inherit the handles of ! 60: * the parent we need to close the input of the pipe. If we ! 61: * don't then the child will hang on the output of the pipe. (since ! 62: * it still has an open handle to the input). ! 63: * ! 64: * We don't really close the input, simply make it non-inheritable ! 65: * to the child. Thus the only input to the pipe is from the parent. ! 66: * When the parent closes the pipe, any outstanding READs from the ! 67: * child will return a length of 0 (EOF). ! 68: */ ! 69: i = DOSQFHANDSTATE(pwrite, (unsigned far *)&FileHandlState); ! 70: if (i) printf("Query of pwrite failed\n"); ! 71: FileHandlState &= 0x7F88; /* Mask bits offensive to the call */ ! 72: FileHandlState |= 0x080; /* Deny inheritance to child */ ! 73: i = DOSSETFHANDSTATE(pwrite, FileHandlState); ! 74: if (i) printf("Set of pwrite failed, i = %x\n",i); ! 75: #ifdef NOCODE ! 76: i = DOSQFHANDSTATE(pread, (unsigned far *)&FileHandlState); ! 77: if (i) printf("Query of pread failed\n"); ! 78: FileHandlState &= 0x7F88; /* Mask bits offensive to the call */ ! 79: FileHandlState |= 0x080; /* Deny inheritance to child */ ! 80: i = DOSSETFHANDSTATE(pread, FileHandlState); ! 81: if (i) printf("Set of pread failed, i = %x\n",i); ! 82: #endif ! 83: /* exec child program, which will inherit new stdin */ ! 84: DOSEXECPGM(exec_buf, sizeof(exec_buf), 1, (unsigned *)0L, ! 85: (unsigned *)0L, &rc2, pgmname); ! 86: ! 87: /* write 20 messages down the pipe */ ! 88: printf("Writing messages to the pipe\n"); ! 89: for(i = 0; i < 20; i++) ! 90: DOSWRITE(pwrite, msg, sizeof(msg) - 1, &bytecount); ! 91: ! 92: DOSCLOSE(pwrite); ! 93: DOSCLOSE(pread); ! 94: printf("Parent exiting\n"); ! 95: DOSEXIT(1,0); /* Terminate and kill any lingering children */ ! 96: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.