On Sun, Oct 13, 2013 at 12:26 AM, ольга крыжановская
<[email protected]> wrote:
> Glenn, David, the patch is missing in ast-ksh.2013-10-10. Could you
> have a look at this issue please?
>
> Olga
>
> On Mon, Sep 30, 2013 at 2:48 PM, Roland Mainz <[email protected]>
> wrote:
>> On Sun, Sep 29, 2013 at 1:34 AM, Glenn Fowler <[email protected]> wrote:
>>>
>>> On Sat, 28 Sep 2013 15:29:36 +0200 Roland Mainz wrote:
>>>> 2013/9/27 Roland Mainz <[email protected]>:
>>>> > 2013/9/18 Roland Mainz <[email protected]>:
>>>> >> 2013/9/17 Glenn Fowler <[email protected]>:
>>>> >>> On Tue, 17 Sep 2013 21:14:38 +0200 Lionel Cons wrote:
>>>> >>>> On 17 September 2013 20:49, Glenn Fowler <[email protected]>
>>>> >>>> wrote:
>>>> [snip]
>>>> >> ... on the bright side... adding |fpathconf()| support looks quite
>>>> >> easy to implement... if Glenn agrees I can make the patch for that
>>>> >> tonight...
>>>> >
>>>> > Erm... ping!
>>>> >
>>>> > Can I craft the patch for this one, please ?
>>>
>>>> Erm... should I make the patch - [yes]/[no]/[chicken] ? :-)
>>>
>>> go for it
>>
>> _Thanks_! ... :-)
>>
>> Attached (as "astksh20130926_getconf_f_001.diff.txt") is a _prototype_
>> patch to add a -f $fd option to getconf(1) ...
>>
>> * Notes:
>> - this is a prototype... it requires more testing and minor other changes
>> - still need to hook-up the usual AST versioning system to make sure
>> we don't hit any symbol collisions
>> - Need to do build tests with ast-open
>> - During development we hit a bug that Linux's |fstatfs()| - used by
>> |fpathconf()| - does not like |O_PATH|. Olga notified Linus himself to
>> have a look at this issue. The patch contains a workaround. Note that
>> the workaround is only used if both -f $fd and a _relative_ path are
>> given, the issue does not affect anything which uses an absolute path.
>>
>> Erm... Glenn.. any feedback/rants/comments for the patch ?
Trying again, this time with the original patch attached...
... Glenn: Any feedback (or better: Integration into ast-ksh - since a
lot of people either are desperately waiting for the patch or just use
it already (like Lionel&&Cedric)) welcome ...
----
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/include/ast.h
build_fgetconf/src/lib/libast/include/ast.h
--- src/lib/libast/include/ast.h 2013-09-18 21:53:42.000000000 +0200
+++ src/lib/libast/include/ast.h 2013-09-30 12:55:57.074998985 +0200
@@ -275,10 +275,10 @@
#define extern __EXPORT__
#endif
-extern char* astgetconf(const char*, const char*, const char*, int,
Error_f);
+extern char* astgetconf(const char*, int, const char*, const char*,
int, Error_f);
extern char* astconf(const char*, const char*, const char*);
extern Ast_confdisc_f astconfdisc(Ast_confdisc_f);
-extern void astconflist(Sfio_t*, const char*, int, const char*);
+extern void astconflist(Sfio_t*, int, const char*, int, const
char*);
extern off_t astcopy(int, int, off_t);
extern int astlicense(char*, int, char*, char*, int, int, int);
extern int astquery(int, const char*, ...);
diff -r -u original/src/lib/libast/port/astconf.c
build_fgetconf/src/lib/libast/port/astconf.c
--- src/lib/libast/port/astconf.c 2013-08-20 18:55:15.000000000 +0200
+++ src/lib/libast/port/astconf.c 2013-09-30 13:51:22.292943470 +0200
@@ -22,11 +22,11 @@
#pragma prototyped
/*
- * string interface to confstr(),pathconf(),sysconf(),sysinfo()
+ * string interface to confstr(),pathconf(),fpathconf(),sysconf(),sysinfo()
* extended to allow some features to be set per-process
*/
-static const char id[] = "\n@(#)$Id: getconf (AT&T Research) 2012-05-01 $\0\n";
+static const char id[] = "\n@(#)$Id: getconf (AT&T Research) 2013-09-30 $\0\n";
#include "univlib.h"
@@ -76,7 +76,7 @@
#define CONF_GLOBAL (CONF_USER<<3)
#define DEFAULT(o)
((state.std||!dynamic[o].ast)?dynamic[o].std:dynamic[o].ast)
-#define INITIALIZE() do{if(!state.data)synthesize(NiL,NiL,NiL);}while(0)
+#define INITIALIZE() do{if(!state.data)synthesize(NiL,-1,NiL,NiL);}while(0)
#define STANDARD(v)
(streq(v,"standard")||streq(v,"strict")||streq(v,"posix")||streq(v,"xopen"))
#define MAXVAL 256
@@ -302,7 +302,7 @@
static State_t state = { "getconf", "_AST_FEATURES", "CONFORMANCE = standard",
"POSIXLY_CORRECT", dynamic, -1 };
-static char* feature(Feature_t*, const char*, const char*, const char*,
unsigned int, Error_f);
+static char* feature(Feature_t*, const char*, int, const char*, const char*,
unsigned int, Error_f);
/*
* return fmtbuf() copy of s
@@ -322,7 +322,7 @@
*/
static char*
-synthesize(register Feature_t* fp, const char* path, const char* value)
+synthesize(register Feature_t* fp, int fd, const char* path, const char* value)
{
register char* s;
register char* d;
@@ -332,7 +332,7 @@
#if DEBUG_astconf
if (fp)
- error(-6, "astconf synthesize name=%s path=%s value=%s
fp=%p%s", fp->name, path, value, fp, state.synthesizing ? " SYNTHESIZING" : "");
+ error(-6, "astconf synthesize name=%s fd=%d path=%s value=%s
fp=%p%s", fp->name, fd, path, value, fp, state.synthesizing ? " SYNTHESIZING" :
"");
#endif
if (state.synthesizing)
{
@@ -380,7 +380,7 @@
ve = 0;
*de = 0;
*se = 0;
- feature(0, s, d, v, 0, 0);
+ feature(0, s, fd, d, v, 0, 0);
*se = ' ';
*de = ' ';
if (!ve)
@@ -501,18 +501,18 @@
/*
* initialize the value for fp
* if command!=0 then it is checked for on $PATH
- * synthesize(fp,path,succeed) called on success
+ * synthesize(fp,fd,path,succeed) called on success
* otherwise synthesize(fp,path,fail) called
*/
static void
-initialize(register Feature_t* fp, const char* path, const char* command,
const char* succeed, const char* fail)
+initialize(register Feature_t* fp, int fd, const char* path, const char*
command, const char* succeed, const char* fail)
{
register char* p;
register int ok = 1;
#if DEBUG_astconf
- error(-6, "astconf initialize name=%s path=%s command=%s succeed=%s
fail=%s fp=%p%s", fp->name, path, command, succeed, fail, fp,
state.synthesizing ? " SYNTHESIZING" : "");
+ error(-6, "astconf initialize name=%s fd=%d path=%s command=%s
succeed=%s fail=%s fp=%p%s", fp->name, fd, path, command, succeed, fail, fp,
state.synthesizing ? " SYNTHESIZING" : "");
#endif
switch (fp->op)
{
@@ -617,7 +617,7 @@
#if DEBUG_astconf
error(-6, "state.std=%d %s [%s] std=%s ast=%s value=%s ok=%d",
state.std, fp->name, ok ? succeed : fail, fp->std, fp->ast, fp->value, ok);
#endif
- synthesize(fp, path, ok ? succeed : fail);
+ synthesize(fp, fd, path, ok ? succeed : fail);
}
/*
@@ -625,7 +625,7 @@
*/
static char*
-format(register Feature_t* fp, const char* path, const char* value, unsigned
int flags, Error_f conferror)
+format(register Feature_t* fp, int fd, const char* path, const char* value,
unsigned int flags, Error_f conferror)
{
register Feature_t* sp;
register int n;
@@ -682,8 +682,8 @@
#endif
if (state.synthesizing && value == (char*)fp->std)
fp->value = (char*)value;
- else if (!synthesize(fp, path, value))
- initialize(fp, path, NiL, fp->std, fp->value);
+ else if (!synthesize(fp, fd, path, value))
+ initialize(fp, fd, path, NiL, fp->std, fp->value);
#if DEBUG_astconf
error(-6, "state.std=%d %s [%s] std=%s ast=%s value=%s",
state.std, fp->name, value, fp->std, fp->ast, fp->value);
#endif
@@ -692,7 +692,7 @@
state.std = 1;
for (sp = state.features; sp; sp = sp->next)
if (sp->std && sp->op && sp->op !=
OP_conformance)
- feature(sp, 0, path, sp->std, 0, 0);
+ feature(sp, 0, fd, path, sp->std, 0, 0);
}
#if DEBUG_astconf
error(-6, "state.std=%d %s [%s] std=%s ast=%s value=%s",
state.std, fp->name, value, fp->std, fp->ast, fp->value);
@@ -717,7 +717,11 @@
* _PC_PATH_ATTRIBUTES is a bitmap for 'a' to 'z'
*/
- if ((v = pathconf(path, _PC_PATH_ATTRIBUTES)) == -1L)
+ if (fd != -1)
+ v = fpathconf(fd, _PC_PATH_ATTRIBUTES);
+ else
+ v = pathconf(path, _PC_PATH_ATTRIBUTES);
+ if (v) == -1L)
return 0;
s = fp->value;
e = s + sizeof(fp->value) - 1;
@@ -736,8 +740,8 @@
case OP_path_resolve:
if (state.synthesizing && value == (char*)fp->std)
fp->value = (char*)value;
- else if (!synthesize(fp, path, value))
- initialize(fp, path, NiL, "logical",
DEFAULT(OP_path_resolve));
+ else if (!synthesize(fp, fd, path, value))
+ initialize(fp, fd, path, NiL, "logical",
DEFAULT(OP_path_resolve));
break;
case OP_universe:
@@ -788,10 +792,10 @@
}
}
else
- synthesize(fp, path, value);
+ synthesize(fp, fd, path, value);
}
else
- initialize(fp, path, "echo", DEFAULT(OP_universe),
"ucb");
+ initialize(fp, fd, path, "echo", DEFAULT(OP_universe),
"ucb");
#endif
#endif
break;
@@ -800,7 +804,7 @@
if (state.synthesizing && value == (char*)fp->std)
fp->value = (char*)value;
else
- synthesize(fp, path, value);
+ synthesize(fp, fd, path, value);
break;
}
@@ -816,7 +820,7 @@
*/
static char*
-feature(register Feature_t* fp, const char* name, const char* path, const
char* value, unsigned int flags, Error_f conferror)
+feature(register Feature_t* fp, const char* name, int fd, const char* path,
const char* value, unsigned int flags, Error_f conferror)
{
register int n;
@@ -861,7 +865,7 @@
}
else
state.recent = fp;
- return format(fp, path, value, flags, conferror);
+ return format(fp, fd, path, value, flags, conferror);
}
/*
@@ -1006,7 +1010,7 @@
*/
static char*
-print(Sfio_t* sp, register Lookup_t* look, const char* name, const char* path,
int listflags, Error_f conferror)
+print(Sfio_t* sp, register Lookup_t* look, const char* name, int fd, const
char* path, int listflags, Error_f conferror)
{
register Conf_t* p = look->conf;
register unsigned int flags = look->flags;
@@ -1058,14 +1062,14 @@
switch (p->call)
{
case CONF_pathconf:
- if (path == root)
+ if ((path == root) && (fd == -1))
{
(*conferror)(&state, &state, 2, "%s:
path expected", name);
goto bad;
}
break;
default:
- if (path != root)
+ if ((path != root) || (fd != -1))
{
(*conferror)(&state, &state, 2, "%s:
path not expected", name);
goto bad;
@@ -1119,7 +1123,11 @@
case CONF_pathconf:
call = "pathconf";
#if _lib_pathconf
- if ((v = pathconf(path, p->op)) < 0)
+ if (fd != -1)
+ v = fpathconf(fd, p->op);
+ else
+ v = pathconf(path, p->op);
+ if (v < 0)
defined = 0;
break;
#else
@@ -1369,7 +1377,7 @@
if (!(listflags & ~(ASTCONF_error|ASTCONF_system)))
for (fp = state.features; fp; fp = fp->next)
if (streq(name, fp->name))
- return format(fp, path, 0, listflags,
conferror);
+ return format(fp, fd, path, 0, listflags,
conferror);
return (listflags & ASTCONF_error) ? (char*)0 : null;
}
@@ -1414,10 +1422,10 @@
* settable return values are in permanent store
* non-settable return values copied to a tmp fmtbuf() buffer
*
- * if (streq(astgetconf("PATH_RESOLVE", NiL, NiL, 0, 0), "logical"))
+ * if (streq(astgetconf("PATH_RESOLVE", -1, NiL, NiL, 0, 0), "logical"))
* our_way();
*
- * universe = astgetconf("UNIVERSE", NiL, "att", 0, 0);
+ * universe = astgetconf("UNIVERSE", -1, NiL, "att", 0, 0);
* astgetconf("UNIVERSE", NiL, universe, 0, 0);
*
* if (flags&ASTCONF_error)!=0 then error return value is 0
@@ -1427,7 +1435,7 @@
#define ALT 16
char*
-astgetconf(const char* name, const char* path, const char* value, int flags,
Error_f conferror)
+astgetconf(const char* name, int fd, const char* path, const char* value, int
flags, Error_f conferror)
{
register char* s;
int n;
@@ -1445,7 +1453,7 @@
#endif
if (!name)
{
- if (path)
+ if (path || (fd != -1))
return null;
if (!(name = value))
{
@@ -1467,9 +1475,9 @@
value = 0;
}
INITIALIZE();
- if (!path)
+ if (!path && (fd == -1))
path = root;
- if (state.recent && streq(name, state.recent->name) && (s =
format(state.recent, path, value, flags, conferror)))
+ if (state.recent && streq(name, state.recent->name) && (s =
format(state.recent, fd, path, value, flags, conferror)))
return s;
if (lookup(&look, name, flags))
{
@@ -1481,7 +1489,7 @@
(*conferror)(&state, &state, 2, "%s: cannot set
value", name);
return (flags & ASTCONF_error) ? (char*)0 : null;
}
- return print(NiL, &look, name, path, flags, conferror);
+ return print(NiL, &look, name, fd, path, flags, conferror);
}
if ((n = strlen(name)) > 3 && n < (ALT + 3))
{
@@ -1521,7 +1529,7 @@
(*conferror)(&state, &state, 2,
"%s: cannot set value", altname);
return (flags & ASTCONF_error) ?
(char*)0 : null;
}
- return print(NiL, &altlook, altname, path,
flags, conferror);
+ return print(NiL, &altlook, altname, fd, path,
flags, conferror);
}
for (s = altname; *s; s++)
if (isupper(*s))
@@ -1544,7 +1552,7 @@
}
}
}
- if ((look.standard < 0 || look.standard == CONF_AST) && look.call <= 0
&& look.section <= 1 && (s = feature(0, look.name, path, value, flags,
conferror)))
+ if ((look.standard < 0 || look.standard == CONF_AST) && look.call <= 0
&& look.section <= 1 && (s = feature(0, look.name, fd, path, value, flags,
conferror)))
return s;
errno = EINVAL;
if (conferror && !(flags & ASTCONF_system))
@@ -1562,11 +1570,11 @@
#if DEBUG_astconf
char* r;
- r = astgetconf(name, path, value, 0, 0);
+ r = astgetconf(name, -1, path, value, 0, 0);
error(-1, "astconf(%s,%s,%s) => '%s'", name, path, value, r);
return r;
#else
- return astgetconf(name, path, value, 0, 0);
+ return astgetconf(name, -1, path, value, 0, 0);
#endif
}
@@ -1592,7 +1600,7 @@
*/
void
-astconflist(Sfio_t* sp, const char* path, int flags, const char* pattern)
+astconflist(Sfio_t* sp, int fd, const char* path, int flags, const char*
pattern)
{
char* s;
char* f;
@@ -1609,7 +1617,21 @@
#endif
INITIALIZE();
- if (!path)
+
+ if((path != NULL) && (fd != -1))
+ {
+ /*
+ * |fd| and |path| arguments are currently mutually exclusive.
+ * If we ever allow this then we should create an |ASTCONF_open|
+ * flag to explicitly use |openat(fd, path, ...)| to open the
+ * file requested. On the other hand it may be better to let
+ * the caller handle this detail
+ */
+ errorf(&state, &state, 2, "Cannot pass both fd and path");
+ return;
+ }
+
+ if (!path || (fd != -1))
path = root;
else if (access(path, F_OK))
{
@@ -1657,7 +1679,7 @@
}
look.standard = look.conf->standard;
look.section = look.conf->section;
- print(sp, &look, NiL, path, flags, errorf);
+ print(sp, &look, NiL, -1, path, flags, errorf);
}
#ifdef _pth_getconf_a
if (pp = nativeconf(&proc, _pth_getconf_a))
@@ -1712,7 +1734,7 @@
continue;
}
}
- if (!(s = feature(fp, 0, path, NiL, 0, 0)) || !*s)
+ if (!(s = feature(fp, 0, fd, path, NiL, 0, 0)) || !*s)
s = "0";
if (flags & ASTCONF_table)
{
diff -r -u original/src/lib/libcmd/getconf.c
build_fgetconf/src/lib/libcmd/getconf.c
--- src/lib/libcmd/getconf.c 2012-06-26 00:45:10.000000000 +0200
+++ src/lib/libcmd/getconf.c 2013-09-30 14:33:16.645535121 +0200
@@ -27,7 +27,7 @@
*/
static const char usage[] =
-"[-?\n@(#)$Id: getconf (AT&T Research) 2012-06-25 $\n]"
+"[-?\n@(#)$Id: getconf (AT&T Research) 2013-09-30 $\n]"
USAGE_LICENSE
"[+NAME?getconf - get configuration values]"
"[+DESCRIPTION?\bgetconf\b displays the system configuration value for"
@@ -52,8 +52,9 @@
" \aname\a=\avalue\a form to the standard output, one per line."
" Only one of \b--call\b, \b--name\b or \b--standard\b may be specified.]"
"[+?This implementation uses the \bastgetconf\b(3) string interface to the
native"
-" \bsysconf\b(2), \bconfstr\b(2), \bpathconf\b(2), and \bsysinfo\b(2)"
-" system calls. If \bgetconf\b on \b$PATH\b is not the default native"
+" \bsysconf\b(2), \bconfstr\b(2), \bpathconf\b(2), \bfpathconf\b(2), "
+" and \bsysinfo\b(2) system calls. "
+" If \bgetconf\b on \b$PATH\b is not the default native"
" \bgetconf\b, named by \b$(getconf GETCONF)\b, then \bastgetconf\b(3)"
" checks only \bast\b specific extensions and the native system calls;"
" invalid options and/or names not supported by \bastgetconf\b(3) cause"
@@ -65,11 +66,13 @@
" prefixes are:]:[RE]{"
" [+CS?\bconfstr\b(2)]"
" [+PC?\bpathconf\b(2)]"
+" [+PC?\bfpathconf\b(2)]"
" [+SC?\bsysconf\b(2)]"
" [+SI?\bsysinfo\b(2)]"
" [+XX?Constant value.]"
"}"
"[d:defined?Only display defined values when no operands are specified.]"
+"[f?Use \bfd\b instead of a file name.]#[fd]"
"[l:lowercase?List variable names in lower case.]"
"[n:name?Display variables with name that match \aRE\a.]:[RE]"
"[p:portable?Display the named \bwritable\b variables and values in a form
that"
@@ -116,7 +119,7 @@
"is an implementation detail of process inheritance; it may "
"change or vanish in the future; don't rely on it.]"
"}"
-"[+SEE ALSO?\bpathchk\b(1), \bconfstr\b(2), \bpathconf\b(2),"
+"[+SEE ALSO?\bpathchk\b(1), \bconfstr\b(2), \bpathconf\b(2), \bfpathconf\b(2),"
" \bsysconf\b(2), \bastgetconf\b(3)]"
;
@@ -133,6 +136,7 @@
int
b_getconf(int argc, char** argv, Shbltin_t* context)
{
+ register int fd = -1;
register char* name;
register char* path;
register char* value;
@@ -182,6 +186,9 @@
case 'd':
flags |= ASTCONF_defined;
continue;
+ case 'f':
+ fd = opt_info.num;
+ continue;
case 'l':
flags |= ASTCONF_lower;
continue;
@@ -236,17 +243,19 @@
path = 0;
}
}
- if (error_info.errors || !name && *argv)
+ if (error_info.errors || !name && (fd == -1) && *argv)
error(ERROR_usage(2), "%s", optusage(NiL));
if (!name)
- astconflist(sfstdout, path, flags, pattern);
+ astconflist(sfstdout, fd, path, flags, pattern);
else
{
if (native)
flags |= (ASTCONF_system|ASTCONF_error);
do
{
- if (!(path = *++argv))
+ int pfd = -1; /* |fpathconf()| file descriptor */
+
+ if (!(path = *++argv) || (fd != -1))
value = 0;
else
{
@@ -261,7 +270,33 @@
flags = 0;
}
}
- s = astgetconf(name, path, value, flags, errorf);
+ if (path && (path[0] != '/') && (path[0] != '\0'))
+ {
+#ifdef O_PATH
+ /*
+ * Note that we have to try with |O_RDONLY|
first for now since
+ * Linux's |fstatfs()| (used by glibc
|fpathconf()|) currently
+ * does not like |O_PATH| (we alias |O_SEARCH|
to |O_PATH| if
+ * |O_SEARCH| is not natively available) and
returns a |EBADF|.
+ * This workaround limits the damage until
Linus fixes |fstatfs()|.
+ */
+ pfd = openat((fd !=
-1)?fd:(context?context->pwdfd:AT_FDCWD), path, O_RDONLY);
+ if (pfd == -1)
+#endif /* O_PATH */
+ {
+ pfd = openat((fd !=
-1)?fd:(context?context->pwdfd:AT_FDCWD), path, O_SEARCH);
+ }
+ if (pfd == -1)
+ {
+ error(ERROR_SYSTEM|2, "Cannot open %s",
path);
+ break;
+ }
+ }
+ s = astgetconf(name, (pfd >= 0)?pfd:fd, path, value,
flags, errorf);
+ if (pfd >= 0)
+ {
+ close(pfd);
+ }
if (error_info.errors)
break;
if (!s)
diff -r -u original/src/lib/libcmd/uname.c build_fgetconf/src/lib/libcmd/uname.c
--- src/lib/libcmd/uname.c 2012-01-10 19:57:03.000000000 +0100
+++ src/lib/libcmd/uname.c 2013-09-30 12:51:48.222260396 +0200
@@ -356,7 +356,7 @@
error(ERROR_system(1), "%s: cannot set host name", sethost);
}
else if (list)
- astconflist(sfstdout, NiL,
ASTCONF_base|ASTCONF_defined|ASTCONF_lower|ASTCONF_quote|ASTCONF_matchcall,
"CS|SI");
+ astconflist(sfstdout, -1, NiL,
ASTCONF_base|ASTCONF_defined|ASTCONF_lower|ASTCONF_quote|ASTCONF_matchcall,
"CS|SI");
else if (*argv)
{
e = &buf[sizeof(buf)-1];
_______________________________________________
ast-developers mailing list
[email protected]
http://lists.research.att.com/mailman/listinfo/ast-developers