Re: [CFT] Patch to bsdinstall to support root-on-ZFS and GELI

From: Teske, Devin <Devin.Teske_at_fisglobal.com>
Date: Wed, 9 Oct 2013 16:19:48 +0000
On Oct 9, 2013, at 8:29 AM, Warren Block wrote:

> On Tue, 8 Oct 2013, Teske, Devin wrote:
> 
>> "But shell is nasty; slow; and not as powerful as C" (it depends in what
>> context; the first is rhetoric, the second is only true for poor implement-
>> ations, and the third may be true in some contexts, but I consider the
>> answer to "how maintainable is it" to be a factor in the "power" of a
>> language, so don't necessarily consider C to be more powerful than
>> shell as the latter is as-or-more maintainable with fewer LoC and a
>> higher return on investment; see previous [above] arguments).
> 
> My question would be: why are sh and C the only choices?  If the answer is "because that's all we have in base", is that a valid concern?
> 
> As far as sh, it lacks many high- or even mid-level constructs and has real problems with quoting,

Enter helper functions...

dteske_at_scribe9.vicor.com bsdconfig $ grep '^# f_' /usr/share/bsdconfig/strings.subr 
# f_substr "$string" $start [ $length ]
# f_snprintf $var_to_set $size $format ...
# f_vsnprintf $var_to_set $size $format $format_args
# f_longest_line_length
# f_number_of_lines
# f_isinteger $arg
# f_uriencode [$text]
# f_uridecode [$text]
# f_replaceall $string $find $replace [$var_to_set]
# f_str2varname $string [$var_to_set]
# f_shell_escape $string [$var_to_set]
# f_shell_unescape $string [$var_to_set]
# f_expand_number $string [$var_to_set]

The ones dealing specifically with quoting are f_shell_escape() and f_shell_unescape().
With those two helper functions, I consider quoting in sh(1) to be complete and maleable
to handle all situations.



> parsing,

Surely, a strength. It can take a while to engrain or impart all the expansions and at-
what stage (and in what context) they are performed, but when you understand the
mechanics of (for example) in what order each element (escaped-sequences, params,
newlines, and sub-shells) is expanded... the parsing becomes an asset, not a
hindrance (imho). Not to mention the flexibility afforded by "compound strings".

Take for example, the following syntax (leveraging ordered expansion and compound
strings):

f_dialog_input bar \
	'Enter *any* text; including globs [*] and shell special chars [$`#'"']..."
f_dialog_input baz \
	"Enter some *more* non-conforming text please..."
f_shell_escape "$bar" bar
f_shell_escape "$baz" baz
items="'$bar' '$baz'"
show="You entered:\n1=%s\n2=%s\n"
eval printf \"\$show\" $items

I'd be surprised if you could get anything out but the values you enter.



> and output (2>&1 >&3, for example).

I think it helps to highlight a technique for solving the general-purpose issue of
how you launch a program and have it talk to a parent's maintained file-descriptor.

In C, you'd have to pass special args to posix_spawn(3) to get this functionality.
Talking about succinctness of syntax... that sequence is likely much shorter than
any syntax I've ever seen in C for setting up file descriptors. I've interfaced with
dialog(1) from within C and getting the data back from it is non-trivial.

ASIDE: You may be asking yourself... why on Earth would you fork-exec an
instance of dialog(1) from within C instead of using dialog(3)? There are some
rare cases when this is advantageous. Usually when you want to support a drop-
in replacement (like Xdialog(1)) for a long-running stateful widget (e.g. gauge).
Usually (>=99% of the time) a C program _should_ use dialog(3) but in those
rare cases ( see http://druidbsd.cvs.sf.net/viewvc/druidbsd/fdpv/ ) thank goodness
I haven't had to mangle the file descriptors to get back any data (I call out to gauge
and just pump it massive amounts of data via stdin through a pipe passed to the
posix_spawn(3) call -- no data to read back.

So I don't see the above syntax as anything to point out -- C programs have more
complicated setup for doing the same thing (they just have to do it less often).

Oh... and in bsdconfig, you'll notice I don't do that. Upon initialization I clone the
*real* terminal fd's _once_ and then use variables to reference the dup'd fd.


> These make it harder to do things (aka, more code to accomplish a task, more code to be maintained, more difficult to modify) than the higher level Perubython languages.
> 

Only because those languages have APIs that handle those things.

Which I might add that those APIs have to be maintained. In that spirit,
bsdconfig(8) provides the API for shell -- and similarly, said API (like most
APIs) will be need much less maintenance than the programs using said
API (how often do we make changes to posix_spawn(3)? or how often
does Perubython change an API call?).

It's in that light that the bsdconfig(8) shell API is also treated just like any
other API with respect to changes (I treat all the "*.subr" includes as though
they are an ABI -- changes to function arguments must be well thought out).


> In any case, thanks for working on this.  A functioning program in any language is better than a non-existent "better" one.

Indeed.
-- 
Devin

_____________
The information contained in this message is proprietary and/or confidential. If you are not the intended recipient, please: (i) delete the message and all copies; (ii) do not disclose, distribute or use the message in any manner; and (iii) notify the sender immediately. In addition, please be aware that any message addressed to our domain is subject to archiving and review by persons other than the intended recipient. Thank you.
Received on Wed Oct 09 2013 - 14:19:51 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:42 UTC