|
|
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.