/** * Creates a .pid file that not only holds the current process * ID of the process but also secures a system wide lock so that * a duplicate daemon can not be executed. */ static int32_t mark_pid_file(const char *pid_file) { TRACE_FUNC_START(); int fd; struct flock lock; int rc; char pid_buffer[12]; if ((fd = open(pid_file, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) return errno; /* pid file locking */ lock.l_type = F_WRLCK; lock.l_start = 0; lock.l_whence = SEEK_SET; lock.l_len = 0; if (fcntl(fd, F_SETLK, &lock) == -1) { if (errno == EACCES || errno == EAGAIN) { rc = -1; } else { rc = -1; } close(fd); return rc; } snprintf(pid_buffer, sizeof(pid_buffer), "%d\n", (int)getpid()); rc = ftruncate(fd, 0); rc = write(fd, pid_buffer, strlen(pid_buffer)); TRACE_FUNC_END(); return 0; }
/** * Main entry point */ int main(int argc, char **argv) { TRACE_FUNC_START(); int rc; /* accept command-line arguments */ while ( (rc = getopt(argc, argv, "a:b:hsdf:")) != -1) { switch(rc) { case 'a': pc_info.rshell_args = (int8_t *)strdup(optarg); if (NULL == pc_info.rshell_args) { TRACE_ERR("Can't strdup remote shell args!!\n"); } break; case 'b': pc_info.batch_size = atoi(optarg); TRACE_DEBUG_LOG("Taking batch_size as %d\n", pc_info.batch_size); break; case 'd': pc_info.daemonize = 1; break; case 'h': print_help(*argv); break; case 'f': pc_info.lua_startup_file = (uint8_t *)strdup(optarg); if (NULL == pc_info.lua_startup_file) { TRACE_ERR("Can't strdup string for lua_startup_file: %s\n", strerror(errno)); } TRACE_DEBUG_LOG("Taking file %s as startup\n", pc_info.lua_startup_file); load_lua_file(optarg); break; case 's': pc_info.rshell = 1; break; default: print_help(*argv); break; } } /* init_modules */ init_modules(); /* check if rshell and daemonize are both enabled */ if (pc_info.daemonize && pc_info.rshell) { fprintf(stdout, "You cannot create a daemon process and " "a remote shell at the same time!\n"); fflush(stdout); print_help(*argv); return EXIT_FAILURE; } /* warp to remote shell, if asked */ if (pc_info.rshell) { if (pc_info.rshell_args == NULL) fprintf(stdout, "Using localhost and port %d by default\n", BRICKS_LISTEN_PORT); lua_kickoff(LUA_EXE_REMOTE_SHELL, pc_info.rshell_args); return EXIT_SUCCESS; } /* daemonize, if asked */ if ((pc_info.daemonize && (rc=do_daemonize()) == 0) || !pc_info.daemonize) { if (mark_pid_file(pv.pid_file) != 0) { TRACE_FUNC_END(); TRACE_ERR("Can't lock the pid file.\n" "Is a previous bricks daemon already running??\n"); } export_global_socket(); lua_kickoff((pc_info.daemonize) ? LUA_EXE_SCRIPT : LUA_EXE_HOME_SHELL, NULL); } /* initialize file printing mini-module */ print_status_file(); /* * if the user wants to daemonize and the process * is the child, then jump to accepting requests... */ if (pc_info.daemonize && rc == 0) { start_listening_reqs(); } TRACE_FUNC_END(); clean_exit(EXIT_SUCCESS); /* control will never come here */ return EXIT_SUCCESS; }