当从CentOS上的C中的信号处理程序中调用时,localtime_r卡在一个锁上

Fat*_*ure 2 c linux

Env - C on CentOs,glib 2.5

我从我的信号处理程序中调用了一个日志功能.我想我正在使用所有异步信号安全功能.我的信号处理程序被调用两次并在localtime_r上被锁定.我需要做些什么来解决这个问题?

我的日志功能如下所示.如果格式化关闭,我道歉.

/**
 * Following async signal safe functions are used
 * fstat, time, localtime_r, asctime_r, rename, open, write, close
 *
 */

void sysLog( Sint8 *fname, Sint32 tskId, Sint32 logType, const char *format, ...)

{

FILE          *fp;

   time_t        sysTime;

   va_list       args;

   struct stat   fStat;

   mode_t        usrMask;

   Sint8         tmpStg[256];

   char         newFileName[256];

   char         localtimestamp[256];

   struct       tm newtime;

   int pfd;

   //-- to sprintf base header and main msg into buffers before write
   char logTimeEtc[255];

   char logMainMsg[1000];


    //Startup task must create this file
    if (stat( fname, &fStat ) < 0)
      if(errno!= ENOENT)
        return;

    //-- Get the local time
    time( &sysTime);
    localtime_r(&sysTime, &newtime);
    asctime_r(&newtime, localtimestamp );
    localtimestamp[24]=0;//remove line feed

    //clear user file and dir permissions
    usrMask = umask(0);

    //-- rename file when >10MB
    if (fStat.st_size < (10000000)) {
      if ((pfd = open(fname, O_WRONLY | O_CREAT | O_APPEND )) == -1){
        printf ("\n**ERR.%s fopen() %s Failed: name=%s  %s >> errno= %d\n",__FUNCTION__, fname, cmnTskName[tskId], strerror(errno), errno);
        return;
      }

    }
    else {
      //-- rename the current file, with current time stamp attached.
      strcpy(newFileName,fname);
      strcat(newFileName,"-");
      strcat(newFileName, (const char *)&localtimestamp[4]);
      rename(fname,newFileName);

      //-- open the file as new now
      if ((pfd = open(fname, O_WRONLY | O_CREAT | O_TRUNC)) == -1){
        printf ("\n**ERR.%s fopen() %s Failed: name=%s  %s >> errno= %d\n",__FUNCTION__, fname, cmnTskName[tskId], strerror(errno), errno);
        return;
      }
    }

    umask(usrMask);




    //-- Write initial standard stuff like timestamp, log type etc
    sprintf(logTimeEtc,"%s %s.%s: pid=%d ", &localtimestamp[4], logTypeName[logType],cmnTskName[tskId], getpid());
    write(pfd,logTimeEtc,strlen(logTimeEtc));

    //-- write main message
    va_start(args, format);
    vsprintf(logMainMsg, format, args);
    va_end(args);
    write(pfd,logMainMsg,strlen(logMainMsg));

    close(pfd);
}//-- sysLog
Run Code Online (Sandbox Code Playgroud)

Dav*_*har 6

这个问题可能是localtime_r()不是其实aysnc信号安全CentOS上.

它肯定不在POSIX指定的异步信号安全功能列表中.

  • @Amit:答案显然是"你没有".您需要重构代码,以便不需要从信号处理程序调用localtime_r().比如说,让信号处理程序设置一些标志并稍后进行格式化. (2认同)