update openharmony 1.0.1

This commit is contained in:
mamingshuai
2021-03-11 18:43:57 +08:00
parent e351799d39
commit 73a7b66116
611 changed files with 17977 additions and 14077 deletions

325
compat/posix/src/mqueue.c Normal file → Executable file
View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@@ -36,6 +36,8 @@
#include "time_posix.h"
#include "los_memory.h"
#include "los_vm_map.h"
#include "los_process_pri.h"
#include "fs_file.h"
#include "user_copy.h"
#ifdef __cplusplus
@@ -46,9 +48,14 @@ extern "C" {
#define FNONBLOCK O_NONBLOCK
#ifndef MAX_MQ_FD
#define MAX_MQ_FD CONFIG_NQUEUE_DESCRIPTORS
#endif
/* GLOBALS */
STATIC struct mqarray g_queueTable[LOSCFG_BASE_IPC_QUEUE_LIMIT];
STATIC pthread_mutex_t g_mqueueMutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
STATIC struct mqpersonal *g_mqPrivBuf[MAX_MQ_FD];
/* LOCAL FUNCTIONS */
STATIC INLINE INT32 MqNameCheck(const CHAR *mqName)
@@ -100,7 +107,6 @@ STATIC INLINE struct mqarray *GetMqueueCBByName(const CHAR *name)
return &(g_queueTable[index]);
}
}
return NULL;
}
@@ -114,6 +120,10 @@ STATIC INT32 DoMqueueDelete(struct mqarray *mqueueCB)
}
mqueueCB->mqcb = NULL;
/* When mqueue-list head node needed free ,reset the mode_data */
mqueueCB->mode_data.data = 0;
mqueueCB->euid = -1;
mqueueCB->egid = -1;
ret = LOS_QueueDelete(mqueueCB->mq_id);
switch (ret) {
@@ -152,7 +162,7 @@ STATIC int SaveMqueueName(const CHAR *mqName, struct mqarray *mqueueCB)
return LOS_OK;
}
STATIC struct mqpersonal *DoMqueueCreate(const struct mq_attr *attr, const CHAR *mqName, INT32 openFlag)
STATIC struct mqpersonal *DoMqueueCreate(const struct mq_attr *attr, const CHAR *mqName, INT32 openFlag, UINT32 mode)
{
struct mqarray *mqueueCB = NULL;
UINT32 mqueueID;
@@ -191,10 +201,13 @@ STATIC struct mqpersonal *DoMqueueCreate(const struct mq_attr *attr, const CHAR
}
mqueueCB->unlinkflag = FALSE;
mqueueCB->unlink_ref = 0;
mqueueCB->mq_personal->mq_status = MQ_USE_MAGIC;
mqueueCB->mq_personal->mq_next = NULL;
mqueueCB->mq_personal->mq_posixdes = mqueueCB;
mqueueCB->mq_personal->mq_flags = (INT32)((UINT32)openFlag | ((UINT32)attr->mq_flags & (UINT32)FNONBLOCK));
mqueueCB->mq_personal->mq_mode = mode;
mqueueCB->mq_personal->mq_refcount = 0;
return mqueueCB->mq_personal;
ERROUT:
@@ -228,6 +241,7 @@ STATIC struct mqpersonal *DoMqueueOpen(struct mqarray *mqueueCB, INT32 openFlag)
privateMqPersonal->mq_posixdes = mqueueCB;
privateMqPersonal->mq_flags = openFlag;
privateMqPersonal->mq_status = MQ_USE_MAGIC;
privateMqPersonal->mq_refcount = 0;
return privateMqPersonal;
@@ -235,14 +249,226 @@ ERROUT:
return (struct mqpersonal *)-1;
}
/* Translate a sysFd into privateMqPersonal */
STATIC struct mqpersonal *MqGetPrivDataBuff(mqd_t personal)
{
INT32 sysFd = (INT32)personal;
INT32 id = sysFd - MQUEUE_FD_OFFSET;
/* Filter illegal id */
if ((id < 0) || (id >= MAX_MQ_FD)) {
errno = EBADF;
return NULL;
}
return g_mqPrivBuf[id];
}
/**
* Alloc sysFd, storage mq private data, set using bit.
*
* @param maxfdp: Maximum allowed application of mqueue sysFd.
* @param fdset: Mqueue sysFd bit map.
* @param privateMqPersonal: Private data.
* @return the index of the new fd; -1 on error
*/
STATIC INT32 MqAllocSysFd(int maxfdp, struct mqpersonal *privateMqPersonal)
{
INT32 i;
struct mqarray *mqueueCB = privateMqPersonal->mq_posixdes;
fd_set *fdset = &mqueueCB->mq_fdset;
for (i = 0; i < maxfdp; i++) {
/* sysFd: used bit setting, and get the index of swtmrID buffer */
if (!(fdset && FD_ISSET(i + MQUEUE_FD_OFFSET, fdset))) {
FD_SET(i + MQUEUE_FD_OFFSET, fdset);
if (!g_mqPrivBuf[i]) {
g_mqPrivBuf[i] = mqueueCB->mq_personal;
return i + MQUEUE_FD_OFFSET;
}
}
}
/* there are no more mq sysFd to use, free the personal */
LOS_MemFree(OS_SYS_MEM_ADDR, privateMqPersonal);
privateMqPersonal = NULL;
mqueueCB->mq_personal = NULL;
return -1;
}
STATIC VOID MqFreeSysFd(struct mqarray *mqueueCB, mqd_t personal)
{
INT32 sysFd = (INT32)personal;
fd_set *fdset = &mqueueCB->mq_fdset;
if (fdset && FD_ISSET(sysFd, fdset)) {
FD_CLR(sysFd, fdset);
g_mqPrivBuf[sysFd - MQUEUE_FD_OFFSET] = NULL;
}
}
/* Mqueue fd reference count */
void mqueue_refer(int sysFd)
{
struct mqarray *mqueueCB = NULL;
struct mqpersonal *privateMqPersonal = NULL;
(VOID)pthread_mutex_lock(&g_mqueueMutex);
/* Get the personal sysFd and reset personal fd -1 */
privateMqPersonal = MqGetPrivDataBuff((mqd_t)sysFd);
if (privateMqPersonal == NULL) {
goto OUT_UNLOCK;
}
mqueueCB = privateMqPersonal->mq_posixdes;
if (mqueueCB == NULL) {
goto OUT_UNLOCK;
}
privateMqPersonal->mq_refcount++;
mqueueCB->unlink_ref++;
OUT_UNLOCK:
(VOID)pthread_mutex_unlock(&g_mqueueMutex);
}
STATIC INT32 MqTryClose(struct mqpersonal *privateMqPersonal)
{
struct mqarray *mqueueCB = NULL;
mqueueCB = privateMqPersonal->mq_posixdes;
if (mqueueCB == NULL) {
errno = ENFILE;
return false;
}
if (privateMqPersonal->mq_refcount == 0) {
return TRUE;
}
privateMqPersonal->mq_refcount--;
return FALSE;
}
STATIC INT32 MqTryUnlink(struct mqarray *mqueueCB)
{
if (mqueueCB->unlink_ref == 0) {
return TRUE;
}
mqueueCB->unlink_ref--;
return FALSE;
}
/* Set the mode data bit,for consumer's mode comparing. */
STATIC INT32 MqueueModeAnalysisSet(struct mqpersonal *privateMqPersonal)
{
UINT32 mode;
UINT32 intSave;
User *user = NULL;
struct mqarray *mqueueCB = NULL;
if ((INT32)(UINTPTR)privateMqPersonal < 0) {
return -1;
}
/* Get mqueueCB of first time creating mqueue */
mqueueCB = privateMqPersonal->mq_posixdes;
if (mqueueCB == NULL) {
errno = ENFILE;
return -1;
}
mode = mqueueCB->mq_personal->mq_mode;
/* Set mqueue gid uid */
SCHEDULER_LOCK(intSave);
user = OsCurrUserGet();
mqueueCB->euid = user->effUserID;
mqueueCB->egid = user->effGid;
SCHEDULER_UNLOCK(intSave);
/* Set mode data bit */
if (mode & S_IRUSR) {
mqueueCB->mode_data.usr |= S_IRUSR;
}
if (mode & S_IWUSR) {
mqueueCB->mode_data.usr |= S_IWUSR;
}
if (mode & S_IRGRP) {
mqueueCB->mode_data.grp |= S_IRGRP;
}
if (mode & S_IWGRP) {
mqueueCB->mode_data.grp |= S_IWGRP;
}
if (mode & S_IROTH) {
mqueueCB->mode_data.oth |= S_IROTH;
}
if (mode & S_IWOTH) {
mqueueCB->mode_data.oth |= S_IWOTH;
}
return 0;
}
STATIC INT32 GetPermissionOfVisitor(struct mqarray *mqueueCB)
{
uid_t euid;
gid_t egid;
UINT32 intSave;
User *user = NULL;
if (mqueueCB == NULL) {
errno = ENOENT;
return -EPERM;
}
/* Get the visitor process euid and egid */
SCHEDULER_LOCK(intSave);
user = OsCurrUserGet();
euid = user->effUserID;
egid = user->effGid;
SCHEDULER_UNLOCK(intSave);
/* root */
if (euid == 0) {
return ENOERR;
}
if (euid == mqueueCB->euid) { /* usr */
if (!((mqueueCB->mode_data.usr & S_IRUSR) || (mqueueCB->mode_data.usr & S_IWUSR))) {
errno = EACCES;
goto ERR_OUT;
}
} else if (egid == mqueueCB->egid) { /* grp */
if (!((mqueueCB->mode_data.grp & S_IRGRP) || (mqueueCB->mode_data.grp & S_IWGRP))) {
errno = EACCES;
goto ERR_OUT;
}
} else { /* oth */
if (!((mqueueCB->mode_data.oth & S_IROTH) || (mqueueCB->mode_data.oth & S_IWOTH))) {
errno = EACCES;
goto ERR_OUT;
}
}
return ENOERR;
ERR_OUT:
return -EPERM;
}
STATIC INT32 GetMqueueAttr(struct mq_attr *defaultAttr, struct mq_attr *attr)
{
if (attr != NULL) {
if (LOS_ArchCopyFromUser(defaultAttr, attr, sizeof(struct mq_attr))) {
errno = EFAULT;
return -1;
}
if ((defaultAttr->mq_maxmsg < 0) || (defaultAttr->mq_maxmsg > (long int)USHRT_MAX) ||
(defaultAttr->mq_msgsize < 0) || (defaultAttr->mq_msgsize > (long int)(USHRT_MAX - sizeof(UINT32)))) {
errno = EINVAL;
return -1;
}
}
return 0;
}
mqd_t mq_open(const char *mqName, int openFlag, ...)
{
struct mqarray *mqueueCB = NULL;
struct mqpersonal *privateMqPersonal = (struct mqpersonal *)-1;
struct mq_attr *attr = NULL;
struct mq_attr defaultAttr = { 0, MQ_MAX_MSG_NUM, MQ_MAX_MSG_LEN, 0 };
int retVal;
va_list ap;
int sysFd;
mqd_t mqFd = -1;
unsigned int mode = 0;
if (MqNameCheck(mqName) == -1) {
return (mqd_t)-1;
@@ -259,56 +485,62 @@ mqd_t mq_open(const char *mqName, int openFlag, ...)
privateMqPersonal = DoMqueueOpen(mqueueCB, openFlag);
} else {
va_start(ap, openFlag);
(VOID)va_arg(ap, int);
mode = va_arg(ap, unsigned int);
attr = va_arg(ap, struct mq_attr *);
va_end(ap);
if (attr != NULL) {
retVal = LOS_ArchCopyFromUser(&defaultAttr, attr, sizeof(struct mq_attr));
if (retVal != 0) {
errno = EFAULT;
goto OUT;
}
if ((defaultAttr.mq_maxmsg < 0) || (defaultAttr.mq_maxmsg > (long int)USHRT_MAX) ||
(defaultAttr.mq_msgsize < 0) || (defaultAttr.mq_msgsize > (long int)(USHRT_MAX - sizeof(UINT32)))) {
errno = EINVAL;
goto OUT;
}
if (GetMqueueAttr(&defaultAttr, attr)) {
goto OUT;
}
privateMqPersonal = DoMqueueCreate(&defaultAttr, mqName, openFlag);
privateMqPersonal = DoMqueueCreate(&defaultAttr, mqName, openFlag, mode);
}
/* Set mode data bit ,just for the first node */
if (MqueueModeAnalysisSet(privateMqPersonal)) {
goto OUT;
}
} else {
if (mqueueCB == NULL) {
errno = ENOENT;
if (GetPermissionOfVisitor(mqueueCB)) {
goto OUT;
}
privateMqPersonal = DoMqueueOpen(mqueueCB, openFlag);
}
OUT:
if ((INT32)(UINTPTR)privateMqPersonal > 0) {
/* alloc sysFd */
sysFd = MqAllocSysFd(MAX_MQ_FD, privateMqPersonal);
if (sysFd == -1) {
errno = ENFILE;
}
mqFd = (mqd_t)sysFd;
}
(VOID)pthread_mutex_unlock(&g_mqueueMutex);
return (mqd_t)privateMqPersonal;
return mqFd;
}
int mq_close(mqd_t personal)
{
INT32 ret = 0;
INT32 ret = -1;
struct mqarray *mqueueCB = NULL;
struct mqpersonal *privateMqPersonal = NULL;
struct mqpersonal *tmp = NULL;
if (!LOS_IsKernelAddressRange(personal, sizeof(struct mqpersonal))) {
errno = EBADF;
return -1;
(VOID)pthread_mutex_lock(&g_mqueueMutex);
/* Get the personal sysFd and reset personal fd -1 */
privateMqPersonal = MqGetPrivDataBuff(personal);
if (privateMqPersonal == NULL) {
goto OUT_UNLOCK;
}
(VOID)pthread_mutex_lock(&g_mqueueMutex);
privateMqPersonal = (struct mqpersonal *)personal;
if (privateMqPersonal->mq_status != MQ_USE_MAGIC) {
errno = EBADF;
goto OUT_UNLOCK;
}
/* there have other thread used the fd */
if (!MqTryClose(privateMqPersonal)) {
ret = 0;
goto OUT_UNLOCK;
}
mqueueCB = privateMqPersonal->mq_posixdes;
if (mqueueCB->mq_personal == NULL) {
errno = EBADF;
@@ -332,6 +564,7 @@ int mq_close(mqd_t personal)
}
/* flag no use */
privateMqPersonal->mq_status = 0;
MqFreeSysFd(mqueueCB, personal);
/* free the personal */
ret = LOS_MemFree(OS_SYS_MEM_ADDR, privateMqPersonal);
@@ -354,8 +587,8 @@ int OsMqGetAttr(mqd_t personal, struct mq_attr *mqAttr)
struct mqarray *mqueueCB = NULL;
struct mqpersonal *privateMqPersonal = NULL;
if (!LOS_IsKernelAddressRange(personal, sizeof(struct mqpersonal))) {
errno = EBADF;
privateMqPersonal = MqGetPrivDataBuff(personal);
if (privateMqPersonal == NULL) {
return -1;
}
@@ -365,7 +598,6 @@ int OsMqGetAttr(mqd_t personal, struct mq_attr *mqAttr)
}
(VOID)pthread_mutex_lock(&g_mqueueMutex);
privateMqPersonal = (struct mqpersonal *)personal;
if (privateMqPersonal->mq_status != MQ_USE_MAGIC) {
errno = EBADF;
(VOID)pthread_mutex_unlock(&g_mqueueMutex);
@@ -385,8 +617,8 @@ int OsMqSetAttr(mqd_t personal, const struct mq_attr *mqSetAttr, struct mq_attr
{
struct mqpersonal *privateMqPersonal = NULL;
if (!LOS_IsKernelAddressRange(personal, sizeof(struct mqpersonal))) {
errno = EBADF;
privateMqPersonal = MqGetPrivDataBuff(personal);
if (privateMqPersonal == NULL) {
return -1;
}
@@ -396,7 +628,6 @@ int OsMqSetAttr(mqd_t personal, const struct mq_attr *mqSetAttr, struct mq_attr
}
(VOID)pthread_mutex_lock(&g_mqueueMutex);
privateMqPersonal = (struct mqpersonal *)personal;
if (privateMqPersonal->mq_status != MQ_USE_MAGIC) {
errno = EBADF;
(VOID)pthread_mutex_unlock(&g_mqueueMutex);
@@ -404,7 +635,7 @@ int OsMqSetAttr(mqd_t personal, const struct mq_attr *mqSetAttr, struct mq_attr
}
if (mqOldAttr != NULL) {
(VOID)OsMqGetAttr((mqd_t)privateMqPersonal, mqOldAttr);
(VOID)OsMqGetAttr(personal, mqOldAttr);
}
privateMqPersonal->mq_flags = (INT32)((UINT32)privateMqPersonal->mq_flags & (UINT32)(~FNONBLOCK)); /* clear */
@@ -438,10 +669,13 @@ int mq_unlink(const char *mqName)
errno = ENOENT;
goto ERROUT_UNLOCK;
}
if (!MqTryUnlink(mqueueCB)) {
(VOID)pthread_mutex_unlock(&g_mqueueMutex);
return 0;
}
if (mqueueCB->mq_personal != NULL) {
mqueueCB->unlinkflag = TRUE;
} else {
} else if (mqueueCB->unlink_ref == 0) {
ret = DoMqueueDelete(mqueueCB);
}
@@ -476,8 +710,7 @@ STATIC INT32 ConvertTimeout(long flags, const struct timespec *absTimeout, UINT6
STATIC INLINE BOOL MqParamCheck(mqd_t personal, const char *msg, size_t msgLen)
{
if (!LOS_IsKernelAddressRange(personal, sizeof(struct mqpersonal))) {
errno = EBADF;
if (personal < 0) {
return FALSE;
}
@@ -507,11 +740,14 @@ int mq_timedsend(mqd_t personal, const char *msg, size_t msgLen, unsigned int ms
struct mqpersonal *privateMqPersonal = NULL;
OS_MQ_GOTO_ERROUT_IF(!MqParamCheck(personal, msg, msgLen), errno);
OS_MQ_GOTO_ERROUT_IF(msgPrio > (MQ_PRIO_MAX - 1), EINVAL);
(VOID)pthread_mutex_lock(&g_mqueueMutex);
privateMqPersonal = (struct mqpersonal *)personal;
privateMqPersonal = MqGetPrivDataBuff(personal);
if (privateMqPersonal == NULL) {
goto ERROUT_UNLOCK;
}
OS_MQ_GOTO_ERROUT_UNLOCK_IF(privateMqPersonal->mq_status != MQ_USE_MAGIC, EBADF);
mqueueCB = privateMqPersonal->mq_posixdes;
@@ -554,7 +790,10 @@ ssize_t mq_timedreceive(mqd_t personal, char *msg, size_t msgLen, unsigned int *
}
(VOID)pthread_mutex_lock(&g_mqueueMutex);
privateMqPersonal = (struct mqpersonal *)personal;
privateMqPersonal = MqGetPrivDataBuff(personal);
if (privateMqPersonal == NULL) {
goto ERROUT_UNLOCK;
}
if (privateMqPersonal->mq_status != MQ_USE_MAGIC) {
errno = EBADF;
goto ERROUT_UNLOCK;