更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
ipc_syscall.c 文件参考

浏览源代码.

函数

mqd_t SysMqOpen (const char *mqName, int openFlag, mode_t mode, struct mq_attr *attr)
 打开一个消息队列,由posix接口封装 更多...
 
int SysMqClose (mqd_t personal)
 关闭一个消息队列 更多...
 
int SysMqNotify (mqd_t personal, const struct sigevent *sigev)
 
int SysMqGetSetAttr (mqd_t mqd, const struct mq_attr *new, struct mq_attr *old)
 封装posix的标准接口,获取和设置消息队列的属性 更多...
 
int SysMqUnlink (const char *mqName)
 
int SysMqTimedSend (mqd_t personal, const char *msg, size_t msgLen, unsigned int msgPrio, const struct timespec *absTimeout)
 定时时间发送消息,任务将被阻塞,等待被唤醒写入消息 更多...
 
ssize_t SysMqTimedReceive (mqd_t personal, char *msg, size_t msgLen, unsigned int *msgPrio, const struct timespec *absTimeout)
 定时接收消息,任务将被阻塞,等待被唤醒读取 更多...
 
int SysSigAction (int sig, const sigaction_t *restrict sa, sigaction_t *restrict old, size_t sigsetsize)
 注册信号,鸿蒙内核只捕捉了SIGSYS 信号 更多...
 
int SysSigprocMask (int how, const sigset_t_l *restrict setl, sigset_t_l *restrict oldl, size_t sigsetsize)
 系统调用之进程信号屏蔽, 什么意思?简单说就是 一个信号来了进程要不要处理,屏蔽就是不处理,注意不能屏蔽SIGKILL和SIGSTOP信号,必须要处理. 更多...
 
int SysKill (pid_t pid, int sig)
 系统调用之向进程发送信号 更多...
 
int SysPthreadKill (pid_t pid, int sig)
 系统调用之之向进程发送信号 更多...
 
int SysSigTimedWait (const sigset_t_l *setl, siginfo_t *info, const struct timespec *timeout, size_t sigsetsize)
 
int SysPause (void)
 系统调用之暂停任务 更多...
 
int SysSigPending (sigset_t_l *setl)
 获取阻塞当前任务的信号集 更多...
 
int SysSigSuspend (sigset_t_l *setl)
 
int SysMkFifo (const char *pathName, mode_t mode)
 

函数说明

◆ SysKill()

int SysKill ( pid_t  pid,
int  sig 
)

系统调用之向进程发送信号

在文件 ipc_syscall.c302 行定义.

303{
304 return OsKillLock(pid, sig);
305}
int OsKillLock(pid_t pid, int sig)
给发送信号过程加锁
Definition: los_signal.c:480
函数调用图:

◆ SysMkFifo()

int SysMkFifo ( const char *  pathName,
mode_t  mode 
)

在文件 ipc_syscall.c389 行定义.

390{
391 int retValue;
392 char kPathName[PATH_MAX + 1] = { 0 };
393
394 retValue = LOS_StrncpyFromUser(kPathName, pathName, PATH_MAX);
395 if (retValue < 0) {
396 return retValue;
397 }
398 return mkfifo(kPathName, mode);
399}
INT32 LOS_StrncpyFromUser(CHAR *dst, const CHAR *src, INT32 count)
函数调用图:

◆ SysMqClose()

int SysMqClose ( mqd_t  personal)

关闭一个消息队列

在文件 ipc_syscall.c106 行定义.

107{
108 int ret;
109 int ufd = (INTPTR)personal;
110
111 MQUEUE_FD_U2K(personal);
112 ret = mq_close(personal);
113 if (ret < 0) {
114 return -get_errno();
115 }
116 FreeProcessFd(ufd);
117 return ret;
118}
int mq_close(mqd_t personal)
Definition: mqueue.c:550
signed long INTPTR
Definition: los_typedef.h:69
void FreeProcessFd(int procFd)
释放进程文件描述符
Definition: vfs_procfd.c:191
函数调用图:

◆ SysMqGetSetAttr()

int SysMqGetSetAttr ( mqd_t  mqd,
const struct mq_attr new,
struct mq_attr old 
)

封装posix的标准接口,获取和设置消息队列的属性

参数
mqd
new判断是否是获取还是设置功能,new==null 获取 否则为设置
old
返回
int

在文件 ipc_syscall.c138 行定义.

