From bfa7967c4a18c9a7addbe853cf9f736ac34b4e5b Mon Sep 17 00:00:00 2001 From: Matt Kraai Date: Fri, 15 Dec 2000 22:34:34 +0000 Subject: [PATCH] Rewrite nc to be simpler, smaller, and to check syscalls for errors. --- busybox.h | 1 + include/busybox.h | 1 + nc.c | 57 +++++++++++++---------------------------------- networking/nc.c | 57 +++++++++++++---------------------------------- utility.c | 15 ++++++++++++- 5 files changed, 46 insertions(+), 85 deletions(-) diff --git a/busybox.h b/busybox.h index 41421ae56..5ff3975b9 100644 --- a/busybox.h +++ b/busybox.h @@ -147,6 +147,7 @@ int makeString(int argc, const char **argv, char *buf, int bufLen); char *getChunk(int size); char *chunkstrdup(const char *str); void freeChunks(void); +ssize_t safe_read(int fd, void *buf, size_t count); int full_write(int fd, const char *buf, int len); int full_read(int fd, char *buf, int len); int recursive_action(const char *fileName, int recurse, int followLinks, int depthFirst, diff --git a/include/busybox.h b/include/busybox.h index 41421ae56..5ff3975b9 100644 --- a/include/busybox.h +++ b/include/busybox.h @@ -147,6 +147,7 @@ int makeString(int argc, const char **argv, char *buf, int bufLen); char *getChunk(int size); char *chunkstrdup(const char *str); void freeChunks(void); +ssize_t safe_read(int fd, void *buf, size_t count); int full_write(int fd, const char *buf, int len); int full_read(int fd, char *buf, int len); int recursive_action(const char *fileName, int recurse, int followLinks, int depthFirst, diff --git a/nc.c b/nc.c index 84c1a815e..a2be8ec46 100644 --- a/nc.c +++ b/nc.c @@ -38,14 +38,10 @@ #include #include -#define BUFSIZE 100 - int nc_main(int argc, char **argv) { int sfd; - int result; - int len; - char ch[BUFSIZE]; + char buf[BUFSIZ]; struct sockaddr_in address; struct hostent *hostinfo; @@ -54,34 +50,26 @@ int nc_main(int argc, char **argv) argc--; argv++; - if (argc < 2 || **(argv + 1) == '-') { + if (argc < 2 || **argv == '-') { usage(nc_usage); } - sfd = socket(AF_INET, SOCK_STREAM, 0); + if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + perror_msg_and_die("socket"); - hostinfo = (struct hostent *) gethostbyname(*argv); - - if (!hostinfo) { + if ((hostinfo = gethostbyname(*argv)) == NULL) error_msg_and_die("cannot resolve %s\n", *argv); - } address.sin_family = AF_INET; address.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list; address.sin_port = htons(atoi(*(++argv))); - len = sizeof(address); - - result = connect(sfd, (struct sockaddr *) &address, len); - - if (result < 0) { - perror("nc: connect"); - exit(2); - } + if (connect(sfd, (struct sockaddr *) &address, sizeof(address)) < 0) + perror_msg_and_die("connect"); FD_ZERO(&readfds); FD_SET(sfd, &readfds); - FD_SET(fileno(stdin), &readfds); + FD_SET(STDIN_FILENO, &readfds); while (1) { int fd; @@ -90,41 +78,26 @@ int nc_main(int argc, char **argv) testfds = readfds; - result = - select(FD_SETSIZE, &testfds, (fd_set *) NULL, (fd_set *) NULL, - (struct timeval *) 0); - - if (result < 1) { - perror("nc: select"); - exit(3); - } + if (select(FD_SETSIZE, &testfds, NULL, NULL, NULL) < 0) + perror_msg_and_die("select"); for (fd = 0; fd < FD_SETSIZE; fd++) { if (FD_ISSET(fd, &testfds)) { - int trn = 0; - int rn; - - ioctl(fd, FIONREAD, &nread); + if ((nread = safe_read(fd, buf, sizeof(buf))) < 0) + perror_msg_and_die("read"); if (fd == sfd) { if (nread == 0) exit(0); - ofd = fileno(stdout); + ofd = STDOUT_FILENO; } else { if (nread == 0) shutdown(sfd, 1); ofd = sfd; } - - - do { - rn = (BUFSIZE < nread - trn) ? BUFSIZE : nread - trn; - trn += rn; - read(fd, ch, rn); - write(ofd, ch, rn); - } - while (trn < nread); + if (full_write(ofd, buf, nread) < 0) + perror_msg_and_die("write"); } } } diff --git a/networking/nc.c b/networking/nc.c index 84c1a815e..a2be8ec46 100644 --- a/networking/nc.c +++ b/networking/nc.c @@ -38,14 +38,10 @@ #include #include -#define BUFSIZE 100 - int nc_main(int argc, char **argv) { int sfd; - int result; - int len; - char ch[BUFSIZE]; + char buf[BUFSIZ]; struct sockaddr_in address; struct hostent *hostinfo; @@ -54,34 +50,26 @@ int nc_main(int argc, char **argv) argc--; argv++; - if (argc < 2 || **(argv + 1) == '-') { + if (argc < 2 || **argv == '-') { usage(nc_usage); } - sfd = socket(AF_INET, SOCK_STREAM, 0); + if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + perror_msg_and_die("socket"); - hostinfo = (struct hostent *) gethostbyname(*argv); - - if (!hostinfo) { + if ((hostinfo = gethostbyname(*argv)) == NULL) error_msg_and_die("cannot resolve %s\n", *argv); - } address.sin_family = AF_INET; address.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list; address.sin_port = htons(atoi(*(++argv))); - len = sizeof(address); - - result = connect(sfd, (struct sockaddr *) &address, len); - - if (result < 0) { - perror("nc: connect"); - exit(2); - } + if (connect(sfd, (struct sockaddr *) &address, sizeof(address)) < 0) + perror_msg_and_die("connect"); FD_ZERO(&readfds); FD_SET(sfd, &readfds); - FD_SET(fileno(stdin), &readfds); + FD_SET(STDIN_FILENO, &readfds); while (1) { int fd; @@ -90,41 +78,26 @@ int nc_main(int argc, char **argv) testfds = readfds; - result = - select(FD_SETSIZE, &testfds, (fd_set *) NULL, (fd_set *) NULL, - (struct timeval *) 0); - - if (result < 1) { - perror("nc: select"); - exit(3); - } + if (select(FD_SETSIZE, &testfds, NULL, NULL, NULL) < 0) + perror_msg_and_die("select"); for (fd = 0; fd < FD_SETSIZE; fd++) { if (FD_ISSET(fd, &testfds)) { - int trn = 0; - int rn; - - ioctl(fd, FIONREAD, &nread); + if ((nread = safe_read(fd, buf, sizeof(buf))) < 0) + perror_msg_and_die("read"); if (fd == sfd) { if (nread == 0) exit(0); - ofd = fileno(stdout); + ofd = STDOUT_FILENO; } else { if (nread == 0) shutdown(sfd, 1); ofd = sfd; } - - - do { - rn = (BUFSIZE < nread - trn) ? BUFSIZE : nread - trn; - trn += rn; - read(fd, ch, rn); - write(ofd, ch, rn); - } - while (trn < nread); + if (full_write(ofd, buf, nread) < 0) + perror_msg_and_die("write"); } } } diff --git a/utility.c b/utility.c index 02479d977..4654daec4 100644 --- a/utility.c +++ b/utility.c @@ -536,7 +536,7 @@ const char *time_string(time_t timeVal) } #endif /* BB_TAR || BB_AR */ -#if defined BB_TAR || defined BB_CP_MV || defined BB_AR || defined BB_DD +#if defined BB_AR || defined BB_CP_MV || defined BB_DD || defined BB_NC || defined BB_TAR /* * Write all of the supplied buffer out to a file. * This does multiple writes as necessary. @@ -1791,6 +1791,19 @@ int applet_name_compare(const void *x, const void *y) return strcmp(applet1->name, applet2->name); } +#if defined BB_NC +ssize_t safe_read(int fd, void *buf, size_t count) +{ + ssize_t n; + + do { + n = read(fd, buf, count); + } while (n < 0 && errno == EINTR); + + return n; +} +#endif + /* END CODE */ /* Local Variables: