Exemplo n.º 1
0
extern "C" intptr_t SystemNative_MksTemps(char* pathTemplate, int32_t suffixLength)
{
    intptr_t result;
#if HAVE_MKSTEMPS
    while (CheckInterrupted(result = mkstemps(pathTemplate, suffixLength)));
#elif HAVE_MKSTEMP
    // mkstemps is not available bionic/Android, but mkstemp is
    // mkstemp doesn't allow the suffix that msktemps does allow, so we'll need to
    // remove that before passing pathTemplate to mkstemp

    int32_t pathTemplateLength = static_cast<int32_t>(strlen(pathTemplate));

    // pathTemplate must include at least XXXXXX (6 characters) which are not part of
    // the suffix
    if (suffixLength < 0 || suffixLength > pathTemplateLength - 6)
    {
        errno = EINVAL;
        return -1;
    }

    // Make mkstemp ignore the suffix by setting the first char of the suffix to \0,
    // if there is a suffix
    int32_t firstSuffixIndex = 0;
    char firstSuffixChar = 0;

    if (suffixLength > 0)
    {
        firstSuffixIndex = pathTemplateLength - suffixLength;
        firstSuffixChar = pathTemplate[firstSuffixIndex];
        pathTemplate[firstSuffixIndex] = 0;
    }

    while (CheckInterrupted(result = mkstemp(pathTemplate)));

    // Reset the first char of the suffix back to its original value, if there is a suffix
    if (suffixLength > 0)
    {
        pathTemplate[firstSuffixIndex] = firstSuffixChar;
    }
#else
#error "Cannot find mkstemps nor mkstemp on this platform"
#endif
    return  result;
}
Exemplo n.º 2
0
extern "C" int32_t SystemNative_Pipe(int32_t pipeFds[2], int32_t flags)
{
    switch (flags)
    {
        case 0:
            break;
        case PAL_O_CLOEXEC:
            flags = O_CLOEXEC;
            break;
        default:
            assert(false && "Unknown flag.");
            errno = EINVAL;
            return -1;
    }

    int32_t result;
#if HAVE_PIPE2
    // If pipe2 is available, use it.  This will handle O_CLOEXEC if it was set.
    while (CheckInterrupted(result = pipe2(pipeFds, flags)));
#else
    // Otherwise, use pipe.
    while (CheckInterrupted(result = pipe(pipeFds)));

    // Then, if O_CLOEXEC was specified, use fcntl to configure the file descriptors appropriately.
    if ((flags & O_CLOEXEC) != 0 && result == 0)
    {
        while (CheckInterrupted(result = fcntl(pipeFds[0], F_SETFD, FD_CLOEXEC)));
        if (result == 0)
        {
            while (CheckInterrupted(result = fcntl(pipeFds[1], F_SETFD, FD_CLOEXEC)));
        }

        if (result != 0)
        {
            int tmpErrno = errno;
            close(pipeFds[0]);
            close(pipeFds[1]);
            errno = tmpErrno;
        }
    }
#endif
    return result;
}
Exemplo n.º 3
0
extern "C" void SystemNative_ReadEvents(int32_t sock, NetworkChangeEvent onNetworkChange)
{
    char buffer[4096];
    iovec iov = {buffer, sizeof(buffer)};
    sockaddr_nl sanl;
    msghdr msg = { .msg_name = reinterpret_cast<void*>(&sanl), .msg_namelen = sizeof(sockaddr_nl), .msg_iov = &iov, .msg_iovlen = 1 };
    ssize_t len;
    while (CheckInterrupted(len = recvmsg(sock, &msg, 0)));
    if (len == -1)
    {
        // Probably means the socket has been closed.
        return;
    }

    for (nlmsghdr* hdr = reinterpret_cast<nlmsghdr*>(buffer); NLMSG_OK(hdr, UnsignedCast(len)); NLMSG_NEXT(hdr, len))
    {
        switch (hdr->nlmsg_type)
        {
            case NLMSG_DONE:
                return; // End of a multi-part message; stop reading.
            case NLMSG_ERROR:
                return;
            case RTM_NEWADDR:
                onNetworkChange(sock, NetworkChangeKind::AddressAdded);
                break;
            case RTM_DELADDR:
                onNetworkChange(sock, NetworkChangeKind::AddressRemoved);
                break;
            case RTM_NEWLINK:
                onNetworkChange(sock, ReadNewLinkMessage(hdr));
                break;
            case RTM_DELLINK:
                onNetworkChange(sock, NetworkChangeKind::LinkRemoved);
                break;
            default:
                break;
        }
    }
}

