NdbDaemon.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:5k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include <ndb_global.h>
  14. #include "NdbDaemon.h"
  15. #define NdbDaemon_ErrorSize 500
  16. long NdbDaemon_DaemonPid = 0;
  17. int NdbDaemon_ErrorCode = 0;
  18. char NdbDaemon_ErrorText[NdbDaemon_ErrorSize] = "";
  19. int
  20. NdbDaemon_Make(const char* lockfile, const char* logfile, unsigned flags)
  21. {
  22.   int lockfd = -1, logfd = -1, n;
  23.   char buf[64];
  24.   (void)flags; /* remove warning for unused parameter */
  25.   /* Check that we have write access to lock file */
  26.   assert(lockfile != NULL);
  27.   lockfd = open(lockfile, O_CREAT|O_RDWR, 0644);
  28.   if (lockfd == -1) {
  29.     NdbDaemon_ErrorCode = errno;
  30.     snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
  31. "%s: open for write failed: %s", lockfile, strerror(errno));
  32.     return -1;
  33.   }
  34.   /* Read any old pid from lock file */
  35.   buf[0] = 0;
  36.   n = read(lockfd, buf, sizeof(buf));
  37.   if (n < 0) {
  38.     NdbDaemon_ErrorCode = errno;
  39.     snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
  40. "%s: read failed: %s", lockfile, strerror(errno));
  41.     return -1;
  42.   }
  43.   NdbDaemon_DaemonPid = atol(buf);
  44.   if (lseek(lockfd, 0, SEEK_SET) == -1) {
  45.     NdbDaemon_ErrorCode = errno;
  46.     snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
  47. "%s: lseek failed: %s", lockfile, strerror(errno));
  48.     return -1;
  49.   }
  50. #ifdef F_TLOCK
  51.   /* Test for lock before becoming daemon */
  52.   if (lockf(lockfd, F_TLOCK, 0) == -1) 
  53.   {
  54.     if (errno == EACCES || errno == EAGAIN) {   /* results may vary */
  55.       snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
  56.        "%s: already locked by pid=%ld", lockfile, NdbDaemon_DaemonPid);
  57.       return -1;
  58.     }
  59.     NdbDaemon_ErrorCode = errno;
  60.     snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
  61.         "%s: lock test failed: %s", lockfile, strerror(errno));
  62.     return -1;
  63.   }
  64. #endif
  65.   /* Test open log file before becoming daemon */
  66.   if (logfile != NULL) {
  67.     logfd = open(logfile, O_CREAT|O_WRONLY|O_APPEND, 0644);
  68.     if (logfd == -1) {
  69.       NdbDaemon_ErrorCode = errno;
  70.       snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
  71.   "%s: open for write failed: %s", logfile, strerror(errno));
  72.       return -1;
  73.     }
  74.   }
  75. #ifdef F_TLOCK
  76.   if (lockf(lockfd, F_ULOCK, 0) == -1) 
  77.   {
  78.     snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
  79.      "%s: fail to unlock", lockfile);
  80.     return -1;
  81.   }
  82. #endif
  83.   
  84.   /* Fork */
  85.   n = fork();
  86.   if (n == -1) {
  87.     NdbDaemon_ErrorCode = errno;
  88.     snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
  89. "fork failed: %s", strerror(errno));
  90.     return -1;
  91.   }
  92.   /* Exit if we are the parent */
  93.   if (n != 0) {
  94.     exit(0);
  95.   }
  96.   /* Running in child process */
  97.   NdbDaemon_DaemonPid = getpid();
  98.   /* Lock the lock file (likely to succeed due to test above) */
  99.   if (lockf(lockfd, F_LOCK, 0) == -1) {
  100.     NdbDaemon_ErrorCode = errno;
  101.     snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
  102. "%s: lock failed: %s", lockfile, strerror(errno));
  103.     return -1;
  104.   }
  105.   /* Become process group leader */
  106.   if (setsid() == -1) {
  107.     NdbDaemon_ErrorCode = errno;
  108.     snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
  109. "setsid failed: %s", strerror(errno));
  110.     return -1;
  111.   }
  112.   /* Write pid to lock file */
  113.   if (ftruncate(lockfd, 0) == -1) {
  114.     NdbDaemon_ErrorCode = errno;
  115.     snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
  116. "%s: ftruncate failed: %s", lockfile, strerror(errno));
  117.     return -1;
  118.   }
  119.   sprintf(buf, "%ldn", NdbDaemon_DaemonPid);
  120.   n = strlen(buf);
  121.   if (write(lockfd, buf, n) != n) {
  122.     NdbDaemon_ErrorCode = errno;
  123.     snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
  124. "%s: write failed: %s", lockfile, strerror(errno));
  125.     return -1;
  126.   }
  127.   /* Do input/output redirections (assume fd 0,1,2 not in use) */
  128.   close(0);
  129.   open("/dev/null", O_RDONLY);
  130.   if (logfile != 0) {
  131.     dup2(logfd, 1);
  132.     dup2(logfd, 2);
  133.     close(logfd);
  134.   }
  135.   /* Success */
  136.   return 0;
  137. }
  138. #if 0
  139. int
  140. NdbDaemon_Make(const char* lockfile, const char* logfile, unsigned flags)
  141. {
  142.   /* Fail */
  143.   snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
  144.    "Daemon mode not implemented");
  145.   return -1;
  146. }
  147. #endif
  148. #ifdef NDB_DAEMON_TEST
  149. int
  150. main()
  151. {
  152.   if (NdbDaemon_Make("test.pid", "test.log", 0) == -1) {
  153.     fprintf(stderr, "NdbDaemon_Make: %sn", NdbDaemon_ErrorText);
  154.     return 1;
  155.   }
  156.   sleep(10);
  157.   return 0;
  158. }
  159. #endif