On Sun, Jul 28, 2013 at 6:51 AM, Glenn Fowler <[email protected]> wrote:
> On Sun, 28 Jul 2013 01:53:16 +0200 Roland Mainz wrote:
>> Attached (as "astksh20130727_readlink001.diff.txt") is the prototype
>> patch for the readlink(1) builtin.
>
>> ** Notes:
>> * the builtin is currently at the level of functionality which
>> FreeBSD's and busybox's readlink(1) utilities provide... plus -D
>> * AST readlink(1) has an option to pass a directory fd to |readlinkat()|
>> * GNU readlink provides these three extra options...
>> -- snip --
>>   -f, --canonicalize            canonicalize by following every symlink in
>>                                 every component of the given name 
>> recursively;
>>                                 all but the last component must exist
>>   -e, --canonicalize-existing   canonicalize by following every symlink in
>>                                 every component of the given name 
>> recursively,
>>                                 all components must exist
>>   -m, --canonicalize-missing    canonicalize by following every symlink in
>>                                 every component of the given name 
>> recursively,
>>                                 without requirements on components existence
>> -- snip --
>> ... are these options needed by anyone... and if "yes" ... what would
>> be the best way to implement them ?
>
> see src/lib/libast/path/pathcanon.c
> the PATH_* flags handle all but the "all but the last component must exist" 
> part
> by default pathcanon() does logical canonicalization (not existence checks, 
> no symlinks)

OK... but I defer that work to a late ast-ksh alpha release because I
first like to get some feedback on which options are really required
(for example busybox and FreeBSD seems to be OK without { -e, -f, -m }
...) ... and the work for the { -e, -f, -m }-options has a dependency
on |fgetcwd()|.

Attached (as "astksh20130727_readlink002.diff.txt") is an updated
patch for ast-ksh.2013-07-27 ... AFAIK the work is isolated enough
that it can make it into the next alpha... right ?

----

Bye,
Roland

-- 
  __ .  . __
 (o.\ \/ /.o) [email protected]
  \__\/\/__/  MPEG specialist, C&&JAVA&&Sun&&Unix programmer
  /O /==\ O\  TEL +49 641 3992797
 (;O/ \/ \O;)
diff -N -r -u build_i386_64bit_debug/src/lib/libcmd/Makefile 
build_readlink/src/lib/libcmd/Makefile
--- src/lib/libcmd/Makefile     2013-04-22 07:12:50.000000000 +0200
+++ src/lib/libcmd/Makefile     2013-07-27 21:57:39.311526852 +0200
@@ -24,7 +24,7 @@
        getconf.c head.c id.c join.c ln.c logname.c md5sum.c mkdir.c \
        mkfifo.c mktemp.c mv.c paste.c pathchk.c pids.c rev.c rm.c \
        rmdir.c stty.c sum.c sync.c tail.c tee.c tty.c uname.c uniq.c \
-       vmstate.c wc.c revlib.c wclib.c sumlib.o context.c \
+       vmstate.c wc.c readlink.c revlib.c wclib.c sumlib.o context.c \
        fts_fix.c lib.c \
        grep.c xargs.c iconv.c \
        od.c tr.c \
diff -N -r -u build_i386_64bit_debug/src/lib/libcmd/Mamfile 
build_readlink/src/lib/libcmd/Mamfile
--- src/lib/libcmd/Mamfile      2013-07-27 17:46:53.000000000 +0200
+++ src/lib/libcmd/Mamfile      2013-07-27 21:57:39.315526885 +0200
@@ -451,6 +451,11 @@
 done wc.h
 prev cmd.h implicit
 done wc.c
+make readlink.c
+prev ${PACKAGE_ast_INCLUDE}/ls.h implicit
+prev ${PACKAGE_ast_INCLUDE}/ast.h implicit
+prev cmd.h implicit
+done readlink.c
 make revlib.c
 prev rev.h implicit
 prev cmd.h implicit
