On Wed, Aug 21, 2013 at 12:58 AM, Irek Szczesniak <[email protected]> wrote:
> On Wed, Aug 14, 2013 at 9:37 PM, Glenn Fowler <[email protected]> wrote:
>> On Wed, 14 Aug 2013 15:36:26 -0400 Glenn Fowler wrote:
>>> On Wed, 14 Aug 2013 21:29:50 +0200 Irek Szczesniak wrote:
>>> > On Wed, Aug 14, 2013 at 8:18 PM, Glenn Fowler <[email protected]>
>>> > wrote:
>>> > >
>>> > > invalid assumption that if this works
>>> > > open("/proc/self/fd/<DIRFD>/.")
>>> > > then other pathname calls will too
>>> > > and this is then used to emulate missing *at() calls
>>
>>> > Curse SUN and its half baked innovations.
>>> > if anyone of you have a patch send it to me or the list, please
>>
>>> yes
>>
>> yes to the curse
>
> How did you fix this for ast-ksh.2013-08-14?
See |pathdev()| in src/lib/libast/path/pathcanon.c (and see my patch below) ...
> First I thought the code
> is clever and extracts the fd number from /proc/self/fd/<DIRFD>/ but
> then I found it just uses open() toopen /proc/self/fd/<DIRFD>/ and
> pass that to mkdirat(), which is a waste of good syscalls and doesn't
> work:
> ksh -c '/usr/bin/rm -Rf t1 ; mkdir t1 ; redirect {n}<t1 ; chmod a-r t1
> ; mkdir /proc/$$/fd/$n/t2 ; true'
> mkdir: /proc/645/fd/11/t2: [Permission denied]
>
> I would fix it myself but can't find the place which converts the
> /proc/$$/fd/$n/$path to a <fd>,<path> pair as it should be.
Attached (as "astksh20130814_solaris_proc_fixes001.diff.txt") is a
patch which fixes the bug from two directions:
1. If /proc/$pid/fd/$fd is used and $pid is the same as the current
process's pid then it works now the same as /proc/self/fd/$fd has been
used
2. The intercept code (see src/lib/libast/port/intercept.c) now
retries |open()| calls to /proc with a native |O_SEARCH| if the
previous attempt with |O_RDONLY| failed with |EACCES|. This fixes
issues when the /proc path is coming from a different process
----
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/lib/libast/path/pathcanon.c
build_i386_64bit_debug/src/lib/libast/path/pathcanon.c
--- src/lib/libast/path/pathcanon.c 2013-08-12 22:35:27.000000000 +0200
+++ src/lib/libast/path/pathcanon.c 2013-08-21 02:14:48.610012697 +0200
@@ -158,6 +158,8 @@
else
#ifdef _fd_pid_dir_fmt
DIGITS(s, dev->pid);
+ if (dev->pid == getpid())
+ dev->pid = -1;
#else
{
errno = ENOENT;
diff -r -u original/src/lib/libast/port/intercept.c
build_i386_64bit_debug/src/lib/libast/port/intercept.c
--- src/lib/libast/port/intercept.c 2013-08-13 23:03:05.000000000 +0200
+++ src/lib/libast/port/intercept.c 2013-08-21 02:09:20.206940678 +0200
@@ -44,6 +44,9 @@
#define GLOBAL(f) (ast_global.f) /* process global */
#ifdef _fd_pid_dir_fmt
+
+#if _ast_O_LOCAL && O_SEARCH >= _ast_O_LOCAL
+/* |O_SEARCH| is emulated */
#define DEVFD(p, f, r) \
if (p >= 0) \
{ \
@@ -55,6 +58,33 @@
else \
r = f
#else
+/*
+ * If we have native |O_SEARCH| we try with |O_RDONLY| first and if
+ * this fails with |EACCESS| we try again with |O_SEARCH|.
+ * Note that we must try |O_RDONLY| first because |O_SEARCH| does
+ * not work for files (which would give use trouble for Reiser4,
+ * samfs or NFSv4 xattr stores).
+ */
+#define DEVFD(p, f, r) \
+ if (p >= 0) \
+ { \
+ char buf[256]; \
+ sfsprintf(buf, sizeof(buf), _fd_pid_dir_fmt, p, f, "", ""); \
+ if ((r = open(buf, O_RDONLY)) < 0) \
+ { \
+ if (errno == EACCES) \
+ { \
+ if ((r = open(buf, O_SEARCH)) < 0) \
+ return -1; \
+ } \
+ else \
+ return -1; \
+ } \
+ } \
+ else \
+ r = f
+#endif
+#else
#define DEVFD(p, f, r) \
r = f
#endif
_______________________________________________
ast-developers mailing list
[email protected]
http://lists.research.att.com/mailman/listinfo/ast-developers