
#include<stdio.h>
#include<signal.h>
#include<unistd.h>
// for pthread 
#include<pthread.h>

#include<almemsys/almemsys.h>
#include"sitar_com.h"
#include"jpreturn.h"

// static int pids_count[COM_LEN];
// extern int pids_count[COM_LEN];

// for pthread 
// Pthreadに対応していますが、利用する関数側で以下を初期化してください。
extern pthread_mutex_t exec_mutex;

/*
char * execom(char *, char *, int, int);
*/


/* ------------- execom ------------- */
char * execom(char * com, char * buf, int interval, int out)
{
FILE * fp;
int retval;
int stat;
struct timeval tv;
fd_set rfds;
int ret = 0;
int fd;
char * errdata=COM_1;
int pid;
int gid;
int count = 0;  // 未使用

fp = NULL;

// for pthread 
//safe_pthread_mutex_lock(&exec_mutex);
//for(count = 0; count < COM_LEN; count++){
//   if(pids_count[count] != 1){
//      pids_count[count] = 1;
//      break;
//      }
//   if(count >= (COM_LEN - 1)){
//      #ifdef PEXEC_MUTEX_DEBUG
//      printf("PEXEC_MUTEX: execom(): exec command mutex max over!!! wait 3 sec <%d> %s\n", count, com);
//      #endif
//      sleep(1);
//      count = 0;
//      }
//   }
//#ifdef PEXEC_MUTEX_DEBUG
//printf("PEXEC_MUTEX: execom(): exec command mutex no <%d> %s %d\n", count, com, &pids_count);
//#endif
//pthread_mutex_unlock(&exec_mutex);



if((fp = p_popen(fp, com, "r", &pid, &gid, out, count)) == NULL){
   buf = safe_sprintf(buf, BUF_MAX, "%s -- %s --\n", COM_2, com);
   }
else {
   fd = fileno(fp);
   #ifdef PEXEC_DEBUG
   printf("PEXEC: execom(): popen FD %d PID %d\n", fd, pid);
   #endif
   tv.tv_sec = interval;  /* timeout */
   tv.tv_usec = 0;
   while(1){
      FD_ZERO(&rfds);
      FD_SET(fd, &rfds);

      retval = select(fd + 1, &rfds,  &rfds, NULL, &tv); 

      #ifdef PEXEC_DEBUG
      fprintf(stderr, "PEXEC: execom(): SELECT %d\n", retval);
      #endif


      // select にエラーがあったか何もおこらなかった TIME OUT & ERROR
      if(retval <= 0){

//       printf("PEXEC: PID=%d TIME OUT & ERROR retval %d (%s: %s) Limit=%d\n",pid, retval, errdata, com, interval);

         #ifdef PEXEC_DEBUG
         printf("PEXEC: err execom(retval %d): %s%s Kill PID=%d+ Limit=%d\n",retval, errdata, com, pid, interval);
         #endif
         buf = safe_sprintf(buf, BUF_MAX,"%s%s Kill PID=%d+ Limit=%d\n",
            errdata,com,pid,interval);

         if(pid > 1){

            #ifdef PEXEC_DEBUG
            printf("PEXEC: execom(): sitar pid %d gid %d\n", getpid(), getgid());
            printf("PEXEC: execom(): popen pid %d gid %d\n", pid, gid);
            printf("PEXEC: execom(): kill  pid %d pgid %d\n", pid, getpgid(pid));
            #endif

            if(pid != getpgid(pid)){
               if(setpgid(pid, pid)){
                  fprintf(stderr,"execom.c: fork stpgid no chenge!");
                  }
               else{
                  if(kill((pid * -1), SIGTERM)){
                     fprintf(stderr,"child process not killd 1 -PID = %d\n", (pid * -1));
                     }
                  }
               }
            else{
               if(kill((pid * -1), SIGTERM)){
                  fprintf(stderr,"child process not killd 2 -PID = %d\n", (pid * -1));
                  }
               }

            p_pclose(fp, pid, count);

//            // for pthread 
//            safe_pthread_mutex_lock(&exec_mutex);
//            pids_count[count] = 0;
//            #ifdef PEXEC_MUTEX_DEBUG
//            printf("PEXEC_MUTEX: execom(): exec command mutex no exit <%d> %s\n", count, com);
//            #endif
//            pthread_mutex_unlock(&exec_mutex);

            return buf;
            }
         } 

      // select で、時間内にあくしょんがあった。
      else{

//       printf("PEXEC: PID=%d true retval %d (%s: %s) Limit=%d\n",pid, retval, errdata, com, interval);

         #ifdef PEXEC_DEBUG
         printf("PEXEC: true execom(retval %d): %s%s Kill PID=%d+ Limit=%d\n",retval, errdata, com, pid, interval);
         #endif

         buf = safe_filefdcat(fd, buf, &stat, BUF_MAX, interval);
         ret = p_pclose(fp, pid, count);
         break;
         }



      }
   }

// for pthread 
//safe_pthread_mutex_lock(&exec_mutex);
//pids_count[count] = 0;
//#ifdef PEXEC_MUTEX_DEBUG
//printf("PEXEC_MUTEX: execom(): exec command mutex no exit <%d> %s\n", count, com);
//#endif
//pthread_mutex_unlock(&exec_mutex);

return buf;
}




