2013/6/28 Glenn Fowler <[email protected]>:
>
> the AT&T Software Technology ast alpha 2013-06-28 source release
> has been posted to the download site
>         http://www.research.att.com/sw/download/alpha/
> the package names and md5 checksums are
>             INIT  eddbf89d061348519d86f2618b708a94
>         ast-base  a745a7d4ce6f53c2e4134af4cc835ff7
>         ast-open  fdb74839ff041e34c800c333188a050e
>          ast-ksh  8f22428cf30af7146bd210664c2fd166
> the md5 sums should match the ones listed on the download page
>
> NOTE NOTE NOTE NOTE NOTE NOTE
>
> (*) *at() emulations for systems that need it
> (*) O_CLOEXEC F_DUPFD_CLOEXEC SOCK_CLOEXEC
> (*) accept4 pipe2
> (*) syscall restart on EINTR controlled by astserial(AST_SERIAL_RESTART,op)
> (*) REALLY IMPORTANT: works on modern linux, some problems on solaris
>     REASON: one of the ast team will not be logging on for 16 days and
>     didn't have time left to figure out the solaris problems
>     most likely in one of these
>         src/lib/libast/comp/at.c
>         src/lib/libast/port/intercept.c
>     figuring that out left as a summer homework assignment

Homework more or less done for Solaris (including |O_XATTR|/|O_SEARCH|
support) and fixing Linux's |O_PATH| support... the prototype patch is
attached as "astksh20130628_solaris_fixes001.diff.txt".


**Notes:
* Please please leave the comments about |O_PATH| and |#define
__USE_GNU 1| in src/lib/libast/features/fcntl.c intact. They are there
for a very good reason (mostly to bypass bugs in the Linux #includes).
I really don't want to hunt for ghost bugs over and over again.
The core part is this one:
-- snip --
-       printf("#define O_SEARCH                O_PATH\n");
+       /*
+        * O_PATH is a Linux's variation of O_SEARCH. Since this is treated
+        * as extension it may not be available without _GNU_SOURCE.
+        * Even even with _GNU_SOURCE some Linux platforms have bugs in their
+        * headers which prevents the definition of O_PATH in some hideous
+        * cases. To prevent all this mess we just grab the octal value and
+        * define it as O_SEARCH.
+        * Do not change this. You'll end-up in hell, together with the Linux
+        * headers. Quickly.
+        */
+       printf("#define O_SEARCH                0%o\n", (int)O_PATH);
-- snip --
Please please don't change that... otherwise |O_PATH| is *NOT*
available in libast&&co. This is the 4th time I'm fixing this. Again.
;-((


* Solaris didn't work because...
1. ... newer versions have many more |O_*|-flags for |open()|,
including |O_EXEC| and |O_SEARCH|. The same issue applied to the |F_*|
flags (I only added the |F_*| flags with the highest numbers in
Solaris 9/10/11/11.1 like |F_BADFD| ... maybe other platforms require
more "love" in this area...) ...

2. ... -lgen was missing when |eaccess()| is used... but...

3. ... why do we have to use |eaccess()| when |faccess()| is available ?
Remember that modern platforms (like Solaris >= 11) revamped their
syscalls and now map the "old" filesystem calls all to their |*at()|
version, e.g. ...
-- snip --
/* |open()| argument |flags| is part of |__VA_ARGS__| since
|__VA_ARGS__| must never be empty */
#define open(path, ...)                 openat(AST_AT_GET_FDCWD, (path), 
__VA_ARGS__)
#define creat(path, ...)                openat(AST_AT_GET_FDCWD, (path),
O_WRONLY|O_CREAT|O_TRUNC, __VA_ARGS__)
#define unlink(path)                    unlinkat(AST_AT_GET_FDCWD, (path), 0)
#define rmdir(path)                     unlinkat(AST_AT_GET_FDCWD, (path), 
AT_REMOVEDIR)
#define chown(path, uid, gid)           fchownat(AST_AT_GET_FDCWD, (path),
(uid), (gid), 0)
#define lchown(path, uid, gid)          fchownat(AST_AT_GET_FDCWD, (path),
(uid), (gid), AT_SYMLINK_NOFOLLOW)
#define fchown(fd, uid, gid)            fchownat((fd), NULL, (uid), (gid), 0)
#define stat(path, sb)                  fstatat(AST_AT_GET_FDCWD, (path), (sb), 
0)
#define lstat(path, sb)                 fstatat(AST_AT_GET_FDCWD, (path), (sb),
AT_SYMLINK_NOFOLLOW)
#define fstat(fd, sb)                   fstatat((fd), NULL, (sb), 0)
#define rename(oldname, newname)        renameat(AST_AT_GET_FDCWD, (oldname),
AST_AT_GET_FDCWD, (newname))
#define access(path, amode)             faccessat(AST_AT_GET_FDCWD, (path), 
(amode), 0)
#define eaccess(path, amode)            faccessat(AST_AT_GET_FDCWD, (path),
(amode), AT_EACCESS)
#define mkdir(path, amode)              mkdirat(AST_AT_GET_FDCWD, (path), 
(amode))
#define mkfifo(path, amode)             mkfifoat(AST_AT_GET_FDCWD, (path), 
(amode))
#define mknod(path, amode, adev)        mknodat(AST_AT_GET_FDCWD, (path),
(amode), (adev))
#define readlink(path, buf, bufsize)    readlinkat(AST_AT_GET_FDCWD,
(path), (buf), (bufsize))
#define symlink(oldpath, newpath)       symlinkat((oldpath),
AST_AT_GET_FDCWD, (newpath))
-- snip --


* I still have to warm-up with the new syscall restart API. Some
things with trouble me:
- The restart option (as all other signal-related stuff) must be
per-thread. But headaches will occur if a single Shell_t object is
created by one thread and then passed over to another one (possible
fix: Add APIs like |sh_thread_attach()| and |sh_thread_detach()|

- Why does it require an atomic counter (which is _very_ expensive
from the CPU pipeline point of view... basically it can count
(depending on CPU/architecture) as an equivalent of adding a full
pipeline flush+sync... which itself can take 500 or more ticks to
complete) ?

- IMO it would be nice to add |ioctl()| calls per ioctl type with
proper prototypes, e.g. replace something like
|ioctl(JOBTTY,TIOCSETD,&linedisc)| with
|ioctl_TIOCSETD(JOBTTY,&linedisc)|. The point is to get stronger C
type checks and properly pass the types to the real |ioctl()|. Right
now the code assumes a specific layout and padding of the varargs data
which is *NOT* true and *NOT* portable (maybe we should just wait
until something like IA64 breaks and comes back with more teeth&&slime
to bite you... :-) ).
Another nice side-effect would be that we can do per-|ioctl()|-type
breakpoints... :-)

----

Bye,
Roland

-- 
  __ .  . __
 (o.\ \/ /.o) [email protected]
  \__\/\/__/  MPEG specialist, C&&JAVA&&Sun&&Unix programmer
  /O /==\ O\  TEL +49 641 3992797
 (;O/ \/ \O;)
diff -r -u original/src/cmd/ksh93/bltins/cd_pwd.c 
build_i386_64bit_debug/src/cmd/ksh93/bltins/cd_pwd.c
--- src/cmd/ksh93/bltins/cd_pwd.c       Wed Jun 26 22:12:28 2013
+++ src/cmd/ksh93/bltins/cd_pwd.c       Sun Jun 30 00:55:15 2013
@@ -55,9 +55,17 @@
  */
 int sh_diropenat(Shell_t *shp, int dir, const char *path, bool xattr)
 {
+#ifdef O_DIRECTORY
+#define O_directory (O_DIRECTORY)
+#else
+#define O_directory (0)
+#endif
+
        int fd,shfd;
        int savederrno=errno;
+#ifndef O_DIRECTORY
        struct stat fs;
+#endif
 #ifndef O_XATTR
        NOT_USED(xattr);
 #endif
@@ -70,15 +78,47 @@
                if((apfd = openat(dir, path, O_RDONLY|O_NONBLOCK|O_cloexec))>=0)
                {
                        fd = openat(apfd, e_dot, O_XATTR|O_cloexec);
+                       savederrno=errno;
                        close(apfd);
                }
+               else
+               {
+                       return -1;
+               }
        }
        else
 #endif
-               fd = openat(dir, path, O_SEARCH|O_NONBLOCK|O_cloexec);
+       {
+               /*
+                * Open directory. First we try without |O_SEARCH| and
+                * if this fails with EACCESS we try with |O_SEARCH|
+                * again.
+                * This is required ...
+                * - ... because some platforms may require that it can
+                * only be used for directories while some filesystems
+                * (e.g. Reiser4 or HSM systems) allow a |fchdir()| into
+                * files, too)
+                * - ... to preserve the semantics of "cd", e.g.
+                * otherwise "cd" would return [No access] instead of
+                * [Not a directory] for files on filesystems which do
+                * not allow a "cd" into files.
+                * - ... to allow that a
+                * $ redirect {n}</etc ; cd /dev/fd/$n # works on most
+                * platforms.
+                */
 
+               fd = openat(dir, path, O_directory|O_NONBLOCK|O_cloexec);
+               if ((fd < 0) && (errno == EACCES))
+               {
+                       fd = openat(dir, path, 
O_SEARCH|O_directory|O_NONBLOCK|O_cloexec);
+               }
+               savederrno=errno;
+       }
+
        if(fd < 0)
                return fd;
+
+#ifndef O_DIRECTORY
        if (!fstat(fd, &fs) && !S_ISDIR(fs.st_mode))
        {
                close(fd);
@@ -85,10 +125,10 @@
                errno = ENOTDIR;
                return -1;
        }
+#endif
 
        /* Move fd to a number > 10 and register the fd number with the shell */
        shfd = fcntl(fd, F_dupfd_cloexec, 10);
-       savederrno=errno;
        close(fd);
        errno=savederrno;
        return(shfd);
