Page MenuHomeFreeBSD

D55617.id173018.diff
No OneTemporary

D55617.id173018.diff

diff --git a/usr.bin/yes/yes.1 b/usr.bin/yes/yes.1
--- a/usr.bin/yes/yes.1
+++ b/usr.bin/yes/yes.1
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd June 4, 2014
+.Dd March 2, 2026
.Dt YES 1
.Os
.Sh NAME
@@ -33,7 +33,7 @@
.Nd be repetitively affirmative
.Sh SYNOPSIS
.Nm
-.Op Ar expletive
+.Op Ar expletive ...
.Sh DESCRIPTION
The
.Nm
@@ -42,6 +42,8 @@
or, by default,
.Dq y ,
forever.
+If multiple arguments are given, they are concatenated into a single
+space-separated string.
.Sh SEE ALSO
.Xr jot 1 ,
.Xr seq 1
diff --git a/usr.bin/yes/yes.c b/usr.bin/yes/yes.c
--- a/usr.bin/yes/yes.c
+++ b/usr.bin/yes/yes.c
@@ -35,40 +35,71 @@
#include <string.h>
#include <unistd.h>
+#define EXP "y\n"
+#define EXPLEN strlen(EXP)
+#define MINBUF 8192
+#define MAXBUF (ARG_MAX + 2)
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: yes [expletive ...]\n");
+ exit(1);
+}
+
int
main(int argc, char **argv)
{
- char buf[8192];
- char y[2] = { 'y', '\n' };
- char * exp = y;
- size_t buflen = 0;
- size_t explen = sizeof(y);
- size_t more;
- ssize_t ret;
+ static char buf[MAXBUF] = EXP;
+ char *end = buf + sizeof(buf), *exp, *pos = buf + EXPLEN;
+ size_t buflen, explen = EXPLEN;
+ ssize_t wlen = 0;
+ int opt;
if (caph_limit_stdio() < 0 || caph_enter() < 0)
err(1, "capsicum");
- if (argc > 1) {
- exp = argv[1];
- explen = strlen(exp) + 1;
- exp[explen - 1] = '\n';
+ while ((opt = getopt(argc, argv, "")) != -1) {
+ switch (opt) {
+ default:
+ usage();
+ }
}
- if (explen <= sizeof(buf)) {
- while (buflen < sizeof(buf) - explen) {
- memcpy(buf + buflen, exp, explen);
- buflen += explen;
+ argc -= optind;
+ argv += optind;
+
+ /* Assemble the expletive */
+ if (argc > 0) {
+ /* Copy positional arguments into expletive buffer */
+ for (pos = buf, end = buf + sizeof(buf);
+ argc > 0 && pos < end; argc--, argv++) {
+ /* Separate with spaces */
+ if (pos > buf)
+ *pos++ = ' ';
+ exp = *argv;
+ while (*exp != '\0' && pos < end)
+ *pos++ = *exp++;
}
- exp = buf;
- explen = buflen;
+ /* This should not be possible, but check anyway */
+ if (pos > end - 2)
+ pos = end - 2;
+ *pos++ = '\n';
+ explen = pos - buf;
}
- more = explen;
- while ((ret = write(STDOUT_FILENO, exp + (explen - more), more)) > 0)
- if ((more -= ret) == 0)
- more = explen;
+ /* Double until we've passed MINBUF */
+ for (buflen = explen; buflen < MINBUF; pos += buflen, buflen += buflen)
+ memcpy(pos, buf, buflen);
+ *pos = '\0';
+ fprintf(stderr, "%zu\n", buflen);
+ /* Dump it to stdout */
+ end = (pos = buf) + buflen;
+ do {
+ pos = buf + (pos - buf + wlen) % explen;
+ wlen = write(STDOUT_FILENO, pos, end - pos);
+ } while (wlen > 0);
err(1, "stdout");
/*NOTREACHED*/
}

File Metadata

Mime Type
text/plain
Expires
Tue, Mar 3, 7:57 PM (2 h, 50 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29210790
Default Alt Text
D55617.id173018.diff (2 KB)

Event Timeline