Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief Posix queues support
0003  *
0004  * @file sys_posixq.c
0005  */
0006 /* -----------------------------------------------------------------------------
0007  * Enduro/X Middleware Platform for Distributed Transaction Processing
0008  * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0009  * Copyright (C) 2017-2023, Mavimax, Ltd. All Rights Reserved.
0010  * This software is released under one of the following licenses:
0011  * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0012  * See LICENSE file for full text.
0013  * -----------------------------------------------------------------------------
0014  * AGPL license:
0015  *
0016  * This program is free software; you can redistribute it and/or modify it under
0017  * the terms of the GNU Affero General Public License, version 3 as published
0018  * by the Free Software Foundation;
0019  *
0020  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0021  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0022  * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
0023  * for more details.
0024  *
0025  * You should have received a copy of the GNU Affero General Public License along 
0026  * with this program; if not, write to the Free Software Foundation, Inc.,
0027  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0028  *
0029  * -----------------------------------------------------------------------------
0030  * A commercial use license is available from Mavimax, Ltd
0031  * contact@mavimax.com
0032  * -----------------------------------------------------------------------------
0033  */
0034 
0035 /*---------------------------Includes-----------------------------------*/
0036 #include <stdio.h>
0037 #include <stdlib.h>
0038 #include <time.h>
0039 
0040 #include <unistd.h>
0041 #include <stdarg.h>
0042 #include <ctype.h>
0043 #include <memory.h>
0044 #include <errno.h>
0045 #include <signal.h>
0046 #include <limits.h>
0047 #include <pthread.h>
0048 #include <string.h>
0049 
0050 #include <ndrx_config.h>
0051 #include <ndrstandard.h>
0052 #include <ndebug.h>
0053 #include <nstdutil.h>
0054 #include <limits.h>
0055 #include <mqueue.h>
0056 #include <sys/stat.h>
0057 #include <fcntl.h>
0058 
0059 /*---------------------------Externs------------------------------------*/
0060 /*---------------------------Macros-------------------------------------*/
0061 
0062 /*
0063  * We assume that this is thread safe.
0064  * Even if two threads get here. The work result will be the same.
0065  */
0066 #define API_ENTRY  if (M_first)\
0067     {\
0068         strcpy(M_qpath, getenv(CONF_NDRX_QPATH));\
0069         M_first = EXFALSE;\
0070     }
0071 /*---------------------------Enums--------------------------------------*/
0072 /*---------------------------Typedefs-----------------------------------*/
0073 /*---------------------------Globals------------------------------------*/
0074 /*---------------------------Statics------------------------------------*/
0075 static int M_first = EXTRUE;
0076 static char M_qpath[PATH_MAX] = {EXEOS};
0077 /*---------------------------Prototypes---------------------------------*/
0078 
0079 /**
0080  * This is version with registry files to FS
0081  * - Firstly open the queue,
0082  * - The open fifo file
0083  */
0084 expublic mqd_t ndrx_mq_open_with_registry(char *name, int oflag, 
0085         mode_t mode, struct mq_attr *attr)
0086 {
0087     mqd_t ret;
0088     char regpath[PATH_MAX];
0089     int err;
0090     API_ENTRY;
0091     
0092     sprintf(regpath, "%s%s", M_qpath, name);
0093     
0094     NDRX_LOG(log_debug, "opening, registry path built: [%s]", regpath);
0095     
0096     ret = mq_open(name, oflag, mode, attr);
0097     
0098     if ((mqd_t)EXFAIL!=ret && (oflag & O_CREAT))
0099     {
0100         if (EXSUCCEED!=mkfifo(regpath, S_IWUSR | S_IRUSR))
0101         {
0102             err = errno;
0103             NDRX_LOG(log_error, "Failed to open fifo file [%s]: %s", 
0104                     regpath, strerror(errno));
0105             if (EEXIST==err)
0106             {
0107                 NDRX_LOG(log_warn, "File already exists, ignore error...");
0108                 errno = 0;
0109             }
0110             else
0111             {
0112                 ret=(mqd_t)EXFAIL;
0113                 errno = err;
0114                 NDRX_LOG(log_error, "Removing queue...");
0115                 if (EXSUCCEED!=mq_unlink(name))
0116                 {
0117                     NDRX_LOG(log_error, "Failed to mq_unlink [%s]: %s", 
0118                             name, strerror(errno));
0119                 }
0120             }
0121         }
0122     }
0123     
0124     return ret;
0125 }
0126 
0127 /**
0128  * Remove the queue name from registry
0129  * - Remove the queue
0130  * - Then remove fifo file
0131  */
0132 expublic int ndrx_mq_unlink_with_registry (char *name)
0133 {   
0134     char regpath[PATH_MAX];
0135     int ret, err;
0136     API_ENTRY;
0137     
0138     sprintf(regpath, "%s%s", M_qpath, name);
0139     
0140     NDRX_LOG(log_debug, "deleting, registry path built: [%s]", regpath);
0141     
0142     if (EXSUCCEED!=(ret = mq_unlink(name)))
0143     {
0144         err = errno;
0145         NDRX_LOG(log_error, "Failed to mq_unlink [%s]: %s", name, strerror(err));
0146     }
0147     
0148     if (EXSUCCEED!=unlink(regpath))
0149     {
0150         NDRX_LOG(log_error, "Failed to unlink [%s]: %s", regpath, strerror(errno));
0151     }
0152     
0153     errno = err;
0154     
0155     return ret;
0156 }
0157 
0158 /* vim: set ts=4 sw=4 et smartindent: */