The following outputs only $ with a newline.

{ i=0; while [ $i -lt 89 ]; do printf $i\\0; : $(( i++ )); done; } | 
        xargs -0 -I $ printf '%s\n' $

The problem is two fold. The first is that strnsubst gives up on
substituting since replstr is greater than maxsize. This should likely
cause an error, but I don't know the preferred way to do that.

The second problem is that count needs to be incremented so that the
utility will be run after a null byte. The patch below comes from
FreeBSD. https://svnweb.freebsd.org/base?view=revision&revision=142604

That commit also moved a count++. While I don't believe that it is
necessary; but it also doesn't hurt. I believe it makes the code easier
to follow as now all paths immediately short circuit to addch except
null and EOL.


Index: xargs.c
===================================================================
RCS file: /cvs/src/usr.bin/xargs/xargs.c,v
retrieving revision 1.29
diff -u -p -r1.29 xargs.c
--- xargs.c     18 Apr 2015 18:28:38 -0000      1.29
+++ xargs.c     27 Sep 2015 06:20:01 -0000
@@ -255,11 +255,9 @@ parse_input(int argc, char *argv[])
        ch = getchar();
        if (isblank(ch)) {
                /* Quotes escape tabs and spaces. */
-               if (insingle || indouble)
+               if (insingle || indouble || zflag)
                        goto addch;
                hasblank = 1;
-               if (zflag)
-                       goto addch;
                goto arg2;
        }
 
@@ -274,15 +272,22 @@ parse_input(int argc, char *argv[])
                }
                goto arg1;
        case '\0':
-               if (zflag)
+               if (zflag) {
+                       /*
+                        * Increment 'count', so that nulls will be treated
+                        * as end-of-line, as well as end-of-argument.  This
+                        * is needed so -0 works properly with -I and -L.
+                        */
+                       count++;
                        goto arg2;
+               }
                goto addch;
        case '\n':
+               if (zflag)
+                       goto addch;
                hasblank = 1;
                if (hadblank == 0)
                        count++;
-               if (zflag)
-                       goto addch;
 
                /* Quotes do not escape newlines. */
 arg1:          if (insingle || indouble)

Reply via email to