int main(int argc, char *argv[]) { int lfd, cfd; /* Listening and connected sockets */ struct sigaction sa; /* The "-i" option means we were invoked from inetd(8), so that all we need to do is handle the connection on STDIN_FILENO */ if (argc > 1 && strcmp(argv[1], "-i") == 0) { handleRequest(STDIN_FILENO); exit(EXIT_SUCCESS); } if (becomeDaemon(0) == -1) errExit("becomeDaemon"); sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; sa.sa_handler = grimReaper; if (sigaction(SIGCHLD, &sa, NULL) == -1) { syslog(LOG_ERR, "Error from sigaction(): %s", strerror(errno)); exit(EXIT_FAILURE); } lfd = inetListen(SERVICE, 10, NULL); if (lfd == -1) { syslog(LOG_ERR, "Could not create server socket (%s)", strerror(errno)); exit(EXIT_FAILURE); } for (;;) { cfd = accept(lfd, NULL, 0); /* Wait for connection */ if (cfd == -1) { syslog(LOG_ERR, "Failure in accept(): %s", strerror(errno)); continue; /* Try next */ } switch (fork()) { /* Create child for each client */ case -1: syslog(LOG_ERR, "Can't create child (%s)", strerror(errno)); close(cfd); /* Give up on this client */ break; /* May be temporary; try next client */ case 0: /* Child */ close(lfd); /* Don't need copy of listening socket */ handleRequest(cfd); _exit(EXIT_SUCCESS); default: /* Parent */ close(cfd); /* Don't need copy of connected socket */ break; /* Loop to accept next connection */ } } }
int main(int argc, char *argv[]) { int listenFd, acceptFd, connFd; socklen_t len; /* Size of socket address buffer */ void *addr; /* Buffer for socket address */ char addrStr[IS_ADDR_STR_LEN]; if (argc != 2 || strcmp(argv[1], "--help") == 0) usageErr("%s service\n", argv[0]); /* Create listening socket, obtain size of address structure */ listenFd = inetListen(argv[1], 5, &len); if (listenFd == -1) errExit("inetListen"); connFd = inetConnect(NULL, argv[1], SOCK_STREAM); if (connFd == -1) errExit("inetConnect"); acceptFd = accept(listenFd, NULL, NULL); if (acceptFd == -1) errExit("accept"); addr = malloc(len); if (addr == NULL) errExit("malloc"); if (getsockname(connFd, addr, &len) == -1) errExit("getsockname"); printf("getsockname(connFd): %s\n", inetAddressStr(addr, len, addrStr, IS_ADDR_STR_LEN)); if (getsockname(acceptFd, addr, &len) == -1) errExit("getsockname"); printf("getsockname(acceptFd): %s\n", inetAddressStr(addr, len, addrStr, IS_ADDR_STR_LEN)); if (getpeername(connFd, addr, &len) == -1) errExit("getpeername"); printf("getpeername(connFd): %s\n", inetAddressStr(addr, len, addrStr, IS_ADDR_STR_LEN)); if (getpeername(acceptFd, addr, &len) == -1) errExit("getpeername"); printf("getpeername(acceptFd): %s\n", inetAddressStr(addr, len, addrStr, IS_ADDR_STR_LEN)); sleep(30); /* Give us time to run netstat(8) */ exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { int lfd, cfd; /* Listening and connected sockets */ struct sigaction sa; if (becomeDaemon(0) == -1) errExit("becomeDaemon"); /* Establish SIGCHLD handler to reap terminated child processes */ sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; sa.sa_handler = grimReaper; if (sigaction(SIGCHLD, &sa, NULL) == -1) { syslog(LOG_ERR, "Error from sigaction(): %s", strerror(errno)); exit(EXIT_FAILURE); } lfd = inetListen(SERVICE, 10, NULL); if (lfd == -1) { syslog(LOG_ERR, "Could not create server socket (%s)", strerror(errno)); exit(EXIT_FAILURE); } for (;;) { cfd = accept(lfd, NULL, NULL); /* Wait for connection */ if (cfd == -1) { syslog(LOG_ERR, "Failure in accept(): %s", strerror(errno)); exit(EXIT_FAILURE); } /* Handle each client request in a new child process */ switch (fork()) { case -1: syslog(LOG_ERR, "Can't create child (%s)", strerror(errno)); close(cfd); /* Give up on this client */ break; /* May be temporary; try next client */ case 0: /* Child */ close(lfd); /* Unneeded copy of listening socket */ handleRequest(cfd); _exit(EXIT_SUCCESS); default: /* Parent */ close(cfd); /* Unneeded copy of connected socket */ break; /* Loop to accept next connection */ } } }
void startServer(void) { int pidfd; char pidpath[PATH_MAX]; int lfd, cfd; socklen_t addrlen; struct sockaddr claddr; lfd = inetListen(config.port, 0, &addrlen); if (lfd == -1) { errMsg(LOG_ERR, "Could not listen on port %s.", config.port); return; } snprintf(pidpath, PATH_MAX, "/var/run/syncedfs/server/%s.pid", config.resource); pidfd = createPidFile(config.ident, pidpath, 0); if (pidfd == -1) { errMsg(LOG_ERR, "Could not create pid file %s, Exiting server.", pidpath); return; } errMsg(LOG_INFO, "Server booted."); //setup signal handler to stop handling requests for (;;) { cfd = accept(lfd, (struct sockaddr *) &claddr, &addrlen); if (cfd == -1) { errnoMsg(LOG_ERR, "Error accepting client."); continue; } handleClient(cfd, &claddr, &addrlen); } // delete pid file if (deletePidFile(pidfd, pidpath) == -1) errExit(LOG_ERR, "Deleting PID file '%s'", pidpath); }
int main(int argc, char *argv[]) { uint32_t seqNum; char reqLenStr[INT_LEN]; /* Length of requested sequence */ char seqNumStr[INT_LEN]; /* Start of granted sequence */ struct sockaddr *claddr; int lfd, cfd, reqLen; socklen_t addrlen, alen; char addrStr[IS_ADDR_STR_LEN]; if (argc > 1 && strcmp(argv[1], "--help") == 0) usageErr("%s [init-seq-num]\n", argv[0]); seqNum = (argc > 1) ? getInt(argv[1], 0, "init-seq-num") : 0; /* Ignore the SIGPIPE signal, so that we find out about broken connection errors via a failure from write(). */ if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) errExit("signal"); lfd = inetListen(PORT_NUM_STR, 5, &addrlen); if (lfd == -1) fatal("inetListen() failed"); /* Allocate a buffer large enough to hold the client's socket address */ claddr = malloc(addrlen); if (claddr == NULL) errExit("malloc"); for (;;) { /* Handle clients iteratively */ /* Accept a client connection, obtaining client's address */ alen = addrlen; cfd = accept(lfd, (struct sockaddr *) claddr, &alen); if (cfd == -1) { errMsg("accept"); continue; } printf("Connection from %s\n", inetAddressStr(claddr, alen, addrStr, IS_ADDR_STR_LEN)); /* Read client request, send sequence number back */ if (readLine(cfd, reqLenStr, INT_LEN) <= 0) { close(cfd); continue; /* Failed read; skip request */ } reqLen = atoi(reqLenStr); if (reqLen <= 0) { /* Watch for misbehaving clients */ close(cfd); continue; /* Bad request; skip it */ } snprintf(seqNumStr, INT_LEN, "%d\n", seqNum); if (write(cfd, &seqNumStr, strlen(seqNumStr)) != strlen(seqNumStr)) fprintf(stderr, "Error on write"); seqNum += reqLen; /* Update sequence number */ if (close(cfd) == -1) /* Close connection */ errMsg("close"); } }