NetworkChangeKind ReadNewLinkMessage(nlmsghdr* hdr)
{
    assert(hdr != nullptr);
    ifinfomsg* ifimsg;
    ifimsg = reinterpret_cast<ifinfomsg*>(NLMSG_DATA(hdr));
    if (ifimsg->ifi_family == AF_INET)
    {
        if ((ifimsg->ifi_flags & IFF_UP) != 0)
        {
            return NetworkChangeKind::LinkAdded;
        }
    }

    return NetworkChangeKind::None;
}
Exemplo n.º 4
0
static void WriteKeypadXmit()
{
    // If a terminfo "application mode" keypad_xmit string has been supplied,
    // write it out to the terminal to enter the mode.
    if (g_keypadXmit != NULL)
    {
        ssize_t ret;
        while (CheckInterrupted(ret = write(STDOUT_FILENO, g_keypadXmit, (size_t)(sizeof(char) * strlen(g_keypadXmit)))));
        assert(ret >= 0); // failure to change the mode should not prevent app from continuing
    }
}
Exemplo n.º 5
0
extern "C" int32_t SystemNative_UTime(const char* path, UTimBuf* times)
{
    assert(times != nullptr);

    utimbuf temp;
    ConvertUTimBuf(*times, temp);

    int32_t result;
    while (CheckInterrupted(result = utime(path, &temp)));
    return result;
}
Exemplo n.º 6
0
extern "C" NetworkChangeKind SystemNative_ReadSingleEvent(int32_t sock)
{
    char buffer[4096];
    iovec iov = {buffer, sizeof(buffer)};
    sockaddr_nl sanl;
    msghdr msg = { .msg_name = reinterpret_cast<void*>(&sanl), .msg_namelen = sizeof(sockaddr_nl), .msg_iov = &iov, .msg_iovlen = 1 };
    ssize_t len;
    while (CheckInterrupted(len = recvmsg(sock, &msg, 0)));
    if (len == -1)
    {
        // Probably means the socket has been closed.
        // If so, the managed side will ignore the return value.
        return NetworkChangeKind::None;
    }

    nlmsghdr* hdr = reinterpret_cast<nlmsghdr*>(buffer);
    // This channel should only send a single message at a time.
    // This means there should be no multi-part messages (NLM_F_MULTI).
    assert((hdr->nlmsg_flags & NLM_F_MULTI) == 0);
    switch (hdr->nlmsg_type)
    {
        case NLMSG_DONE:
            return NetworkChangeKind::None;
        case NLMSG_ERROR:
            return NetworkChangeKind::None;
        case RTM_NEWADDR:
            return NetworkChangeKind::AddressAdded;
        case RTM_DELADDR:
            return NetworkChangeKind::AddressRemoved;
        case RTM_NEWLINK:
            return ReadNewLinkMessage(hdr);
        case RTM_DELLINK:
            return NetworkChangeKind::LinkRemoved;
        default:
            return NetworkChangeKind::None;
    }
}