139{
140 int ret;
141 struct mq_attr knew, kold;
142
143 if (new != NULL) {
144 ret = LOS_ArchCopyFromUser(&knew, new, sizeof(struct mq_attr));
145 if (ret != 0) {
146 return -EFAULT;
147 }
148 }
149 MQUEUE_FD_U2K(mqd);
150 ret = mq_getsetattr(mqd, new ? &knew : NULL, old ? &kold : NULL);
151 if (ret < 0) {
152 return -get_errno();
153 }
154 if (old != NULL) {
155 ret = LOS_ArchCopyToUser(old, &kold, sizeof(struct mq_attr));
156 if (ret != 0) {
157 return -EFAULT;
158 }
159 }
160 return ret;
161}
int mq_getsetattr(mqd_t personal, const struct mq_attr *mqSetAttr, struct mq_attr *MqOldAttr)
Definition: mqueue.c:648
size_t LOS_ArchCopyToUser(void *dst, const void *src, size_t len)
从内核空间拷贝到用户空间
Definition: user_copy.c:79
size_t LOS_ArchCopyFromUser(void *dst, const void *src, size_t len)
Definition: user_copy.c:58
函数调用图:

◆ SysMqNotify()

int SysMqNotify ( mqd_t  personal,
const struct sigevent *  sigev 
)

在文件 ipc_syscall.c119 行定义.

120{
121 int ret;
122
123 MQUEUE_FD_U2K(personal);
124 ret = OsMqNotify(personal, sigev);
125 if (ret < 0) {
126 return -get_errno();
127 }
128 return ret;
129}
int OsMqNotify(mqd_t personal, const struct sigevent *sigev)
Definition: mqueue.c:891
函数调用图:

◆ SysMqOpen()

mqd_t SysMqOpen ( const char *  mqName,
int  openFlag,
mode_t  mode,
struct mq_attr attr 
)

打开一个消息队列,由posix接口封装

   IPC(Inter-Process Communication,进程间通信)
   每个进程各自有不同的用户地址空间,进程之间地址保护,相互隔离,任何一个进程的信息在另一个进程中都看不到,
   所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程A把数据从用户空间拷到内核缓冲区,
   进程B再从内核缓冲区把数据读走,

   IPC实现方式之消息队列:
   消息队列特点总结:
   (1)消息队列是消息的链表,具有特定的格式,存放在内存中并由消息队列标识符标识.
   (2)消息队列允许一个或多个进程向它写入与读取消息.
   (3)管道和消息队列的通信数据都是先进先出的原则。
   (4)消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取.比FIFO更有优势。
   (5)消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。
   (6)目前主要有两种类型的消息队列:POSIX消息队列以及System V消息队列,System V消息队列是随内核持续的,
       只有在内核重起或者人工删除时,该消息队列才会被删除。
       
   鸿蒙liteos 支持POSIX消息队列并加入了一种自研的消息队列 liteipc,此处重点讲 posix消息队列
* 
参数
mqName
openFlag
mode
attr
返回
mqd_t

在文件 ipc_syscall.c87 行定义.

88{
89 mqd_t ret;
90 int retValue;
91 char kMqName[PATH_MAX + 1] = { 0 };
92
93 retValue = LOS_StrncpyFromUser(kMqName, mqName, PATH_MAX);
94 if (retValue < 0) {
95 return retValue;
96 }
97 ret = mq_open(kMqName, openFlag, mode, attr);//posix ,一个消息队列可以有多个进程向它读写消息
98 if (ret == -1) {
99 return (mqd_t)-get_errno();
100 }
101 /* SysFd to procFd */
102 MQUEUE_FD_K2U(ret);
103 return ret;
104}
mqd_t mq_open(const char *mqName, int openFlag,...)
Definition: mqueue.c:486
UINTPTR mqd_t
Definition: mqueue.h:127
函数调用图:

◆ SysMqTimedReceive()

ssize_t SysMqTimedReceive ( mqd_t  personal,
char *  msg,
size_t  msgLen,
unsigned int msgPrio,
const struct timespec *  absTimeout 
)

定时接收消息,任务将被阻塞,等待被唤醒读取

在文件 ipc_syscall.c230 行定义.

232{
233 int ret, receiveLen;
234 struct timespec timeout;
235 char *msgIntr = NULL;
236 unsigned int kMsgPrio;
237
238 if (absTimeout != NULL) {
239 ret = LOS_ArchCopyFromUser(&timeout, absTimeout, sizeof(struct timespec));
240 if (ret != 0) {
241 return -EFAULT;
242 }
243 }
244 if (msgLen == 0) {
245 return -EINVAL;
246 }
247 msgIntr = (char *)malloc(msgLen);
248 if (msgIntr == NULL) {
249 return -ENOMEM;
250 }
251 MQUEUE_FD_U2K(personal);
252 receiveLen = mq_timedreceive(personal, msgIntr, msgLen, &kMsgPrio, absTimeout ? &timeout : NULL);//posix 接口的实现
253 if (receiveLen < 0) {
254 free(msgIntr);
255 return -get_errno();
256 }
257
258 if (msgPrio != NULL) {
259 ret = LOS_ArchCopyToUser(msgPrio, &kMsgPrio, sizeof(unsigned int));
260 if (ret != 0) {
261 free(msgIntr);
262 return -EFAULT;
263 }
264 }
265
266 ret = LOS_ArchCopyToUser(msg, msgIntr, receiveLen);
267 free(msgIntr);
268 if (ret != 0) {
269 return -EFAULT;
270 }
271 return receiveLen;
272}
ssize_t mq_timedreceive(mqd_t personal, char *msg, size_t msgLen, unsigned int *msgPrio, const struct timespec *absTimeout)
Definition: mqueue.c:801
void * malloc(size_t size)
动态分配内存块大小
Definition: malloc.c:81
void free(void *ptr)
释放ptr所指向的内存空间
Definition: malloc.c:66
函数调用图:

