mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-02 17:28:30 +00:00
Make improvements
- This commit mints a new release of APE Loader v1.2 which supports loading ELF programs with a non-contiguous virtual address layout even though we've never been able to take advantage of it, due to how `objcopy -SO binary` fills any holes left by PT_LOAD. This'll change soon, since we'll have a new way of creating APE binaries. - The undiamonding trick with our ioctl() implementation is removed since POSIX has been killing ioctl() for years and they've done a much better job. One problem it resolves, is that ioctl(FIONREAD) wasn't working earlier and that caused issues when building Emacs
This commit is contained in:
parent
a1b1fdd1a4
commit
1ee2e89326
53 changed files with 1155 additions and 1255 deletions
|
@ -114,6 +114,7 @@ int getpriority(int, unsigned);
|
|||
int getresgid(unsigned *, unsigned *, unsigned *);
|
||||
int getresuid(unsigned *, unsigned *, unsigned *);
|
||||
int getsid(int) nosideeffect libcesque;
|
||||
int ioctl(int, unsigned long, ...);
|
||||
int ioprio_get(int, int);
|
||||
int ioprio_set(int, int, int);
|
||||
int issetugid(void);
|
||||
|
|
|
@ -136,8 +136,6 @@ o/$(MODE)/libc/calls/mkntenvblock.o: private \
|
|||
|
||||
# we must segregate codegen because:
|
||||
# file contains multiple independently linkable apis
|
||||
o/$(MODE)/libc/calls/ioctl-siocgifconf.o \
|
||||
o/$(MODE)/libc/calls/ioctl-siocgifconf-nt.o: private \
|
||||
COPTS += \
|
||||
-ffunction-sections \
|
||||
-fdata-sections
|
||||
|
@ -146,14 +144,7 @@ o/$(MODE)/libc/calls/ioctl-siocgifconf-nt.o: private \
|
|||
# va_arg codegen is very bloated in default mode
|
||||
o//libc/calls/open.o \
|
||||
o//libc/calls/openat.o \
|
||||
o//libc/calls/prctl.o \
|
||||
o//libc/calls/ioctl.o \
|
||||
o//libc/calls/ioctl_default.o \
|
||||
o//libc/calls/ioctl_fioclex-nt.o \
|
||||
o//libc/calls/ioctl_fioclex.o \
|
||||
o//libc/calls/ioctl_siocgifconf-nt.o \
|
||||
o//libc/calls/ioctl_siocgifconf.o \
|
||||
o//libc/calls/fcntl.o: private \
|
||||
o//libc/calls/prctl.o: \
|
||||
CFLAGS += \
|
||||
-Os
|
||||
|
||||
|
|
|
@ -16,27 +16,686 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#ifdef __STRICT_ANSI__
|
||||
#undef __STRICT_ANSI__
|
||||
#endif
|
||||
#include "libc/calls/ioctl.h"
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/calls/termios.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/intrin/cmpxchg.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/alloca.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/nt/iphlpapi.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/ipadapteraddresses.h"
|
||||
#include "libc/nt/winsock.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sock/struct/ifconf.h"
|
||||
#include "libc/sock/struct/ifreq.h"
|
||||
#include "libc/sock/struct/sockaddr.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
#include "libc/sysv/consts/fio.h"
|
||||
#include "libc/sysv/consts/iff.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/sio.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
#define EQUAL(X, Y) ((X) == (Y))
|
||||
/* Maximum number of unicast addresses handled for each interface */
|
||||
#define MAX_UNICAST_ADDR 32
|
||||
#define MAX_NAME_CLASH ((int)('z' - 'a')) /* Allow a..z */
|
||||
|
||||
static struct HostAdapterInfoNode {
|
||||
struct HostAdapterInfoNode *next;
|
||||
char name[IFNAMSIZ]; /* Obtained from FriendlyName */
|
||||
struct sockaddr unicast;
|
||||
struct sockaddr netmask;
|
||||
struct sockaddr broadcast;
|
||||
short flags;
|
||||
} * __hostInfo;
|
||||
|
||||
static int ioctl_default(int fd, unsigned long request, ...) {
|
||||
int rc;
|
||||
void *arg;
|
||||
va_list va;
|
||||
int64_t handle;
|
||||
va_start(va, request);
|
||||
arg = va_arg(va, void *);
|
||||
va_end(va);
|
||||
if (!IsWindows()) {
|
||||
return sys_ioctl(fd, request, arg);
|
||||
} else if (__isfdopen(fd)) {
|
||||
if (g_fds.p[fd].kind == kFdSocket) {
|
||||
handle = __getfdhandleactual(fd);
|
||||
if ((rc = _weaken(__sys_ioctlsocket_nt)(handle, request, arg)) != -1) {
|
||||
return rc;
|
||||
} else {
|
||||
return _weaken(__winsockerr)();
|
||||
}
|
||||
} else {
|
||||
return eopnotsupp();
|
||||
}
|
||||
} else {
|
||||
return ebadf();
|
||||
}
|
||||
}
|
||||
|
||||
/* Frees all the nodes of the _hostInfo */
|
||||
static textwindows void freeHostInfo(void) {
|
||||
struct HostAdapterInfoNode *next, *node = __hostInfo;
|
||||
if (_weaken(free)) {
|
||||
while (node) {
|
||||
next = node->next;
|
||||
_weaken(free)(node);
|
||||
node = next;
|
||||
}
|
||||
}
|
||||
__hostInfo = NULL;
|
||||
}
|
||||
|
||||
/* Given a short adapter name, look into __hostInfo to see if there is
|
||||
* an adapter with the same name. Returns the pointer to the HostAdapterInfoNode
|
||||
* if found, or NULL if not found
|
||||
*/
|
||||
static textwindows struct HostAdapterInfoNode *findAdapterByName(
|
||||
const char *name) {
|
||||
struct HostAdapterInfoNode *node = __hostInfo;
|
||||
while (node) {
|
||||
if (!strncmp(name, node->name, IFNAMSIZ)) {
|
||||
return node;
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Creates a new HostAdapterInfoNode object, initializes it from
|
||||
* the given adapter, unicast address and address prefixes
|
||||
* and insert it in the __hostInfo.
|
||||
* Increments the pointers to the unicast addresses and
|
||||
* the address prefixes
|
||||
* Returns NULL if an error occurred or the newly created
|
||||
* HostAdapterInfoNode object (last in the list)
|
||||
*/
|
||||
static textwindows struct HostAdapterInfoNode *appendHostInfo(
|
||||
struct HostAdapterInfoNode *parentInfoNode,
|
||||
const char *baseName, /* Max length = IFNAMSIZ-1 */
|
||||
const struct NtIpAdapterAddresses
|
||||
*aa, /* Top level adapter object being processed */
|
||||
struct NtIpAdapterUnicastAddress *
|
||||
*ptrUA, /* Ptr to ptr to unicast address list node */
|
||||
struct NtIpAdapterPrefix *
|
||||
*ptrAP, /* Ptr to ptr to Adapter prefix list node */
|
||||
int count) { /* count is used to create a unique name in case of alias */
|
||||
|
||||
struct HostAdapterInfoNode *temp;
|
||||
struct HostAdapterInfoNode *node;
|
||||
uint32_t ip, netmask, broadcast;
|
||||
struct sockaddr_in *a;
|
||||
int attemptNum;
|
||||
|
||||
if (!_weaken(calloc) || !(node = _weaken(calloc)(1, sizeof(*node)))) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(node->name, baseName, IFNAMSIZ);
|
||||
|
||||
/* Are there more than a single unicast address ? */
|
||||
if (count > 0 || ((*ptrUA)->Next != NULL)) {
|
||||
/* Yes, compose it using <baseName>:<count> */
|
||||
size_t nameLen = strlen(node->name);
|
||||
if (nameLen + 2 > IFNAMSIZ - 2) {
|
||||
/* Appending the ":x" will exceed the size, need to chop the end */
|
||||
nameLen -= 2;
|
||||
}
|
||||
node->name[nameLen - 2] = ':';
|
||||
node->name[nameLen - 1] = '0' + count;
|
||||
node->name[nameLen] = '\0';
|
||||
}
|
||||
|
||||
/* Is there a name clash with other interfaces? */
|
||||
for (attemptNum = 0; attemptNum < MAX_NAME_CLASH; ++attemptNum) {
|
||||
temp = findAdapterByName(node->name);
|
||||
if (!temp) {
|
||||
break;
|
||||
} else {
|
||||
/* Yes, this name has been already used, append an extra
|
||||
* character to resolve conflict. Note since the max length
|
||||
* of the string now is IFNAMSIZ-2, we have just enough space for this.
|
||||
* E.g. 'Ethernet_1' -> 'Ethernet_1a'
|
||||
*/
|
||||
size_t pos = strlen(node->name);
|
||||
node->name[pos] = 'a' + attemptNum;
|
||||
node->name[pos + 1] = '\0';
|
||||
/* Try again */
|
||||
}
|
||||
}
|
||||
|
||||
if (attemptNum == MAX_NAME_CLASH) {
|
||||
/* Cannot resolve the conflict */
|
||||
if (_weaken(free)) {
|
||||
_weaken(free)(node);
|
||||
}
|
||||
errno = EEXIST;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Finally we got a unique short and friendly name */
|
||||
node->unicast = *((*ptrUA)->Address.lpSockaddr);
|
||||
if (*ptrUA == aa->FirstUnicastAddress) {
|
||||
short flags;
|
||||
/* This is the first unicast address of this interface
|
||||
* calculate the flags for this adapter. Flags to consider:
|
||||
* IFF_UP
|
||||
* IFF_BROADCAST ** TODO: We need to validate
|
||||
* IFF_LOOPBACK
|
||||
* IFF_POINTOPOINT
|
||||
* IFF_MULTICAST
|
||||
* IFF_RUNNING ** Same as IFF_UP for now
|
||||
* IFF_PROMISC ** NOT SUPPORTED, unknown how to retrieve it
|
||||
*/
|
||||
flags = 0;
|
||||
if (aa->OperStatus == kNtIfOperStatusUp) flags |= IFF_UP | IFF_RUNNING;
|
||||
if (aa->IfType == kNtIfTypePpp) flags |= IFF_POINTOPOINT;
|
||||
if (!(aa->Flags & kNtIpAdapterNoMulticast)) flags |= IFF_MULTICAST;
|
||||
if (aa->IfType == kNtIfTypeSoftwareLoopback) flags |= IFF_LOOPBACK;
|
||||
if (aa->FirstPrefix) flags |= IFF_BROADCAST;
|
||||
node->flags = flags;
|
||||
} else {
|
||||
/* Copy from previous node */
|
||||
node->flags = parentInfoNode->flags;
|
||||
}
|
||||
|
||||
ip = ntohl(
|
||||
((struct sockaddr_in *)(*ptrUA)->Address.lpSockaddr)->sin_addr.s_addr);
|
||||
netmask = (uint32_t)-1 << (32 - (*ptrUA)->OnLinkPrefixLength);
|
||||
broadcast = (ip & netmask) | (~netmask & -1);
|
||||
|
||||
a = (struct sockaddr_in *)&node->netmask;
|
||||
a->sin_family = AF_INET;
|
||||
a->sin_addr.s_addr = htonl(netmask);
|
||||
|
||||
a = (struct sockaddr_in *)&node->broadcast;
|
||||
a->sin_family = AF_INET;
|
||||
a->sin_addr.s_addr = htonl(broadcast);
|
||||
|
||||
/* Process the prefix and extract the netmask and broadcast */
|
||||
/* According to the doc:
|
||||
*
|
||||
* On Windows Vista and later, the linked IP_ADAPTER_PREFIX
|
||||
* structures pointed to by the FirstPrefix member include three
|
||||
* IP adapter prefixes for each IP address assigned to the
|
||||
* adapter. These include the host IP address prefix, the subnet
|
||||
* IP address prefix, and the subnet broadcast IP address prefix.
|
||||
* In addition, for each adapter there is a multicast address
|
||||
* prefix and a broadcast address prefix.
|
||||
* -Source: MSDN on IP_ADAPTER_ADDRESSES_LH
|
||||
*
|
||||
* For example, interface "Ethernet", with 2 unicast addresses:
|
||||
*
|
||||
* - 192.168.1.84
|
||||
* - 192.168.5.99
|
||||
*
|
||||
* The Prefix list has 8 elements:
|
||||
*
|
||||
* #1: 192.168.1.0/24 <- Network, use the PrefixLength for netmask
|
||||
* #2: 192.168.1.84/32 <- Host IP
|
||||
* #3: 192.168.1.255/32 <- Subnet broadcast
|
||||
*
|
||||
* #4: 192.168.5.0/24 <- Network
|
||||
* #5: 192.168.5.99/32 <- Host IP
|
||||
* #6: 192.168.5.255/32 <- Subnet broadcast
|
||||
*
|
||||
* #7: 224.0.0.0/4 <- Multicast
|
||||
* #8: 255.255.255.255/32 <- Broadcast
|
||||
*/
|
||||
|
||||
if (ptrAP && *ptrAP) {
|
||||
*ptrAP = (*ptrAP)->Next; /* skip net ip */
|
||||
if (*ptrAP) {
|
||||
*ptrAP = (*ptrAP)->Next; /* skip host ip */
|
||||
if (*ptrAP) {
|
||||
node->broadcast = *((*ptrAP)->Address.lpSockaddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*ptrUA = (*ptrUA)->Next;
|
||||
|
||||
/* Append this node to the last node (if any) */
|
||||
if (parentInfoNode) {
|
||||
parentInfoNode->next = node;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
return node;
|
||||
}
|
||||
|
||||
/* Returns -1 in case of failure */
|
||||
static textwindows int createHostInfo(
|
||||
struct NtIpAdapterAddresses *firstAdapter) {
|
||||
static bool once;
|
||||
struct NtIpAdapterAddresses *aa;
|
||||
struct NtIpAdapterUnicastAddress *ua;
|
||||
struct NtIpAdapterPrefix *ap;
|
||||
struct HostAdapterInfoNode *node = NULL;
|
||||
char baseName[IFNAMSIZ];
|
||||
char name[IFNAMSIZ];
|
||||
int count, i;
|
||||
/* __hostInfo must be empty */
|
||||
_unassert(__hostInfo == NULL);
|
||||
for (aa = firstAdapter; aa; aa = aa->Next) {
|
||||
/* Skip all the interfaces with no address and the ones that are not AF_INET
|
||||
*/
|
||||
if (!aa->FirstUnicastAddress ||
|
||||
aa->FirstUnicastAddress->Address.lpSockaddr->sa_family != AF_INET) {
|
||||
continue;
|
||||
}
|
||||
/* Use max IFNAMSIZ-1 chars, leave the last char for eventual conflicts */
|
||||
tprecode16to8(baseName, IFNAMSIZ - 1, aa->FriendlyName);
|
||||
baseName[IFNAMSIZ - 2] = '\0';
|
||||
/* Replace any space with a '_' */
|
||||
for (i = 0; i < IFNAMSIZ - 2; ++i) {
|
||||
if (baseName[i] == ' ') baseName[i] = '_';
|
||||
if (!baseName[i]) break;
|
||||
}
|
||||
for (count = 0, ua = aa->FirstUnicastAddress, ap = aa->FirstPrefix;
|
||||
(ua != NULL) && (count < MAX_UNICAST_ADDR); ++count) {
|
||||
node = appendHostInfo(node, baseName, aa, &ua, &ap, count);
|
||||
if (!node) goto err;
|
||||
if (!__hostInfo) {
|
||||
__hostInfo = node;
|
||||
if (_cmpxchg(&once, false, true)) {
|
||||
atexit(freeHostInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Note: do we need to process the remaining adapter prefix?
|
||||
* ap - points to broadcast addr
|
||||
* ap->Next - points to interface multicast addr
|
||||
* Ignoring them for now
|
||||
*/
|
||||
}
|
||||
return 0;
|
||||
err:
|
||||
freeHostInfo();
|
||||
return -1;
|
||||
}
|
||||
|
||||
static textwindows int readAdapterAddresses(void) {
|
||||
uint32_t size, rc;
|
||||
struct NtIpAdapterAddresses *aa = NULL;
|
||||
/*
|
||||
* Calculate the required data size
|
||||
* Note: alternatively you can use AF_UNSPEC to also return IPv6 interfaces
|
||||
*/
|
||||
rc = GetAdaptersAddresses(AF_INET,
|
||||
kNtGaaFlagSkipAnycast | kNtGaaFlagSkipMulticast |
|
||||
kNtGaaFlagSkipDnsServer |
|
||||
kNtGaaFlagIncludePrefix,
|
||||
NULL, /* Reserved */
|
||||
NULL, /* Ptr */
|
||||
&size);
|
||||
if (rc != kNtErrorBufferOverflow) {
|
||||
ebadf();
|
||||
goto err;
|
||||
}
|
||||
if (!_weaken(malloc) ||
|
||||
!(aa = (struct NtIpAdapterAddresses *)_weaken(malloc)(size))) {
|
||||
enomem();
|
||||
goto err;
|
||||
}
|
||||
/* Re-run GetAdaptersAddresses this time with a valid buffer */
|
||||
rc = GetAdaptersAddresses(AF_INET,
|
||||
kNtGaaFlagSkipAnycast | kNtGaaFlagSkipMulticast |
|
||||
kNtGaaFlagSkipDnsServer |
|
||||
kNtGaaFlagIncludePrefix,
|
||||
// kNtGaaFlagIncludePrefix,
|
||||
NULL, aa, &size);
|
||||
if (rc != kNtErrorSuccess) {
|
||||
errno = GetLastError();
|
||||
goto err;
|
||||
}
|
||||
if (createHostInfo(aa) == -1) {
|
||||
goto err;
|
||||
}
|
||||
if (_weaken(free)) {
|
||||
_weaken(free)(aa);
|
||||
}
|
||||
return 0;
|
||||
err:
|
||||
if (_weaken(free)) {
|
||||
_weaken(free)(aa);
|
||||
}
|
||||
freeHostInfo();
|
||||
return -1;
|
||||
}
|
||||
|
||||
static textwindows int ioctl_siocgifconf_nt(int fd, struct ifconf *ifc) {
|
||||
struct ifreq *ptr;
|
||||
struct NtIpAdapterAddresses *aa;
|
||||
struct HostAdapterInfoNode *node;
|
||||
if (__hostInfo) {
|
||||
freeHostInfo();
|
||||
}
|
||||
if (readAdapterAddresses() == -1) {
|
||||
return -1;
|
||||
}
|
||||
for (ptr = ifc->ifc_req, node = __hostInfo;
|
||||
(((char *)(ptr + 1) - ifc->ifc_buf) < ifc->ifc_len) && node;
|
||||
ptr++, node = node->next) {
|
||||
memcpy(ptr->ifr_name, node->name, IFNAMSIZ);
|
||||
memcpy(&ptr->ifr_addr, &node->unicast, sizeof(struct sockaddr));
|
||||
}
|
||||
ifc->ifc_len = (char *)ptr - ifc->ifc_buf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls settings on device.
|
||||
* Returns unicast addresses.
|
||||
*/
|
||||
static textwindows int ioctl_siocgifaddr_nt(int fd, struct ifreq *ifr) {
|
||||
struct HostAdapterInfoNode *node;
|
||||
node = findAdapterByName(ifr->ifr_name);
|
||||
if (!node) return ebadf();
|
||||
memcpy(&ifr->ifr_addr, &node->unicast, sizeof(struct sockaddr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Performs the SIOCGIFFLAGS operation */
|
||||
static textwindows int ioctl_siocgifflags_nt(int fd, struct ifreq *ifr) {
|
||||
struct HostAdapterInfoNode *node;
|
||||
node = findAdapterByName(ifr->ifr_name);
|
||||
if (!node) return ebadf();
|
||||
ifr->ifr_flags = node->flags;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Performs the SIOCGIFNETMASK operation */
|
||||
static textwindows int ioctl_siocgifnetmask_nt(int fd, struct ifreq *ifr) {
|
||||
struct HostAdapterInfoNode *node;
|
||||
node = findAdapterByName(ifr->ifr_name);
|
||||
if (!node) return ebadf();
|
||||
memcpy(&ifr->ifr_netmask, &node->netmask, sizeof(struct sockaddr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns broadcast address.
|
||||
*/
|
||||
static textwindows int ioctl_siocgifbrdaddr_nt(int fd, struct ifreq *ifr) {
|
||||
struct HostAdapterInfoNode *node;
|
||||
node = findAdapterByName(ifr->ifr_name);
|
||||
if (!node) return ebadf();
|
||||
memcpy(&ifr->ifr_broadaddr, &node->broadcast, sizeof(struct sockaddr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ioctl_siocgifconf_sysv(int fd, struct ifconf *ifc) {
|
||||
/*
|
||||
* We're 100% compatible with Linux.
|
||||
* BSD ABIs mainly differ by having sockaddr::sa_len
|
||||
* XNU uses a 32-bit length in a struct that's packed!
|
||||
*/
|
||||
int i, rc, fam;
|
||||
char *b, *p, *e;
|
||||
char ifcBsd[16];
|
||||
struct ifreq *req;
|
||||
uint32_t bufLen, ip;
|
||||
size_t numReq, bufMax;
|
||||
if (IsLinux()) {
|
||||
return sys_ioctl(fd, SIOCGIFCONF, ifc);
|
||||
}
|
||||
bufMax = 15000; /* conservative guesstimate */
|
||||
b = alloca(bufMax);
|
||||
memcpy(ifcBsd, &bufMax, 8); /* ifc_len */
|
||||
memcpy(ifcBsd + (IsXnu() ? 4 : 8), &b, 8); /* ifc_buf */
|
||||
if ((rc = sys_ioctl(fd, SIOCGIFCONF, &ifcBsd)) != -1) {
|
||||
/*
|
||||
* On XNU the size of the struct ifreq is different than Linux.
|
||||
* On Linux is fixed (40 bytes), but on XNU the struct sockaddr
|
||||
* has variable length, making the whole struct ifreq a variable
|
||||
* sized record.
|
||||
*/
|
||||
memcpy(&bufLen, b, 4);
|
||||
req = ifc->ifc_req;
|
||||
for (p = b, e = p + MIN(bufMax, READ32LE(ifcBsd)); p + 16 + 16 <= e;
|
||||
p += IsBsd() ? 16 + MAX(16, p[16] & 255) : 40) {
|
||||
fam = p[IsBsd() ? 17 : 16] & 255;
|
||||
if (fam != AF_INET) continue;
|
||||
ip = READ32BE(p + 20);
|
||||
bzero(req, sizeof(*req));
|
||||
memcpy(req->ifr_name, p, 16);
|
||||
memcpy(&req->ifr_addr, p + 16, 16);
|
||||
req->ifr_addr.sa_family = fam;
|
||||
((struct sockaddr_in *)&req->ifr_addr)->sin_addr.s_addr = htonl(ip);
|
||||
++req;
|
||||
}
|
||||
ifc->ifc_len = (char *)req - ifc->ifc_buf; /* Adjust len */
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static inline void ioctl_sockaddr2linux(void *saddr) {
|
||||
char *p;
|
||||
if (saddr) {
|
||||
p = saddr;
|
||||
p[0] = p[1];
|
||||
p[1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Used for all the ioctl that returns sockaddr structure that
|
||||
* requires adjustment between Linux and XNU
|
||||
*/
|
||||
static int ioctl_siocgifaddr_sysv(int fd, uint64_t op, struct ifreq *ifr) {
|
||||
if (sys_ioctl(fd, op, ifr) == -1) return -1;
|
||||
if (IsBsd()) ioctl_sockaddr2linux(&ifr->ifr_addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ioctl_siocgifconf(int fd, void *arg) {
|
||||
if (!IsWindows()) {
|
||||
return ioctl_siocgifconf_sysv(fd, arg);
|
||||
} else {
|
||||
return ioctl_siocgifconf_nt(fd, arg);
|
||||
}
|
||||
}
|
||||
|
||||
static int ioctl_siocgifaddr(int fd, void *arg) {
|
||||
if (!IsWindows()) {
|
||||
return ioctl_siocgifaddr_sysv(fd, SIOCGIFADDR, arg);
|
||||
} else {
|
||||
return ioctl_siocgifaddr_nt(fd, arg);
|
||||
}
|
||||
}
|
||||
|
||||
static int ioctl_siocgifnetmask(int fd, void *arg) {
|
||||
if (!IsWindows()) {
|
||||
return ioctl_siocgifaddr_sysv(fd, SIOCGIFNETMASK, arg);
|
||||
} else {
|
||||
return ioctl_siocgifnetmask_nt(fd, arg);
|
||||
}
|
||||
}
|
||||
|
||||
static int ioctl_siocgifbrdaddr(int fd, void *arg) {
|
||||
if (!IsWindows()) {
|
||||
return ioctl_siocgifaddr_sysv(fd, SIOCGIFBRDADDR, arg);
|
||||
} else {
|
||||
return ioctl_siocgifbrdaddr_nt(fd, arg);
|
||||
}
|
||||
}
|
||||
|
||||
static int ioctl_siocgifdstaddr(int fd, void *arg) {
|
||||
if (!IsWindows()) {
|
||||
return ioctl_siocgifaddr_sysv(fd, SIOCGIFDSTADDR, arg);
|
||||
} else {
|
||||
return enotsup();
|
||||
/* Not supported - Unknown how to find out how to retrieve the destination
|
||||
* address of a PPP from the interface list returned by the
|
||||
* GetAdaptersAddresses function
|
||||
*
|
||||
return ioctl_siocgifdstaddr_nt(fd, arg);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
static int ioctl_siocgifflags(int fd, void *arg) {
|
||||
if (!IsWindows()) {
|
||||
/* Both XNU and Linux are for once compatible here... */
|
||||
return ioctl_default(fd, SIOCGIFFLAGS, arg);
|
||||
} else {
|
||||
return ioctl_siocgifflags_nt(fd, arg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets "close on exec" on file descriptor the fast way.
|
||||
*
|
||||
* @see ioctl(fd, FIOCLEX, 0) dispatches here
|
||||
*/
|
||||
static int ioctl_fioclex(int fd, int req) {
|
||||
int rc;
|
||||
if (fd >= 0) {
|
||||
if (IsWindows() || (fd < g_fds.n && g_fds.p[fd].kind == kFdZip)) {
|
||||
if (__isfdopen(fd)) {
|
||||
if (req == FIOCLEX) {
|
||||
g_fds.p[fd].flags |= O_CLOEXEC;
|
||||
} else {
|
||||
g_fds.p[fd].flags &= ~O_CLOEXEC;
|
||||
}
|
||||
rc = 0;
|
||||
} else {
|
||||
rc = ebadf();
|
||||
}
|
||||
} else {
|
||||
rc = sys_ioctl(fd, req);
|
||||
}
|
||||
} else {
|
||||
rc = einval();
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs special i/o operation on file descriptor.
|
||||
*
|
||||
* @param request can be any of:
|
||||
*
|
||||
* - `FIONREAD` takes an `int *` and returns how many bytes of input
|
||||
* are available on a terminal or socket, waiting to be read. On
|
||||
* Windows this currently won't work for console file descriptors.
|
||||
*
|
||||
* - `TIOCGWINSZ` populates `struct winsize *` with the dimensions
|
||||
* of your teletypewriter. It's an alias for tcgetwinsize().
|
||||
*
|
||||
* - `TIOCSWINSZ` with the dimensions of your teletypewriter to
|
||||
* `struct winsize *`. It's an alias for tcsetwinsize().
|
||||
*
|
||||
* - `TIOCOUTQ` takes an `int *` and returns the number of bytes in
|
||||
* the terminal's output buffer. Only available on UNIX.
|
||||
*
|
||||
* - `TIOCSTI` takes a `const char *` and may be used to fake input
|
||||
* to a tty. This API isn't available on OpenBSD. Only available
|
||||
* on UNIX.
|
||||
*
|
||||
* - `TIOCNOTTY` takes an `int tty_fd` arg and makes it the
|
||||
* controlling terminal of the calling process, which should have
|
||||
* called setsid() beforehand.
|
||||
*
|
||||
* - `TIOCNOTTY` to give up the controlling terminal. Only available
|
||||
* on UNIX.
|
||||
*
|
||||
* - `TIOCNXCL` to give up exclusive mode on terminal. Only
|
||||
* available on UNIX.
|
||||
*
|
||||
* - `FIOCLEX` sets the `O_CLOEXEC` state (no arg) noting that this
|
||||
* polyfill may be removed in the future, and code should migrate
|
||||
* to the equivalent fcntl() api.
|
||||
*
|
||||
* - `FIONBIO` sets the `O_NONBLOCK` state (arg is `int *enabled`)
|
||||
* which is supported on Windows for sockets.
|
||||
*
|
||||
* - `FIONCLEX` clears the `O_CLOEXEC` state (no arg) noting that
|
||||
* this polyfill may be removed in the future, and code should
|
||||
* migrate to the equivalent fcntl() api.
|
||||
*
|
||||
* - `SIOCGIFCONF` takes an struct ifconf object of a given size,
|
||||
* whose arg is `struct ifconf *`. It implements the Linux style
|
||||
* and modifies the following:
|
||||
* - ifc_len: set it to the number of valid ifreq structures
|
||||
* representingthe interfaces
|
||||
* - ifc_ifcu.ifcu_req: sets the name of the interface for each
|
||||
* interface
|
||||
* The ifc_len is an input/output parameter: set it to the total
|
||||
* size of the ifcu_buf (ifcu_req) buffer on input.
|
||||
*
|
||||
* - `SIOCGIFNETMASK` populates a `struct ifconf *` record with the
|
||||
* network interface mask. This data structure should be obtained
|
||||
* by calling `SIOCGIFCONF`.
|
||||
*
|
||||
* - `SIOCGIFBRDADDR` populates a `struct ifconf *` record with the
|
||||
* network broadcast addr. This data structure should be obtained
|
||||
* by calling `SIOCGIFCONF`.
|
||||
*
|
||||
* - `TCGETS` isn't polyfilled; use tcgetattr()
|
||||
* - `TCSETS` isn't polyfilled; use tcsetattr()
|
||||
* - `TCSETSW` isn't polyfilled; use tcsetattr()
|
||||
* - `TCSETSF` isn't polyfilled; use tcsetattr()
|
||||
* - `TCXONC` isn't polyfilled; use tcflow()
|
||||
* - `TCSBRK` isn't polyfilled; use tcdrain()
|
||||
* - `TCFLSH` isn't polyfilled; use tcflush()
|
||||
* - `TIOCGPTN` isn't polyfilled; use ptsname()
|
||||
* - `TIOCGSID` isn't polyfilled; use tcgetsid()
|
||||
* - `TCSBRK` isn't polyfilled; use tcsendbreak()
|
||||
* - `TCSBRK` isn't polyfilled; use tcsendbreak()
|
||||
* - `TIOCSPGRP` isn't polyfilled; use tcsetpgrp()
|
||||
* - `TIOCSPTLCK` isn't polyfilled; use unlockpt()
|
||||
*
|
||||
* @restartable
|
||||
* @vforksafe
|
||||
*/
|
||||
int(ioctl)(int fd, uint64_t request, ...) {
|
||||
int ioctl(int fd, unsigned long request, ...) {
|
||||
int rc;
|
||||
void *arg;
|
||||
va_list va;
|
||||
va_start(va, request);
|
||||
arg = va_arg(va, void *);
|
||||
va_end(va);
|
||||
if (request == TIOCGWINSZ) return tcgetwinsize(fd, arg);
|
||||
if (request == TIOCSWINSZ) return tcsetwinsize(fd, arg);
|
||||
return __IOCTL_DISPATCH(EQUAL, -1, fd, request, arg);
|
||||
if (request == FIONBIO) {
|
||||
rc = ioctl_default(fd, request, arg);
|
||||
} else if (request == FIOCLEX) {
|
||||
rc = ioctl_fioclex(fd, request);
|
||||
} else if (request == FIONCLEX) {
|
||||
rc = ioctl_fioclex(fd, request);
|
||||
} else if (request == TIOCGWINSZ) {
|
||||
rc = tcgetwinsize(fd, arg);
|
||||
} else if (request == TIOCSWINSZ) {
|
||||
rc = tcsetwinsize(fd, arg);
|
||||
} else if (request == SIOCGIFCONF) {
|
||||
rc = ioctl_siocgifconf(fd, arg);
|
||||
} else if (request == SIOCGIFADDR) {
|
||||
rc = ioctl_siocgifaddr(fd, arg);
|
||||
} else if (request == SIOCGIFNETMASK) {
|
||||
rc = ioctl_siocgifnetmask(fd, arg);
|
||||
} else if (request == SIOCGIFBRDADDR) {
|
||||
rc = ioctl_siocgifbrdaddr(fd, arg);
|
||||
} else if (request == SIOCGIFDSTADDR) {
|
||||
rc = ioctl_siocgifdstaddr(fd, arg);
|
||||
} else if (request == SIOCGIFFLAGS) {
|
||||
rc = ioctl_siocgifflags(fd, arg);
|
||||
} else {
|
||||
rc = ioctl_default(fd, request, arg);
|
||||
}
|
||||
STRACE("ioctl(%d, %#lx, %p) → %d% m", fd, request, arg, rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_CALLS_IOCTL_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_IOCTL_H_
|
||||
#include "libc/calls/termios.h"
|
||||
#include "libc/sysv/consts/fio.h"
|
||||
#include "libc/sysv/consts/sio.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § system calls » ioctl ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
int ioctl(int, uint64_t, ...);
|
||||
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && defined(COSMO)
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § system calls » ioctl » undiamonding ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
#define ioctl(FD, REQUEST, ...) \
|
||||
__IOCTL_DISPATCH(__EQUIVALENT, ioctl_default(FD, REQUEST, ##__VA_ARGS__), \
|
||||
FD, REQUEST, ##__VA_ARGS__)
|
||||
|
||||
#define __EQUIVALENT(X, Y) (__builtin_constant_p((X) == (Y)) && ((X) == (Y)))
|
||||
|
||||
#define __IOCTL_DISPATCH(CMP, DEFAULT, FD, REQUEST, ...) \
|
||||
({ \
|
||||
int ReZ; \
|
||||
if (CMP(REQUEST, SIOCGIFCONF)) { \
|
||||
ReZ = ioctl_siocgifconf(FD, ##__VA_ARGS__); \
|
||||
} else if (CMP(REQUEST, SIOCGIFADDR)) { \
|
||||
ReZ = ioctl_siocgifaddr(FD, ##__VA_ARGS__); \
|
||||
} else if (CMP(REQUEST, SIOCGIFNETMASK)) { \
|
||||
ReZ = ioctl_siocgifnetmask(FD, ##__VA_ARGS__); \
|
||||
} else if (CMP(REQUEST, SIOCGIFBRDADDR)) { \
|
||||
ReZ = ioctl_siocgifbrdaddr(FD, ##__VA_ARGS__); \
|
||||
} else if (CMP(REQUEST, SIOCGIFDSTADDR)) { \
|
||||
ReZ = ioctl_siocgifdstaddr(FD, ##__VA_ARGS__); \
|
||||
} else if (CMP(REQUEST, SIOCGIFFLAGS)) { \
|
||||
ReZ = ioctl_siocgifflags(FD, ##__VA_ARGS__); \
|
||||
} else if (CMP(REQUEST, FIONBIO)) { \
|
||||
ReZ = ioctl_default(FD, REQUEST, ##__VA_ARGS__); \
|
||||
} else if (CMP(REQUEST, FIOCLEX)) { \
|
||||
ReZ = ioctl_fioclex(FD, REQUEST); \
|
||||
} else if (CMP(REQUEST, FIONCLEX)) { \
|
||||
ReZ = ioctl_fioclex(FD, REQUEST); \
|
||||
} else { \
|
||||
ReZ = DEFAULT; \
|
||||
} \
|
||||
ReZ; \
|
||||
})
|
||||
|
||||
int ioctl_default(int, uint64_t, ...);
|
||||
int ioctl_fioclex(int, int);
|
||||
int ioctl_siocgifaddr(int, ...);
|
||||
int ioctl_siocgifbrdaddr(int, ...);
|
||||
int ioctl_siocgifconf(int, ...);
|
||||
int ioctl_siocgifdstaddr(int, ...);
|
||||
int ioctl_siocgifflags(int, ...);
|
||||
int ioctl_siocgifnetmask(int, ...);
|
||||
|
||||
#endif /* GNUC && !ANSI */
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_IOCTL_H_ */
|
|
@ -1,52 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/ioctl.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/nt/winsock.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
int ioctl_default(int fd, uint64_t request, ...) {
|
||||
int rc;
|
||||
void *arg;
|
||||
va_list va;
|
||||
int64_t handle;
|
||||
va_start(va, request);
|
||||
arg = va_arg(va, void *);
|
||||
va_end(va);
|
||||
if (!IsWindows()) {
|
||||
return sys_ioctl(fd, request, arg);
|
||||
} else if (__isfdopen(fd)) {
|
||||
if (g_fds.p[fd].kind == kFdSocket) {
|
||||
handle = __getfdhandleactual(fd);
|
||||
if ((rc = _weaken(__sys_ioctlsocket_nt)(handle, request, arg)) != -1) {
|
||||
return rc;
|
||||
} else {
|
||||
return _weaken(__winsockerr)();
|
||||
}
|
||||
} else {
|
||||
return eopnotsupp();
|
||||
}
|
||||
} else {
|
||||
return ebadf();
|
||||
}
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/ioctl.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Sets "close on exec" on file descriptor the fast way.
|
||||
*
|
||||
* @see ioctl(fd, FIOCLEX, 0) dispatches here
|
||||
*/
|
||||
int ioctl_fioclex(int fd, int req) {
|
||||
int rc;
|
||||
if (fd >= 0) {
|
||||
if (IsWindows() || (fd < g_fds.n && g_fds.p[fd].kind == kFdZip)) {
|
||||
if (__isfdopen(fd)) {
|
||||
if (req == FIOCLEX) {
|
||||
g_fds.p[fd].flags |= O_CLOEXEC;
|
||||
} else {
|
||||
g_fds.p[fd].flags &= ~O_CLOEXEC;
|
||||
}
|
||||
rc = 0;
|
||||
} else {
|
||||
rc = ebadf();
|
||||
}
|
||||
} else {
|
||||
rc = sys_ioctl(fd, req);
|
||||
}
|
||||
} else {
|
||||
rc = einval();
|
||||
}
|
||||
STRACE("%s(%d, %d) → %d% m", "ioctl_fioclex", fd, req, rc);
|
||||
return rc;
|
||||
}
|
|
@ -1,414 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/cmpxchg.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/nt/iphlpapi.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/ipadapteraddresses.h"
|
||||
#include "libc/nt/winsock.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/sock/struct/ifconf.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
#include "libc/sysv/consts/iff.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/* Maximum number of unicast addresses handled for each interface */
|
||||
#define MAX_UNICAST_ADDR 32
|
||||
#define MAX_NAME_CLASH ((int)('z' - 'a')) /* Allow a..z */
|
||||
|
||||
struct HostAdapterInfoNode {
|
||||
struct HostAdapterInfoNode *next;
|
||||
char name[IFNAMSIZ]; /* Obtained from FriendlyName */
|
||||
struct sockaddr unicast;
|
||||
struct sockaddr netmask;
|
||||
struct sockaddr broadcast;
|
||||
short flags;
|
||||
} * __hostInfo;
|
||||
|
||||
/* Frees all the nodes of the _hostInfo */
|
||||
static void freeHostInfo(void) {
|
||||
struct HostAdapterInfoNode *next, *node = __hostInfo;
|
||||
if (_weaken(free)) {
|
||||
while (node) {
|
||||
next = node->next;
|
||||
_weaken(free)(node);
|
||||
node = next;
|
||||
}
|
||||
}
|
||||
__hostInfo = NULL;
|
||||
}
|
||||
|
||||
/* Given a short adapter name, look into __hostInfo to see if there is
|
||||
* an adapter with the same name. Returns the pointer to the HostAdapterInfoNode
|
||||
* if found, or NULL if not found
|
||||
*/
|
||||
static struct HostAdapterInfoNode *findAdapterByName(const char *name) {
|
||||
struct HostAdapterInfoNode *node = __hostInfo;
|
||||
while (node) {
|
||||
if (!strncmp(name, node->name, IFNAMSIZ)) {
|
||||
return node;
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Creates a new HostAdapterInfoNode object, initializes it from
|
||||
* the given adapter, unicast address and address prefixes
|
||||
* and insert it in the __hostInfo.
|
||||
* Increments the pointers to the unicast addresses and
|
||||
* the address prefixes
|
||||
* Returns NULL if an error occurred or the newly created
|
||||
* HostAdapterInfoNode object (last in the list)
|
||||
*/
|
||||
struct HostAdapterInfoNode *appendHostInfo(
|
||||
struct HostAdapterInfoNode *parentInfoNode,
|
||||
const char *baseName, /* Max length = IFNAMSIZ-1 */
|
||||
const struct NtIpAdapterAddresses
|
||||
*aa, /* Top level adapter object being processed */
|
||||
struct NtIpAdapterUnicastAddress *
|
||||
*ptrUA, /* Ptr to ptr to unicast address list node */
|
||||
struct NtIpAdapterPrefix *
|
||||
*ptrAP, /* Ptr to ptr to Adapter prefix list node */
|
||||
int count) { /* count is used to create a unique name in case of alias */
|
||||
|
||||
struct HostAdapterInfoNode *temp;
|
||||
struct HostAdapterInfoNode *node;
|
||||
uint32_t ip, netmask, broadcast;
|
||||
struct sockaddr_in *a;
|
||||
int attemptNum;
|
||||
|
||||
if (!_weaken(calloc) || !(node = _weaken(calloc)(1, sizeof(*node)))) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(node->name, baseName, IFNAMSIZ);
|
||||
|
||||
/* Are there more than a single unicast address ? */
|
||||
if (count > 0 || ((*ptrUA)->Next != NULL)) {
|
||||
/* Yes, compose it using <baseName>:<count> */
|
||||
size_t nameLen = strlen(node->name);
|
||||
if (nameLen + 2 > IFNAMSIZ - 2) {
|
||||
/* Appending the ":x" will exceed the size, need to chop the end */
|
||||
nameLen -= 2;
|
||||
}
|
||||
node->name[nameLen - 2] = ':';
|
||||
node->name[nameLen - 1] = '0' + count;
|
||||
node->name[nameLen] = '\0';
|
||||
}
|
||||
|
||||
/* Is there a name clash with other interfaces? */
|
||||
for (attemptNum = 0; attemptNum < MAX_NAME_CLASH; ++attemptNum) {
|
||||
temp = findAdapterByName(node->name);
|
||||
if (!temp) {
|
||||
break;
|
||||
} else {
|
||||
/* Yes, this name has been already used, append an extra
|
||||
* character to resolve conflict. Note since the max length
|
||||
* of the string now is IFNAMSIZ-2, we have just enough space for this.
|
||||
* E.g. 'Ethernet_1' -> 'Ethernet_1a'
|
||||
*/
|
||||
size_t pos = strlen(node->name);
|
||||
node->name[pos] = 'a' + attemptNum;
|
||||
node->name[pos + 1] = '\0';
|
||||
/* Try again */
|
||||
}
|
||||
}
|
||||
|
||||
if (attemptNum == MAX_NAME_CLASH) {
|
||||
/* Cannot resolve the conflict */
|
||||
if (_weaken(free)) {
|
||||
_weaken(free)(node);
|
||||
}
|
||||
errno = EEXIST;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Finally we got a unique short and friendly name */
|
||||
node->unicast = *((*ptrUA)->Address.lpSockaddr);
|
||||
if (*ptrUA == aa->FirstUnicastAddress) {
|
||||
short flags;
|
||||
/* This is the first unicast address of this interface
|
||||
* calculate the flags for this adapter. Flags to consider:
|
||||
* IFF_UP
|
||||
* IFF_BROADCAST ** TODO: We need to validate
|
||||
* IFF_LOOPBACK
|
||||
* IFF_POINTOPOINT
|
||||
* IFF_MULTICAST
|
||||
* IFF_RUNNING ** Same as IFF_UP for now
|
||||
* IFF_PROMISC ** NOT SUPPORTED, unknown how to retrieve it
|
||||
*/
|
||||
flags = 0;
|
||||
if (aa->OperStatus == kNtIfOperStatusUp) flags |= IFF_UP | IFF_RUNNING;
|
||||
if (aa->IfType == kNtIfTypePpp) flags |= IFF_POINTOPOINT;
|
||||
if (!(aa->Flags & kNtIpAdapterNoMulticast)) flags |= IFF_MULTICAST;
|
||||
if (aa->IfType == kNtIfTypeSoftwareLoopback) flags |= IFF_LOOPBACK;
|
||||
if (aa->FirstPrefix) flags |= IFF_BROADCAST;
|
||||
node->flags = flags;
|
||||
} else {
|
||||
/* Copy from previous node */
|
||||
node->flags = parentInfoNode->flags;
|
||||
}
|
||||
|
||||
ip = ntohl(
|
||||
((struct sockaddr_in *)(*ptrUA)->Address.lpSockaddr)->sin_addr.s_addr);
|
||||
netmask = (uint32_t)-1 << (32 - (*ptrUA)->OnLinkPrefixLength);
|
||||
broadcast = (ip & netmask) | (~netmask & -1);
|
||||
|
||||
a = (struct sockaddr_in *)&node->netmask;
|
||||
a->sin_family = AF_INET;
|
||||
a->sin_addr.s_addr = htonl(netmask);
|
||||
|
||||
a = (struct sockaddr_in *)&node->broadcast;
|
||||
a->sin_family = AF_INET;
|
||||
a->sin_addr.s_addr = htonl(broadcast);
|
||||
|
||||
/* Process the prefix and extract the netmask and broadcast */
|
||||
/* According to the doc:
|
||||
*
|
||||
* On Windows Vista and later, the linked IP_ADAPTER_PREFIX
|
||||
* structures pointed to by the FirstPrefix member include three
|
||||
* IP adapter prefixes for each IP address assigned to the
|
||||
* adapter. These include the host IP address prefix, the subnet
|
||||
* IP address prefix, and the subnet broadcast IP address prefix.
|
||||
* In addition, for each adapter there is a multicast address
|
||||
* prefix and a broadcast address prefix.
|
||||
* -Source: MSDN on IP_ADAPTER_ADDRESSES_LH
|
||||
*
|
||||
* For example, interface "Ethernet", with 2 unicast addresses:
|
||||
*
|
||||
* - 192.168.1.84
|
||||
* - 192.168.5.99
|
||||
*
|
||||
* The Prefix list has 8 elements:
|
||||
*
|
||||
* #1: 192.168.1.0/24 <- Network, use the PrefixLength for netmask
|
||||
* #2: 192.168.1.84/32 <- Host IP
|
||||
* #3: 192.168.1.255/32 <- Subnet broadcast
|
||||
*
|
||||
* #4: 192.168.5.0/24 <- Network
|
||||
* #5: 192.168.5.99/32 <- Host IP
|
||||
* #6: 192.168.5.255/32 <- Subnet broadcast
|
||||
*
|
||||
* #7: 224.0.0.0/4 <- Multicast
|
||||
* #8: 255.255.255.255/32 <- Broadcast
|
||||
*/
|
||||
|
||||
if (ptrAP && *ptrAP) {
|
||||
*ptrAP = (*ptrAP)->Next; /* skip net ip */
|
||||
if (*ptrAP) {
|
||||
*ptrAP = (*ptrAP)->Next; /* skip host ip */
|
||||
if (*ptrAP) {
|
||||
node->broadcast = *((*ptrAP)->Address.lpSockaddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*ptrUA = (*ptrUA)->Next;
|
||||
|
||||
/* Append this node to the last node (if any) */
|
||||
if (parentInfoNode) {
|
||||
parentInfoNode->next = node;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
return node;
|
||||
}
|
||||
|
||||
/* Returns -1 in case of failure */
|
||||
static int createHostInfo(struct NtIpAdapterAddresses *firstAdapter) {
|
||||
static bool once;
|
||||
struct NtIpAdapterAddresses *aa;
|
||||
struct NtIpAdapterUnicastAddress *ua;
|
||||
struct NtIpAdapterPrefix *ap;
|
||||
struct HostAdapterInfoNode *node = NULL;
|
||||
char baseName[IFNAMSIZ];
|
||||
char name[IFNAMSIZ];
|
||||
int count, i;
|
||||
|
||||
/* __hostInfo must be empty */
|
||||
_unassert(__hostInfo == NULL);
|
||||
|
||||
for (aa = firstAdapter; aa; aa = aa->Next) {
|
||||
/* Skip all the interfaces with no address and the ones that are not AF_INET
|
||||
*/
|
||||
if (!aa->FirstUnicastAddress ||
|
||||
aa->FirstUnicastAddress->Address.lpSockaddr->sa_family != AF_INET) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Use max IFNAMSIZ-1 chars, leave the last char for eventual conflicts */
|
||||
tprecode16to8(baseName, IFNAMSIZ - 1, aa->FriendlyName);
|
||||
baseName[IFNAMSIZ - 2] = '\0';
|
||||
/* Replace any space with a '_' */
|
||||
for (i = 0; i < IFNAMSIZ - 2; ++i) {
|
||||
if (baseName[i] == ' ') baseName[i] = '_';
|
||||
if (!baseName[i]) break;
|
||||
}
|
||||
for (count = 0, ua = aa->FirstUnicastAddress, ap = aa->FirstPrefix;
|
||||
(ua != NULL) && (count < MAX_UNICAST_ADDR); ++count) {
|
||||
node = appendHostInfo(node, baseName, aa, &ua, &ap, count);
|
||||
if (!node) goto err;
|
||||
if (!__hostInfo) {
|
||||
__hostInfo = node;
|
||||
if (_cmpxchg(&once, false, true)) {
|
||||
atexit(freeHostInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Note: do we need to process the remaining adapter prefix?
|
||||
* ap - points to broadcast addr
|
||||
* ap->Next - points to interface multicast addr
|
||||
* Ignoring them for now
|
||||
*/
|
||||
}
|
||||
return 0;
|
||||
|
||||
err:
|
||||
freeHostInfo();
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int readAdapterAddresses(void) {
|
||||
uint32_t size, rc;
|
||||
struct NtIpAdapterAddresses *aa = NULL;
|
||||
|
||||
/* Calculate the required data size
|
||||
* Note: alternatively you can use AF_UNSPEC to also return IPv6 interfaces
|
||||
*/
|
||||
rc = GetAdaptersAddresses(AF_INET,
|
||||
kNtGaaFlagSkipAnycast | kNtGaaFlagSkipMulticast |
|
||||
kNtGaaFlagSkipDnsServer |
|
||||
kNtGaaFlagIncludePrefix,
|
||||
NULL, /* Reserved */
|
||||
NULL, /* Ptr */
|
||||
&size);
|
||||
if (rc != kNtErrorBufferOverflow) {
|
||||
ebadf();
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!_weaken(malloc) ||
|
||||
!(aa = (struct NtIpAdapterAddresses *)_weaken(malloc)(size))) {
|
||||
enomem();
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Re-run GetAdaptersAddresses this time with a valid buffer */
|
||||
rc = GetAdaptersAddresses(AF_INET,
|
||||
kNtGaaFlagSkipAnycast | kNtGaaFlagSkipMulticast |
|
||||
kNtGaaFlagSkipDnsServer |
|
||||
kNtGaaFlagIncludePrefix,
|
||||
// kNtGaaFlagIncludePrefix,
|
||||
NULL, aa, &size);
|
||||
if (rc != kNtErrorSuccess) {
|
||||
errno = GetLastError();
|
||||
goto err;
|
||||
}
|
||||
if (createHostInfo(aa) == -1) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (_weaken(free)) {
|
||||
_weaken(free)(aa);
|
||||
}
|
||||
return 0;
|
||||
|
||||
err:
|
||||
if (_weaken(free)) {
|
||||
_weaken(free)(aa);
|
||||
}
|
||||
freeHostInfo();
|
||||
return -1;
|
||||
}
|
||||
|
||||
textwindows int ioctl_siocgifconf_nt(int fd, struct ifconf *ifc) {
|
||||
struct NtIpAdapterAddresses *aa;
|
||||
struct HostAdapterInfoNode *node;
|
||||
struct ifreq *ptr;
|
||||
|
||||
if (__hostInfo) {
|
||||
freeHostInfo();
|
||||
}
|
||||
|
||||
if (readAdapterAddresses() == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (ptr = ifc->ifc_req, node = __hostInfo;
|
||||
(((char *)(ptr + 1) - ifc->ifc_buf) < ifc->ifc_len) && node;
|
||||
ptr++, node = node->next) {
|
||||
memcpy(ptr->ifr_name, node->name, IFNAMSIZ);
|
||||
memcpy(&ptr->ifr_addr, &node->unicast, sizeof(struct sockaddr));
|
||||
}
|
||||
ifc->ifc_len = (char *)ptr - ifc->ifc_buf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns unicast addresses.
|
||||
*/
|
||||
int ioctl_siocgifaddr_nt(int fd, struct ifreq *ifr) {
|
||||
struct HostAdapterInfoNode *node;
|
||||
node = findAdapterByName(ifr->ifr_name);
|
||||
if (!node) return ebadf();
|
||||
memcpy(&ifr->ifr_addr, &node->unicast, sizeof(struct sockaddr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Performs the SIOCGIFFLAGS operation */
|
||||
int ioctl_siocgifflags_nt(int fd, struct ifreq *ifr) {
|
||||
struct HostAdapterInfoNode *node;
|
||||
node = findAdapterByName(ifr->ifr_name);
|
||||
if (!node) return ebadf();
|
||||
ifr->ifr_flags = node->flags;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Performs the SIOCGIFNETMASK operation */
|
||||
int ioctl_siocgifnetmask_nt(int fd, struct ifreq *ifr) {
|
||||
struct HostAdapterInfoNode *node;
|
||||
node = findAdapterByName(ifr->ifr_name);
|
||||
if (!node) return ebadf();
|
||||
memcpy(&ifr->ifr_netmask, &node->netmask, sizeof(struct sockaddr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns broadcast address.
|
||||
*/
|
||||
int ioctl_siocgifbrdaddr_nt(int fd, struct ifreq *ifr) {
|
||||
struct HostAdapterInfoNode *node;
|
||||
node = findAdapterByName(ifr->ifr_name);
|
||||
if (!node) return ebadf();
|
||||
memcpy(&ifr->ifr_broadaddr, &node->broadcast, sizeof(struct sockaddr));
|
||||
return 0;
|
||||
}
|
|
@ -1,206 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/ioctl.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/sock/struct/ifconf.h"
|
||||
#include "libc/sock/struct/ifreq.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
#include "libc/sysv/consts/sio.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/* SIOCGIFCONF:
|
||||
* Takes an struct ifconf object of a given size
|
||||
* Modifies the following:
|
||||
* - ifc_len: set it to the number of valid ifreq structures representing
|
||||
* the interfaces
|
||||
* - ifc_ifcu.ifcu_req: sets the name of the interface for each interface
|
||||
* The ifc_len is an input/output parameter: set it to the total size of
|
||||
* the ifcu_buf (ifcu_req) buffer on input.
|
||||
*/
|
||||
int ioctl_siocgifconf_nt(int, struct ifconf *) _Hide;
|
||||
int ioctl_siocgifaddr_nt(int, struct ifreq *) _Hide;
|
||||
int ioctl_siocgifflags_nt(int, struct ifreq *) _Hide;
|
||||
int ioctl_siocgifnetmask_nt(int, struct ifreq *) _Hide;
|
||||
int ioctl_siocgifbrdaddr_nt(int, struct ifreq *) _Hide;
|
||||
|
||||
static int ioctl_siocgifconf_sysv(int fd, struct ifconf *ifc) {
|
||||
/*
|
||||
* We're 100% compatible with Linux.
|
||||
* BSD ABIs mainly differ by having sockaddr::sa_len
|
||||
* XNU uses a 32-bit length in a struct that's packed!
|
||||
*/
|
||||
int i, rc, fam;
|
||||
char *b, *p, *e;
|
||||
char ifcBsd[16];
|
||||
struct ifreq *req;
|
||||
uint32_t bufLen, ip;
|
||||
size_t numReq, bufMax;
|
||||
if (IsLinux()) return sys_ioctl(fd, SIOCGIFCONF, ifc);
|
||||
if (!_weaken(malloc)) return enomem();
|
||||
bufMax = 15000; /* conservative guesstimate */
|
||||
if (!(b = _weaken(malloc)(bufMax))) return enomem();
|
||||
memcpy(ifcBsd, &bufMax, 8); /* ifc_len */
|
||||
memcpy(ifcBsd + (IsXnu() ? 4 : 8), &b, 8); /* ifc_buf */
|
||||
if ((rc = sys_ioctl(fd, SIOCGIFCONF, &ifcBsd)) != -1) {
|
||||
/*
|
||||
* On XNU the size of the struct ifreq is different than Linux.
|
||||
* On Linux is fixed (40 bytes), but on XNU the struct sockaddr
|
||||
* has variable length, making the whole struct ifreq a variable
|
||||
* sized record.
|
||||
*/
|
||||
memcpy(&bufLen, b, 4);
|
||||
req = ifc->ifc_req;
|
||||
for (p = b, e = p + MIN(bufMax, READ32LE(ifcBsd)); p + 16 + 16 <= e;
|
||||
p += IsBsd() ? 16 + MAX(16, p[16] & 255) : 40) {
|
||||
fam = p[IsBsd() ? 17 : 16] & 255;
|
||||
if (fam != AF_INET) continue;
|
||||
ip = READ32BE(p + 20);
|
||||
bzero(req, sizeof(*req));
|
||||
memcpy(req->ifr_name, p, 16);
|
||||
memcpy(&req->ifr_addr, p + 16, 16);
|
||||
req->ifr_addr.sa_family = fam;
|
||||
((struct sockaddr_in *)&req->ifr_addr)->sin_addr.s_addr = htonl(ip);
|
||||
++req;
|
||||
}
|
||||
ifc->ifc_len = (char *)req - ifc->ifc_buf; /* Adjust len */
|
||||
}
|
||||
if (_weaken(free)) _weaken(free)(b);
|
||||
return rc;
|
||||
}
|
||||
|
||||
forceinline void Sockaddr2linux(void *saddr) {
|
||||
char *p;
|
||||
if (saddr) {
|
||||
p = saddr;
|
||||
p[0] = p[1];
|
||||
p[1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Used for all the ioctl that returns sockaddr structure that
|
||||
* requires adjustment between Linux and XNU
|
||||
*/
|
||||
static int ioctl_siocgifaddr_sysv(int fd, uint64_t op, struct ifreq *ifr) {
|
||||
if (sys_ioctl(fd, op, ifr) == -1) return -1;
|
||||
if (IsBsd()) Sockaddr2linux(&ifr->ifr_addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about network interfaces.
|
||||
*
|
||||
* @see ioctl(fd, SIOCGIFCONF, tio) dispatches here
|
||||
*/
|
||||
int ioctl_siocgifconf(int fd, ...) {
|
||||
int rc;
|
||||
va_list va;
|
||||
struct ifconf *ifc;
|
||||
va_start(va, fd);
|
||||
ifc = va_arg(va, struct ifconf *);
|
||||
va_end(va);
|
||||
if (!IsWindows()) {
|
||||
rc = ioctl_siocgifconf_sysv(fd, ifc);
|
||||
} else {
|
||||
rc = ioctl_siocgifconf_nt(fd, ifc);
|
||||
}
|
||||
STRACE("%s(%d) → %d% m", "ioctl_siocgifconf", fd, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int ioctl_siocgifaddr(int fd, ...) {
|
||||
va_list va;
|
||||
struct ifreq *ifr;
|
||||
va_start(va, fd);
|
||||
ifr = va_arg(va, struct ifreq *);
|
||||
va_end(va);
|
||||
if (!IsWindows()) {
|
||||
return ioctl_siocgifaddr_sysv(fd, SIOCGIFADDR, ifr);
|
||||
} else {
|
||||
return ioctl_siocgifaddr_nt(fd, ifr);
|
||||
}
|
||||
}
|
||||
|
||||
int ioctl_siocgifnetmask(int fd, ...) {
|
||||
va_list va;
|
||||
struct ifreq *ifr;
|
||||
va_start(va, fd);
|
||||
ifr = va_arg(va, struct ifreq *);
|
||||
va_end(va);
|
||||
if (!IsWindows()) {
|
||||
return ioctl_siocgifaddr_sysv(fd, SIOCGIFNETMASK, ifr);
|
||||
} else {
|
||||
return ioctl_siocgifnetmask_nt(fd, ifr);
|
||||
}
|
||||
}
|
||||
|
||||
int ioctl_siocgifbrdaddr(int fd, ...) {
|
||||
va_list va;
|
||||
struct ifreq *ifr;
|
||||
va_start(va, fd);
|
||||
ifr = va_arg(va, struct ifreq *);
|
||||
va_end(va);
|
||||
if (!IsWindows()) {
|
||||
return ioctl_siocgifaddr_sysv(fd, SIOCGIFBRDADDR, ifr);
|
||||
} else {
|
||||
return ioctl_siocgifbrdaddr_nt(fd, ifr);
|
||||
}
|
||||
}
|
||||
|
||||
int ioctl_siocgifdstaddr(int fd, ...) {
|
||||
va_list va;
|
||||
struct ifreq *ifr;
|
||||
va_start(va, fd);
|
||||
ifr = va_arg(va, struct ifreq *);
|
||||
va_end(va);
|
||||
if (!IsWindows()) {
|
||||
return ioctl_siocgifaddr_sysv(fd, SIOCGIFDSTADDR, ifr);
|
||||
} else {
|
||||
return enotsup();
|
||||
/* Not supported - Unknown how to find out how to retrieve the destination
|
||||
* address of a PPP from the interface list returned by the
|
||||
* GetAdaptersAddresses function
|
||||
*
|
||||
return ioctl_siocgifdstaddr_nt(fd, ifc);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
int ioctl_siocgifflags(int fd, ...) {
|
||||
va_list va;
|
||||
struct ifreq *ifr;
|
||||
va_start(va, fd);
|
||||
ifr = va_arg(va, struct ifreq *);
|
||||
va_end(va);
|
||||
if (!IsWindows()) {
|
||||
/* Both XNU and Linux are for once compatible here... */
|
||||
return ioctl_default(fd, SIOCGIFFLAGS, ifr);
|
||||
} else {
|
||||
return ioctl_siocgifflags_nt(fd, ifr);
|
||||
}
|
||||
}
|
|
@ -19,7 +19,6 @@
|
|||
#include "libc/assert.h"
|
||||
#include "libc/calls/blockcancel.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/ioctl.h"
|
||||
#include "libc/calls/struct/metatermios.internal.h"
|
||||
#include "libc/calls/struct/termios.h"
|
||||
#include "libc/calls/struct/winsize.h"
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/ioctl.h"
|
||||
#include "libc/calls/struct/winsize.h"
|
||||
#include "libc/calls/struct/winsize.internal.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/ioctl.h"
|
||||
#include "libc/calls/struct/metatermios.internal.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/calls/termios.h"
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef LIBC_ISYSTEM_SYS_IOCTL_H_
|
||||
#define LIBC_ISYSTEM_SYS_IOCTL_H_
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/ioctl.h"
|
||||
#include "libc/calls/struct/winsize.h"
|
||||
#include "libc/sysv/consts/fd.h"
|
||||
#include "libc/sysv/consts/fio.h"
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/ioctl.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
|
|
|
@ -351,6 +351,7 @@ syscon fcntl2 F_GETFD 1 1 1 1 1 1 1 1 # unix consensus & fak
|
|||
syscon fcntl2 F_SETFD 2 2 2 2 2 2 2 2 # unix consensus & faked nt
|
||||
syscon fcntl2 F_GETFL 3 3 3 3 3 3 3 3 # unix consensus & faked nt
|
||||
syscon fcntl2 F_SETFL 4 4 4 4 4 4 4 4 # unix consensus & faked nt
|
||||
syscon fcntl F_DUPFD_CLOEXEC 0x0406 0x0406 67 67 17 10 12 0x0406 # Linux 2.6.24+; faked nt
|
||||
syscon fcntl2 F_SETOWN 8 8 6 6 6 6 6 -1 # bsd consensus
|
||||
syscon fcntl2 F_GETOWN 9 9 5 5 5 5 5 -1 # bsd consensus
|
||||
syscon fcntl2 F_SETOWN_EX 15 15 -1 -1 -1 -1 -1 -1 # TODO(jart): polyfill
|
||||
|
@ -362,7 +363,6 @@ syscon fcntl3 F_SETNOSIGPIPE -1 -1 73 73 -1 -1 14 -1 #
|
|||
syscon fcntl3 F_GETNOSIGPIPE -1 -1 74 74 -1 -1 13 -1 #
|
||||
syscon fcntl3 F_GETPATH -1 -1 50 50 -1 -1 15 -1 # geth path associated with fd into buffer with PATH_MAX (1024) bytes
|
||||
syscon fcntl3 FD_CLOEXEC 1 1 1 1 1 1 1 1 # unix consensus & faked nt
|
||||
syscon fcntl F_DUPFD_CLOEXEC 0x0406 0x0406 67 67 17 10 12 0x0406 # Linux 2.6.24+; faked nt
|
||||
syscon fcntl F_MAXFD -1 -1 -1 -1 -1 -1 11 -1 #
|
||||
syscon fcntl F_NOTIFY 0x0402 0x0402 -1 -1 -1 -1 -1 -1
|
||||
syscon fcntl F_SETPIPE_SZ 0x0407 0x0407 -1 -1 -1 -1 -1 -1
|
||||
|
@ -399,14 +399,6 @@ syscon fcntl F_GETOWN_EX 0x10 0x10 -1 -1 -1 -1 -1 -1
|
|||
syscon fcntl F_SETLEASE 0x0400 0x0400 -1 106 -1 -1 -1 -1
|
||||
syscon fcntl F_GETLEASE 0x0401 0x0401 -1 107 -1 -1 -1 -1
|
||||
|
||||
syscon ioctl FIONBIO 0x5421 0x5421 0x8004667e 0x8004667e 0x8004667e 0x8004667e 0x8004667e 0x8004667e # BSD-The New Technology consensus; FIONBIO is traditional O_NONBLOCK; see F_SETFL for re-imagined api
|
||||
syscon ioctl FIOASYNC 0x5452 0x5452 0x8004667d 0x8004667d 0x8004667d 0x8004667d 0x8004667d 0x8004667d # BSD-The New Technology consensus
|
||||
syscon ioctl FIONREAD 0x541b 0x541b 0x4004667f 0x4004667f 0x4004667f 0x4004667f 0x4004667f 0x4004667f # BSD-The New Technology consensus; bytes waiting in FD's input buffer
|
||||
syscon ioctl FIOCLEX 0x5451 0x5451 0x20006601 0x20006601 0x20006601 0x20006601 0x20006601 0x5451 # sets "close on exec" on file descriptor the fast way; faked nt
|
||||
syscon ioctl FIONCLEX 0x5450 0x5450 0x20006602 0x20006602 0x20006602 0x20006602 0x20006602 0x5450 # clears "close on exec" on file descriptor the fast way; faked nt
|
||||
#syscon ioctl FIONWRITE 0x0 0x0 0x0 0x0 0x40046677 0x0 0x0 -1 # [FreeBSD Generalization] bytes queued in FD's output buffer (same as TIOCOUTQ for TTY FDs; see also SO_SNDBUF)
|
||||
#syscon ioctl FIONSPACE 0x0 0x0 0x0 0x0 0x40046676 0x0 0x0 -1 # [FreeBSD Generalization] capacity of FD's output buffer, e.g. equivalent to TIOCGSERIAL w/ UART
|
||||
|
||||
# openat(), fstatat(), linkat(), etc. magnums
|
||||
#
|
||||
# group name GNU/Systemd GNU/Systemd (Aarch64) XNU's Not UNIX! MacOS (Arm64) FreeBSD OpenBSD NetBSD The New Technology Commentary
|
||||
|
@ -944,68 +936,76 @@ syscon ptrace PTRACE_EVENT_STOP 128 128 -1 -1 -1 -1 -1 -1
|
|||
# group name GNU/Systemd GNU/Systemd (Aarch64) XNU's Not UNIX! MacOS (Arm64) FreeBSD OpenBSD NetBSD The New Technology Commentary
|
||||
syscon clone CLONE_VM 0x00000100 0x00000100 0x00000100 0x00000100 0x00000100 0x00000100 0x00000100 0x00000100 # intentionally symbolic so we can tell if clone() is being used to create threads
|
||||
|
||||
# socket ioctl()
|
||||
# ioctl() requests
|
||||
#
|
||||
# group name GNU/Systemd GNU/Systemd (Aarch64) XNU's Not UNIX! MacOS (Arm64) FreeBSD OpenBSD NetBSD The New Technology Commentary
|
||||
syscon sio SIOCATMARK 0x8905 0x8905 0x40047307 0x40047307 0x40047307 0x40047307 0x40047307 0x40047307 # use sockatmark(); determines if oob is available; bsd consensus
|
||||
syscon sio SIOCADDMULTI 0x8931 0x8931 0x80206931 0x80206931 0x80206931 0x80206931 0x80206931 0 # bsd consensus
|
||||
syscon sio SIOCDELMULTI 0x8932 0x8932 0x80206932 0x80206932 0x80206932 0x80206932 0x80206932 0 # bsd consensus
|
||||
syscon sio SIOCDIFADDR 0x8936 0x8936 0x80206919 0x80206919 0x80206919 0x80206919 0x80206919 0 # bsd consensus
|
||||
syscon sio SIOCGIFADDR 0x8915 0x8915 0xc0206921 0xc0206921 0xc0206921 0xc0206921 0xc0206921 0 # bsd consensus
|
||||
syscon sio SIOCGIFBRDADDR 0x8919 0x8919 0xc0206923 0xc0206923 0xc0206923 0xc0206923 0xc0206923 0 # bsd consensus
|
||||
syscon sio SIOCGIFDSTADDR 0x8917 0x8917 0xc0206922 0xc0206922 0xc0206922 0xc0206922 0xc0206922 0 # bsd consensus
|
||||
syscon sio SIOCGIFFLAGS 0x8913 0x8913 0xc0206911 0xc0206911 0xc0206911 0xc0206911 0xc0206911 0 # bsd consensus
|
||||
syscon sio SIOCGIFMETRIC 0x891d 0x891d 0xc0206917 0xc0206917 0xc0206917 0xc0206917 0xc0206917 0 # bsd consensus
|
||||
syscon sio SIOCGIFNETMASK 0x891b 0x891b 0xc0206925 0xc0206925 0xc0206925 0xc0206925 0xc0206925 0 # bsd consensus
|
||||
syscon sio SIOCGPGRP 0x8904 0x8904 0x40047309 0x40047309 0x40047309 0x40047309 0x40047309 0 # bsd consensus
|
||||
syscon sio SIOCSIFADDR 0x8916 0x8916 0x8020690c 0x8020690c 0x8020690c 0x8020690c 0x8020690c 0 # bsd consensus
|
||||
syscon sio SIOCSIFBRDADDR 0x891a 0x891a 0x80206913 0x80206913 0x80206913 0x80206913 0x80206913 0 # bsd consensus
|
||||
syscon sio SIOCSIFDSTADDR 0x8918 0x8918 0x8020690e 0x8020690e 0x8020690e 0x8020690e 0x8020690e 0 # bsd consensus
|
||||
syscon sio SIOCSIFFLAGS 0x8914 0x8914 0x80206910 0x80206910 0x80206910 0x80206910 0x80206910 0 # bsd consensus
|
||||
syscon sio SIOCSIFMETRIC 0x891e 0x891e 0x80206918 0x80206918 0x80206918 0x80206918 0x80206918 0 # bsd consensus
|
||||
syscon sio SIOCSIFNETMASK 0x891c 0x891c 0x80206916 0x80206916 0x80206916 0x80206916 0x80206916 0 # bsd consensus
|
||||
syscon sio SIOCSPGRP 0x8902 0x8902 0x80047308 0x80047308 0x80047308 0x80047308 0x80047308 0 # bsd consensus
|
||||
syscon sio SIOCGIFCONF 0x8912 0x8912 0xc00c6924 0xc00c6924 0xc0106924 0xc0106924 0xc0106924 0
|
||||
syscon sio SIOCGIFMTU 0x8921 0x8921 0xc0206933 0xc0206933 0xc0206933 0xc020697e 0xc020697e 0
|
||||
syscon sio SIOCSIFMTU 0x8922 0x8922 0x80206934 0x80206934 0x80206934 0x8020697f 0x8020697f 0
|
||||
syscon sio SIOCGIFINDEX 0x8933 0x8933 0 0 0xc0206920 0 0 0
|
||||
syscon sio SIOCSIFNAME 0x8923 0x8923 0 0 0x80206928 0 0 0
|
||||
syscon sio SIOCADDDLCI 0x8980 0x8980 0 0 0 0 0 0
|
||||
syscon sio SIOCADDRT 0x890b 0x890b 0 0 0 0 0 0
|
||||
syscon sio SIOCDARP 0x8953 0x8953 0 0 0 0 0 0
|
||||
syscon sio SIOCDELDLCI 0x8981 0x8981 0 0 0 0 0 0
|
||||
syscon sio SIOCDELRT 0x890c 0x890c 0 0 0 0 0 0
|
||||
syscon sio SIOCDEVPRIVATE 0x89f0 0x89f0 0 0 0 0 0 0
|
||||
syscon sio SIOCDRARP 0x8960 0x8960 0 0 0 0 0 0
|
||||
syscon sio SIOCGARP 0x8954 0x8954 0 0 0 0 0 0
|
||||
syscon sio SIOCGIFBR 0x8940 0x8940 0 0 0 0 0 0
|
||||
syscon sio SIOCGIFCOUNT 0x8938 0x8938 0 0 0 0 0 0
|
||||
syscon sio SIOCGIFENCAP 0x8925 0x8925 0 0 0 0 0 0
|
||||
syscon sio SIOCGIFHWADDR 0x8927 0x8927 0 0 0 0 0 0
|
||||
syscon sio SIOCGIFMAP 0x8970 0x8970 0 0 0 0 0 0
|
||||
syscon sio SIOCGIFMEM 0x891f 0x891f 0 0 0 0 0 0
|
||||
syscon sio SIOCGIFNAME 0x8910 0x8910 0 0 0 0 0 0
|
||||
syscon sio SIOCGIFPFLAGS 0x8935 0x8935 0 0 0 0 0 0
|
||||
syscon sio SIOCGIFSLAVE 0x8929 0x8929 0 0 0 0 0 0
|
||||
syscon sio SIOCGIFTXQLEN 0x8942 0x8942 0 0 0 0 0 0
|
||||
syscon sio SIOCGRARP 0x8961 0x8961 0 0 0 0 0 0
|
||||
syscon sio SIOCGSTAMP 0x8906 0x8906 0 0 0 0 0 0
|
||||
syscon sio SIOCGSTAMPNS 0x8907 0x8907 0 0 0 0 0 0
|
||||
syscon sio SIOCPROTOPRIVATE 0x89e0 0x89e0 0 0 0 0 0 0
|
||||
syscon sio SIOCRTMSG 0x890d 0x890d 0 0 0 0 0 0
|
||||
syscon sio SIOCSARP 0x8955 0x8955 0 0 0 0 0 0
|
||||
syscon sio SIOCSIFBR 0x8941 0x8941 0 0 0 0 0 0
|
||||
syscon sio SIOCSIFENCAP 0x8926 0x8926 0 0 0 0 0 0
|
||||
syscon sio SIOCSIFHWADDR 0x8924 0x8924 0 0 0 0 0 0
|
||||
syscon sio SIOCSIFHWBROADCAST 0x8937 0x8937 0 0 0 0 0 0
|
||||
syscon sio SIOCSIFLINK 0x8911 0x8911 0 0 0 0 0 0
|
||||
syscon sio SIOCSIFMAP 0x8971 0x8971 0 0 0 0 0 0
|
||||
syscon sio SIOCSIFMEM 0x8920 0x8920 0 0 0 0 0 0
|
||||
syscon sio SIOCSIFPFLAGS 0x8934 0x8934 0 0 0 0 0 0
|
||||
syscon sio SIOCSIFSLAVE 0x8930 0x8930 0 0 0 0 0 0
|
||||
syscon sio SIOCSIFTXQLEN 0x8943 0x8943 0 0 0 0 0 0
|
||||
syscon sio SIOCSRARP 0x8962 0x8962 0 0 0 0 0 0
|
||||
syscon sio SIOGIFINDEX 0x8933 0x8933 0 0 0 0 0 0
|
||||
syscon ioctl FIONBIO 0x5421 0x5421 0x8004667e 0x8004667e 0x8004667e 0x8004667e 0x8004667e 0x8004667e # BSD-The New Technology consensus; FIONBIO is traditional O_NONBLOCK; see F_SETFL for re-imagined api
|
||||
syscon ioctl FIOASYNC 0x5452 0x5452 0x8004667d 0x8004667d 0x8004667d 0x8004667d 0x8004667d 0x8004667d # BSD-The New Technology consensus
|
||||
syscon ioctl FIONREAD 0x541b 0x541b 0x4004667f 0x4004667f 0x4004667f 0x4004667f 0x4004667f 0x4004667f # BSD-The New Technology consensus; bytes waiting in FD's input buffer
|
||||
syscon ioctl FIOCLEX 0x5451 0x5451 0x20006601 0x20006601 0x20006601 0x20006601 0x20006601 0x5451 # sets "close on exec" on file descriptor the fast way; faked nt
|
||||
syscon ioctl FIONCLEX 0x5450 0x5450 0x20006602 0x20006602 0x20006602 0x20006602 0x20006602 0x5450 # clears "close on exec" on file descriptor the fast way; faked nt
|
||||
#syscon ioctl FIONWRITE 0x0 0x0 0x0 0x0 0x40046677 0x0 0x0 -1 # [FreeBSD Generalization] bytes queued in FD's output buffer (same as TIOCOUTQ for TTY FDs; see also SO_SNDBUF)
|
||||
#syscon ioctl FIONSPACE 0x0 0x0 0x0 0x0 0x40046676 0x0 0x0 -1 # [FreeBSD Generalization] capacity of FD's output buffer, e.g. equivalent to TIOCGSERIAL w/ UART
|
||||
syscon ioctl SIOCGIFCONF 0x8912 0x8912 0xc00c6924 0xc00c6924 0xc0106924 0xc0106924 0xc0106924 0
|
||||
syscon ioctl SIOCATMARK 0x8905 0x8905 0x40047307 0x40047307 0x40047307 0x40047307 0x40047307 0x40047307 # use sockatmark(); determines if oob is available; bsd consensus
|
||||
syscon ioctl SIOCADDMULTI 0x8931 0x8931 0x80206931 0x80206931 0x80206931 0x80206931 0x80206931 0 # bsd consensus
|
||||
syscon ioctl SIOCDELMULTI 0x8932 0x8932 0x80206932 0x80206932 0x80206932 0x80206932 0x80206932 0 # bsd consensus
|
||||
syscon ioctl SIOCDIFADDR 0x8936 0x8936 0x80206919 0x80206919 0x80206919 0x80206919 0x80206919 0 # bsd consensus
|
||||
syscon ioctl SIOCGIFADDR 0x8915 0x8915 0xc0206921 0xc0206921 0xc0206921 0xc0206921 0xc0206921 0 # bsd consensus
|
||||
syscon ioctl SIOCGIFBRDADDR 0x8919 0x8919 0xc0206923 0xc0206923 0xc0206923 0xc0206923 0xc0206923 0 # bsd consensus
|
||||
syscon ioctl SIOCGIFDSTADDR 0x8917 0x8917 0xc0206922 0xc0206922 0xc0206922 0xc0206922 0xc0206922 0 # bsd consensus
|
||||
syscon ioctl SIOCGIFFLAGS 0x8913 0x8913 0xc0206911 0xc0206911 0xc0206911 0xc0206911 0xc0206911 0 # bsd consensus
|
||||
syscon ioctl SIOCGIFMETRIC 0x891d 0x891d 0xc0206917 0xc0206917 0xc0206917 0xc0206917 0xc0206917 0 # bsd consensus
|
||||
syscon ioctl SIOCGIFNETMASK 0x891b 0x891b 0xc0206925 0xc0206925 0xc0206925 0xc0206925 0xc0206925 0 # bsd consensus
|
||||
syscon ioctl SIOCGPGRP 0x8904 0x8904 0x40047309 0x40047309 0x40047309 0x40047309 0x40047309 0 # bsd consensus
|
||||
syscon ioctl SIOCSIFADDR 0x8916 0x8916 0x8020690c 0x8020690c 0x8020690c 0x8020690c 0x8020690c 0 # bsd consensus
|
||||
syscon ioctl SIOCSIFBRDADDR 0x891a 0x891a 0x80206913 0x80206913 0x80206913 0x80206913 0x80206913 0 # bsd consensus
|
||||
syscon ioctl SIOCSIFDSTADDR 0x8918 0x8918 0x8020690e 0x8020690e 0x8020690e 0x8020690e 0x8020690e 0 # bsd consensus
|
||||
syscon ioctl SIOCSIFFLAGS 0x8914 0x8914 0x80206910 0x80206910 0x80206910 0x80206910 0x80206910 0 # bsd consensus
|
||||
syscon ioctl SIOCSIFMETRIC 0x891e 0x891e 0x80206918 0x80206918 0x80206918 0x80206918 0x80206918 0 # bsd consensus
|
||||
syscon ioctl SIOCSIFNETMASK 0x891c 0x891c 0x80206916 0x80206916 0x80206916 0x80206916 0x80206916 0 # bsd consensus
|
||||
syscon ioctl SIOCSPGRP 0x8902 0x8902 0x80047308 0x80047308 0x80047308 0x80047308 0x80047308 0 # bsd consensus
|
||||
syscon ioctl SIOCGIFMTU 0x8921 0x8921 0xc0206933 0xc0206933 0xc0206933 0xc020697e 0xc020697e 0
|
||||
syscon ioctl SIOCSIFMTU 0x8922 0x8922 0x80206934 0x80206934 0x80206934 0x8020697f 0x8020697f 0
|
||||
|
||||
syscon ioctl SIOCGIFINDEX 0x8933 0x8933 0 0 0xc0206920 0 0 0
|
||||
syscon ioctl SIOCSIFNAME 0x8923 0x8923 0 0 0x80206928 0 0 0
|
||||
syscon ioctl SIOCADDDLCI 0x8980 0x8980 0 0 0 0 0 0
|
||||
syscon ioctl SIOCADDRT 0x890b 0x890b 0 0 0 0 0 0
|
||||
syscon ioctl SIOCDARP 0x8953 0x8953 0 0 0 0 0 0
|
||||
syscon ioctl SIOCDELDLCI 0x8981 0x8981 0 0 0 0 0 0
|
||||
syscon ioctl SIOCDELRT 0x890c 0x890c 0 0 0 0 0 0
|
||||
syscon ioctl SIOCDEVPRIVATE 0x89f0 0x89f0 0 0 0 0 0 0
|
||||
syscon ioctl SIOCDRARP 0x8960 0x8960 0 0 0 0 0 0
|
||||
syscon ioctl SIOCGARP 0x8954 0x8954 0 0 0 0 0 0
|
||||
syscon ioctl SIOCGIFBR 0x8940 0x8940 0 0 0 0 0 0
|
||||
syscon ioctl SIOCGIFCOUNT 0x8938 0x8938 0 0 0 0 0 0
|
||||
syscon ioctl SIOCGIFENCAP 0x8925 0x8925 0 0 0 0 0 0
|
||||
syscon ioctl SIOCGIFHWADDR 0x8927 0x8927 0 0 0 0 0 0
|
||||
syscon ioctl SIOCGIFMAP 0x8970 0x8970 0 0 0 0 0 0
|
||||
syscon ioctl SIOCGIFMEM 0x891f 0x891f 0 0 0 0 0 0
|
||||
syscon ioctl SIOCGIFNAME 0x8910 0x8910 0 0 0 0 0 0
|
||||
syscon ioctl SIOCGIFPFLAGS 0x8935 0x8935 0 0 0 0 0 0
|
||||
syscon ioctl SIOCGIFSLAVE 0x8929 0x8929 0 0 0 0 0 0
|
||||
syscon ioctl SIOCGIFTXQLEN 0x8942 0x8942 0 0 0 0 0 0
|
||||
syscon ioctl SIOCGRARP 0x8961 0x8961 0 0 0 0 0 0
|
||||
syscon ioctl SIOCGSTAMP 0x8906 0x8906 0 0 0 0 0 0
|
||||
syscon ioctl SIOCGSTAMPNS 0x8907 0x8907 0 0 0 0 0 0
|
||||
syscon ioctl SIOCPROTOPRIVATE 0x89e0 0x89e0 0 0 0 0 0 0
|
||||
syscon ioctl SIOCRTMSG 0x890d 0x890d 0 0 0 0 0 0
|
||||
syscon ioctl SIOCSARP 0x8955 0x8955 0 0 0 0 0 0
|
||||
syscon ioctl SIOCSIFBR 0x8941 0x8941 0 0 0 0 0 0
|
||||
syscon ioctl SIOCSIFENCAP 0x8926 0x8926 0 0 0 0 0 0
|
||||
syscon ioctl SIOCSIFHWADDR 0x8924 0x8924 0 0 0 0 0 0
|
||||
syscon ioctl SIOCSIFHWBROADCAST 0x8937 0x8937 0 0 0 0 0 0
|
||||
syscon ioctl SIOCSIFLINK 0x8911 0x8911 0 0 0 0 0 0
|
||||
syscon ioctl SIOCSIFMAP 0x8971 0x8971 0 0 0 0 0 0
|
||||
syscon ioctl SIOCSIFMEM 0x8920 0x8920 0 0 0 0 0 0
|
||||
syscon ioctl SIOCSIFPFLAGS 0x8934 0x8934 0 0 0 0 0 0
|
||||
syscon ioctl SIOCSIFSLAVE 0x8930 0x8930 0 0 0 0 0 0
|
||||
syscon ioctl SIOCSIFTXQLEN 0x8943 0x8943 0 0 0 0 0 0
|
||||
syscon ioctl SIOCSRARP 0x8962 0x8962 0 0 0 0 0 0
|
||||
syscon ioctl SIOGIFINDEX 0x8933 0x8933 0 0 0 0 0 0
|
||||
|
||||
# socket() address families
|
||||
#
|
||||
|
|
|
@ -3,6 +3,11 @@
|
|||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
/*
|
||||
* full set of fcntl() commands
|
||||
* many are only provided by a single platform
|
||||
* will be equal to -1 when not available on host
|
||||
*/
|
||||
extern const int F_BARRIERFSYNC;
|
||||
extern const int F_DUPFD;
|
||||
extern const int F_DUPFD_CLOEXEC;
|
||||
|
@ -42,34 +47,28 @@ extern const int F_WRLCK;
|
|||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
||||
#define F_DUPFD 0
|
||||
#define F_GETFD 1
|
||||
#define F_SETFD 2
|
||||
#define F_GETFL 3
|
||||
#define F_SETFL 4
|
||||
|
||||
/*
|
||||
* portable fcntl() commands
|
||||
*/
|
||||
#define F_DUPFD 0
|
||||
#define F_GETFD 1
|
||||
#define F_SETFD 2
|
||||
#define F_GETFL 3
|
||||
#define F_SETFL 4
|
||||
#define F_DUPFD_CLOEXEC F_DUPFD_CLOEXEC
|
||||
#define F_GETLEASE F_GETLEASE
|
||||
#define F_GETLK F_GETLK
|
||||
#define F_GETLK64 F_GETLK64
|
||||
#define F_GETOWN F_GETOWN
|
||||
#define F_GETPATH F_GETPATH
|
||||
#define F_GETPIPE_SZ F_GETPIPE_SZ
|
||||
#define F_GETSIG F_GETSIG
|
||||
#define F_MAXFD F_MAXFD
|
||||
#define F_NOCACHE F_NOCACHE
|
||||
#define F_NOTIFY F_NOTIFY
|
||||
#define F_RDLCK F_RDLCK
|
||||
#define F_SETLEASE F_SETLEASE
|
||||
#define F_SETLK F_SETLK
|
||||
#define F_SETLK64 F_SETLK64
|
||||
#define F_SETLKW F_SETLKW
|
||||
#define F_SETLKW64 F_SETLKW64
|
||||
#define F_SETOWN F_SETOWN
|
||||
#define F_SETPIPE_SZ F_SETPIPE_SZ
|
||||
#define F_SETSIG F_SETSIG
|
||||
#define F_UNLCK F_UNLCK
|
||||
#define F_WRLCK F_WRLCK
|
||||
|
||||
/*
|
||||
* posix advisory locks
|
||||
* polyfilled poorly on windows
|
||||
*/
|
||||
#define F_SETLK F_SETLK
|
||||
#define F_SETLK64 F_SETLK64
|
||||
#define F_SETLKW F_SETLKW
|
||||
#define F_SETLKW64 F_SETLKW64
|
||||
#define F_GETLK F_GETLK
|
||||
#define F_GETLK64 F_GETLK64
|
||||
#define F_RDLCK F_RDLCK
|
||||
#define F_UNLCK F_UNLCK
|
||||
#define F_WRLCK F_WRLCK
|
||||
|
||||
#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_F_H_ */
|
||||
|
|
|
@ -3,126 +3,88 @@
|
|||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
extern const uint64_t SIOCADDDLCI;
|
||||
extern const uint64_t SIOCADDMULTI;
|
||||
extern const uint64_t SIOCADDRT;
|
||||
extern const uint64_t SIOCATMARK;
|
||||
extern const uint64_t SIOCDARP;
|
||||
extern const uint64_t SIOCDELDLCI;
|
||||
extern const uint64_t SIOCDELMULTI;
|
||||
extern const uint64_t SIOCDELRT;
|
||||
extern const uint64_t SIOCDEVPRIVATE;
|
||||
extern const uint64_t SIOCDIFADDR;
|
||||
extern const uint64_t SIOCDRARP;
|
||||
extern const uint64_t SIOCGARP;
|
||||
extern const uint64_t SIOCGIFADDR;
|
||||
extern const uint64_t SIOCGIFBR;
|
||||
extern const uint64_t SIOCGIFBRDADDR;
|
||||
extern const uint64_t SIOCGIFCONF;
|
||||
extern const uint64_t SIOCGIFCOUNT;
|
||||
extern const uint64_t SIOCGIFDSTADDR;
|
||||
extern const uint64_t SIOCGIFENCAP;
|
||||
extern const uint64_t SIOCGIFFLAGS;
|
||||
extern const uint64_t SIOCGIFHWADDR;
|
||||
extern const uint64_t SIOCGIFINDEX;
|
||||
extern const uint64_t SIOCGIFMAP;
|
||||
extern const uint64_t SIOCGIFMEM;
|
||||
extern const uint64_t SIOCGIFMETRIC;
|
||||
extern const uint64_t SIOCGIFMTU;
|
||||
extern const uint64_t SIOCGIFNAME;
|
||||
extern const uint64_t SIOCGIFNETMASK;
|
||||
extern const uint64_t SIOCGIFPFLAGS;
|
||||
extern const uint64_t SIOCGIFSLAVE;
|
||||
extern const uint64_t SIOCGIFTXQLEN;
|
||||
extern const uint64_t SIOCGPGRP;
|
||||
extern const uint64_t SIOCGRARP;
|
||||
extern const uint64_t SIOCGSTAMP;
|
||||
extern const uint64_t SIOCGSTAMPNS;
|
||||
extern const uint64_t SIOCPROTOPRIVATE;
|
||||
extern const uint64_t SIOCRTMSG;
|
||||
extern const uint64_t SIOCSARP;
|
||||
extern const uint64_t SIOCSIFADDR;
|
||||
extern const uint64_t SIOCSIFBR;
|
||||
extern const uint64_t SIOCSIFBRDADDR;
|
||||
extern const uint64_t SIOCSIFDSTADDR;
|
||||
extern const uint64_t SIOCSIFENCAP;
|
||||
extern const uint64_t SIOCSIFFLAGS;
|
||||
extern const uint64_t SIOCSIFHWADDR;
|
||||
extern const uint64_t SIOCSIFHWBROADCAST;
|
||||
extern const uint64_t SIOCSIFLINK;
|
||||
extern const uint64_t SIOCSIFMAP;
|
||||
extern const uint64_t SIOCSIFMEM;
|
||||
extern const uint64_t SIOCSIFMETRIC;
|
||||
extern const uint64_t SIOCSIFMTU;
|
||||
extern const uint64_t SIOCSIFNAME;
|
||||
extern const uint64_t SIOCSIFNETMASK;
|
||||
extern const uint64_t SIOCSIFPFLAGS;
|
||||
extern const uint64_t SIOCSIFSLAVE;
|
||||
extern const uint64_t SIOCSIFTXQLEN;
|
||||
extern const uint64_t SIOCSPGRP;
|
||||
extern const uint64_t SIOCSRARP;
|
||||
extern const uint64_t SIOGIFINDEX;
|
||||
extern const unsigned long SIOCADDDLCI;
|
||||
extern const unsigned long SIOCADDMULTI;
|
||||
extern const unsigned long SIOCADDRT;
|
||||
extern const unsigned long SIOCATMARK; /* use sockatmark() */
|
||||
extern const unsigned long SIOCDARP;
|
||||
extern const unsigned long SIOCDELDLCI;
|
||||
extern const unsigned long SIOCDELMULTI;
|
||||
extern const unsigned long SIOCDELRT;
|
||||
extern const unsigned long SIOCDEVPRIVATE;
|
||||
extern const unsigned long SIOCDIFADDR;
|
||||
extern const unsigned long SIOCDRARP;
|
||||
extern const unsigned long SIOCGARP;
|
||||
extern const unsigned long SIOCGIFADDR;
|
||||
extern const unsigned long SIOCGIFBR;
|
||||
extern const unsigned long SIOCGIFBRDADDR;
|
||||
extern const unsigned long SIOCGIFCONF;
|
||||
extern const unsigned long SIOCGIFCOUNT;
|
||||
extern const unsigned long SIOCGIFDSTADDR;
|
||||
extern const unsigned long SIOCGIFENCAP;
|
||||
extern const unsigned long SIOCGIFFLAGS;
|
||||
extern const unsigned long SIOCGIFHWADDR;
|
||||
extern const unsigned long SIOCGIFINDEX;
|
||||
extern const unsigned long SIOCGIFMAP;
|
||||
extern const unsigned long SIOCGIFMEM;
|
||||
extern const unsigned long SIOCGIFMETRIC;
|
||||
extern const unsigned long SIOCGIFMTU;
|
||||
extern const unsigned long SIOCGIFNAME;
|
||||
extern const unsigned long SIOCGIFNETMASK;
|
||||
extern const unsigned long SIOCGIFPFLAGS;
|
||||
extern const unsigned long SIOCGIFSLAVE;
|
||||
extern const unsigned long SIOCGIFTXQLEN;
|
||||
extern const unsigned long SIOCGPGRP;
|
||||
extern const unsigned long SIOCGRARP;
|
||||
extern const unsigned long SIOCGSTAMP;
|
||||
extern const unsigned long SIOCGSTAMPNS;
|
||||
extern const unsigned long SIOCPROTOPRIVATE;
|
||||
extern const unsigned long SIOCRTMSG;
|
||||
extern const unsigned long SIOCSARP;
|
||||
extern const unsigned long SIOCSIFADDR;
|
||||
extern const unsigned long SIOCSIFBR;
|
||||
extern const unsigned long SIOCSIFBRDADDR;
|
||||
extern const unsigned long SIOCSIFDSTADDR;
|
||||
extern const unsigned long SIOCSIFENCAP;
|
||||
extern const unsigned long SIOCSIFFLAGS;
|
||||
extern const unsigned long SIOCSIFHWADDR;
|
||||
extern const unsigned long SIOCSIFHWBROADCAST;
|
||||
extern const unsigned long SIOCSIFLINK;
|
||||
extern const unsigned long SIOCSIFMAP;
|
||||
extern const unsigned long SIOCSIFMEM;
|
||||
extern const unsigned long SIOCSIFMETRIC;
|
||||
extern const unsigned long SIOCSIFMTU;
|
||||
extern const unsigned long SIOCSIFNAME;
|
||||
extern const unsigned long SIOCSIFNETMASK;
|
||||
extern const unsigned long SIOCSIFPFLAGS;
|
||||
extern const unsigned long SIOCSIFSLAVE;
|
||||
extern const unsigned long SIOCSIFTXQLEN;
|
||||
extern const unsigned long SIOCSPGRP;
|
||||
extern const unsigned long SIOCSRARP;
|
||||
extern const unsigned long SIOGIFINDEX;
|
||||
|
||||
#define SIOCADDDLCI SIOCADDDLCI
|
||||
#define SIOCADDMULTI SIOCADDMULTI
|
||||
#define SIOCADDRT SIOCADDRT
|
||||
#define SIOCATMARK SIOCATMARK
|
||||
#define SIOCDARP SIOCDARP
|
||||
#define SIOCDELDLCI SIOCDELDLCI
|
||||
#define SIOCDELMULTI SIOCDELMULTI
|
||||
#define SIOCDELRT SIOCDELRT
|
||||
#define SIOCDEVPRIVATE SIOCDEVPRIVATE
|
||||
#define SIOCDIFADDR SIOCDIFADDR
|
||||
#define SIOCDRARP SIOCDRARP
|
||||
#define SIOCGARP SIOCGARP
|
||||
#define SIOCGIFADDR SIOCGIFADDR
|
||||
#define SIOCGIFBR SIOCGIFBR
|
||||
#define SIOCGIFBRDADDR SIOCGIFBRDADDR
|
||||
#define SIOCGIFCONF SIOCGIFCONF
|
||||
#define SIOCGIFCOUNT SIOCGIFCOUNT
|
||||
#define SIOCGIFDSTADDR SIOCGIFDSTADDR
|
||||
#define SIOCGIFENCAP SIOCGIFENCAP
|
||||
#define SIOCGIFFLAGS SIOCGIFFLAGS
|
||||
#define SIOCGIFHWADDR SIOCGIFHWADDR
|
||||
#define SIOCGIFINDEX SIOCGIFINDEX
|
||||
#define SIOCGIFMAP SIOCGIFMAP
|
||||
#define SIOCGIFMEM SIOCGIFMEM
|
||||
#define SIOCGIFMETRIC SIOCGIFMETRIC
|
||||
#define SIOCGIFMTU SIOCGIFMTU
|
||||
#define SIOCGIFNAME SIOCGIFNAME
|
||||
#define SIOCGIFNETMASK SIOCGIFNETMASK
|
||||
#define SIOCGIFPFLAGS SIOCGIFPFLAGS
|
||||
#define SIOCGIFSLAVE SIOCGIFSLAVE
|
||||
#define SIOCGIFTXQLEN SIOCGIFTXQLEN
|
||||
#define SIOCGPGRP SIOCGPGRP
|
||||
#define SIOCGRARP SIOCGRARP
|
||||
#define SIOCGSTAMP SIOCGSTAMP
|
||||
#define SIOCGSTAMPNS SIOCGSTAMPNS
|
||||
#define SIOCPROTOPRIVATE SIOCPROTOPRIVATE
|
||||
#define SIOCRTMSG SIOCRTMSG
|
||||
#define SIOCSARP SIOCSARP
|
||||
#define SIOCSIFADDR SIOCSIFADDR
|
||||
#define SIOCSIFBR SIOCSIFBR
|
||||
#define SIOCSIFBRDADDR SIOCSIFBRDADDR
|
||||
#define SIOCSIFDSTADDR SIOCSIFDSTADDR
|
||||
#define SIOCSIFENCAP SIOCSIFENCAP
|
||||
#define SIOCSIFFLAGS SIOCSIFFLAGS
|
||||
#define SIOCSIFHWADDR SIOCSIFHWADDR
|
||||
#define SIOCSIFHWBROADCAST SIOCSIFHWBROADCAST
|
||||
#define SIOCSIFLINK SIOCSIFLINK
|
||||
#define SIOCSIFMAP SIOCSIFMAP
|
||||
#define SIOCSIFMEM SIOCSIFMEM
|
||||
#define SIOCSIFMETRIC SIOCSIFMETRIC
|
||||
#define SIOCSIFMTU SIOCSIFMTU
|
||||
#define SIOCSIFNAME SIOCSIFNAME
|
||||
#define SIOCSIFNETMASK SIOCSIFNETMASK
|
||||
#define SIOCSIFPFLAGS SIOCSIFPFLAGS
|
||||
#define SIOCSIFSLAVE SIOCSIFSLAVE
|
||||
#define SIOCSIFTXQLEN SIOCSIFTXQLEN
|
||||
#define SIOCSPGRP SIOCSPGRP
|
||||
#define SIOCSRARP SIOCSRARP
|
||||
#define SIOGIFINDEX SIOGIFINDEX
|
||||
#define SIOCGIFCONF SIOCGIFCONF
|
||||
#define SIOCGIFADDR SIOCGIFADDR
|
||||
#define SIOCSIFADDR SIOCSIFADDR
|
||||
#define SIOCDIFADDR SIOCDIFADDR
|
||||
#define SIOCGIFBRDADDR SIOCGIFBRDADDR
|
||||
#define SIOCGIFNETMASK SIOCGIFNETMASK
|
||||
#define SIOCGIFFLAGS SIOCGIFFLAGS
|
||||
#define SIOCSIFFLAGS SIOCSIFFLAGS
|
||||
#define SIOCGIFMETRIC SIOCGIFMETRIC
|
||||
#define SIOCSIFMETRIC SIOCSIFMETRIC
|
||||
#define SIOCSIFBRDADDR SIOCSIFBRDADDR
|
||||
#define SIOCSIFNETMASK SIOCSIFNETMASK
|
||||
#define SIOCGIFDSTADDR SIOCGIFDSTADDR
|
||||
#define SIOCSIFDSTADDR SIOCSIFDSTADDR
|
||||
#define SIOCGIFMTU SIOCGIFMTU
|
||||
#define SIOCSIFMTU SIOCSIFMTU
|
||||
|
||||
#define SIOCGPGRP SIOCGPGRP
|
||||
#define SIOCSPGRP SIOCSPGRP
|
||||
|
||||
#define SIOCADDMULTI SIOCADDMULTI
|
||||
#define SIOCDELMULTI SIOCDELMULTI
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -155,73 +155,74 @@ extern const uint32_t CRTSCTS;
|
|||
#define FF1 FF1
|
||||
#define FF2 FF2
|
||||
|
||||
#define CLOCAL CLOCAL
|
||||
#define CREAD CREAD
|
||||
#define CS5 CS5
|
||||
#define CS6 CS6
|
||||
#define CS7 CS7
|
||||
#define CS8 CS8
|
||||
#define CSIZE CSIZE
|
||||
#define CSTOPB CSTOPB
|
||||
#define ECHO 8
|
||||
#define ECHOCTL ECHOCTL
|
||||
#define ECHOE ECHOE
|
||||
#define ECHOK ECHOK
|
||||
#define ECHOKE ECHOKE
|
||||
#define ECHONL ECHONL
|
||||
#define ECHOPRT ECHOPRT
|
||||
#define EXTPROC EXTPROC
|
||||
#define FLUSHO FLUSHO
|
||||
#define HUPCL HUPCL
|
||||
#define ICANON ICANON
|
||||
#define IEXTEN IEXTEN
|
||||
#define ISIG ISIG
|
||||
#define IUCLC IUCLC
|
||||
#define IUTF8 IUTF8
|
||||
#define IXOFF IXOFF
|
||||
#define IXON IXON
|
||||
#define NOFLSH NOFLSH
|
||||
#define OCRNL OCRNL
|
||||
#define OFDEL OFDEL
|
||||
#define OFILL OFILL
|
||||
#define OLCUC OLCUC
|
||||
#define ONLCR ONLCR
|
||||
#define ONLRET ONLRET
|
||||
#define ONOCR ONOCR
|
||||
#define PARENB PARENB
|
||||
#define PARODD PARODD
|
||||
#define PENDIN PENDIN
|
||||
#define TIOCCONS TIOCCONS
|
||||
#define TIOCGETD TIOCGETD
|
||||
#define TIOCGWINSZ TIOCGWINSZ
|
||||
#define TIOCNOTTY TIOCNOTTY
|
||||
#define TIOCNXCL TIOCNXCL
|
||||
#define TIOCOUTQ TIOCOUTQ
|
||||
#define TIOCSCTTY TIOCSCTTY
|
||||
#define TIOCSETD TIOCSETD
|
||||
#define TIOCSIG TIOCSIG
|
||||
#define TIOCSPGRP TIOCSPGRP
|
||||
#define TIOCSTI TIOCSTI
|
||||
#define TIOCSWINSZ TIOCSWINSZ
|
||||
#define TOSTOP TOSTOP
|
||||
#define VDISCARD VDISCARD
|
||||
#define VEOF VEOF
|
||||
#define VEOL VEOL
|
||||
#define VEOL2 VEOL2
|
||||
#define VERASE VERASE
|
||||
#define VINTR VINTR
|
||||
#define VKILL VKILL
|
||||
#define VLNEXT VLNEXT
|
||||
#define VMIN VMIN
|
||||
#define VQUIT VQUIT
|
||||
#define VREPRINT VREPRINT
|
||||
#define VSTART VSTART
|
||||
#define VSTOP VSTOP
|
||||
#define VSUSP VSUSP
|
||||
#define VSWTC VSWTC
|
||||
#define VTIME VTIME
|
||||
#define VWERASE VWERASE
|
||||
#define XCASE XCASE
|
||||
#define CLOCAL CLOCAL
|
||||
#define CREAD CREAD
|
||||
#define CS5 CS5
|
||||
#define CS6 CS6
|
||||
#define CS7 CS7
|
||||
#define CS8 CS8
|
||||
#define CSIZE CSIZE
|
||||
#define CSTOPB CSTOPB
|
||||
#define ECHO 8
|
||||
#define ECHOCTL ECHOCTL
|
||||
#define ECHOE ECHOE
|
||||
#define ECHOK ECHOK
|
||||
#define ECHOKE ECHOKE
|
||||
#define ECHONL ECHONL
|
||||
#define ECHOPRT ECHOPRT
|
||||
#define EXTPROC EXTPROC
|
||||
#define FLUSHO FLUSHO
|
||||
#define HUPCL HUPCL
|
||||
#define ICANON ICANON
|
||||
#define IEXTEN IEXTEN
|
||||
#define ISIG ISIG
|
||||
#define IUCLC IUCLC
|
||||
#define IUTF8 IUTF8
|
||||
#define IXOFF IXOFF
|
||||
#define IXON IXON
|
||||
#define NOFLSH NOFLSH
|
||||
#define OCRNL OCRNL
|
||||
#define OFDEL OFDEL
|
||||
#define OFILL OFILL
|
||||
#define OLCUC OLCUC
|
||||
#define ONLCR ONLCR
|
||||
#define ONLRET ONLRET
|
||||
#define ONOCR ONOCR
|
||||
#define PARENB PARENB
|
||||
#define PARODD PARODD
|
||||
#define PENDIN PENDIN
|
||||
#define TOSTOP TOSTOP
|
||||
#define VDISCARD VDISCARD
|
||||
#define VEOF VEOF
|
||||
#define VEOL VEOL
|
||||
#define VEOL2 VEOL2
|
||||
#define VERASE VERASE
|
||||
#define VINTR VINTR
|
||||
#define VKILL VKILL
|
||||
#define VLNEXT VLNEXT
|
||||
#define VMIN VMIN
|
||||
#define VQUIT VQUIT
|
||||
#define VREPRINT VREPRINT
|
||||
#define VSTART VSTART
|
||||
#define VSTOP VSTOP
|
||||
#define VSUSP VSUSP
|
||||
#define VSWTC VSWTC
|
||||
#define VTIME VTIME
|
||||
#define VWERASE VWERASE
|
||||
#define XCASE XCASE
|
||||
|
||||
/* terminal ioctls */
|
||||
#define TIOCGWINSZ TIOCGWINSZ /* get tty dimensions */
|
||||
#define TIOCSWINSZ TIOCSWINSZ /* set tty dimensions */
|
||||
#define TIOCCONS TIOCCONS /* redirect terminal */
|
||||
#define TIOCGETD TIOCGETD /* get line discipline */
|
||||
#define TIOCSETD TIOCSETD /* set line discipline */
|
||||
#define TIOCNOTTY TIOCNOTTY /* give up terminal */
|
||||
#define TIOCNXCL TIOCNXCL /* disable exclusive mode */
|
||||
#define TIOCOUTQ TIOCOUTQ /* bytes in output buffer */
|
||||
#define TIOCSCTTY TIOCSCTTY /* make controlling terminal */
|
||||
#define TIOCSIG TIOCSIG /* generate pty signal */
|
||||
#define TIOCSTI TIOCSTI /* insert fake tty input */
|
||||
|
||||
/* tcsetattr() */
|
||||
#define TCSANOW 0
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue