-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[libc] add ioctl macros #142080
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[libc] add ioctl macros #142080
Conversation
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
@llvm/pr-subscribers-libc Author: W. Turner Abney (cowtoolz) ChangesSuggested reading: This is a decent starting point I think. I have no idea how this project handles the issue of multiple architectures, but the dance here with cc @michaelrj-google Full diff: https://github.com/llvm/llvm-project/pull/142080.diff 1 Files Affected:
diff --git a/libc/include/llvm-libc-macros/linux/sys-ioctl-macros.h b/libc/include/llvm-libc-macros/linux/sys-ioctl-macros.h
index 5eb779aeeca56..20a980ff7da00 100644
--- a/libc/include/llvm-libc-macros/linux/sys-ioctl-macros.h
+++ b/libc/include/llvm-libc-macros/linux/sys-ioctl-macros.h
@@ -9,11 +9,155 @@
#ifndef LLVM_LIBC_MACROS_LINUX_SYS_IOCTL_MACROS_H
#define LLVM_LIBC_MACROS_LINUX_SYS_IOCTL_MACROS_H
-// TODO (michaelrj): Finish defining these macros.
-// Just defining this macro for the moment since it's all that we need right
-// now. The other macros are mostly just constants, but there's some complexity
-// around the definitions of macros like _IO, _IOR, _IOW, and _IOWR that I don't
-// think is worth digging into right now.
-#define TIOCGETD 0x5424
+// Macros that determine command construction
+
+#define _IOC_NRBITS 8
+#define _IOC_TYPEBITS 8
+
+#ifndef _IOC_SIZEBITS
+#define _IOC_SIZEBITS 14
+#endif
+
+#ifndef _IOC_DIRBITS
+#define _IOC_DIRBITS 2
+#endif
+
+#define _IOC_NRMASK ((1 << _IOC_NRBITS) - 1)
+#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS) - 1)
+#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS) - 1)
+#define _IOC_DIRMASK ((1 << _IOC_DIRBITS) - 1)
+
+#define _IOC_NRSHIFT 0
+#define _IOC_TYPESHIFT (_IOC_NRSHIFT + _IOC_NRBITS)
+#define _IOC_SIZESHIFT (_IOC_TYPESHIFT + _IOC_TYPEBITS)
+#define _IOC_DIRSHIFT (_IOC_SIZESHIFT + _IOC_SIZEBITS)
+
+#ifndef _IOC_NONE
+#define _IOC_NONE 0U
+#endif
+
+#ifndef _IOC_WRITE
+#define _IOC_WRITE 1U
+#endif
+
+#ifndef _IOC_READ
+#define _IOC_READ 2U
+#endif
+
+// Macros for constructing commands
+
+#define _IOC(dir, type, nr, size) \
+ (((dir) << _IOC_DIRSHIFT) | ((type) << _IOC_TYPESHIFT) | \
+ ((nr) << _IOC_NRSHIFT) | ((size) << _IOC_SIZESHIFT))
+
+#define _IO(type, nr) _IOC(_IOC_NONE, (type), (nr), 0)
+#define _IOR(type, nr, argtype) _IOC(_IOC_READ, (type), (nr), sizeof(argtype))
+#define _IOW(type, nr, argtype) _IOC(_IOC_WRITE, (type), (nr), sizeof(argtype))
+#define _IOWR(type, nr, argtype) \
+ _IOC(_IOC_READ | _IOC_WRITE, (type), (nr), sizeof(argtype))
+
+// Macros for deconstructing commands
+
+#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT)
+#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT)
+#define IOC_INOUT ((_IOC_WRITE | _IOC_READ) << _IOC_DIRSHIFT)
+#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_SHIFT (_IOC_SIZESHIFT)
+
+// Macros that define commands
+
+#define TIOCPKT_DATA 0
+#define TIOCSER_TEMT 1
+#define TIOCPKT_FLUSHREAD TIOCSER_TEMT
+#define TIOCPKT_FLUSHWRITE 2
+#define TIOCPKT_STOP 4
+#define TIOCPKT_START 8
+#define TIOCPKT_NOSTOP 16
+#define TIOCPKT_DOSTOP 32
+#define TIOCPKT_IOCTL 64
+
+#define TCGETS _IO('T', 1)
+#define TCSETS _IO('T', 2)
+#define TCSETSW _IO('T', 3)
+#define TCSETSF _IO('T', 4)
+#define TCGETA _IO('T', 5)
+#define TCSETA _IO('T', 6)
+#define TCSETAW _IO('T', 7)
+#define TCSETAF _IO('T', 8)
+#define TCSBRK _IO('T', 9)
+#define TCXONC _IO('T', 10)
+#define TCFLSH _IO('T', 11)
+#define TIOCEXCL _IO('T', 12)
+#define TIOCNXCL _IO('T', 13)
+#define TIOCSCTTY _IO('T', 14)
+#define TIOCGPGRP _IO('T', 15)
+#define TIOCSPGRP _IO('T', 16)
+#define TIOCOUTQ _IO('T', 17)
+#define TIOCSTI _IO('T', 18)
+#define TIOCGWINSZ _IO('T', 19)
+#define TIOCSWINSZ _IO('T', 20)
+#define TIOCMGET _IO('T', 21)
+#define TIOCMBIS _IO('T', 22)
+#define TIOCMBIC _IO('T', 23)
+#define TIOCMSET _IO('T', 24)
+#define TIOCGSOFTCAR _IO('T', 25)
+#define TIOCSSOFTCAR _IO('T', 26)
+#define FIONREAD _IO('T', 27)
+#define TIOCINQ FIONREAD
+#define TIOCLINUX _IO('T', 28)
+#define TIOCCONS _IO('T', 29)
+#define TIOCGSERIAL _IO('T', 30)
+#define TIOCSSERIAL _IO('T', 31)
+#define TIOCPKT _IO('T', 32)
+#define FIONBIO _IO('T', 33)
+#define TIOCNOTTY _IO('T', 34)
+#define TIOCSETD _IO('T', 35)
+#define TIOCGETD _IO('T', 36)
+#define TCSBRKP _IO('T', 37)
+
+#define TIOCSBRK _IO('T', 39)
+#define TIOCCBRK _IO('T', 40)
+#define TIOCGSID _IO('T', 41)
+
+#define TIOCGRS485 _IO('T', 46)
+#define TIOCSRS485 _IO('T', 47)
+
+#define TIOCGPTN _IOR('T', 48, unsigned int)
+#define TIOCSPTLCK _IOW('T', 49, int)
+#define TIOCGDEV _IOR('T', 50, unsigned int)
+#define TCGETX TIOCGDEV
+
+#define TCSETX _IO('T', 51)
+#define TCSETXF _IO('T', 52)
+#define TCSETXW _IO('T', 53)
+#define TIOCSIG _IOW('T', 54, int)
+#define TIOCVHANGUP _IO('T', 55)
+#define TIOCGPKT _IOR('T', 56, int)
+#define TIOCGPTLCK _IOR('T', 57, int)
+
+#define TIOCGEXCL _IOR('T', 64, int)
+#define TIOCGPTPEER _IO('T', 65)
+
+#define FIONCLEX _IO('T', 80)
+#define FIOCLEX _IO('T', 81)
+#define FIOASYNC _IO('T', 82)
+#define TIOCSERCONFIG _IO('T', 83)
+#define TIOCSERGWILD _IO('T', 84)
+#define TIOCSERSWILD _IO('T', 85)
+#define TIOCGLCKTRMIOS _IO('T', 86)
+#define TIOCSLCKTRMIOS _IO('T', 87)
+#define TIOCSERGSTRUCT _IO('T', 88)
+#define TIOCSERGETLSR _IO('T', 89)
+#define TIOCSERGETMULTI _IO('T', 90)
+#define TIOCSERSETMULTI _IO('T', 91)
+#define TIOCMIWAIT IO('T', 92)
+#define TIOCGICOUNT _IO('T', 93)
+
+#define FIOQSIZE _IO('T', 96)
#endif // LLVM_LIBC_MACROS_LINUX_SYS_IOCTL_MACROS_H
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if _IO
is the most suitable prefix for public header. Otherwise, the patch looks good to me.
If the UAPI headers expose these macros it's probably best to just include those if possible. There are also license issues if we directly copy from the linux headers, so we can't do that. |
Suggested reading:
https://github.com/torvalds/linux/blob/master/include/uapi/asm-generic/ioctl.h (
_IO
macros)https://github.com/torvalds/linux/blob/master/include/uapi/asm-generic/ioctls.h (the actual IOCTLs)
This is a decent starting point I think. I have no idea how this project handles the issue of multiple architectures, but the ifndef dance here with
_IOC_NRBITS
,_IOC_TYPEBITS
,_IOC_SIZEBITS
, and_IOC_DIRBITS
allows for flexibility on different architectures, where they can be redefined. As far as I can tell from my research, though, the only architecture on which any ioctls have been changed is SuperH. The uapi even defines the generic ones without the _IO form because it's basically expected that some software hardcodes the numbers regardless of platform. If we're willing to lose that flexibility (as I assume other libcs do), there isn't as much nuance here as there would seem to be and these definitions can be simplified greatly. I do, however, think that we should use the _IO form (as I have submitted them here) both for transparency (i.e. demonstrates how the actual numbers are implemented as opposed to providing the numbers without explanation) and to make practical use of the _IO constructors within the libc itself. I don't think it would hurt to add the numbers they resolve to as comments, though.cc @michaelrj-google
#141393 #85275