1
/* Copyright (C) 2003 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
#include <ndb_global.h>
17
#include "NdbDaemon.h"
19
#define NdbDaemon_ErrorSize 500
20
long NdbDaemon_DaemonPid = 0;
21
int NdbDaemon_ErrorCode = 0;
22
char NdbDaemon_ErrorText[NdbDaemon_ErrorSize] = "";
25
NdbDaemon_Make(const char* lockfile, const char* logfile, unsigned flags)
27
int lockfd = -1, logfd = -1, n;
30
(void)flags; /* remove warning for unused parameter */
32
/* Check that we have write access to lock file */
33
assert(lockfile != NULL);
34
lockfd = open(lockfile, O_CREAT|O_RDWR, 0644);
36
NdbDaemon_ErrorCode = errno;
37
snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
38
"%s: open for write failed: %s", lockfile, strerror(errno));
41
/* Read any old pid from lock file */
43
n = read(lockfd, buf, sizeof(buf));
45
NdbDaemon_ErrorCode = errno;
46
snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
47
"%s: read failed: %s", lockfile, strerror(errno));
50
NdbDaemon_DaemonPid = atol(buf);
51
if (lseek(lockfd, 0, SEEK_SET) == -1) {
52
NdbDaemon_ErrorCode = errno;
53
snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
54
"%s: lseek failed: %s", lockfile, strerror(errno));
58
/* Test for lock before becoming daemon */
59
if (lockf(lockfd, F_TLOCK, 0) == -1)
61
if (errno == EACCES || errno == EAGAIN) { /* results may vary */
62
snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
63
"%s: already locked by pid=%ld", lockfile, NdbDaemon_DaemonPid);
66
NdbDaemon_ErrorCode = errno;
67
snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
68
"%s: lock test failed: %s", lockfile, strerror(errno));
72
/* Test open log file before becoming daemon */
73
if (logfile != NULL) {
74
logfd = open(logfile, O_CREAT|O_WRONLY|O_APPEND, 0644);
76
NdbDaemon_ErrorCode = errno;
77
snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
78
"%s: open for write failed: %s", logfile, strerror(errno));
83
if (lockf(lockfd, F_ULOCK, 0) == -1)
85
snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
86
"%s: fail to unlock", lockfile);
94
NdbDaemon_ErrorCode = errno;
95
snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
96
"fork failed: %s", strerror(errno));
99
/* Exit if we are the parent */
103
/* Running in child process */
104
NdbDaemon_DaemonPid = getpid();
105
/* Lock the lock file (likely to succeed due to test above) */
106
if (lockf(lockfd, F_LOCK, 0) == -1) {
107
NdbDaemon_ErrorCode = errno;
108
snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
109
"%s: lock failed: %s", lockfile, strerror(errno));
112
/* Become process group leader */
113
if (setsid() == -1) {
114
NdbDaemon_ErrorCode = errno;
115
snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
116
"setsid failed: %s", strerror(errno));
119
/* Write pid to lock file */
120
if (ftruncate(lockfd, 0) == -1) {
121
NdbDaemon_ErrorCode = errno;
122
snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
123
"%s: ftruncate failed: %s", lockfile, strerror(errno));
126
sprintf(buf, "%ld\n", NdbDaemon_DaemonPid);
128
if (write(lockfd, buf, n) != n) {
129
NdbDaemon_ErrorCode = errno;
130
snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
131
"%s: write failed: %s", lockfile, strerror(errno));
134
/* Do input/output redirections (assume fd 0,1,2 not in use) */
136
open("/dev/null", O_RDONLY);
148
NdbDaemon_Make(const char* lockfile, const char* logfile, unsigned flags)
151
snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
152
"Daemon mode not implemented");
157
#ifdef NDB_DAEMON_TEST
162
if (NdbDaemon_Make("test.pid", "test.log", 0) == -1) {
163
fprintf(stderr, "NdbDaemon_Make: %s\n", NdbDaemon_ErrorText);