diff -r -u original/src/lib/libast/features/eaccess 
build_i386_64bit_debug/src/lib/libast/features/eaccess
--- src/lib/libast/features/eaccess     Fri Jul 23 08:02:25 2004
+++ src/lib/libast/features/eaccess     Sun Jun 30 00:55:15 2013
@@ -1,4 +1,4 @@
-lib    eaccess,euidaccess
+lib    eaccess,euidaccess -lgen
 macro{
        #include <sys/types.h>
        #include <unistd.h>
diff -r -u original/src/lib/libast/features/fcntl.c 
build_i386_64bit_debug/src/lib/libast/features/fcntl.c
--- src/lib/libast/features/fcntl.c     Thu Jun 27 08:39:11 2013
+++ src/lib/libast/features/fcntl.c     Sun Jun 30 07:41:16 2013
@@ -27,10 +27,30 @@
  * generate POSIX fcntl.h
  */
 
+/*
+ * We use this to force Linux and some *BSD versions to tell us all
+ * their flags
+ */
+#define _GNU_SOURCE 1
+#define __USE_GNU 1 /* why is this neccesary on Linux ? */
+
 #include <sys/types.h>
 
 #include "FEATURE/lib"
 
+/*
+ * Make sure _GNU_SOURCE is active on Linux. Some versions
+ * give us serious trouble in this case so we have this
+ * assert to *abort* early instead of let us hunt for "ghost
+ * bugs"
+ */
+#ifdef __linux__
+#ifndef __USE_GNU
+#error "ASSERT: __USE_GNU should be defined by now"
+#endif
+#endif
+
+
 #define getdtablesize  ______getdtablesize
 #define getpagesize    ______getpagesize
 #define ioctl          ______ioctl
@@ -186,6 +206,15 @@
 #ifdef F_SHLCK
        if (F_SHLCK > f_local) f_local = F_SHLCK;
 #endif
+#ifdef F_SHARE
+       if (F_SHARE > f_local) f_local = F_SHARE;
+#endif
+#ifdef F_UNSHARE
+       if (F_UNSHARE > f_local) f_local = F_UNSHARE;
+#endif
+#ifdef F_BADFD /* Create Poison FD */
+       if (F_BADFD > f_local) f_local = F_BADFD;
+#endif
 
 #if    NEED_F
 #if    _lib_fcntl
@@ -240,12 +269,12 @@
 #define NEED_O 1
 #endif
 
-#ifdef O_DSYNC
-       if (O_DSYNC > o_local) o_local = O_DSYNC;
-#endif
 #ifdef O_LARGEFILE
        if (O_LARGEFILE > o_local) o_local = O_LARGEFILE;
 #endif
+#ifdef O_LARGEFILE128
+       if (O_LARGEFILE128 > o_local) o_local = O_LARGEFILE128;
+#endif
 #ifdef O_NOFOLLOW
        if (O_NOFOLLOW > o_local) o_local = O_NOFOLLOW;
 #endif
@@ -258,6 +287,9 @@
 #ifdef O_RSYNC
        if (O_RSYNC > o_local) o_local = O_RSYNC;
 #endif
+#ifdef O_DSYNC
+       if (O_DSYNC > o_local) o_local = O_DSYNC;
+#endif
 #ifdef O_SYNC
        if (O_SYNC > o_local) o_local = O_SYNC;
 #endif
@@ -264,6 +296,24 @@
 #ifdef O_XATTR
        if (O_XATTR > o_local) o_local = O_XATTR;
 #endif
+#ifdef O_DIRECTORY
+       if (O_DIRECTORY > o_local) o_local = O_DIRECTORY;
+#endif
+#ifdef O_SEARCH
+       if (O_SEARCH > o_local) o_local = O_SEARCH;
+#endif
+#ifdef O_PATH
+       if (O_PATH > o_local) o_local = O_PATH;
+#endif
+#ifdef O_EXEC
+       if (O_EXEC > o_local) o_local = O_EXEC;
+#endif
+#ifdef O_CLOEXEC
+       if (O_CLOEXEC > o_local) o_local = O_CLOEXEC;
+#endif
+#ifdef O_TTY_INIT
+       if (O_TTY_INIT > o_local) o_local = O_TTY_INIT;
+#endif
 
        printf("#define _ast_O_LOCAL            0%o\n", o_local<<1);
 #if    NEED_O
@@ -316,7 +366,17 @@
 #endif
 #ifndef        O_SEARCH
 #ifdef O_PATH
-       printf("#define O_SEARCH                O_PATH\n");
+       /*
+        * O_PATH is a Linux's variation of O_SEARCH. Since this is treated
+        * as extension it may not be available without _GNU_SOURCE.
+        * Even even with _GNU_SOURCE some Linux platforms have bugs in their
+        * headers which prevents the definition of O_PATH in some hideous
+        * cases. To prevent all this mess we just grab the octal value and
+        * define it as O_SEARCH.
+        * Do not change this. You'll end-up in hell, together with the Linux
+        * headers. Quickly.
+        */
+       printf("#define O_SEARCH                0%o\n", (int)O_PATH);
 #else
        printf("#define O_SEARCH                0%o\n", o_local <<= 1);
 #endif
_______________________________________________
ast-developers mailing list
[email protected]
http://lists.research.att.com/mailman/listinfo/ast-developers

Reply via email to