NetworkChangeKind ReadNewLinkMessage(nlmsghdr* hdr)
{
    assert(hdr != nullptr);
    ifinfomsg* ifimsg;
    ifimsg = reinterpret_cast<ifinfomsg*>(NLMSG_DATA(hdr));
    if (ifimsg->ifi_family == AF_INET)
    {
        if ((ifimsg->ifi_flags & IFF_UP) != 0)
        {
            return NetworkChangeKind::LinkAdded;
        }
    }

    return NetworkChangeKind::None;
}
Exemplo n.º 7
0
extern "C" int32_t SystemNative_FcntlSetPipeSz(intptr_t fd, int32_t size)
{
#ifdef F_SETPIPE_SZ
    int32_t result;
    while (CheckInterrupted(result = fcntl(ToFileDescriptor(fd), F_SETPIPE_SZ, size)));
    return result;
#else
    (void)fd, (void)size;
    errno = ENOTSUP;
    return -1;
#endif
}
Exemplo n.º 8
0
extern "C" int32_t SystemNative_FStat(intptr_t fd, FileStatus* output)
{
    struct stat_ result;
    int ret;
    while (CheckInterrupted(ret = fstat_(ToFileDescriptor(fd), &result)));

    if (ret == 0)
    {
        ConvertFileStatus(result, output);
    }

    return ret;
}
Exemplo n.º 9
0
extern "C" int32_t SystemNative_ShmUnlink(const char* name)
{
#if HAVE_SHM_OPEN_THAT_WORKS_WELL_ENOUGH_WITH_MMAP
    int32_t result;
    while (CheckInterrupted(result = shm_unlink(name)));
    return result;
#else
    // Not supported on e.g. Android. Also, prevent a compiler error because name is unused
    (void)name;
    errno = ENOTSUP;
    return -1;
#endif
}
Exemplo n.º 10
0
extern "C" int32_t SystemNative_Stat(const char* path, FileStatus* output)
{
    struct stat_ result;
    int ret;
    while (CheckInterrupted(ret = stat_(path, &result)));

    if (ret == 0)
    {
        ConvertFileStatus(result, output);
    }

    return ret;
}
Exemplo n.º 11
0
extern "C" intptr_t SystemNative_Open(const char* path, int32_t flags, int32_t mode)
{
    flags = ConvertOpenFlags(flags);
    if (flags == -1)
    {
        errno = EINVAL;
        return -1;
    }

    int result;
    while (CheckInterrupted(result = open(path, flags, static_cast<mode_t>(mode))));
    return result;
}
Exemplo n.º 12
0
int32_t SystemNative_UTimensat(const char* path, TimeSpec* times)
{
    int32_t result;
#if HAVE_UTIMENSAT
    struct timespec updatedTimes[2];
    updatedTimes[0].tv_sec = (time_t)times[0].tv_sec;
    updatedTimes[0].tv_nsec = (long)times[0].tv_nsec;

    updatedTimes[1].tv_sec = (time_t)times[1].tv_sec;
    updatedTimes[1].tv_nsec = (long)times[1].tv_nsec;    
    while (CheckInterrupted(result = utimensat(AT_FDCWD, path, updatedTimes, 0)));
#else
    struct timeval updatedTimes[2];
    updatedTimes[0].tv_sec = (long)times[0].tv_sec;
    updatedTimes[0].tv_usec = (int)times[0].tv_nsec / 1000;
    
    updatedTimes[1].tv_sec = (long)times[1].tv_sec;
    updatedTimes[1].tv_usec = (int)times[1].tv_nsec / 1000;
    while (CheckInterrupted(result = utimes(path, updatedTimes)));
#endif

    return result;
}
Exemplo n.º 13
0
extern "C" int32_t SystemNative_FTruncate(intptr_t fd, int64_t length)
{
    int32_t result;
    while (CheckInterrupted(
        result =
#if HAVE_FTRUNCATE64
        ftruncate64(
#else
        ftruncate(
#endif
            ToFileDescriptor(fd),
            length)));
    return result;
}
Exemplo n.º 14
0
extern "C" int32_t SystemNative_Pipe(int32_t pipeFds[2], int32_t flags)
{
    switch (flags)
    {
        case 0:
            break;
        case PAL_O_CLOEXEC:
            flags = O_CLOEXEC;
            break;
        default:
            assert(false && "Unknown flag.");
            errno = EINVAL;
            return -1;
    }

    int32_t result;
#if HAVE_PIPE2
    while (CheckInterrupted(result = pipe2(pipeFds, flags)));
#else
    while (CheckInterrupted(result = pipe(pipeFds)));         // CLOEXEC intentionally ignored on platforms without pipe2.
#endif
    return result;
}
Exemplo n.º 15
0
extern "C" int64_t SystemNative_LSeek(intptr_t fd, int64_t offset, SeekWhence whence)
{
    int64_t result;
    while (CheckInterrupted(
        result =
#if HAVE_LSEEK64
            lseek64(
#else
            lseek(
#endif
                 ToFileDescriptor(fd),
                 offset,
                 whence)));
    return result;
}
Exemplo n.º 16
0
int32_t SystemNative_ReadStdin(void* buffer, int32_t bufferSize)
{
    assert(buffer != NULL || bufferSize == 0);
    assert(bufferSize >= 0);

     if (bufferSize < 0)
    {
        errno = EINVAL;
        return -1;
    }

    ssize_t count;
    while (CheckInterrupted(count = read(STDIN_FILENO, buffer, Int32ToSizeT(bufferSize))));
    return (int32_t)count;
}
Exemplo n.º 17
0
extern "C" int32_t SystemNative_ReadStdinUnbuffered(void* buffer, int32_t bufferSize)
{
    assert(buffer != nullptr || bufferSize == 0);
    assert(bufferSize >= 0);

    if (bufferSize < 0)
    {
        errno = EINVAL;
        return -1;
    }

    ssize_t count;
    while (CheckInterrupted(count = read(STDIN_FILENO, buffer, UnsignedCast(bufferSize))));
    return static_cast<int32_t>(count);
}
Exemplo n.º 18
0
extern "C" int32_t SystemNative_Write(intptr_t fd, const void* buffer, int32_t bufferSize)
{
    assert(buffer != nullptr || bufferSize == 0);
    assert(bufferSize >= 0);

    if (bufferSize < 0)
    {
        errno = ERANGE;
        return -1;
    }

    ssize_t count;
    while (CheckInterrupted(count = write(ToFileDescriptor(fd), buffer, UnsignedCast(bufferSize))));

    assert(count >= -1 && count <= bufferSize);
    return static_cast<int32_t>(count);
}
Exemplo n.º 19
0
extern "C" int32_t SystemNative_LockFileRegion(intptr_t fd, int64_t offset, int64_t length, int16_t lockType)
{
    if (offset < 0 || length < 0) 
    {
        errno = EINVAL;
        return -1;
    }

#if HAVE_FLOCK64
    struct flock64 lockArgs;
#else
    struct flock lockArgs;
#endif

    lockArgs.l_type = lockType;
    lockArgs.l_whence = SEEK_SET;
    lockArgs.l_start = offset;
    lockArgs.l_len = length;

    int32_t ret;
    while (CheckInterrupted(ret = fcntl (ToFileDescriptor(fd), F_SETLK, &lockArgs)));
    return ret;
}
Exemplo n.º 20
0
extern "C" int32_t SystemNative_RmDir(const char* path)
{
    int32_t result;
    while (CheckInterrupted(result = rmdir(path)));
    return result;
}
Exemplo n.º 21
0
extern "C" int32_t SystemNative_Rename(const char* oldPath, const char* newPath)
{
    int32_t result;
    while (CheckInterrupted(result = rename(oldPath, newPath)));
    return result;
}
Exemplo n.º 22
0
extern "C" Error SystemNative_Poll(PollEvent* pollEvents, uint32_t eventCount, int32_t milliseconds, uint32_t* triggered)
{
    if (pollEvents == nullptr || triggered == nullptr)
    {
        return PAL_EFAULT;
    }

    if (milliseconds < -1)
    {
        return PAL_EINVAL;
    }

    size_t bufferSize = sizeof(pollfd) * static_cast<size_t>(eventCount);
    bool useStackBuffer = bufferSize <= 2048;
    pollfd* pollfds = reinterpret_cast<pollfd*>(useStackBuffer ? alloca(bufferSize) : malloc(bufferSize));

    for (uint32_t i = 0; i < eventCount; i++)
    {
        const PollEvent& event = pollEvents[i];
        pollfds[i] = { .fd = event.FileDescriptor, .events = event.Events, .revents = 0 };
    }

    int rv;
    while (CheckInterrupted(rv = poll(pollfds, static_cast<nfds_t>(eventCount), milliseconds)));

    if (rv < 0)
    {
        if (!useStackBuffer)
        {
            free(pollfds);
        }

        *triggered = 0;
        return SystemNative_ConvertErrorPlatformToPal(errno);
    }

    for (uint32_t i = 0; i < eventCount; i++)
    {
        const pollfd& pfd = pollfds[i];
        assert(pfd.fd == pollEvents[i].FileDescriptor);
        assert(pfd.events == pollEvents[i].Events);

        pollEvents[i].TriggeredEvents = static_cast<PollEvents>(pfd.revents);
    }

    *triggered = static_cast<uint32_t>(rv);

    if (!useStackBuffer)
    {
        free(pollfds);
    }

    return PAL_SUCCESS;
}

extern "C" int32_t SystemNative_PosixFAdvise(intptr_t fd, int64_t offset, int64_t length, FileAdvice advice)
{
#if HAVE_POSIX_ADVISE
    int32_t result;
    while (CheckInterrupted(result = posix_fadvise(ToFileDescriptor(fd), offset, length, advice)));
    return result;
#else
    // Not supported on this platform. Caller can ignore this failure since it's just a hint.
    (void)fd, (void)offset, (void)length, (void)advice;
    return ENOTSUP;
#endif
}
Exemplo n.º 23
0
extern "C" int32_t SystemNative_FTruncate(intptr_t fd, int64_t length)
{
    int32_t result;
    while (CheckInterrupted(result = ftruncate(ToFileDescriptor(fd), length)));
    return result;
}
Exemplo n.º 24
0
extern "C" intptr_t SystemNative_MksTemps(char* pathTemplate, int32_t suffixLength)
{
    intptr_t result;
    while (CheckInterrupted(result = mkstemps(pathTemplate, suffixLength)));
    return  result;
}
Exemplo n.º 25
0
extern "C" int32_t SystemNative_Link(const char* source, const char* linkTarget)
{
    int32_t result;
    while (CheckInterrupted(result = link(source, linkTarget)));
    return result;
}
Exemplo n.º 26
0
extern "C" int64_t SystemNative_LSeek(intptr_t fd, int64_t offset, SeekWhence whence)
{
    int64_t result;
    while (CheckInterrupted(result = lseek(ToFileDescriptor(fd), offset, whence)));
    return result;
}
Exemplo n.º 27
0
extern "C" int32_t SystemNative_FLock(intptr_t fd, LockOperations operation)
{
    int32_t result;
    while (CheckInterrupted(result = flock(ToFileDescriptor(fd), operation)));
    return result;
}
Exemplo n.º 28
0
extern "C" int32_t SystemNative_FSync(intptr_t fd)
{
    int32_t result;
    while (CheckInterrupted(result = fsync(ToFileDescriptor(fd))));
    return result;
}
Exemplo n.º 29
0
extern "C" int32_t SystemNative_FChMod(intptr_t fd, int32_t mode)
{
    int32_t result;
    while (CheckInterrupted(result = fchmod(ToFileDescriptor(fd), static_cast<mode_t>(mode))));
    return result;
}
Exemplo n.º 30
0
extern "C" int32_t SystemNative_ChMod(const char* path, int32_t mode)
{
    int32_t result;
    while (CheckInterrupted(result = chmod(path, static_cast<mode_t>(mode))));
    return result;
}