@@ -542,7 +547,7 @@
 exec - -e 's/^b_//' \
 exec - -e 's/(.*//' \
 exec - -e 's/.*/extern int     b_&(int, char**, Shbltin_t*);/' \
-exec - cmdinit.c basename.c cat.c chgrp.c chmod.c chown.c cksum.c cmp.c comm.c 
cp.c cut.c dirname.c date.c expr.c fds.c fmt.c fold.c getconf.c head.c id.c 
join.c ln.c logname.c md5sum.c mkdir.c mkfifo.c mktemp.c mv.c paste.c pathchk.c 
pids.c rev.c rm.c rmdir.c stty.c sum.c sync.c tail.c tee.c tty.c uname.c uniq.c 
vmstate.c wc.c revlib.c wclib.c context.c fts_fix.c lib.c grep.c xargs.c 
iconv.c od.c tr.c |
+exec - cmdinit.c basename.c cat.c chgrp.c chmod.c chown.c cksum.c cmp.c comm.c 
cp.c cut.c dirname.c date.c expr.c fds.c fmt.c fold.c getconf.c head.c id.c 
join.c ln.c logname.c md5sum.c mkdir.c mkfifo.c mktemp.c mv.c paste.c pathchk.c 
pids.c rev.c rm.c rmdir.c stty.c sum.c sync.c tail.c tee.c tty.c uname.c uniq.c 
vmstate.c wc.c readlink.c revlib.c wclib.c context.c fts_fix.c lib.c grep.c 
xargs.c iconv.c od.c tr.c |
 exec - sort -u
 exec - } > 1.${COTEMP}.h
 exec - if cmp 2>/dev/null -s 1.${COTEMP}.h cmdext.h
@@ -822,6 +827,12 @@
 prev wc.c
 exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -I${PACKAGE_ast_INCLUDE} 