◆ SysMqTimedSend()

int SysMqTimedSend ( mqd_t  personal,
const char *  msg,
size_t  msgLen,
unsigned int  msgPrio,
const struct timespec *  absTimeout 
)

定时时间发送消息,任务将被阻塞,等待被唤醒写入消息

在文件 ipc_syscall.c195 行定义.

197{
198 int ret;
199 struct timespec timeout;
200 char *msgIntr = NULL;
201
202 if (absTimeout != NULL) {
203 ret = LOS_ArchCopyFromUser(&timeout, absTimeout, sizeof(struct timespec));
204 if (ret != 0) {
205 return -EFAULT;
206 }
207 }
208 if (msgLen == 0) {
209 return -EINVAL;
210 }
211 msgIntr = (char *)malloc(msgLen);
212 if (msgIntr == NULL) {
213 return -ENOMEM;
214 }
215 ret = LOS_ArchCopyFromUser(msgIntr, msg, msgLen);
216 if (ret != 0) {
217 free(msgIntr);
218 return -EFAULT;
219 }
220 MQUEUE_FD_U2K(personal);
221 ret = mq_timedsend(personal, msgIntr, msgLen, msgPrio, absTimeout ? &timeout : NULL);//posix 接口的实现
222 free(msgIntr);
223 if (ret < 0) {
224 return -get_errno();
225 }
226 return ret;
227}
int mq_timedsend(mqd_t personal, const char *msg, size_t msgLen, unsigned int msgPrio, const struct timespec *absTimeout)
Definition: mqueue.c:759
函数调用图:

◆ SysMqUnlink()

int SysMqUnlink ( const char *  mqName)
   从内核中删除名为mqName的消息队列
   如果该函数被调用了,但是仍然有进程已经打开了这个消息队列,那么这个消息队列
   的销毁会被推迟到所有的引用都被关闭时执行.并且函数 mq_unlink() 不需要阻塞
   到所有的引用都被关闭为止,它会立即返回.函数 mq_unlink()调用成功后, 如果在
   随后调用 mq_open() 时重用这个消息队列名字,效果就像这个名字的消息队列不存在,
   如果没有设置O_CREAT标志,函数mq_open() 会返回失败,否则会创建一个新的消息队列.
* 
参数
mqName
返回
int

在文件 ipc_syscall.c176 行定义.

177{
178 int ret;
179 int retValue;
180 char kMqName[PATH_MAX + 1] = { 0 };
181
182 retValue = LOS_StrncpyFromUser(kMqName, mqName, PATH_MAX);
183 if (retValue < 0) {
184 return retValue;
185 }
186
187 ret = mq_unlink(kMqName);
188 if (ret < 0) {
189 return -get_errno();
190 }
191 return ret;
192}
int mq_unlink(const char *mqName)
Definition: mqueue.c:656
函数调用图:

◆ SysPause()

int SysPause ( void  )

系统调用之暂停任务

在文件 ipc_syscall.c350 行定义.

351{
352 return OsPause();
353}
int OsPause(void)
通过信号挂起当前任务
Definition: los_signal.c:617
函数调用图:

◆ SysPthreadKill()

int SysPthreadKill ( pid_t  pid,
int  sig 
)

系统调用之之向进程发送信号

在文件 ipc_syscall.c307 行定义.

308{
309 return OsPthreadKill(pid, sig);
310}
int OsPthreadKill(UINT32 tid, int signo)
发送信号
Definition: los_signal.c:509
函数调用图:

◆ SysSigAction()

int SysSigAction ( int  sig,
const sigaction_t *restrict  sa,
sigaction_t *restrict  old,
size_t  sigsetsize 
)

注册信号,鸿蒙内核只捕捉了SIGSYS 信号

在文件 ipc_syscall.c274 行定义.

275{
276 return OsSigAction(sig, sa, old);
277}
int OsSigAction(int sig, const sigaction_t *act, sigaction_t *oact)
Definition: los_signal.c:677
函数调用图:

◆ SysSigPending()

int SysSigPending ( sigset_t_l setl)

获取阻塞当前任务的信号集

