static void do_daemon(const char *opt) { if (!(opt && *opt)) die(2, "daemon requires an option (i.e. daemon=sys)"); int (*daemon_)(int,int); if (!strcmp(opt,"sys")) daemon_ = sys_daemon; else if (!strcmp(opt, "ours")) daemon_ = our_daemon; else die(2, "daemon: unknown option: %s", opt); int r = daemon_(1,0); if (r) die_errno(2, "%s daemon() failed = %d", opt, r); }
/** * Run daemon service */ void daemonize(char *port){ FNAME(); int sock = -1; struct addrinfo hints, *res, *p; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; if(getaddrinfo(NULL, port, &hints, &res) != 0){ ERR("getaddrinfo"); } struct sockaddr_in *ia = (struct sockaddr_in*)res->ai_addr; char str[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &(ia->sin_addr), str, INET_ADDRSTRLEN); // loop through all the results and bind to the first we can for(p = res; p != NULL; p = p->ai_next){ if((sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1){ WARN("socket"); continue; } int reuseaddr = 1; if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(int)) == -1){ ERR("setsockopt"); } if(bind(sock, p->ai_addr, p->ai_addrlen) == -1){ close(sock); WARN("bind"); continue; } break; // if we get here, we have a successfull connection } if(p == NULL){ putlog("failed to bind socket, exit"); // looped off the end of the list with no successful bind ERRX("failed to bind socket"); } freeaddrinfo(res); daemon_(sock); close(sock); putlog("socket closed, exit"); signals(0); }