Discussion:
[ast-developers] FreeBSD readlink(1)+realpath(1) sources + some test results... / was: Re: [urgent] realpath(1)+readlink(1) in libcmd?
Roland Mainz
2013-09-21 16:45:15 UTC
Permalink
can someone post urls for the man pages for
readlink(1)
realpath(1)
http://busybox.net/downloads/BusyBox.html
http://www.freebsd.org/cgi/man.cgi?query=readlink&apropos=0&sektion=1&manpath=FreeBSD+9.1-RELEASE&arch=default&format=html
http://www.freebsd.org/cgi/man.cgi?query=realpath&apropos=0&sektion=1&manpath=FreeBSD+9.1-RELEASE&arch=default&format=html
both man pages describe the operands as
[ path ... ]
[ file ... ]
but only the realpath says what happens if file is omitted (. is used)
neither say what happens if more than one path/file operand is specified
readlink annoyingly inverts -q/-v -- diagnostics are off by default -- *what other posix utility does that*
so what does readlink do in silent mode when it is invoked with
readlink is-a-symlink is-not-a-symlink is-another-symlink
from the refs roland supplied the gnu readlink and realpath are very close modulo defaults
mainly readlink with no --canonicalize* options is in "readlink" mode, otherwise "realpath" mode
and the annoying one: readlink by default suppresses diagnostics
so I need to know what happens on bsd and gnu for readlink and realpath for various combinations of
0,1,2,3 path/file operands and within that various combinations of
is-a-symlink is-not-a-symlink is-an-existing-path is-not-an-existing-path
in particular when there are multiple operands and an error occurs does the output have a blank line to mark the errors?
Only realpath(1) supports multiple paths per invocation while
readlink(1) only takes one link per invocation...
my intention is to provide one implementation of realpath with a union of the
ast --dirfd=fd + gnu readlink/realpath + bsd readlink/realpath options
and an additional --readlink option that puts it into "readlink" mode (operand is a symlink, diagnostics suppressed),
and a note that argv[0]=="*readlink" => --readlink
Ahhgllll... IMO it would be easier (and cleaner... and easier to
debug) to have two seperate utilities. I still haven't sorted out the
sum(1) thing which provides almost all possible (hash-)sums with the
slight twist that somewhere in the code is a small bug which makes it
incompatible in the output to md5sum(1) ... please... just try to
follow "KISS" and make two utilities from it (precedent: busybox(1)
did the same...) ...
this will given us one implementation and one document to manage
Just for the log:
1. FreeBSD readlink is available from
http://ftp.FreeBSD.org/pub/FreeBSD/ports/local-distfiles/dd/readlink-20010616.tar.gz
-- snip --
$ sum -x sha512 ../readlink-20010616.tar.gz'
a323c8afccdc25c8a63d97e0ed08674e7f63347c5910bcc453bf2baf87aa82ae1a63fb21e17ff5ab31a192a28c32946078d264620759d808c4ca4f775305b038
readlink-20010616.tar.gz
-- snip --

2. FreeBSD realpath(1) can be found here:
http://svnweb.freebsd.org/base/head/bin/realpath/

Took some searching to find them... it seems FreeBSD doesn't maintain
an unified search engine to find source files across projects like
OpenSolaris.org did... ;-(

Here are the test results for "readlink" ... note that busybox has no -f option:
-- snip --
$ readlink_freebsd bar
foo
$ busybox readlink bar
foo
$ readlink_freebsd . ; echo $?
1
$ readlink_gnu . ; echo $?
1
$ busybox readlink . ; echo $?
1
$ readlink_freebsd -f bar
/home/test001/tmp/readlink_test/readlink-20010616/foo
$ readlink_gnu -f bar
/home/test001/tmp/readlink_test/readlink-20010616/foo
$ readlink_gnu -f .
/home/test001/tmp/readlink_test/readlink-20010616
$ readlink_freebsd -f .
/home/test001/tmp/readlink_test/readlink-20010616
$ readlink does_not_exist ; echo $?
1
$ readlink_freebsd does_not_exist ; echo $?
1
$ readlink -f does_not_exist ; echo $?
/home/test001/tmp/readlink_test/readlink-20010616/does_not_exist
0
$ readlink_freebsd -f does_not_exist ; echo $?
/home/test001/tmp/readlink_test/readlink-20010616/does_not_exist
0
-- snip --


Quick dumb testscript for realpath(1):
-- snip --
typeset -a cmd=(
realpath_gnu
realpath_bsd
realpath_busybox
)

function realpath_gnu
{
/usr/bin/realpath_gnu "$@"
}
function realpath_bsd
{
/usr/bin/realpath_bsd "$@"
}
function realpath_busybox
{
busybox realpath "$@"
}

ln -sf foo bar

for cmd in "${cmd[@]}" ; do
for options in '.' "$PWD" 'bar' 'foo' 'no_such_file'; do
output="${ ${cmd} ${options} 2>&1 ; (( res=$?)) ; }"
printf '# cmd=%q: options=%q output=%q, exit_code=%d\n' \
"${cmd}" \
"${options}" \
"${output}" "res"
done
done

-- snip --
... and the output is:
-- snip --
# cmd=realpath_gnu: options=.
output=/home/test001/tmp/readlink_test/readlink-20010616, exit_code=0
# cmd=realpath_gnu:
options=/home/test001/tmp/readlink_test/readlink-20010616
output=/home/test001/tmp/readlink_test/readlink-20010616, exit_code=0
# cmd=realpath_gnu: options=bar
output=/home/test001/tmp/readlink_test/readlink-20010616/foo,
exit_code=0
# cmd=realpath_gnu: options=foo
output=/home/test001/tmp/readlink_test/readlink-20010616/foo,
exit_code=0
# cmd=realpath_gnu: options=no_such_file
output=/home/test001/tmp/readlink_test/readlink-20010616/no_such_file,
exit_code=0
# cmd=realpath_bsd: options=.
output=/home/test001/tmp/readlink_test/readlink-20010616, exit_code=0
# cmd=realpath_bsd:
options=/home/test001/tmp/readlink_test/readlink-20010616
output=/home/test001/tmp/readlink_test/readlink-20010616, exit_code=0
# cmd=realpath_bsd: options=bar
output=/home/test001/tmp/readlink_test/readlink-20010616/foo,
exit_code=0
# cmd=realpath_bsd: options=foo
output=/home/test001/tmp/readlink_test/readlink-20010616/foo,
exit_code=0
# cmd=realpath_bsd: options=no_such_file
output=/home/test001/tmp/readlink_test/readlink-20010616/no_such_file,
exit_code=0
# cmd=realpath_busybox: options=.
output=/home/test001/tmp/readlink_test/readlink-20010616, exit_code=0
# cmd=realpath_busybox:
options=/home/test001/tmp/readlink_test/readlink-20010616
output=/home/test001/tmp/readlink_test/readlink-20010616, exit_code=0
# cmd=realpath_busybox: options=bar
output=/home/test001/tmp/readlink_test/readlink-20010616/foo,
exit_code=0
# cmd=realpath_busybox: options=foo
output=/home/test001/tmp/readlink_test/readlink-20010616/foo,
exit_code=0
# cmd=realpath_busybox: options=no_such_file
output=/home/test001/tmp/readlink_test/readlink-20010616/no_such_file,
exit_code=0
-- snip --

I still need some time (mostly due to being sick (still twitching)) to
come up with good testcases... ;-/

----

Bye,
Roland
--
__ . . __
(o.\ \/ /.o) roland.mainz at nrubsig.org
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer
/O /==\ O\ TEL +49 641 3992797
(;O/ \/ \O;)
Glenn Fowler
2013-09-22 03:01:15 UTC
Permalink
Post by Roland Mainz
can someone post urls for the man pages for
readlink(1)
realpath(1)
http://busybox.net/downloads/BusyBox.html
http://www.freebsd.org/cgi/man.cgi?query=readlink&apropos=0&sektion=1&manpath=FreeBSD+9.1-RELEASE&arch=default&format=html
http://www.freebsd.org/cgi/man.cgi?query=realpath&apropos=0&sektion=1&manpath=FreeBSD+9.1-RELEASE&arch=default&format=html
both man pages describe the operands as
[ path ... ]
[ file ... ]
but only the realpath says what happens if file is omitted (. is used)
neither say what happens if more than one path/file operand is specified
readlink annoyingly inverts -q/-v -- diagnostics are off by default -- *what other posix utility does that*
so what does readlink do in silent mode when it is invoked with
readlink is-a-symlink is-not-a-symlink is-another-symlink
from the refs roland supplied the gnu readlink and realpath are very close modulo defaults
mainly readlink with no --canonicalize* options is in "readlink" mode, otherwise "realpath" mode
and the annoying one: readlink by default suppresses diagnostics
so I need to know what happens on bsd and gnu for readlink and realpath for various combinations of
0,1,2,3 path/file operands and within that various combinations of
is-a-symlink is-not-a-symlink is-an-existing-path is-not-an-existing-path
in particular when there are multiple operands and an error occurs does the output have a blank line to mark the errors?
Only realpath(1) supports multiple paths per invocation while
readlink(1) only takes one link per invocation...
my intention is to provide one implementation of realpath with a union of the
ast --dirfd=fd + gnu readlink/realpath + bsd readlink/realpath options
and an additional --readlink option that puts it into "readlink" mode (operand is a symlink, diagnostics suppressed),
and a note that argv[0]=="*readlink" => --readlink
Ahhgllll... IMO it would be easier (and cleaner... and easier to
debug) to have two seperate utilities. I still haven't sorted out the
sum(1) thing which provides almost all possible (hash-)sums with the
slight twist that somewhere in the code is a small bug which makes it
incompatible in the output to md5sum(1) ... please... just try to
follow "KISS" and make two utilities from it (precedent: busybox(1)
did the same...) ...
this will given us one implementation and one document to manage
1. FreeBSD readlink is available from
http://ftp.FreeBSD.org/pub/FreeBSD/ports/local-distfiles/dd/readlink-20010616.tar.gz
-- snip --
$ sum -x sha512 ../readlink-20010616.tar.gz'
a323c8afccdc25c8a63d97e0ed08674e7f63347c5910bcc453bf2baf87aa82ae1a63fb21e17ff5ab31a192a28c32946078d264620759d808c4ca4f775305b038
readlink-20010616.tar.gz
-- snip --
http://svnweb.freebsd.org/base/head/bin/realpath/
Took some searching to find them... it seems FreeBSD doesn't maintain
an unified search engine to find source files across projects like
OpenSolaris.org did... ;-(
-- snip --
$ readlink_freebsd bar
foo
$ busybox readlink bar
foo
$ readlink_freebsd . ; echo $?
1
$ readlink_gnu . ; echo $?
1
$ busybox readlink . ; echo $?
1
$ readlink_freebsd -f bar
/home/test001/tmp/readlink_test/readlink-20010616/foo
$ readlink_gnu -f bar
/home/test001/tmp/readlink_test/readlink-20010616/foo
$ readlink_gnu -f .
/home/test001/tmp/readlink_test/readlink-20010616
$ readlink_freebsd -f .
/home/test001/tmp/readlink_test/readlink-20010616
$ readlink does_not_exist ; echo $?
1
$ readlink_freebsd does_not_exist ; echo $?
1
$ readlink -f does_not_exist ; echo $?
/home/test001/tmp/readlink_test/readlink-20010616/does_not_exist
0
$ readlink_freebsd -f does_not_exist ; echo $?
/home/test001/tmp/readlink_test/readlink-20010616/does_not_exist
0
-- snip --
-- snip --
typeset -a cmd=(
realpath_gnu
realpath_bsd
realpath_busybox
)
function realpath_gnu
{
}
function realpath_bsd
{
}
function realpath_busybox
{
}
ln -sf foo bar
for options in '.' "$PWD" 'bar' 'foo' 'no_such_file'; do
output="${ ${cmd} ${options} 2>&1 ; (( res=$?)) ; }"
printf '# cmd=%q: options=%q output=%q, exit_code=%d\n' \
"${cmd}" \
"${options}" \
"${output}" "res"
done
done
-- snip --
-- snip --
# cmd=realpath_gnu: options=.
output=/home/test001/tmp/readlink_test/readlink-20010616, exit_code=0
options=/home/test001/tmp/readlink_test/readlink-20010616
output=/home/test001/tmp/readlink_test/readlink-20010616, exit_code=0
# cmd=realpath_gnu: options=bar
output=/home/test001/tmp/readlink_test/readlink-20010616/foo,
exit_code=0
# cmd=realpath_gnu: options=foo
output=/home/test001/tmp/readlink_test/readlink-20010616/foo,
exit_code=0
# cmd=realpath_gnu: options=no_such_file
output=/home/test001/tmp/readlink_test/readlink-20010616/no_such_file,
exit_code=0
# cmd=realpath_bsd: options=.
output=/home/test001/tmp/readlink_test/readlink-20010616, exit_code=0
options=/home/test001/tmp/readlink_test/readlink-20010616
output=/home/test001/tmp/readlink_test/readlink-20010616, exit_code=0
# cmd=realpath_bsd: options=bar
output=/home/test001/tmp/readlink_test/readlink-20010616/foo,
exit_code=0
# cmd=realpath_bsd: options=foo
output=/home/test001/tmp/readlink_test/readlink-20010616/foo,
exit_code=0
# cmd=realpath_bsd: options=no_such_file
output=/home/test001/tmp/readlink_test/readlink-20010616/no_such_file,
exit_code=0
# cmd=realpath_busybox: options=.
output=/home/test001/tmp/readlink_test/readlink-20010616, exit_code=0
options=/home/test001/tmp/readlink_test/readlink-20010616
output=/home/test001/tmp/readlink_test/readlink-20010616, exit_code=0
# cmd=realpath_busybox: options=bar
output=/home/test001/tmp/readlink_test/readlink-20010616/foo,
exit_code=0
# cmd=realpath_busybox: options=foo
output=/home/test001/tmp/readlink_test/readlink-20010616/foo,
exit_code=0
# cmd=realpath_busybox: options=no_such_file
output=/home/test001/tmp/readlink_test/readlink-20010616/no_such_file,
exit_code=0
-- snip --
I still need some time (mostly due to being sick (still twitching)) to
come up with good testcases... ;-/
thanks for the tests
I won't be reading the other implementation sources
what happens with 0 operands and 2 operands
both man pages specify
[ path ... ]
which implies 0 or more path args
ольга крыжановская
2013-09-22 17:35:39 UTC
Permalink
Test data from GNU and busybox readlink(1):
$ ln -s valeria vem
$ ln -s ilja iam
$ /usr/bin/readlink vem iam
/usr/bin/readlink: extra operand ?iam?
Try '/usr/bin/readlink --help' for more information.
$ busybox readlink vem iam
BusyBox v1.20.2 (2013-01-26 23:10:13 UTC) multi-call binary.

Usage: readlink FILE

Display the value of a symlink

Test data from GNU and busybox realpath(1):
$ ln -s valeria vem
$ ln -s ilja iam
$ /usr/bin/realpath $PWD/vem $PWD/iam
/tmp/linktest/valeria
/tmp/linktest/ilja
$ busybox realpath $PWD/vem $PWD/iam
/tmp/linktest/valeria
/tmp/linktest/ilja

Olga
Post by Glenn Fowler
Post by Roland Mainz
can someone post urls for the man pages for
readlink(1)
realpath(1)
http://busybox.net/downloads/BusyBox.html
http://www.freebsd.org/cgi/man.cgi?query=readlink&apropos=0&sektion=1&manpath=FreeBSD+9.1-RELEASE&arch=default&format=html
http://www.freebsd.org/cgi/man.cgi?query=realpath&apropos=0&sektion=1&manpath=FreeBSD+9.1-RELEASE&arch=default&format=html
both man pages describe the operands as
[ path ... ]
[ file ... ]
but only the realpath says what happens if file is omitted (. is used)
neither say what happens if more than one path/file operand is specified
readlink annoyingly inverts -q/-v -- diagnostics are off by default -- *what other posix utility does that*
so what does readlink do in silent mode when it is invoked with
readlink is-a-symlink is-not-a-symlink is-another-symlink
from the refs roland supplied the gnu readlink and realpath are very close modulo defaults
mainly readlink with no --canonicalize* options is in "readlink" mode, otherwise "realpath" mode
and the annoying one: readlink by default suppresses diagnostics
so I need to know what happens on bsd and gnu for readlink and realpath for various combinations of
0,1,2,3 path/file operands and within that various combinations of
is-a-symlink is-not-a-symlink is-an-existing-path is-not-an-existing-path
in particular when there are multiple operands and an error occurs does the output have a blank line to mark the errors?
Only realpath(1) supports multiple paths per invocation while
readlink(1) only takes one link per invocation...
my intention is to provide one implementation of realpath with a union of the
ast --dirfd=fd + gnu readlink/realpath + bsd readlink/realpath options
and an additional --readlink option that puts it into "readlink" mode (operand is a symlink, diagnostics suppressed),
and a note that argv[0]=="*readlink" => --readlink
Ahhgllll... IMO it would be easier (and cleaner... and easier to
debug) to have two seperate utilities. I still haven't sorted out the
sum(1) thing which provides almost all possible (hash-)sums with the
slight twist that somewhere in the code is a small bug which makes it
incompatible in the output to md5sum(1) ... please... just try to
follow "KISS" and make two utilities from it (precedent: busybox(1)
did the same...) ...
this will given us one implementation and one document to manage
1. FreeBSD readlink is available from
http://ftp.FreeBSD.org/pub/FreeBSD/ports/local-distfiles/dd/readlink-20010616.tar.gz
-- snip --
$ sum -x sha512 ../readlink-20010616.tar.gz'
a323c8afccdc25c8a63d97e0ed08674e7f63347c5910bcc453bf2baf87aa82ae1a63fb21e17ff5ab31a192a28c32946078d264620759d808c4ca4f775305b038
readlink-20010616.tar.gz
-- snip --
http://svnweb.freebsd.org/base/head/bin/realpath/
Took some searching to find them... it seems FreeBSD doesn't maintain
an unified search engine to find source files across projects like
OpenSolaris.org did... ;-(
-- snip --
$ readlink_freebsd bar
foo
$ busybox readlink bar
foo
$ readlink_freebsd . ; echo $?
1
$ readlink_gnu . ; echo $?
1
$ busybox readlink . ; echo $?
1
$ readlink_freebsd -f bar
/home/test001/tmp/readlink_test/readlink-20010616/foo
$ readlink_gnu -f bar
/home/test001/tmp/readlink_test/readlink-20010616/foo
$ readlink_gnu -f .
/home/test001/tmp/readlink_test/readlink-20010616
$ readlink_freebsd -f .
/home/test001/tmp/readlink_test/readlink-20010616
$ readlink does_not_exist ; echo $?
1
$ readlink_freebsd does_not_exist ; echo $?
1
$ readlink -f does_not_exist ; echo $?
/home/test001/tmp/readlink_test/readlink-20010616/does_not_exist
0
$ readlink_freebsd -f does_not_exist ; echo $?
/home/test001/tmp/readlink_test/readlink-20010616/does_not_exist
0
-- snip --
-- snip --
typeset -a cmd=(
realpath_gnu
realpath_bsd
realpath_busybox
)
function realpath_gnu
{
}
function realpath_bsd
{
}
function realpath_busybox
{
}
ln -sf foo bar
for options in '.' "$PWD" 'bar' 'foo' 'no_such_file'; do
output="${ ${cmd} ${options} 2>&1 ; (( res=$?)) ; }"
printf '# cmd=%q: options=%q output=%q, exit_code=%d\n' \
"${cmd}" \
"${options}" \
"${output}" "res"
done
done
-- snip --
-- snip --
# cmd=realpath_gnu: options=.
output=/home/test001/tmp/readlink_test/readlink-20010616, exit_code=0
options=/home/test001/tmp/readlink_test/readlink-20010616
output=/home/test001/tmp/readlink_test/readlink-20010616, exit_code=0
# cmd=realpath_gnu: options=bar
output=/home/test001/tmp/readlink_test/readlink-20010616/foo,
exit_code=0
# cmd=realpath_gnu: options=foo
output=/home/test001/tmp/readlink_test/readlink-20010616/foo,
exit_code=0
# cmd=realpath_gnu: options=no_such_file
output=/home/test001/tmp/readlink_test/readlink-20010616/no_such_file,
exit_code=0
# cmd=realpath_bsd: options=.
output=/home/test001/tmp/readlink_test/readlink-20010616, exit_code=0
options=/home/test001/tmp/readlink_test/readlink-20010616
output=/home/test001/tmp/readlink_test/readlink-20010616, exit_code=0
# cmd=realpath_bsd: options=bar
output=/home/test001/tmp/readlink_test/readlink-20010616/foo,
exit_code=0
# cmd=realpath_bsd: options=foo
output=/home/test001/tmp/readlink_test/readlink-20010616/foo,
exit_code=0
# cmd=realpath_bsd: options=no_such_file
output=/home/test001/tmp/readlink_test/readlink-20010616/no_such_file,
exit_code=0
# cmd=realpath_busybox: options=.
output=/home/test001/tmp/readlink_test/readlink-20010616, exit_code=0
options=/home/test001/tmp/readlink_test/readlink-20010616
output=/home/test001/tmp/readlink_test/readlink-20010616, exit_code=0
# cmd=realpath_busybox: options=bar
output=/home/test001/tmp/readlink_test/readlink-20010616/foo,
exit_code=0
# cmd=realpath_busybox: options=foo
output=/home/test001/tmp/readlink_test/readlink-20010616/foo,
exit_code=0
# cmd=realpath_busybox: options=no_such_file
output=/home/test001/tmp/readlink_test/readlink-20010616/no_such_file,
exit_code=0
-- snip --
I still need some time (mostly due to being sick (still twitching)) to
come up with good testcases... ;-/
thanks for the tests
I won't be reading the other implementation sources
what happens with 0 operands and 2 operands
both man pages specify
[ path ... ]
which implies 0 or more path args
_______________________________________________
ast-developers mailing list
ast-developers at lists.research.att.com
http://lists.research.att.com/mailman/listinfo/ast-developers
--
, _ _ ,
{ \/`o;====- Olga Kryzhanovska -====;o`\/ }
.----'-/`-/ olga.kryzhanovska at gmail.com \-`\-'----.
`'-..-| / http://twitter.com/fleyta \ |-..-'`
/\/\ Solaris/BSD//C/C++ programmer /\/\
`--` `--`
Roland Mainz
2013-09-24 22:47:20 UTC
Permalink
[snip]
Post by Roland Mainz
I still haven't sorted out the
sum(1) thing which provides almost all possible (hash-)sums with the
slight twist that somewhere in the code is a small bug which makes it
incompatible in the output to md5sum(1) ... please... just try to
follow "KISS" and make two utilities from it (precedent: busybox(1)
did the same...) ...
[snip]

Now I have sorted that bug out... see
http://lists.research.att.com/pipermail/ast-developers/2013q3/003480.html
... :-)

----

Bye,
Roland
--
__ . . __
(o.\ \/ /.o) roland.mainz at nrubsig.org
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer
/O /==\ O\ TEL +49 641 3992797
(;O/ \/ \O;)
Loading...