在文件 ipc_syscall.c355 行定义.

356{
357 sigset_t set;
358 int ret;
359
360 ret = LOS_ArchCopyFromUser(&set, &(setl->sig[0]), sizeof(sigset_t));
361 if (ret != 0) {
362 return -EFAULT;
363 }
364 ret = OsSigPending(&set);
365 if (ret != LOS_OK) {
366 return ret;
367 }
368 ret = LOS_ArchCopyToUser(&(setl->sig[0]), &set, sizeof(sigset_t));
369 if (ret != LOS_OK) {
370 return -EFAULT;
371 }
372 return ret;
373}
int OsSigPending(sigset_t *set)
获取阻塞当前任务的信号集
Definition: los_signal.c:541
unsigned long sig[MAX_SIG_ARRAY_IN_MUSL/sizeof(unsigned long)]
Definition: los_signal.h:166
函数调用图:

◆ SysSigprocMask()

int SysSigprocMask ( int  how,
const sigset_t_l *restrict  setl,
sigset_t_l *restrict  oldl,
size_t  sigsetsize 
)

系统调用之进程信号屏蔽, 什么意思?简单说就是 一个信号来了进程要不要处理,屏蔽就是不处理,注意不能屏蔽SIGKILL和SIGSTOP信号,必须要处理.

参数
howSIG_BLOCK 加入信号到进程屏蔽。set包含了希望阻塞的附加信号
SIG_UNBLOCK 从进程屏蔽里将信号删除。set包含了希望解除阻塞的信号
SIG_SETMASK 将set的值设定为新的进程屏蔽
setl
oldl
sigsetsize
返回
int

在文件 ipc_syscall.c290 行定义.

291{
292 CHECK_ASPACE(setl, sizeof(sigset_t_l));
293 CHECK_ASPACE(oldl, sizeof(sigset_t_l));
294 CPY_FROM_USER(setl);
295 CPY_FROM_USER(oldl);
296 /* Let OsSigprocMask do all of the work */
297 int ret = OsSigprocMask(how, setl, oldl);
298 CPY_TO_USER(oldl);
299 return ret;
300}
int OsSigprocMask(int how, const sigset_t_l *set, sigset_t_l *oldset)
Definition: los_signal.c:233
函数调用图:

◆ SysSigSuspend()

int SysSigSuspend ( sigset_t_l setl)

在文件 ipc_syscall.c375 行定义.

376{
377 sigset_t set;
378 int retVal;
379
380 retVal = LOS_ArchCopyFromUser(&set, &(setl->sig[0]), sizeof(sigset_t));
381 if (retVal != 0) {
382 return -EFAULT;
383 }
384
385 return OsSigSuspend(&set);
386}
int OsSigSuspend(const sigset_t *set)
用参数set代替进程的原有掩码,并暂停进程执行,直到收到信号再恢复原有掩码并继续执行进程。
Definition: los_signal.c:627
函数调用图:

◆ SysSigTimedWait()

int SysSigTimedWait ( const sigset_t_l setl,
siginfo_t *  info,
const struct timespec *  timeout,
size_t  sigsetsize 
)

在文件 ipc_syscall.c312 行定义.

313{
314 sigset_t set;
315 unsigned int tick;
316 int retVal, ret;
317 siginfo_t infoIntr;
318 struct timespec timeoutIntr;
319
320 retVal = LOS_ArchCopyFromUser(&set, &(setl->sig[0]), sizeof(sigset_t));
321 if (retVal != 0) {
322 return -EFAULT;
323 }
324
325 if (timeout == NULL) {
326 tick = LOS_WAIT_FOREVER;
327 } else {
328 retVal = LOS_ArchCopyFromUser(&timeoutIntr, timeout, sizeof(struct timespec));
329 if (retVal != 0) {
330 return -EFAULT;
331 }
332 if (!ValidTimeSpec(&timeoutIntr)) {
333 return -EINVAL;
334 }
335 tick = OsTimeSpec2Tick(&timeoutIntr);
336 }
337 ret = OsSigTimedWait(&set, &infoIntr, tick);
338 if (ret < 0) {
339 return ret;
340 }
341 if (info != NULL) {
342 retVal = LOS_ArchCopyToUser(info, &infoIntr, sizeof(siginfo_t));
343 if (retVal != 0) {
344 return -EFAULT;
345 }
346 }
347 return (ret == 0 ? infoIntr.si_signo : ret);
348}
int OsSigTimedWait(sigset_t *set, siginfo_t *info, unsigned int timeout)
让当前任务等待的信号
Definition: los_signal.c:604
STATIC INLINE BOOL ValidTimeSpec(const struct timespec *tp)
Definition: time_posix.h:53
STATIC INLINE UINT32 OsTimeSpec2Tick(const struct timespec *tp)
Definition: time_posix.h:68
函数调用图: