diff options
Diffstat (limited to 'drivers/staging/usbip/userspace/src/usbipd.c')
-rw-r--r-- | drivers/staging/usbip/userspace/src/usbipd.c | 141 |
1 files changed, 100 insertions, 41 deletions
diff --git a/drivers/staging/usbip/userspace/src/usbipd.c b/drivers/staging/usbip/userspace/src/usbipd.c index 3e913b861dc2..1c76cfd274d0 100644 --- a/drivers/staging/usbip/userspace/src/usbipd.c +++ b/drivers/staging/usbip/userspace/src/usbipd.c @@ -50,21 +50,30 @@ #define MAIN_LOOP_TIMEOUT 10 +#define DEFAULT_PID_FILE "/var/run/" PROGNAME ".pid" + static const char usbip_version_string[] = PACKAGE_STRING; static const char usbipd_help_string[] = - "usage: usbipd [options] \n" - " -D, --daemon \n" - " Run as a daemon process. \n" - " \n" - " -d, --debug \n" - " Print debugging information. \n" - " \n" - " -h, --help \n" - " Print this help. \n" - " \n" - " -v, --version \n" - " Show version. \n"; + "usage: usbipd [options]\n" + " -D, --daemon\n" + " Run as a daemon process.\n" + "\n" + " -d, --debug\n" + " Print debugging information.\n" + "\n" + " -PFILE, --pid FILE\n" + " Write process id to FILE.\n" + " If no FILE specified, use " DEFAULT_PID_FILE "\n" + "\n" + " -tPORT, --tcp-port PORT\n" + " Listen on TCP/IP port PORT.\n" + "\n" + " -h, --help\n" + " Print this help.\n" + "\n" + " -v, --version\n" + " Show version.\n"; static void usbipd_help(void) { @@ -286,13 +295,13 @@ static int do_accept(int listenfd) memset(&ss, 0, sizeof(ss)); - connfd = accept(listenfd, (struct sockaddr *) &ss, &len); + connfd = accept(listenfd, (struct sockaddr *)&ss, &len); if (connfd < 0) { err("failed to accept connection"); return -1; } - rc = getnameinfo((struct sockaddr *) &ss, len, host, sizeof(host), + rc = getnameinfo((struct sockaddr *)&ss, len, host, sizeof(host), port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV); if (rc) err("getnameinfo: %s", gai_strerror(rc)); @@ -328,56 +337,69 @@ int process_request(int listenfd) return 0; } -static void log_addrinfo(struct addrinfo *ai) +static void addrinfo_to_text(struct addrinfo *ai, char buf[], + const size_t buf_size) { char hbuf[NI_MAXHOST]; char sbuf[NI_MAXSERV]; int rc; + buf[0] = '\0'; + rc = getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV); if (rc) err("getnameinfo: %s", gai_strerror(rc)); - info("listening on %s:%s", hbuf, sbuf); + snprintf(buf, buf_size, "%s:%s", hbuf, sbuf); } static int listen_all_addrinfo(struct addrinfo *ai_head, int sockfdlist[]) { struct addrinfo *ai; int ret, nsockfd = 0; + const size_t ai_buf_size = NI_MAXHOST + NI_MAXSERV + 2; + char ai_buf[ai_buf_size]; for (ai = ai_head; ai && nsockfd < MAXSOCKFD; ai = ai->ai_next) { - sockfdlist[nsockfd] = socket(ai->ai_family, ai->ai_socktype, - ai->ai_protocol); - if (sockfdlist[nsockfd] < 0) + int sock; + addrinfo_to_text(ai, ai_buf, ai_buf_size); + dbg("opening %s", ai_buf); + sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (sock < 0) { + err("socket: %s: %d (%s)", + ai_buf, errno, strerror(errno)); continue; + } - usbip_net_set_reuseaddr(sockfdlist[nsockfd]); - usbip_net_set_nodelay(sockfdlist[nsockfd]); + usbip_net_set_reuseaddr(sock); + usbip_net_set_nodelay(sock); - if (sockfdlist[nsockfd] >= FD_SETSIZE) { - close(sockfdlist[nsockfd]); - sockfdlist[nsockfd] = -1; + if (sock >= FD_SETSIZE) { + err("FD_SETSIZE: %s: sock=%d, max=%d", + ai_buf, sock, FD_SETSIZE); + close(sock); continue; } - ret = bind(sockfdlist[nsockfd], ai->ai_addr, ai->ai_addrlen); + ret = bind(sock, ai->ai_addr, ai->ai_addrlen); if (ret < 0) { - close(sockfdlist[nsockfd]); - sockfdlist[nsockfd] = -1; + err("bind: %s: %d (%s)", + ai_buf, errno, strerror(errno)); + close(sock); continue; } - ret = listen(sockfdlist[nsockfd], SOMAXCONN); + ret = listen(sock, SOMAXCONN); if (ret < 0) { - close(sockfdlist[nsockfd]); - sockfdlist[nsockfd] = -1; + err("listen: %s: %d (%s)", + ai_buf, errno, strerror(errno)); + close(sock); continue; } - log_addrinfo(ai); - nsockfd++; + info("listening on %s", ai_buf); + sockfdlist[nsockfd++] = sock; } if (nsockfd == 0) @@ -398,9 +420,9 @@ static struct addrinfo *do_getaddrinfo(char *host, int ai_family) hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; - rc = getaddrinfo(host, USBIP_PORT_STRING, &hints, &ai_head); + rc = getaddrinfo(host, usbip_port_string, &hints, &ai_head); if (rc) { - err("failed to get a network address %s: %s", USBIP_PORT_STRING, + err("failed to get a network address %s: %s", usbip_port_string, gai_strerror(rc)); return NULL; } @@ -426,6 +448,31 @@ static void set_signal(void) sigaction(SIGCLD, &act, NULL); } +static const char *pid_file; + +static void write_pid_file() +{ + if (pid_file) { + dbg("creating pid file %s", pid_file); + FILE *fp = fopen(pid_file, "w"); + if (!fp) { + err("pid_file: %s: %d (%s)", + pid_file, errno, strerror(errno)); + return; + } + fprintf(fp, "%d\n", getpid()); + fclose(fp); + } +} + +static void remove_pid_file() +{ + if (pid_file) { + dbg("removing pid file %s", pid_file); + unlink(pid_file); + } +} + static int do_standalone_mode(int daemonize) { struct addrinfo *ai_head; @@ -452,6 +499,7 @@ static int do_standalone_mode(int daemonize) usbip_use_syslog = 1; } set_signal(); + write_pid_file(); ai_head = do_getaddrinfo(NULL, PF_UNSPEC); if (!ai_head) { @@ -496,8 +544,9 @@ static int do_standalone_mode(int daemonize) process_request(sockfdlist[i]); } } - } else + } else { dbg("heartbeat timeout on ppoll()"); + } } info("shutting down " PROGNAME); @@ -511,11 +560,13 @@ static int do_standalone_mode(int daemonize) int main(int argc, char *argv[]) { static const struct option longopts[] = { - { "daemon", no_argument, NULL, 'D' }, - { "debug", no_argument, NULL, 'd' }, - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, 'v' }, - { NULL, 0, NULL, 0 } + { "daemon", no_argument, NULL, 'D' }, + { "debug", no_argument, NULL, 'd' }, + { "pid", optional_argument, NULL, 'P' }, + { "tcp-port", required_argument, NULL, 't' }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'v' }, + { NULL, 0, NULL, 0 } }; enum { @@ -526,6 +577,7 @@ int main(int argc, char *argv[]) int daemonize = 0; int opt, rc = -1; + pid_file = NULL; usbip_use_stderr = 1; usbip_use_syslog = 0; @@ -535,7 +587,7 @@ int main(int argc, char *argv[]) cmd = cmd_standalone_mode; for (;;) { - opt = getopt_long(argc, argv, "Ddhv", longopts, NULL); + opt = getopt_long(argc, argv, "DdP::t:hv", longopts, NULL); if (opt == -1) break; @@ -550,6 +602,12 @@ int main(int argc, char *argv[]) case 'h': cmd = cmd_help; break; + case 'P': + pid_file = optarg ? optarg : DEFAULT_PID_FILE; + break; + case 't': + usbip_setup_port_number(optarg); + break; case 'v': cmd = cmd_version; break; @@ -563,6 +621,7 @@ int main(int argc, char *argv[]) switch (cmd) { case cmd_standalone_mode: rc = do_standalone_mode(daemonize); + remove_pid_file(); break; case cmd_version: printf(PROGNAME " (%s)\n", usbip_version_string); |