#include #include #include #ifdef SEM_TIMEDWAIT #include #endif #include #include #include #include #include #include "ui_ipc.h" #define JMP_IF(cmd, retval, jmplabel) if ( (cmd) == retval ) { printf("(%s) == %p\n", #cmd, (void*)retval); goto jmplabel; } static sem_t *sems[SEM_NUM]; static mqd_t msqs[MSQ_NUM]; int ui_ipc_init(int is_master) { volatile int sp_oflags, mq_oflags; mode_t crt_flags; struct mq_attr m_attr; bzero(sems, sizeof(sem_t*)*SEM_NUM); bzero(msqs, sizeof(mqd_t)*MSQ_NUM); m_attr.mq_flags = 0; m_attr.mq_msgsize = IPC_MQSIZ; m_attr.mq_maxmsg = 3; m_attr.mq_curmsgs = 0; if (is_master) { sp_oflags = O_CREAT | O_EXCL; mq_oflags = O_NONBLOCK | O_CREAT | O_EXCL; crt_flags = S_IRUSR | S_IWUSR; JMP_IF( msqs[MQ_PW] = mq_open(MSQ_PWD, mq_oflags | O_RDONLY, crt_flags, &m_attr), (mqd_t)-1, error ); JMP_IF( msqs[MQ_IF] = mq_open(MSQ_INF, mq_oflags | O_WRONLY, crt_flags, &m_attr), (mqd_t)-1, error ); } else { sp_oflags = 0; mq_oflags = 0; crt_flags = 0; JMP_IF( msqs[MQ_PW] = mq_open(MSQ_PWD, mq_oflags | O_WRONLY, crt_flags, &m_attr), (mqd_t)-1, error ); JMP_IF( msqs[MQ_IF] = mq_open(MSQ_INF, mq_oflags | O_RDONLY, crt_flags, &m_attr), (mqd_t)-1, error ); } JMP_IF( sems[SEM_UI] = sem_open(SEM_GUI, sp_oflags, crt_flags, 0), SEM_FAILED, error ); return 0; error: return errno; } void ui_ipc_free(int is_master) { int i; for (i = 0; i < SEM_NUM; i++) { if (sems[i]) sem_close(sems[i]); } for (i = 0; i < MSQ_NUM; i++) { if (msqs[i]) mq_close(msqs[i]); } if (is_master > 0) { sem_unlink(SEM_GUI); mq_unlink(MSQ_PWD); mq_unlink(MSQ_INF); } } int ui_ipc_sempost(enum UI_IPC_SEM e_sp) { return ( sem_post(sems[e_sp]) ); } int ui_ipc_semwait(enum UI_IPC_SEM e_sp) { return ( sem_wait(sems[e_sp]) ); } int ui_ipc_semtrywait(enum UI_IPC_SEM e_sp) { return ( sem_trywait(sems[e_sp]) ); } int ui_ipc_getvalue(enum UI_IPC_SEM e_sp) { int sp_val = 0; if (sem_getvalue(sems[e_sp], &sp_val) != 0) { return -1; } return sp_val; } #ifdef SEM_TIMEDWAIT int ui_ipc_semtimedwait(enum UI_IPC_SEM e_sp, int timeout) { struct timespec ts; if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { return -1; } ts.tc_sec += timeout; return ( sem_timedwait(sems[q_mq], &ts) ); } #endif int ui_ipc_msgsend(enum UI_IPC_MSQ e_mq, const char *msg_ptr) { char *tmp = alloca(IPC_MQSIZ); memset(tmp, '\0', IPC_MQSIZ); strncpy(tmp, msg_ptr, IPC_MQSIZ); return ( mq_send(msqs[e_mq], tmp, IPC_MQSIZ, 0) ); } ssize_t ui_ipc_msgrecv(enum UI_IPC_MSQ e_mq, char *msg_ptr) { return mq_receive(msqs[e_mq], msg_ptr, IPC_MQSIZ, NULL); } long ui_ipc_msgcount(enum UI_IPC_MSQ e_mq) { struct mq_attr m_attr; bzero(&m_attr, sizeof(struct mq_attr)); if (mq_getattr(msqs[e_mq], &m_attr) != 0) return -1; return m_attr.mq_curmsgs; }