10d163575Sopenharmony_ci/*
20d163575Sopenharmony_ci * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
30d163575Sopenharmony_ci * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
40d163575Sopenharmony_ci *
50d163575Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification,
60d163575Sopenharmony_ci * are permitted provided that the following conditions are met:
70d163575Sopenharmony_ci *
80d163575Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of
90d163575Sopenharmony_ci *    conditions and the following disclaimer.
100d163575Sopenharmony_ci *
110d163575Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list
120d163575Sopenharmony_ci *    of conditions and the following disclaimer in the documentation and/or other materials
130d163575Sopenharmony_ci *    provided with the distribution.
140d163575Sopenharmony_ci *
150d163575Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used
160d163575Sopenharmony_ci *    to endorse or promote products derived from this software without specific prior written
170d163575Sopenharmony_ci *    permission.
180d163575Sopenharmony_ci *
190d163575Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
200d163575Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
210d163575Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
220d163575Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
230d163575Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
240d163575Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
250d163575Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
260d163575Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
270d163575Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
280d163575Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
290d163575Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
300d163575Sopenharmony_ci */
310d163575Sopenharmony_ci
320d163575Sopenharmony_ci#include "syscall_pub.h"
330d163575Sopenharmony_ci#include "mqueue.h"
340d163575Sopenharmony_ci#include <errno.h>
350d163575Sopenharmony_ci#include <sys/types.h>
360d163575Sopenharmony_ci#include <sys/stat.h>
370d163575Sopenharmony_ci#include "time_posix.h"
380d163575Sopenharmony_ci#include "user_copy.h"
390d163575Sopenharmony_ci#include "los_signal.h"
400d163575Sopenharmony_ci#include "los_process_pri.h"
410d163575Sopenharmony_ci#include "los_strncpy_from_user.h"
420d163575Sopenharmony_ci#include "fs/file.h"
430d163575Sopenharmony_ci
440d163575Sopenharmony_ci#define MQUEUE_FD_U2K(id) \
450d163575Sopenharmony_ci    do { \
460d163575Sopenharmony_ci        int sysFd = GetAssociatedSystemFd((INTPTR)(id)); \
470d163575Sopenharmony_ci        (id) = (mqd_t)sysFd; \
480d163575Sopenharmony_ci    } while (0)
490d163575Sopenharmony_ci#define MQUEUE_FD_K2U(id) \
500d163575Sopenharmony_ci    do { \
510d163575Sopenharmony_ci        int procFd = AllocAndAssocProcessFd((INTPTR)(id), MIN_START_FD); \
520d163575Sopenharmony_ci        if (procFd == -1) { \
530d163575Sopenharmony_ci            mq_close(id); \
540d163575Sopenharmony_ci            set_errno(EMFILE); \
550d163575Sopenharmony_ci            (id) = (mqd_t)(-EMFILE); \
560d163575Sopenharmony_ci        } else { \
570d163575Sopenharmony_ci            (id) = (mqd_t)procFd; \
580d163575Sopenharmony_ci        } \
590d163575Sopenharmony_ci    } while (0)
600d163575Sopenharmony_ci
610d163575Sopenharmony_cimqd_t SysMqOpen(const char *mqName, int openFlag, mode_t mode, struct mq_attr *attr)
620d163575Sopenharmony_ci{
630d163575Sopenharmony_ci    mqd_t ret;
640d163575Sopenharmony_ci    int retValue;
650d163575Sopenharmony_ci    char kMqName[PATH_MAX + 1] = { 0 };
660d163575Sopenharmony_ci
670d163575Sopenharmony_ci    retValue = LOS_StrncpyFromUser(kMqName, mqName, PATH_MAX);
680d163575Sopenharmony_ci    if (retValue < 0) {
690d163575Sopenharmony_ci        return retValue;
700d163575Sopenharmony_ci    }
710d163575Sopenharmony_ci    ret = mq_open(kMqName, openFlag, mode, attr);
720d163575Sopenharmony_ci    if (ret == -1) {
730d163575Sopenharmony_ci        return (mqd_t)-get_errno();
740d163575Sopenharmony_ci    }
750d163575Sopenharmony_ci    /* SysFd to procFd */
760d163575Sopenharmony_ci    MQUEUE_FD_K2U(ret);
770d163575Sopenharmony_ci    return ret;
780d163575Sopenharmony_ci}
790d163575Sopenharmony_ci
800d163575Sopenharmony_ciint SysMqClose(mqd_t personal)
810d163575Sopenharmony_ci{
820d163575Sopenharmony_ci    int ret;
830d163575Sopenharmony_ci    int ufd = (INTPTR)personal;
840d163575Sopenharmony_ci
850d163575Sopenharmony_ci    MQUEUE_FD_U2K(personal);
860d163575Sopenharmony_ci    ret = mq_close(personal);
870d163575Sopenharmony_ci    if (ret < 0) {
880d163575Sopenharmony_ci        return -get_errno();
890d163575Sopenharmony_ci    }
900d163575Sopenharmony_ci    FreeProcessFd(ufd);
910d163575Sopenharmony_ci    return ret;
920d163575Sopenharmony_ci}
930d163575Sopenharmony_ci
940d163575Sopenharmony_ciint SysMqNotify(mqd_t personal, const struct sigevent *sigev)
950d163575Sopenharmony_ci{
960d163575Sopenharmony_ci    int ret;
970d163575Sopenharmony_ci    struct sigevent ksigev;
980d163575Sopenharmony_ci
990d163575Sopenharmony_ci    ret = LOS_ArchCopyFromUser(&ksigev, sigev, sizeof(struct sigevent));
1000d163575Sopenharmony_ci    if (ret != 0) {
1010d163575Sopenharmony_ci        return -EFAULT;
1020d163575Sopenharmony_ci    }
1030d163575Sopenharmony_ci
1040d163575Sopenharmony_ci    MQUEUE_FD_U2K(personal);
1050d163575Sopenharmony_ci    ret = OsMqNotify(personal, &ksigev);
1060d163575Sopenharmony_ci    if (ret < 0) {
1070d163575Sopenharmony_ci        return -get_errno();
1080d163575Sopenharmony_ci    }
1090d163575Sopenharmony_ci    return ret;
1100d163575Sopenharmony_ci}
1110d163575Sopenharmony_ci
1120d163575Sopenharmony_ciint SysMqGetSetAttr(mqd_t mqd, const struct mq_attr *new, struct mq_attr *old)
1130d163575Sopenharmony_ci{
1140d163575Sopenharmony_ci    int ret;
1150d163575Sopenharmony_ci    struct mq_attr knew;
1160d163575Sopenharmony_ci    struct mq_attr kold = { 0 };
1170d163575Sopenharmony_ci
1180d163575Sopenharmony_ci    if (new != NULL) {
1190d163575Sopenharmony_ci        ret = LOS_ArchCopyFromUser(&knew, new, sizeof(struct mq_attr));
1200d163575Sopenharmony_ci        if (ret != 0) {
1210d163575Sopenharmony_ci            return -EFAULT;
1220d163575Sopenharmony_ci        }
1230d163575Sopenharmony_ci    }
1240d163575Sopenharmony_ci    MQUEUE_FD_U2K(mqd);
1250d163575Sopenharmony_ci    ret = mq_getsetattr(mqd, new ? &knew : NULL, old ? &kold : NULL);
1260d163575Sopenharmony_ci    if (ret < 0) {
1270d163575Sopenharmony_ci        return -get_errno();
1280d163575Sopenharmony_ci    }
1290d163575Sopenharmony_ci    if (old != NULL) {
1300d163575Sopenharmony_ci        ret = LOS_ArchCopyToUser(old, &kold, sizeof(struct mq_attr));
1310d163575Sopenharmony_ci        if (ret != 0) {
1320d163575Sopenharmony_ci            return -EFAULT;
1330d163575Sopenharmony_ci        }
1340d163575Sopenharmony_ci    }
1350d163575Sopenharmony_ci    return ret;
1360d163575Sopenharmony_ci}
1370d163575Sopenharmony_ci
1380d163575Sopenharmony_ciint SysMqUnlink(const char *mqName)
1390d163575Sopenharmony_ci{
1400d163575Sopenharmony_ci    int ret;
1410d163575Sopenharmony_ci    int retValue;
1420d163575Sopenharmony_ci    char kMqName[PATH_MAX + 1] = { 0 };
1430d163575Sopenharmony_ci
1440d163575Sopenharmony_ci    retValue = LOS_StrncpyFromUser(kMqName, mqName, PATH_MAX);
1450d163575Sopenharmony_ci    if (retValue < 0) {
1460d163575Sopenharmony_ci        return retValue;
1470d163575Sopenharmony_ci    }
1480d163575Sopenharmony_ci
1490d163575Sopenharmony_ci    ret = mq_unlink(kMqName);
1500d163575Sopenharmony_ci    if (ret < 0) {
1510d163575Sopenharmony_ci        return -get_errno();
1520d163575Sopenharmony_ci    }
1530d163575Sopenharmony_ci    return ret;
1540d163575Sopenharmony_ci}
1550d163575Sopenharmony_ci
1560d163575Sopenharmony_ciint SysMqTimedSend(mqd_t personal, const char *msg, size_t msgLen, unsigned int msgPrio,
1570d163575Sopenharmony_ci                   const struct timespec *absTimeout)
1580d163575Sopenharmony_ci{
1590d163575Sopenharmony_ci    int ret;
1600d163575Sopenharmony_ci    struct timespec timeout;
1610d163575Sopenharmony_ci    char *msgIntr = NULL;
1620d163575Sopenharmony_ci
1630d163575Sopenharmony_ci    if (absTimeout != NULL) {
1640d163575Sopenharmony_ci        ret = LOS_ArchCopyFromUser(&timeout, absTimeout, sizeof(struct timespec));
1650d163575Sopenharmony_ci        if (ret != 0) {
1660d163575Sopenharmony_ci            return -EFAULT;
1670d163575Sopenharmony_ci        }
1680d163575Sopenharmony_ci    }
1690d163575Sopenharmony_ci    if (msgLen == 0) {
1700d163575Sopenharmony_ci        return -EINVAL;
1710d163575Sopenharmony_ci    }
1720d163575Sopenharmony_ci    msgIntr = (char *)malloc(msgLen);
1730d163575Sopenharmony_ci    if (msgIntr == NULL) {
1740d163575Sopenharmony_ci        return -ENOMEM;
1750d163575Sopenharmony_ci    }
1760d163575Sopenharmony_ci    ret = LOS_ArchCopyFromUser(msgIntr, msg, msgLen);
1770d163575Sopenharmony_ci    if (ret != 0) {
1780d163575Sopenharmony_ci        free(msgIntr);
1790d163575Sopenharmony_ci        return -EFAULT;
1800d163575Sopenharmony_ci    }
1810d163575Sopenharmony_ci    MQUEUE_FD_U2K(personal);
1820d163575Sopenharmony_ci    ret = mq_timedsend(personal, msgIntr, msgLen, msgPrio, absTimeout ? &timeout : NULL);
1830d163575Sopenharmony_ci    free(msgIntr);
1840d163575Sopenharmony_ci    if (ret < 0) {
1850d163575Sopenharmony_ci        return -get_errno();
1860d163575Sopenharmony_ci    }
1870d163575Sopenharmony_ci    return ret;
1880d163575Sopenharmony_ci}
1890d163575Sopenharmony_ci
1900d163575Sopenharmony_cissize_t SysMqTimedReceive(mqd_t personal, char *msg, size_t msgLen, unsigned int *msgPrio,
1910d163575Sopenharmony_ci                          const struct timespec *absTimeout)
1920d163575Sopenharmony_ci{
1930d163575Sopenharmony_ci    int ret, receiveLen;
1940d163575Sopenharmony_ci    struct timespec timeout;
1950d163575Sopenharmony_ci    char *msgIntr = NULL;
1960d163575Sopenharmony_ci    unsigned int kMsgPrio;
1970d163575Sopenharmony_ci
1980d163575Sopenharmony_ci    if (absTimeout != NULL) {
1990d163575Sopenharmony_ci        ret = LOS_ArchCopyFromUser(&timeout, absTimeout, sizeof(struct timespec));
2000d163575Sopenharmony_ci        if (ret != 0) {
2010d163575Sopenharmony_ci            return -EFAULT;
2020d163575Sopenharmony_ci        }
2030d163575Sopenharmony_ci    }
2040d163575Sopenharmony_ci    if (msgLen == 0) {
2050d163575Sopenharmony_ci        return -EINVAL;
2060d163575Sopenharmony_ci    }
2070d163575Sopenharmony_ci    msgIntr = (char *)malloc(msgLen);
2080d163575Sopenharmony_ci    if (msgIntr == NULL) {
2090d163575Sopenharmony_ci        return -ENOMEM;
2100d163575Sopenharmony_ci    }
2110d163575Sopenharmony_ci    MQUEUE_FD_U2K(personal);
2120d163575Sopenharmony_ci    receiveLen = mq_timedreceive(personal, msgIntr, msgLen, &kMsgPrio, absTimeout ? &timeout : NULL);
2130d163575Sopenharmony_ci    if (receiveLen < 0) {
2140d163575Sopenharmony_ci        free(msgIntr);
2150d163575Sopenharmony_ci        return -get_errno();
2160d163575Sopenharmony_ci    }
2170d163575Sopenharmony_ci
2180d163575Sopenharmony_ci    if (msgPrio != NULL) {
2190d163575Sopenharmony_ci        ret = LOS_ArchCopyToUser(msgPrio, &kMsgPrio, sizeof(unsigned int));
2200d163575Sopenharmony_ci        if (ret != 0) {
2210d163575Sopenharmony_ci            free(msgIntr);
2220d163575Sopenharmony_ci            return -EFAULT;
2230d163575Sopenharmony_ci        }
2240d163575Sopenharmony_ci    }
2250d163575Sopenharmony_ci
2260d163575Sopenharmony_ci    ret = LOS_ArchCopyToUser(msg, msgIntr, receiveLen);
2270d163575Sopenharmony_ci    free(msgIntr);
2280d163575Sopenharmony_ci    if (ret != 0) {
2290d163575Sopenharmony_ci        return -EFAULT;
2300d163575Sopenharmony_ci    }
2310d163575Sopenharmony_ci    return receiveLen;
2320d163575Sopenharmony_ci}
2330d163575Sopenharmony_ci
2340d163575Sopenharmony_ciint SysSigAction(int sig, const sigaction_t *restrict sa, sigaction_t *restrict old, size_t sigsetsize)
2350d163575Sopenharmony_ci{
2360d163575Sopenharmony_ci    return OsSigAction(sig, sa, old);
2370d163575Sopenharmony_ci}
2380d163575Sopenharmony_ci
2390d163575Sopenharmony_ciint SysSigprocMask(int how, const sigset_t_l *restrict setl, sigset_t_l *restrict oldl, size_t sigsetsize)
2400d163575Sopenharmony_ci{
2410d163575Sopenharmony_ci    CHECK_ASPACE(setl, sizeof(sigset_t_l));
2420d163575Sopenharmony_ci    CHECK_ASPACE(oldl, sizeof(sigset_t_l));
2430d163575Sopenharmony_ci    CPY_FROM_USER(setl);
2440d163575Sopenharmony_ci    CPY_FROM_USER(oldl);
2450d163575Sopenharmony_ci    /* Let OsSigprocMask do all of the work */
2460d163575Sopenharmony_ci    int ret = OsSigprocMask(how, setl, oldl);
2470d163575Sopenharmony_ci    CPY_TO_USER(oldl);
2480d163575Sopenharmony_ci    return ret;
2490d163575Sopenharmony_ci}
2500d163575Sopenharmony_ci
2510d163575Sopenharmony_ciint SysKill(pid_t pid, int sig)
2520d163575Sopenharmony_ci{
2530d163575Sopenharmony_ci    return OsKillLock(pid, sig);
2540d163575Sopenharmony_ci}
2550d163575Sopenharmony_ci
2560d163575Sopenharmony_ciint SysPthreadKill(pid_t pid, int sig)
2570d163575Sopenharmony_ci{
2580d163575Sopenharmony_ci    return OsPthreadKill(pid, sig);
2590d163575Sopenharmony_ci}
2600d163575Sopenharmony_ci
2610d163575Sopenharmony_ciint SysSigTimedWait(const sigset_t_l *setl, siginfo_t *info, const struct timespec *timeout, size_t sigsetsize)
2620d163575Sopenharmony_ci{
2630d163575Sopenharmony_ci    sigset_t set;
2640d163575Sopenharmony_ci    unsigned int tick;
2650d163575Sopenharmony_ci    int retVal, ret;
2660d163575Sopenharmony_ci    siginfo_t infoIntr = { 0 };
2670d163575Sopenharmony_ci    struct timespec timeoutIntr;
2680d163575Sopenharmony_ci
2690d163575Sopenharmony_ci    retVal = LOS_ArchCopyFromUser(&set, &(setl->sig[0]), sizeof(sigset_t));
2700d163575Sopenharmony_ci    if (retVal != 0) {
2710d163575Sopenharmony_ci        return -EFAULT;
2720d163575Sopenharmony_ci    }
2730d163575Sopenharmony_ci
2740d163575Sopenharmony_ci    if (timeout == NULL) {
2750d163575Sopenharmony_ci        tick = LOS_WAIT_FOREVER;
2760d163575Sopenharmony_ci    } else {
2770d163575Sopenharmony_ci        retVal = LOS_ArchCopyFromUser(&timeoutIntr, timeout, sizeof(struct timespec));
2780d163575Sopenharmony_ci        if (retVal != 0) {
2790d163575Sopenharmony_ci            return -EFAULT;
2800d163575Sopenharmony_ci        }
2810d163575Sopenharmony_ci        if (!ValidTimeSpec(&timeoutIntr)) {
2820d163575Sopenharmony_ci            return -EINVAL;
2830d163575Sopenharmony_ci        }
2840d163575Sopenharmony_ci        tick = OsTimeSpec2Tick(&timeoutIntr);
2850d163575Sopenharmony_ci    }
2860d163575Sopenharmony_ci    ret = OsSigTimedWait(&set, &infoIntr, tick);
2870d163575Sopenharmony_ci    if (ret < 0) {
2880d163575Sopenharmony_ci        return ret;
2890d163575Sopenharmony_ci    }
2900d163575Sopenharmony_ci    if (info != NULL) {
2910d163575Sopenharmony_ci        retVal = LOS_ArchCopyToUser(info, &infoIntr, sizeof(siginfo_t));
2920d163575Sopenharmony_ci        if (retVal != 0) {
2930d163575Sopenharmony_ci            return -EFAULT;
2940d163575Sopenharmony_ci        }
2950d163575Sopenharmony_ci    }
2960d163575Sopenharmony_ci    return (ret == 0 ? infoIntr.si_signo : ret);
2970d163575Sopenharmony_ci}
2980d163575Sopenharmony_ci
2990d163575Sopenharmony_ciint SysPause(void)
3000d163575Sopenharmony_ci{
3010d163575Sopenharmony_ci    return OsPause();
3020d163575Sopenharmony_ci}
3030d163575Sopenharmony_ci
3040d163575Sopenharmony_ciint SysSigPending(sigset_t_l *setl)
3050d163575Sopenharmony_ci{
3060d163575Sopenharmony_ci    sigset_t set;
3070d163575Sopenharmony_ci    int ret;
3080d163575Sopenharmony_ci
3090d163575Sopenharmony_ci    ret = LOS_ArchCopyFromUser(&set, &(setl->sig[0]), sizeof(sigset_t));
3100d163575Sopenharmony_ci    if (ret != 0) {
3110d163575Sopenharmony_ci        return -EFAULT;
3120d163575Sopenharmony_ci    }
3130d163575Sopenharmony_ci    ret = OsSigPending(&set);
3140d163575Sopenharmony_ci    if (ret != LOS_OK) {
3150d163575Sopenharmony_ci        return ret;
3160d163575Sopenharmony_ci    }
3170d163575Sopenharmony_ci    ret = LOS_ArchCopyToUser(&(setl->sig[0]), &set, sizeof(sigset_t));
3180d163575Sopenharmony_ci    if (ret != LOS_OK) {
3190d163575Sopenharmony_ci        return -EFAULT;
3200d163575Sopenharmony_ci    }
3210d163575Sopenharmony_ci    return ret;
3220d163575Sopenharmony_ci}
3230d163575Sopenharmony_ci
3240d163575Sopenharmony_ciint SysSigSuspend(sigset_t_l *setl)
3250d163575Sopenharmony_ci{
3260d163575Sopenharmony_ci    sigset_t set;
3270d163575Sopenharmony_ci    int retVal;
3280d163575Sopenharmony_ci
3290d163575Sopenharmony_ci    retVal = LOS_ArchCopyFromUser(&set, &(setl->sig[0]), sizeof(sigset_t));
3300d163575Sopenharmony_ci    if (retVal != 0) {
3310d163575Sopenharmony_ci        return -EFAULT;
3320d163575Sopenharmony_ci    }
3330d163575Sopenharmony_ci
3340d163575Sopenharmony_ci    return OsSigSuspend(&set);
3350d163575Sopenharmony_ci}
3360d163575Sopenharmony_ci
3370d163575Sopenharmony_ci#ifdef LOSCFG_KERNEL_PIPE
3380d163575Sopenharmony_ciint SysMkFifo(const char *pathName, mode_t mode)
3390d163575Sopenharmony_ci{
3400d163575Sopenharmony_ci    int retValue;
3410d163575Sopenharmony_ci    char kPathName[PATH_MAX + 1] = { 0 };
3420d163575Sopenharmony_ci
3430d163575Sopenharmony_ci    retValue = LOS_StrncpyFromUser(kPathName, pathName, PATH_MAX);
3440d163575Sopenharmony_ci    if (retValue < 0) {
3450d163575Sopenharmony_ci        return retValue;
3460d163575Sopenharmony_ci    }
3470d163575Sopenharmony_ci    return mkfifo(kPathName, mode);
3480d163575Sopenharmony_ci}
3490d163575Sopenharmony_ci#endif
350