p The exact method of quoting and escaping may vary, and is intended to match the conventions of the shell used by .Fn system and .Fn popen . It may not match the conventions used by other shells. In this implementation, the following transformation is applied to each input string: l -bullet -width indent t it is surrounded by single quotes
q ' , t any single quotes in the input are escaped by replacing them with the four-character sequence: .Li '\e'' , and t extraneous pairs of single quotes (caused by multiple adjacent single quotes in the input string, or by single quotes at the beginning or end of the input string) are elided. .El
p The .Fn shquote function transforms the string specified by its .Fa arg argument, and places the result into the memory pointed to by .Fa buf .
p The .Fn shquotev function transforms each of the .Fa argc strings specified by the array .Fa argv independently. The transformed strings are placed in the memory pointed to by .Fa buf , separated by spaces. It does not modify the pointer array specified by .Fa argv or the strings pointed to by the pointers in the array.
p Both functions write up to .Fa bufsize - 1 characters of output into the buffer pointed to by .Fa buf , then add a .Li NUL character to terminate the output string. If .Fa bufsize is given as zero, the .Fa buf parameter is ignored and no output is written. .Sh RETURN VALUES The .Fn shquote and .Fn shquotev functions return the number of characters necessary to hold the result from operating on their input strings, not including the terminating .Li NUL . That is, they return the length of the string that would have been written to the output buffer, if it were large enough. If an error occurs during processing, the value ((size_t)-1) is returned and .Va errno is set appropriately. .Sh EXAMPLES The following code fragment demonstrates how you might use .Fn shquotev to construct a command string to be used with .Fn system . The command uses an environment variable (which will be expanded by the shell) to determine the actual program to run. Note that the environment variable may be expanded by the shell into multiple words. The first word of the expansion will be used by the shell as the name of the program to run, and the rest will be passed as arguments to the program. d -literal -offset indent char **argv, c, *cmd; size_t cmdlen, len, qlen; int argc; ... /* * Size buffer to hold the command string, and allocate it. * Buffer of length one given to snprintf() for portability. */ cmdlen = snprintf(&c, 1, "${PROG-%s} ", PROG_DEFAULT); qlen = shquotev(argc, argv, NULL, 0); if (qlen == (size_t)-1) { ... } cmdlen += qlen + 1; cmd = malloc(cmdlen); if (cmd == NULL) { ... } /* Create the command string. */ len = snprintf(cmd, cmdlen, "${PROG-%s} ", PROG_DEFAULT); qlen = shquotev(argc, argv, cmd + len, cmdlen - len); if (qlen == (size_t)-1) { /* Should not ever happen. */ ... } len += qlen; /* "cmd" can now be passed to system(). */ .Ed
p The following example shows how you would implement the same functionality using the .Fn shquote function directly. d -literal -offset indent char **argv, c, *cmd; size_t cmdlen, len, qlen; int argc, i; ... /* * Size buffer to hold the command string, and allocate it. * Buffer of length one given to snprintf() for portability. */ cmdlen = snprintf(&c, 1, "${PROG-%s} ", PROG_DEFAULT); for (i = 0; i < argc; i++) { qlen = shquote(argv[i], NULL, 0); if (qlen == (size_t)-1) { ... } cmdlen += qlen + 1; } cmd = malloc(cmdlen); if (cmd == NULL) { ... } /* Start the command string with the env var reference. */ len = snprintf(cmd, cmdlen, "${PROG-%s} ", PROG_DEFAULT); /* Quote all of the arguments when copying them. */ for (i = 0; i < argc; i++) { qlen = shquote(argv[i], cmd + len, cmdlen - len); if (qlen == (size_t)-1) { /* Should not ever happen. */ ... } len += qlen; cmd[len++] = ' '; } cmd[--len] = '\e0'; /* "cmd" can now be passed to system(). */ .Ed .Sh SEE ALSO .Xr sh 1 , .Xr popen 3 , .Xr system 3 .Sh BUGS This implementation does not currently handle strings containing multibyte characters properly. To address this issue,
o the shell used by .Fn system and .Fn popen
c must first be fixed to handle multibyte characters. When that has been done, these functions can have multibyte character support enabled.