home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #19 / NN_1992_19.iso / spool / comp / os / os2 / programm / 4741 < prev    next >
Encoding:
Internet Message Format  |  1992-09-04  |  4.9 KB

  1. Path: sparky!uunet!ogicse!reed!news
  2. From: celarier@reed.edu (Stuart Celarier)
  3. Newsgroups: comp.os.os2.programmer
  4. Subject: DosSetFHState() and Pipes -- problem
  5. Keywords: OS/2 2.0, API, DosSetFHState, anonymous pipes
  6. Message-ID: <1992Sep4.170103.24099@reed.edu>
  7. Date: 4 Sep 92 17:01:03 GMT
  8. Article-I.D.: reed.1992Sep4.170103.24099
  9. Sender: news@reed.edu (USENET News System)
  10. Organization: Reed College, Portland, OR
  11. Lines: 100
  12.  
  13. I have come across a problem using the DosSetFHState() API call in OS/2 2.0,  
  14. which has to do with creating an anonymous pipe "cleanly".  I begin with some  
  15. backgound on the problem, since there may be a better method for accomplishing  
  16. the task which avoids this problem (wishful thinking).
  17.  
  18. Background.
  19. -----------
  20. In UNIX the fork() and exec() system calls are separate so that one can create  
  21. a pipe using the pipe() call; perform the fork; and then close the parent's  
  22. pipe handles in the child process before performing the exec().  This way the  
  23. child does not inherit the extraneous pipe handles, which [1] would take up  
  24. entries the child's file control structures, and [2] the child should never use  
  25. in the first place.  This mechanism also makes it quite easy to establish the  
  26. child's pipe handles as standard input and standard output so that the child  
  27. knows where to find the pipe, or even better, is blissfully unaware of the  
  28. existence of the pipe -- it is just doing standard I/O.
  29.  
  30. Creating a Pipe "Cleanly" Under OS/2 2.0
  31. ----------------------------------------
  32. Under OS/2 the DosExecPgm() performs the function equivalent to the combination  
  33. of UNIX's fork() and exec() functions, so providing a bidirectional pipe  
  34. between parent and child is more complicated if one wants to do it cleanly.   
  35. This is what I worked out, based on several sources.
  36.  
  37.     // create pipe0 -- child read, parent write
  38.     DosCreatePipe();    // child read, parent write
  39.     DosDupHandle();        // copy parent's stdin to tmpin
  40.     DosDupHandle();        // copy child read to stdin
  41.  
  42.     DosQueryFHState();    // get parent write handle state
  43.     DosSetFHState();    // set parent write handle "no inherit"
  44.     
  45.     DosQueryFHState();    // get tmpin handle state
  46.     DosSetFHState();    // set tmpin handle "no inherit"
  47.  
  48.     // create pipe1 -- parent read, child write
  49.     ...            // as above
  50.  
  51.     // execute child
  52.     //    child should only be inheriting stdin, stdout and stderr
  53.     DosExecPgm();
  54.  
  55.     // clean up from pipe0
  56.     DosDupHandle();        // copy tmpin back to stdin, closes child read
  57.     DosQueryFHState();    // get stdin handle state
  58.     DosSetFHState();    // set stdin handle "inherit"
  59.  
  60.     // clean up from pipe1
  61.     ...            // as above
  62.  
  63. That seems like an awful lot of work (comments anyone?), especially compared to  
  64. the similar activity under UNIX.  However, it is necessary because I ultimately  
  65. will be having this parent creating a large number of children, and if each  
  66. child were to inherit its pipe handles, along with all of the handles of all  
  67. the previously created children's pipes and all of the parent's handles for  
  68. those pipes, well that's far too much overhead inheriting and keeping handles  
  69. which _should_never_be_used_ in those children.  (Yes, I do know that I will  
  70. ultimately have to increase the number of handles available in the parent  
  71. process, the default of twenty will run out pretty quickly.)
  72.  
  73. Are there better, more efficient ways for creating the pipe cleanly?  Are there  
  74. any reasons why this strategy should not work?  I've hit the books and on line  
  75. references (hard), but none of them even mention not having the child inherit  
  76. the parent's handles to the pipe.
  77.  
  78. DosSetFHState() Problem.
  79. ------------------------
  80. This code fragement (with appropriate parameters and error checking) compiled  
  81. just fine, but on execution every one of the DosSetFHState() calls returns an  
  82. error code 87 -- bad parameter.  The actual code looks like this:
  83.  
  84.     ...
  85.     if ((rc = DosQueryFHState (hfParentWrite, &ulState) != 0)
  86.         fatalApiError ("DosQueryFHState()", rc) ;
  87.     if ((rc = DosSetFHState (hfParentWrite,
  88.             ulState | OPEN_FLAGS_NOINHERIT) != 0)
  89.         fatalApiError ("DosSetFHState()", rc) ;
  90.     ...
  91.  
  92. Even if I don't mask on the no-inherit flag, I still get a return code = 87.   
  93. In this case I am just trying to set the state to what the query reported it to  
  94. be!  (The actual state reported is 0x0011, which indicates that it _will_ be  
  95. inherited.)
  96.  
  97. I have no way of telling _which_ of the two parameters DosSetFHState() thinks  
  98. is bad, but I definitely am using the exact same handle in both cases, so I  
  99. can't see why that should be the problem.  I know I need to only mask on the  
  100. one flag in the state that I am interested in, and so I need to perform the  
  101. query first, and then the set.  What is wrong with this picture?  Am I not  
  102. using the call correctly, or is there a bug in the call?
  103.     
  104. Any answers, or suggestions on how to get to the root of the problem (I've  
  105. tried, Lord knows I've tried...) would be greatly appreciated.
  106.  
  107. Thanks in advance,
  108. Stuart Celarier
  109. --
  110. Stuart Celarier
  111. celarier@reed.edu    PO Box 82842
  112. 503/236-9386        Portland, Oregon 97282
  113.