#include "queue.hpp" queue::queue() { m_mode = QUEUE_MODE_RECV; m_filename = NULL; m_mqd = -1; memset( &m_msg, 0, sizeof(m_msg) ); } queue::~queue() { close(); release_filename(); } void queue::release_filename( void ) { if( m_filename ) { free( m_filename ); m_filename = NULL; } } void queue::set_mode_send( void ) { m_mode = QUEUE_MODE_SEND; } void queue::set_mode_recv( void ) { m_mode = QUEUE_MODE_RECV; } void queue::set_filename( const char* filename ) { release_filename(); if( filename ) { size_t size = strlen( filename ) + 1; m_filename = (char*)malloc( size ); snprintf( m_filename, size, "%s", filename ); } } int queue::open( void ) { int ret; int fd; char buf[20]; if( QUEUE_MODE_RECV == m_mode ) { if( -1 == m_mqd ) { m_mqd = msgget( IPC_PRIVATE, IPC_CREAT ); if( -1 == m_mqd ) { printf( "msgget() failed\n" ); return QUEUE_ERR_MSGGET_FAILED; } fd = ::open( m_filename, O_RDWR | O_CREAT ); if( -1 == fd ) { printf( "can not read %s\n", m_filename ); ret = msgctl( m_mqd, IPC_RMID, NULL ); if( -1 == ret ) printf( "msgctl() failed\n" ); return QUEUE_ERR_CANNOT_OPEN_FILE; } memset( buf, 0, 20 ); snprintf( buf, 20, "%d", m_mqd ); ret = write( fd, buf, 20 ); if( -1 == ret || 0 == ret ) { printf( "can not write %s\n", m_filename ); ret = msgctl( m_mqd, IPC_RMID, NULL ); if( -1 == ret ) printf( "msgctl() failed\n" ); } ::fsync( fd ); ::close( fd ); } } else { fd = ::open( m_filename, O_RDONLY ); if( -1 == fd ) { printf( "can not read %s\n", m_filename ); return QUEUE_ERR_CANNOT_OPEN_FILE; } memset( buf, 0, 20 ); ret = read( fd, buf, 20 ); if( -1 == ret ) { printf( "queue id read error\n" ); ::close( fd ); return QUEUE_ERR_ID_READ; } else if( 0 == ret ) { printf( "queue id file blank\n" ); ::close( fd ); return QUEUE_ERR_ID_BLANK; } else { m_mqd = atoi( buf ); } ::close( fd ); } } int queue::close( void ) { int ret; if( QUEUE_MODE_RECV == m_mode ) { if( -1 != m_mqd ) { ret = msgctl( m_mqd, IPC_RMID, NULL ); if( -1 == ret ) { printf( "msgctl( IPC_RMID ) failed\n" ); return QUEUE_ERR_MSGCTL_FAILED; } m_mqd = -1; } } return QUEUE_SUCCESS; } void queue::print( void ) { printf( "----------------------------------\n" ); printf( "m_mode : " ); if( QUEUE_MODE_SEND == m_mode ) printf( "send" ); if( QUEUE_MODE_RECV == m_mode ) printf( "recv" ); printf( "\n" ); printf( "----------------------------------\n" ); printf( "m_filename : " ); if( m_filename ) printf( "%s", m_filename ); printf( "\n" ); printf( "----------------------------------\n" ); printf( "m_mqd : %d\n", m_mqd ); printf( "----------------------------------\n" ); } int queue::recv( void ) { int ret; memset( &m_msg, 0, sizeof(msg_t) ); ret = msgrcv( m_mqd, &m_msg, sizeof(msgcmd_t), 0, IPC_NOWAIT ); if( -1 == ret ) { //printf( "msgrcv() failed\n" ); return QUEUE_ERR_MSGRCV_FAILED; } do_cmd( m_msg.msg.cmd, m_msg.msg.inf ); //printf( "recv cmd = [%s]\n", m_msg.msg.cmd ); //printf( "recv inf = [%s]\n", m_msg.msg.inf ); return QUEUE_SUCCESS; } int queue::send( const char* cmd, const char* inf ) { int ret; memset( &m_msg, 0, sizeof(msg_t) ); m_msg.mtype = 1; snprintf( m_msg.msg.cmd, QUEUE_MAX_CMD, "%s", cmd ); snprintf( m_msg.msg.inf, QUEUE_MAX_INF, "%s", inf ); ret = msgsnd( m_mqd, &m_msg, sizeof(msgcmd_t), 0 ); if( -1 == ret ) { printf( "msgsnd() failed\n" ); return QUEUE_ERR_MSGSND_FAILED; } return QUEUE_SUCCESS; } int queue::list( void ) { int max; int id; struct msqid_ds ds; struct msginfo msginfo; max = msgctl( 0, MSG_INFO, (struct msqid_ds*)&msginfo ); if( -1 == max ) { printf( "msgctl( MSG_INFO ) failed\n" ); return QUEUE_ERR_MSGCTL_FAILED; } printf( "------------------------------------------------\n" ); printf( "max = %d\n", max ); if( max > 0 ) { printf( "index id key messages\n" ); for( int i = 0; i <= max; i++ ) { id = msgctl( i, MSG_STAT, &ds); if( -1 == id ) { printf( "msgctl( MSG_STAT ) failed\n" ); return QUEUE_ERR_MSGCTL_FAILED; } printf( "%4d %8d 0x08lx %7ld\n", i, id, (unsigned long)ds.msg_perm.__key, (long)ds.msg_qnum ); } printf( "------------------------------------------------\n" ); } return QUEUE_SUCCESS; } int queue::all_list_clear( void ) { int ret; int max; int id; struct msqid_ds ds; struct msginfo msginfo; max = msgctl( 0, MSG_INFO, (struct msqid_ds*)&msginfo ); if( -1 == max ) { printf( "msgctl( MSG_INFO ) failed\n" ); return QUEUE_ERR_MSGCTL_FAILED; } if( max > 0 ) { for( int i = 0; i <= max; i++ ) { id = msgctl( i, MSG_STAT, &ds); if( -1 == id ) { printf( "msgctl( MSG_STAT ) failed\n" ); return QUEUE_ERR_MSGCTL_FAILED; } ret = msgctl( id, IPC_RMID, NULL ); if( -1 == ret ) { printf( "msgctl( IPC_RMID ) failed\n" ); return QUEUE_ERR_MSGCTL_FAILED; } } } return QUEUE_SUCCESS; }