home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / std_unix / mod.std.unix.v8 / text0008.txt < prev    next >
Encoding:
Internet Message Format  |  1987-06-30  |  3.0 KB

  1. From: cbosgd!cbosgd.ATT.COM!mark@ucbvax.berkeley.edu (Mark Horton)
  2. Date: 28 Oct 86 03:12:38 GMT
  3. Organization: AT&T Bell Laboratories, Columbus, Oh
  4.  
  5. The iocntl proposal, as stated in section C.3 of the POSIX book,
  6. has a bug.  For those who don't have the book handy, it defines
  7.     iocntl(fildes, command, mask, argp, argpsize)
  8. where command specifies the unique name of the control; mask is
  9. either IO_READ, IO_WRITE, or IO_READ|IO_WRITE; argp is a pointer
  10. to the argument, and argpsize is the number of bytes in the argument.
  11.  
  12. It proposes implementation of upward compatibility
  13. with ioctl with a define such as
  14.     #define ioctl(a, b, c) iocntl(a, b, c, sizeof(c))
  15. and using a two ident define for b, thus
  16.     #define IO_READ        1
  17.     #define IO_WRITE    2
  18.     #define TERM_MASK    ('T'<<8)
  19.     #define SOME_MASK    (IO_READ|IO_WRITE),(TERM_MASK | 0)
  20.     ...
  21.     struct foo *ptr = ...
  22.     ioctl(0, SOME_MASK,ptr);
  23.  
  24. The bug here is that the sizeof is taken on the pointer, not the
  25. item itself, so it will always be 4 on a typical 32 bit machine.
  26.  
  27. One obvious fix might change the spec to read
  28.     #define ioctl(a, b, c) iocntl(a, b, c, sizeof(*c))
  29. This might work for many cases.  But there are two cases for
  30. which it fails:
  31.  
  32. (1) ioctls where the object pointed to is an array.  In particular
  33.     if the argument is a character string, as in SVr3's I_PUSH ioctl
  34.     to push a streams module, this won't work.
  35. (2) ioctls where the argument value itself, rather than what's at
  36.     the end of a pointer, is passed.  System V does this a lot;
  37.     see, for example, TCSBRK, TCXONC, and TCFLSH.
  38.  
  39. One possible solution to this problem would be to rearrange the
  40. order of the arguments to iocntl.  If it becomes
  41.  
  42.     iocntl(fildes, command, mask, argpsize, argp)
  43.  
  44. then a trick similar to the one used in 4.2BSD becomes possible:
  45.  
  46.     #define ioctl iocntl
  47.     #define IO_READ        1
  48.     #define IO_WRITE    2
  49.     #define TERM_MASK ('T'<<8)
  50.     #define SOME_MASK (IO_READ|IO_WRITE),(TERM_MASK | 0),sizeof (struct foo)
  51.     ...
  52.     struct foo *ptr = ...
  53.     ioctl(0, SOME_MASK, ptr);
  54.  
  55. Another possibility is similar, but closer to what 4.2 does.  We
  56. define iocntl as a function that takes three parameters, just like
  57. ioctl, but the second parameter is a long, and we get
  58.  
  59.     iocntl(fildes, (long) command, argp)
  60.  
  61.     #define ioctl iocntl
  62.     #define IO_READ        (1<<14)
  63.     #define IO_WRITE    (2<<14)
  64.     #define TERM_MASK ('T'<<24)
  65.     #define SOME_MASK (long) (IO_READ|IO_WRITE)|(TERM_MASK | 0)|sizeof (struct foo)
  66.     ...
  67.     struct foo *ptr = ...
  68.     ioctl(0, SOME_MASK, ptr);
  69.  
  70. As I understand it, the only reason for playing these games, instead of
  71. just doing what 4.2 did and leaving it called ioctl, is that ioctl is
  72. defined to take an int as the 2nd parameter, and this method has to pass
  73. a long.  It works on a 32 bit machine, but not on a 16 bit CPU such as
  74. an 80286 (unless you implement "int" as 32 bits.)  Am I missing something?
  75.  
  76. These comments apply to termcntl as well as iocntl.
  77.  
  78. By the way, if this proposal is going to be used, please let's change
  79. the name from iocntl to something that doesn't *sound* the same as
  80. ioctl.  Otherwise there will be lots of confusion.
  81.  
  82.     Mark
  83.  
  84. Volume-Number: Volume 8, Number 9
  85.  
  86.