-DERROR_CATALOG=\""libcmd"\" -D_PACKAGE_ast -D_BLD_cmd 
-DUSAGE_LICENSE=\""[-author?Glenn Fowler <[email protected]>][-author?David 
Korn <[email protected]>][-copyright?Copyright (c) 1992-2013 AT&T 
Intellectual 
Property][-license?http://www.eclipse.org/org/documents/epl-v10.html][--catalog?libcmd]"\";
 -c wc.c
 done wc.o generated
+make readlink.o
+prev readlink.c
+meta readlink.o %.c>%.o readlink.c readlink
+prev readlink.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -I${PACKAGE_ast_INCLUDE} 
-DERROR_CATALOG=\""libcmd"\" -D_PACKAGE_ast -D_BLD_cmd 
-DUSAGE_LICENSE=\""[-author?Glenn Fowler <[email protected]>][-author?David 
Korn <[email protected]>][-copyright?Copyright (c) 1992-2013 AT&T 
Intellectual 
Property][-license?http://www.eclipse.org/org/documents/epl-v10.html][--catalog?libcmd]"\";
 -c readlink.c
+done readlink.o generated
 make revlib.o
 prev revlib.c
 meta revlib.o %.c>%.o revlib.c revlib
@@ -890,7 +901,7 @@
 exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -I${PACKAGE_ast_INCLUDE} 
-DERROR_CATALOG=\""libcmd"\" -D_PACKAGE_ast -D_BLD_cmd 
-DUSAGE_LICENSE=\""[-author?Glenn Fowler <[email protected]>][-author?David 
Korn <[email protected]>][-copyright?Copyright (c) 1992-2013 AT&T 
Intellectual 
Property][-license?http://www.eclipse.org/org/documents/epl-v10.html][--catalog?libcmd]"\";
 -c tr.c
 done tr.o generated
 exec - ${AR} rc libcmd.a cmdinit.o basename.o cat.o chgrp.o chmod.o chown.o 
cksum.o cmp.o comm.o cp.o cut.o dirname.o date.o expr.o fds.o fmt.o fold.o 
getconf.o head.o id.o join.o ln.o logname.o md5sum.o mkdir.o mkfifo.o mktemp.o 
mv.o paste.o pathchk.o
-exec - ${AR} rc libcmd.a pids.o rev.o rm.o rmdir.o stty.o sum.o sync.o tail.o 
tee.o tty.o uname.o uniq.o vmstate.o wc.o revlib.o wclib.o sumlib.o context.o 
fts_fix.o lib.o grep.o xargs.o iconv.o od.o tr.o
+exec - ${AR} rc libcmd.a pids.o rev.o rm.o rmdir.o stty.o sum.o sync.o tail.o 
tee.o tty.o uname.o uniq.o vmstate.o wc.o readlink.o revlib.o wclib.o sumlib.o 
context.o fts_fix.o lib.o grep.o xargs.o iconv.o od.o tr.o
 exec - (ranlib libcmd.a) >/dev/null 2>&1 || true
 done libcmd.a generated
 done cmd virtual
@@ -984,6 +995,7 @@
 prev uniq.c
 prev vmstate.c
 prev wc.c
+prev readlink.c
 prev revlib.c
 prev wclib.c
 prev context.c
@@ -1009,7 +1021,7 @@
 exec - -e '/^b_[a-z_][a-z_0-9]*(/!d' \
 exec - -e 's/^b_//' \
 exec - -e 's/(.*//' \
-exec - cmdinit.c basename.c cat.c chgrp.c chmod.c chown.c cksum.c cmp.c comm.c 
cp.c cut.c dirname.c date.c expr.c fds.c fmt.c fold.c getconf.c head.c id.c 
join.c ln.c logname.c md5sum.c mkdir.c mkfifo.c mktemp.c mv.c paste.c pathchk.c 
pids.c rev.c rm.c rmdir.c stty.c sum.c sync.c tail.c tee.c tty.c uname.c uniq.c 
vmstate.c wc.c revlib.c wclib.c context.c fts_fix.c lib.c grep.c xargs.c 
iconv.c od.c tr.c |
+exec - cmdinit.c basename.c cat.c chgrp.c chmod.c chown.c cksum.c cmp.c comm.c 
cp.c cut.c dirname.c date.c expr.c fds.c fmt.c fold.c getconf.c head.c id.c 
join.c ln.c logname.c md5sum.c mkdir.c mkfifo.c mktemp.c mv.c paste.c pathchk.c 
pids.c rev.c rm.c rmdir.c stty.c sum.c sync.c tail.c tee.c tty.c uname.c uniq.c 
vmstate.c wc.c readlink.c revlib.c wclib.c context.c fts_fix.c lib.c grep.c 
xargs.c iconv.c od.c tr.c |
 exec - sort -u
 exec - `
 exec - for cmd
diff -N -r -u build_i386_64bit_debug/src/lib/libcmd/readlink.c 
build_readlink/src/lib/libcmd/readlink.c
--- src/lib/libcmd/readlink.c   1970-01-01 01:00:00.000000000 +0100
+++ src/lib/libcmd/readlink.c   2013-07-29 13:35:57.968064591 +0200
@@ -0,0 +1,129 @@
+/***********************************************************************
+*                                                                      *
+*               This software is part of the ast package               *
+*          Copyright (c) 2013 AT&T Intellectual Property          *
+*                      and is licensed under the                       *
+*                 Eclipse Public License, Version 1.0                  *
+*                    by AT&T Intellectual Property                     *
+*                                                                      *
+*                A copy of the License is available at                 *
+*          http://www.eclipse.org/org/documents/epl-v10.html           *
+*         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
+*                                                                      *
+*              Information and Software Systems Research               *
+*                            AT&T Research                             *
+*                           Florham Park NJ                            *
+*                                                                      *
+*               Roland Mainz <[email protected]>                *
+*                                                                      *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Roland Mainz
+ * AT&T Research
+ */
+
+#include <cmd.h>
+
+static const char optreadlink[] =
+"[-?\n@(#)$Id: readlink (AT&T Research) 2013-07-28 $\n]"
+"[-author?Roland Mainz <[email protected]>]"
+"[+NAME?readlink - print value of a symbolic link]"
+"[+DESCRIPTION?The \breadlink\b(1) Print value of a symbolic link.]"
+"[+?If pathname given in pathname is relative, then it is "
+"interpreted relative to the directory referred to by the file "
+"descriptor dirfd or - if no dirfd is provided - relative to the "
+"current working directory of the calling process, as is done by "
+"readlink(2) for a relative pathname).]"
+"[+?If pathname is absolute, then dirfd is ignored.]"
+"[D]#[dirfd:[fd?Path is interpreted as relative to the by the given "
+       "file descriptor.]"
+#ifdef NOT_YET_IMPLEMENTED
+"[e:canonicalize-existing?Canonicalize by following every symlink "
+       "in every component of the given name recursively, all "
+       "components must exist.]"
+"[f:canonicalize?Canonicalize by following every symlink in every "
+       "component of the given name recursively; all but the last "
+       "component must exist.]"
+"[m:canonicalize-missing?Canonicalize by following every symlink "
+       "in every component of the given name recursively, "
+       "without requirements on components existence.]"
+#endif
+"[n!:newline?Output a trailing newline after the resolved link.]"
+"[q:quiet?Suppress error messages.]"
+"\n"
+"\npath\n"
+"\n"
+"[+SEE ALSO?\breadlinkat\b(2), \breadlink\b(2), \bsymlinkat\b(2)]"
+;
+
+#define sh_contexttoshell(context)     ((context)?((context)->shp):(NULL))
+#define sh_contexttopwdfd(context)     
((context)?((context)->pwdfd):(AT_FDCWD))
+
+int
+b_readlink(int argc, char** argv, Shbltin_t* context)
+{
+        Shell_t                *shp            = sh_contexttoshell(context);
+       int             dirfd           = sh_contexttopwdfd(context);
+       int             n;
+       bool            fquiet          = false;
+       bool            fnewline        = true;
+       const char      *pathname;
+       char            *endp;
+       char            buff[PATH_MAX+2]; /* room for path, '\0' and newline */
+       ssize_t         res;
+
+       while (n = optget(argv, optreadlink)) switch (n)
+       {
+               case 'D':
+                       dirfd = opt_info.num;
+                       break;
+               case 'n':
+                       fnewline = opt_info.num?true:false;
+                       break;
+               case 'q':
+                       fquiet = opt_info.num?true:false;
+                       break;
+               case ':':
+                       error(2, "%s", opt_info.arg);
+                       break;
+               case '?':
+                       error(ERROR_usage(2), "%s", opt_info.arg);
+                       break;
+       }
+       argc -= opt_info.index;
+       argv += opt_info.index;
+       if (argc != 1)
+               error(ERROR_usage(2), "%s", optusage(NiL));
+#if _lib_readlink
+       pathname = argv[0];
+
+       /*
+        * |readlinkat()| will be emulated on systems which do
+        * not provide it
+        */
+       res = readlinkat(dirfd, pathname, buff, sizeof(buff)-1);
+
+       if (res < 0)
+       {
+               if (fquiet)
+                       return (1);
+               else
+                       error(ERROR_system(1), "readlink() failed");
+       }
+
+       endp = &buff[res];
+
+       if (fnewline)
+       {
+               *endp++ = '\n';
+               *endp   = '\0';
+       }
+
+       res = endp-buff;
+       res = (sfwrite(sfstdout, buff, res) == res)?0:1;
+       return (res);
+#else
+       error(ERROR_ERROR, "readlink() not implemented");
+#endif
+}
_______________________________________________
ast-developers mailing list
[email protected]
http://lists.research.att.com/mailman/listinfo/ast-developers

Reply via email to