Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief Generic unix abstractions
0003  *
0004  * @file sys_genunix.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 <ndrstandard.h>
0051 #include <ndebug.h>
0052 #include <nstdutil.h>
0053 #include <limits.h>
0054 
0055 #include <sys_unix.h>
0056 
0057 #include "atmi_int.h"
0058 
0059 /*---------------------------Externs------------------------------------*/
0060 /*---------------------------Macros-------------------------------------*/
0061 /*---------------------------Enums--------------------------------------*/
0062 /*---------------------------Typedefs-----------------------------------*/
0063 /*---------------------------Globals------------------------------------*/
0064 /*---------------------------Statics------------------------------------*/
0065 /*---------------------------Prototypes---------------------------------*/
0066 
0067 
0068 /**
0069  * Checks weither process is running or not...
0070  * @param pid
0071  * @param proc_name
0072  * @return
0073  */
0074 expublic int ndrx_sys_is_process_running_by_ps(pid_t pid, char *proc_name)
0075 {
0076     /* CAUSES STALL ON AIX. */
0077     FILE *fp=NULL;
0078     char cmd[128];
0079     char path[PATH_MAX];
0080     int ret = EXFALSE;
0081     
0082     snprintf(cmd, sizeof(cmd), "ps -p %d -o comm=", pid);
0083     
0084     NDRX_LOG(log_debug, "About to check pid: [%s]", cmd);
0085     
0086     /* Open the command for reading. */
0087     fp = popen(cmd, "r");
0088     if (fp == NULL)
0089     {
0090         NDRX_LOG(log_warn, "failed to run command [%s]: %s", cmd, strerror(errno));
0091         goto out;
0092     }
0093     
0094     /* Check the process name in output... */
0095     while (fgets(path, sizeof(path)-1, fp) != NULL)
0096     {
0097         if (strstr(path, proc_name))
0098         {
0099             ret=EXTRUE;
0100             goto out;
0101         }
0102     }
0103 
0104 out:
0105     /* close */
0106     if (fp!=NULL)
0107     {
0108         pclose(fp);
0109     }
0110 
0111     NDRX_LOG(log_debug, "process %s status: %s", proc_name, 
0112             ret?"running":"not running");
0113     return ret;
0114 }
0115 
0116 
0117 /**
0118  * Checks weither process is running or not...
0119  * @param pid
0120  * @param proc_name
0121  * @return
0122  */
0123 expublic int ndrx_sys_is_process_running_by_kill(pid_t pid, char *proc_name)
0124 {
0125     int ret = EXFALSE;
0126     
0127     if (kill(pid, 0) == 0)
0128     {
0129         /* process is running or a zombie */
0130         ret = EXTRUE;
0131     }
0132     else if (errno == ESRCH)
0133     {
0134         /* no such process with the given pid is running */
0135         ret = EXFALSE;
0136     }
0137     else
0138     {
0139        NDRX_LOG(log_error, "Failed to test processes: %s", strerror(errno));
0140        ret = EXFALSE; /* some other error, assume process running... */ 
0141     }
0142 
0143     NDRX_LOG(log_debug, "process %s status: %s", proc_name?proc_name:"(unnamed)", 
0144             ret?"running":"not running");
0145     return ret;
0146 }
0147 
0148 /**
0149  * Test is pid alive
0150  * @param pid pid number to test
0151  * @return EXTRUE/EXFALSE/EXFAIL
0152  */
0153 expublic int ndrx_sys_is_process_running_by_pid(pid_t pid)
0154 {
0155     return ndrx_sys_is_process_running_by_kill(pid, NULL);
0156 }
0157 
0158 /**
0159  * Get the process name. No debug please, at it gets locked
0160  * because mostly it is firstly called from debug lib, if we call debug
0161  * again it will lock against semaphore.
0162  *
0163  * @param pid
0164  * @param proc_name
0165  * @return
0166  */
0167 expublic char * ndrx_sys_get_proc_name_by_ps(void)
0168 {
0169     static char out[PATH_MAX] = "unknown";
0170     FILE *fp=NULL;
0171     char path[PATH_MAX];
0172     char cmd[128] = {EXEOS};
0173     int ret = EXSUCCEED;
0174     static int first = EXTRUE;
0175     char *p = NULL;
0176     int err;
0177     int l;
0178     
0179     if (first)
0180     {
0181         snprintf(cmd, sizeof(cmd), "ps -p %d -o comm=", getpid());
0182 /* avoid recursive lookup by debug config
0183         NDRX_LOG(log_debug, "About to check pid: [%s]", cmd);
0184 */
0185 
0186         /* Open the command for reading. */
0187         fp = popen(cmd, "r");
0188         if (fp == NULL)
0189         {
0190             first = EXFALSE; /* avoid recursive lookup by debug lib*/
0191  /*           NDRX_LOG(log_warn, "failed to run command [%s]: %s", cmd, strerror(errno));*/
0192             goto out;
0193         }
0194 
0195         /* Check the process name in output... */
0196         if (fgets(path, sizeof(path)-1, fp) == NULL)
0197         {
0198             err = errno;
0199             ret=EXFAIL;
0200             goto out;
0201         }
0202 
0203         if (NULL==(p = strrchr(path, '/')))
0204         {
0205             p = path;
0206         }
0207 out:
0208         /* close */
0209         if (fp != NULL)
0210         {
0211             pclose(fp);
0212         }
0213 
0214         if (EXSUCCEED!=ret)
0215         {
0216             first = EXFALSE;
0217 /*            NDRX_LOG(log_error, "Failed to get proc name: %s", strerror(err));*/
0218         }
0219         else
0220         {
0221             l = strlen(p);
0222             
0223             if (l>0 && '\n'==p[l-1])
0224             {
0225                 p[l-1] = EXEOS;
0226                 l--;
0227             }
0228             
0229             if (l>0 && '\r'==p[l-1])
0230             {
0231                 p[l-1] = EXEOS;
0232                 l--;
0233             }
0234 
0235             while ('/'==p[0])
0236             {
0237                p++;
0238             }
0239 
0240 
0241             if (EXEOS!=*p)
0242             {
0243                 NDRX_STRCPY_SAFE(out, p);
0244             }
0245 
0246             first = EXFALSE;
0247 
0248 /*            NDRX_LOG(log_debug, "current process name [%s]", out);*/
0249         }
0250     }
0251     
0252     return out;
0253 }
0254 
0255 /**
0256  * Return list of message queues (actually it is list of named pipes
0257  * as work around for missing posix queue listing functions.
0258  * For emulated message queue
0259  */
0260 expublic string_list_t* ndrx_sys_mqueue_list_make_emq(char *qpath, int *return_status)
0261 {
0262     return ndrx_sys_folder_list(qpath, return_status);
0263 }
0264 
0265 /* vim: set ts=4 sw=4 et smartindent: */