On Wed, Jul 3, 2013 at 2:06 AM, Roland Mainz <[email protected]> wrote:
> On Tue, Jul 2, 2013 at 8:04 PM, Roland Mainz <[email protected]> wrote:
>> On Tue, Jul 2, 2013 at 4:11 PM, Irek Szczesniak <[email protected]>
>> wrote:
>>> On Sun, Jun 30, 2013 at 11:53 PM, Roland Mainz <[email protected]>
>>> wrote:
>>>> 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".
>> [snip]
>>>> - 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... :-)
>>>
>>> FYI Solaris 7 still doesn't build.
>>
>> Erm... general issue: It would be nice to have a bit more details than
>> just "... it doesn't work... " ... ;-)
>>
>> ... but I'm aware of the problem... right now I'm tracking the issues
>> on SuSE 9.3 (thanks go to SuSE for helping out :-) ) and Solaris 8.
>> _Maybe_ I have a patch in a few hours...
>
> Attached (as "astksh20130628_solaris_fixes002.diff.txt") is the new
> patch. It fixes ast-ksh.2013-06-28 on Solaris 8 and SuSE 9.3 (old
> Linux which even predates any of the |*at()|/|openat()|-APIs).
>
> Notes (Glenn/David: Please *read* this and comment if you don't like it):
> - A lot of calls in libshell have been changed from using |open(...)|
> to |openat(shp->pwdfd, ...| ... mainly to make sure the code goes
> through the intercept and |*at()|-API emulation code so that all
> emulated |O_*| flags are processed correctly and are not passed to the
> native OS'es |open()| syscall and cause trouble there.
> The other reason is to make libshell independent from the global cwd
> so multiple libshell objects can work in a single process and don't
> stomp on each other (the only design issue is that |spawnvex()| needs
> to be enhanced to take a cwd fd as argument in the future to set the
> cwd for a child process (AFAIK this is compatible to |vfork()| since
> we only call |fchdir()| after |vfork()| in the child but do not write
> into global data)).
>
> - src/cmd/ksh93/bltins/cd_pwd.c ... I restored the original comments
> about |O_SEARCH| ... please leave the algorithm as-is to make sure
> cd(1) is standard-conformant
>
> - src/lib/libast/comp/at.c ... added |renameat()| emulation and added
> a missing flag for |unlinkat()| ... I still have to review the code
> completely and add safety checks for unsupported flags... they should
> return an error instead of doing something which may not be intended
>
> - src/lib/libast/features/fcntl.c ... added the __USE_GNU&&co. hacks
> from my original patch... please don't complain... AFAIK there is no
> way to get |O_PATH| working properly otherwise (and |O_DIRECTORY| on
> older Linux versions (like SuSE 9.3))
>
> - src/lib/libast/path/pathopen.c ... off-by-one error which caused $(
> < {fd}/filetoread.txt ) to fail on SuSE 9.3
>
> - src/lib/libast/port/intercept.c ... added some "filters" to remove
> emulation flags so they do not bleed-through to the native syscalls
Attached (as "astksh20130628_solaris_fixes003.diff.txt") is an updated
version of the patch which fixes the issues which came up during code
review:
- Fixed error handling in cd(1) for NFSv4/CIFS/SMBFS XATTR directories
- Opening the history files now goes through the
|*at()|-emulation&&intercept code to make sure extra flags+signal
restart is handled properly (tested)
BTW: No, going through the |*at()| emulation is not slower unless the
|fd| argument in |openat(fd,...)| differs between individual calls
(well... at least the code in
http://svn.nrubsig.org/svn/people/gisburn/code/openat_emu/openat_emu.c
did maintain a cache (which is valid until |fchdir()|/|chdir()| is
called) and AFAIK the |*at()|-emulation in libast should do the same).
Comments/rants/etc. 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/cmd/ksh93/bltins/cd_pwd.c
build_i386_64bit_debug/src/cmd/ksh93/bltins/cd_pwd.c
--- src/cmd/ksh93/bltins/cd_pwd.c 2013-06-26 22:12:28.000000000 +0200
+++ src/cmd/ksh93/bltins/cd_pwd.c 2013-07-04 07:34:14.000000000 +0200
@@ -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;
+ int savederrno;
+#ifndef O_DIRECTORY
struct stat fs;
+#endif
#ifndef O_XATTR
NOT_USED(xattr);
#endif
@@ -70,21 +78,56 @@
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);
+ errno=savederrno;
+ }
+ 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);
+ }
+ }
if(fd < 0)
+ {
return fd;
+ }
+
+#ifndef O_DIRECTORY
if (!fstat(fd, &fs) && !S_ISDIR(fs.st_mode))
{
close(fd);
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);
diff -r -u original/src/cmd/ksh93/bltins/hist.c
build_i386_64bit_debug/src/cmd/ksh93/bltins/hist.c
--- src/cmd/ksh93/bltins/hist.c 2012-08-28 15:59:37.000000000 +0200
+++ src/cmd/ksh93/bltins/hist.c 2013-07-04 06:50:39.000000000 +0200
@@ -190,7 +190,7 @@
{
if(!(fname=pathtmp(NIL(char*),0,0,NIL(int*))))
errormsg(SH_DICT,ERROR_exit(1),e_create,"");
- if((fdo=open(fname,O_CREAT|O_RDWR,S_IRUSR|S_IWUSR|O_cloexec)) <
0)
+
if((fdo=openat(shp->pwdfd,fname,O_CREAT|O_RDWR,S_IRUSR|S_IWUSR|O_cloexec)) < 0)
errormsg(SH_DICT,ERROR_system(1),e_create,fname);
outfile= sfnew(NIL(Sfio_t*),shp->outbuff,IOBSIZE,fdo,SF_WRITE);
arg = "\n";
diff -r -u original/src/cmd/ksh93/edit/history.c
build_i386_64bit_debug/src/cmd/ksh93/edit/history.c
--- src/cmd/ksh93/edit/history.c 2012-09-18 17:20:02.000000000 +0200
+++ src/cmd/ksh93/edit/history.c 2013-07-04 06:50:18.000000000 +0200
@@ -179,7 +179,8 @@
{
char *cp, *last;
int id1, id2, r=0, n, fd;
- if((fd=open(name, O_RDONLY,O_cloexec)) < 0)
+ Shell_t *shp = hp->histshell;
+ if((fd=openat(shp->pwdfd, name, O_RDONLY,O_cloexec)) < 0)
return(0);
if((n = read(fd, logbuf,len-1)) < 0)
goto done;
@@ -262,7 +263,7 @@
cp = path_relative(shp,histname);
if(!histinit)
histmode = S_IRUSR|S_IWUSR;
- if((fd=open(cp,O_BINARY|O_APPEND|O_RDWR|O_CREAT|O_cloexec,histmode))>=0)
+
if((fd=openat(shp->pwdfd,cp,O_BINARY|O_APPEND|O_RDWR|O_CREAT|O_cloexec,histmode))>=0)
{
hsize=lseek(fd,(off_t)0,SEEK_END);
}
@@ -293,7 +294,7 @@
{
if(!(fname = pathtmp(NIL(char*),0,0,NIL(int*))))
return(0);
- fd =
open(fname,O_BINARY|O_APPEND|O_CREAT|O_RDWR,S_IRUSR|S_IWUSR|O_cloexec);
+ fd =
openat(shp->pwdfd,fname,O_BINARY|O_APPEND|O_CREAT|O_RDWR,S_IRUSR|S_IWUSR|O_cloexec);
}
}
if(fd<0)
@@ -457,6 +458,7 @@
static History_t* hist_trim(History_t *hp, int n)
{
+ Shell_t *shp = hp->histshell;
register char *cp;
register int incmd=1, c=0;
register History_t *hist_new, *hist_old = hp;
@@ -484,7 +486,7 @@
free(tmpname);
tmpname = name;
}
- fd = open(tmpname,O_RDONLY|O_cloexec);
+ fd = openat(shp->pwdfd,tmpname,O_RDONLY|O_cloexec);
sfsetfd(hist_old->histfp,fd);
if(tmpname==name)
tmpname = 0;
@@ -623,6 +625,7 @@
void hist_eof(register History_t *hp)
{
+ Shell_t *shp = hp->histshell;
register char *cp,*first,*endbuff;
register int incmd = 0;
register off_t count = hp->histcnt;
@@ -729,7 +732,7 @@
if(last<0)
{
char buff[HIST_MARKSZ];
- int fd = open(hp->histname,O_RDWR|O_cloexec);
+ int fd =
openat(shp->pwdfd,hp->histname,O_RDWR|O_cloexec);
if(fd>=0)
{
hist_marker(buff,hp->histind);
@@ -1186,13 +1189,14 @@
{
register int newfd,oldfd;
History_t *hp = (History_t*)handle;
+ Shell_t *shp = hp->histshell;
if(type==SF_WRITE)
{
if(errno==ENOSPC || hp->histwfail++ >= 10)
return(0);
/* write failure could be NFS problem, try to re-open */
sh_close(oldfd=sffileno(fp));
-
if((newfd=open(hp->histname,O_BINARY|O_APPEND|O_CREAT|O_RDWR|O_cloexec,S_IRUSR|S_IWUSR))
>= 0)
+
if((newfd=openat(shp->pwdfd,hp->histname,O_BINARY|O_APPEND|O_CREAT|O_RDWR|O_cloexec,S_IRUSR|S_IWUSR))
>= 0)
{
if(sh_fcntl(newfd, F_dupfd_cloexec, oldfd) !=oldfd)
return(-1);
diff -r -u original/src/cmd/ksh93/sh/io.c
build_i386_64bit_debug/src/cmd/ksh93/sh/io.c
--- src/cmd/ksh93/sh/io.c 2013-06-27 16:24:09.000000000 +0200
+++ src/cmd/ksh93/sh/io.c 2013-07-02 08:22:55.000000000 +0200
@@ -833,13 +833,13 @@
struct stat st;
if (stat(path,&st) >=0)
{
- while((nfd = open(path,flags,st.st_mode))<0 &&
errno==EINTR)
+ while((nfd =
openat(shp->pwdfd,path,flags,st.st_mode))<0 && errno==EINTR)
errno = err;
}
}
else
{
- while((nfd = open(path,flags))<0 && errno==EINTR)
+ while((nfd = openat(shp->pwdfd,path,flags))<0 &&
errno==EINTR)
errno = err;
}
if(nfd>=0)
@@ -867,7 +867,7 @@
path = buf;
}
#endif
- while((fd = open(path, flags, mode)) < 0)
+ while((fd = openat(shp->pwdfd, path, flags, mode)) < 0)
if(errno!=EINTR || shp->trapnote)
return(-1);
}
@@ -2063,7 +2063,7 @@
if(savefd <0 && (sp=shp->sftable[origfd]) &&
(sfset(sp,0,0)&SF_STRING))
{
savestr = 1;
- if((fd = open("/dev/null",O_RDONLY|O_cloexec)) < 10)
+ if((fd = openat(shp->pwdfd,
"/dev/null",O_RDONLY|O_cloexec)) < 10)
{
savefd = sh_fcntl(fd, F_dupfd_cloexec, 10);
close(fd);
diff -r -u original/src/cmd/ksh93/sh/path.c
build_i386_64bit_debug/src/cmd/ksh93/sh/path.c
--- src/cmd/ksh93/sh/path.c 2013-06-27 09:20:57.000000000 +0200
+++ src/cmd/ksh93/sh/path.c 2013-07-02 08:25:00.000000000 +0200
@@ -393,7 +393,7 @@
struct stat statb;
int fd = -1;
#if SHOPT_ATFUN
- if((fd=open(name,O_search|O_cloexec))<0 || fstat(fd,&statb)<0 ||
!S_ISDIR(statb.st_mode))
+ if((fd=openat(shp->pwdfd, name,O_search|O_cloexec))<0 ||
fstat(fd,&statb)<0 || !S_ISDIR(statb.st_mode))
#else
if(stat(name,&statb)<0 || !S_ISDIR(statb.st_mode))
@@ -951,7 +951,7 @@
path = path_relative(shp,path);
if(isfun)
{
- if((fd=open(path,O_RDONLY|O_cloexec,0))<0 || fstat(fd,&statb)<0)
+ if((fd=openat(shp->pwdfd,path,O_RDONLY|O_cloexec,0))<0 ||
fstat(fd,&statb)<0)
goto err;
}
else if(stat(path,&statb) < 0)
@@ -1351,7 +1351,7 @@
char *savet=0;
struct stat statb;
int err=0;
- if((n=open(path,O_RDONLY|O_cloexec,0)) >= 0)
+ if((n=openat(shp->pwdfd,path,O_RDONLY|O_cloexec,0)) >= 0)
{
/* move <n> if n=0,1,2 */
n = sh_iomovefd(shp,n);
@@ -1365,7 +1365,7 @@
{
strncpy(name+9,fmtbase((long)getpid(),10,0),sizeof(name)-10);
/* create a suid open file with owner equal effective
uid */
-
if((n=open(name,O_CREAT|O_TRUNC|O_WRONLY|O_cloexec,S_ISUID|S_IXUSR)) < 0)
+
if((n=openat(shp->pwdfd,name,O_CREAT|O_TRUNC|O_WRONLY|O_cloexec,S_ISUID|S_IXUSR))
< 0)
goto fail;
unlink(name);
/* make sure that file has right owner */
@@ -1391,7 +1391,7 @@
/*
* The following code is just for compatibility
*/
- if((n=open(path,O_RDONLY|O_cloexec,0)) < 0)
+ if((n=openat(shp->pwdfd,path,O_RDONLY|O_cloexec,0)) < 0)
errormsg(SH_DICT,ERROR_system(ERROR_NOEXEC),e_exec,path);
if(savet)
*argv++ = savet;
@@ -1480,7 +1480,7 @@
sabuf.ac_utime = compress(buffer.tms_utime + buffer.tms_cutime);
sabuf.ac_stime = compress(buffer.tms_stime + buffer.tms_cstime);
sabuf.ac_etime = compress( (time_t)(after-before));
- fd = open( SHACCT , O_WRONLY | O_APPEND |
O_CREAT|O_cloexec,RW_ALL);
+ fd = openat(sh.pwdfd, SHACCT , O_WRONLY | O_APPEND |
O_CREAT|O_cloexec,RW_ALL);
write(fd, (const char*)&sabuf, sizeof( sabuf ));
sh_close( fd);
}
@@ -1598,7 +1598,7 @@
if(pp->len==1 && *stkptr(shp->stk,offset)=='/')
stkseek(shp->stk,offset);
sfputr(shp->stk,"/.paths",-1);
- if((fd=open(stkptr(shp->stk,offset),O_RDONLY|O_cloexec))>=0)
+
if((fd=openat(shp->pwdfd,stkptr(shp->stk,offset),O_RDONLY|O_cloexec))>=0)
{
fstat(fd,&statb);
n = statb.st_size;
diff -r -u original/src/cmd/ksh93/sh/xec.c
build_i386_64bit_debug/src/cmd/ksh93/sh/xec.c
--- src/cmd/ksh93/sh/xec.c 2013-06-14 18:16:08.000000000 +0200
+++ src/cmd/ksh93/sh/xec.c 2013-07-02 08:23:20.000000000 +0200
@@ -862,7 +862,7 @@
sp = sfnew(NULL,NULL,SF_UNBOUND,fd,SF_READ);
while(close(0)<0 && errno==EINTR)
errno = err;
- open(e_devnull,O_RDONLY|O_cloexec);
+ openat(shp->pwdfd, e_devnull,O_RDONLY|O_cloexec);
shp->offsets[0] = -1;
shp->offsets[1] = 0;
*save = savein;
diff -r -u original/src/lib/libast/comp/at.c
build_i386_64bit_debug/src/lib/libast/comp/at.c
--- src/lib/libast/comp/at.c 2013-06-27 04:35:41.000000000 +0200
+++ src/lib/libast/comp/at.c 2013-07-02 08:45:41.000000000 +0200
@@ -45,13 +45,13 @@
#define ATBEG(cwd,path) \
{ \
char _at_##path[PATH_MAX]; \
- if (cwd >= 0) \
+ if (cwd != AT_FDCWD && path[0]!='/') \
sfsprintf(_at_##path, sizeof(_at_##path),
_fd_self_dir_fmt, cwd, "/", path);
#define ATBEGL(lwd,link) \
{ \
char _at_##link[PATH_MAX]; \
- if (lwd >= 0) \
+ if (lwd != AT_FDCWD && link[0]!='/') \
sfsprintf(_at_##link, sizeof(_at_##link),
_fd_self_dir_fmt, lwd, "/", link);
#else
@@ -59,19 +59,19 @@
#define ATBEG(cwd,path) \
{ \
char _at_##path[PATH_MAX]; \
- if (cwd >= 0) \
+ if (cwd != AT_FDCWD && path[0]!='/') \
sfsprintf(_at_##path, sizeof(_at_##path),
_fd_pid_dir_fmt, getpid(), cwd, "/", path);
#define ATBEGL(lwd,path) \
{ \
char _at_##link[PATH_MAX]; \
- if (lwd >= 0) \
+ if (lwd != AT_FDCWD && link[0]!='/') \
sfsprintf(_at_##link, sizeof(_at_##link),
_fd_pid_dir_fmt, getpid(), lwd, "/", link);
#endif
#define ATPATH(cwd,path) \
- ((cwd>=0)?(const char*)_at_##path:path)
+ ((cwd != AT_FDCWD && path[0]!='/')?(const char*)_at_##path:path)
#define ATEND() \
}
@@ -88,7 +88,7 @@
int _at_dot = -1; \
int _at_ret; \
unsigned int _at_tid; \
- if (cwd >= 0) \
+ if (cwd != AT_FDCWD && path[0]!='/') \
{ \
sigcrit(SIG_REG_ALL); \
_at_tid = asothreadid(); \
@@ -204,7 +204,7 @@
int r;
ATBEG(cwd, path);
- r = (flags & AT_SYMLINK_NOFOLLOW) ? lstat(ATPATH(cwd, path), st, flags)
: stat(ATPATH(cwd, path), st, flags);
+ r = (flags & AT_SYMLINK_NOFOLLOW) ? lstat(ATPATH(cwd, path), st) :
stat(ATPATH(cwd, path), st);
ATEND();
return r;
}
@@ -220,9 +220,9 @@
{
int r;
- if (pwd < 0 || *path == '/')
+ if (pwd == AT_FDCWD || *path == '/')
{
- if (lwd < 0 || *linkpath == '/')
+ if (lwd == AT_FDCWD || *linkpath == '/')
r = link(path, linkpath);
else
{
@@ -231,7 +231,7 @@
ATEND();
}
}
- else if (lwd < 0 || *linkpath == '/')
+ else if (lwd == AT_FDCWD || *linkpath == '/')
{
ATBEG(pwd, path);
r = link(ATPATH(pwd, path), linkpath);
@@ -333,7 +333,7 @@
#undef STUB
ssize_t
-readlinkat(int cwd, const char* path, void* buf, size_t size)
+readlinkat(int cwd, const char* path, char* buf, size_t size)
{
ssize_t r;
@@ -372,13 +372,42 @@
int r;
ATBEG(cwd, path);
- r = unlink(ATPATH(cwd, path), flags);
+ if (flags & AT_REMOVEDIR)
+ r = rmdir(ATPATH(cwd, path));
+ else
+ r = unlink(ATPATH(cwd, path));
ATEND();
return r;
}
#endif
+#if !_lib_renameat
+
+#undef STUB
+
+int
+renameat(int fromfd, const char *old, int tofd, const char *new)
+{
+ char oldpathbuf[PATH_MAX];
+ char newpathbuf[PATH_MAX];
+
+ if (fromfd != AT_FDCWD && old[0] != '/')
+ {
+ snprintf(oldpathbuf, sizeof(oldpathbuf), _fd_pid_dir_fmt,
getpid(), fromfd, "/", old);
+ old = oldpathbuf;
+ }
+ if (tofd != AT_FDCWD && new[0] != '/')
+ {
+ snprintf(newpathbuf, sizeof(newpathbuf), _fd_pid_dir_fmt,
getpid(), tofd, "/", new);
+ new = newpathbuf;
+ }
+
+ return rename(old, new);
+}
+
+#endif
+
#if STUB
void _STUB_at(){}
diff -r -u original/src/lib/libast/features/eaccess
build_i386_64bit_debug/src/lib/libast/features/eaccess
--- src/lib/libast/features/eaccess 2004-07-23 08:02:25.000000000 +0200
+++ src/lib/libast/features/eaccess 2013-07-01 05:27:17.000000000 +0200
@@ -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 2013-06-27 08:39:11.000000000 +0200
+++ src/lib/libast/features/fcntl.c 2013-07-03 00:40:08.000000000 +0200
@@ -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,12 +287,36 @@
#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
#ifdef O_XATTR
if (O_XATTR > o_local) o_local = O_XATTR;
#endif
+#ifdef O_DIRECT
+ if (O_DIRECT > o_local) o_local = O_DIRECT;
+#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,11 +369,33 @@
#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
#endif
+#ifdef O_DIRECTORY
+ /*
+ * O_DIRECTORY is only available as extension (hidden by
+ * obscure CPP flags) on older Linux versions. We make it
+ * available here (same as with O_PATH above) in general
+ * without requiring the whole build to use the obsure
+ * CPP flags to prevent any side-effects.
+ */
+ printf("#ifndef O_DIRECTORY\n");
+ printf("#define O_DIRECTORY 0%o\n", (int)O_DIRECTORY);
+ printf("#endif\n");
+#endif
#ifndef O_INTERCEPT
printf("#define O_INTERCEPT 0%o\n", o_local <<= 1);
#endif
@@ -346,7 +421,8 @@
#if !defined(AT_FDCWD) || !defined(AT_SYMLINK_NOFOLLOW) ||
!defined(AT_REMOVEDIR) || !defined(AT_SYMLINK_FOLLOW) || !defined(AT_EACCESS)
printf("\n");
#ifndef AT_FDCWD
- printf("#define AT_FDCWD -100\n");
+ /* AT_FDCWD must be below -256 for portability reasons */
+ printf("#define AT_FDCWD -666\n");
#endif
#ifndef AT_SYMLINK_NOFOLLOW
printf("#define AT_SYMLINK_NOFOLLOW 0x100\n");
@@ -420,10 +496,10 @@
printf("extern int mknodat(int, const char*, mode_t, dev_t);\n");
printf("#endif\n");
printf("#if !_lib_openat\n");
- printf("extern int openat(int, const char*, mode_t, int);\n");
+ printf("extern int openat(int, const char*, int flags, ...);\n");
printf("#endif\n");
printf("#if !_lib_readlinkat\n");
- printf("extern int readlinkat(int, const char*, void*,
size_t);\n");
+ printf("extern ssize_t readlinkat(int, const char*, char*,
size_t);\n");
printf("#endif\n");
printf("#if !_lib_symlinkat\n");
printf("extern int symlinkat(const char*, int, const char*);\n");
@@ -431,6 +507,9 @@
printf("#if !_lib_unlinkat\n");
printf("extern int unlinkat(int, const char*, int);\n");
printf("#endif\n");
+ printf("#if !_lib_renameat\n");
+ printf("extern int renameat(int fromfd, const char *old, int tofd,
const char *new);\n");
+ printf("#endif\n");
printf("\n");
printf("#undef extern\n");
diff -r -u original/src/lib/libast/features/lib
build_i386_64bit_debug/src/lib/libast/features/lib
--- src/lib/libast/features/lib 2013-06-27 04:34:19.000000000 +0200
+++ src/lib/libast/features/lib 2013-07-01 09:45:02.000000000 +0200
@@ -48,7 +48,7 @@
lib openat -D_ATFILE_SOURCE fcntl.h unistd.h yes{
#define _ATFILE_SOURCE 1
}end
-lib
faccessat,fchmodat,fchownat,fstatat,linkat,mkdirat,mkfifoat,mknodat,openat,readlinkat,symlinkat,unlinkat
-D_ATFILE_SOURCE fcntl.h unistd.h
+lib
faccessat,fchmodat,fchownat,fstatat,linkat,mkdirat,mkfifoat,mknodat,openat,readlinkat,symlinkat,unlinkat,renameat
-D_ATFILE_SOURCE fcntl.h unistd.h
lib fstatat64,openat64 -D_ATFILE_SOURCE -D_LARGEFILE64_SOURCE fcntl.h
unistd.h sys/stat.h
lib lchmod note{ lchmod implemented }end execute{
diff -r -u original/src/lib/libast/path/pathopen.c
build_i386_64bit_debug/src/lib/libast/path/pathopen.c
--- src/lib/libast/path/pathopen.c 2013-06-25 23:40:32.000000000 +0200
+++ src/lib/libast/path/pathopen.c 2013-07-02 20:07:30.000000000 +0200
@@ -166,7 +166,7 @@
return dev.pid > 0 && dev.pid != getpid() ?
openat(AT_FDCWD, b, oflags, mode) :
b[dev.path.offset] ?
- openat(dev.fd, b + dev.path.offset + 1, oflags,
mode) :
+ openat(dev.fd, b + dev.path.offset, oflags,
mode) :
fcntl(dev.fd, (oflags & O_CLOEXEC) ?
F_DUPFD_CLOEXEC : F_DUPFD, 0);
else if (dev.prot.offset)
{
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-06-28 08:59:40.000000000 +0200
+++ src/lib/libast/port/intercept.c 2013-07-02 22:56:50.000000000 +0200
@@ -176,7 +176,7 @@
ast_openat(int cwd, const char* path, int flags, ...)
{
int r;
-#if _ast_O_LOCAL && O_CLOEXEC >= _ast_O_LOCAL
+#if defined(_ast_O_LOCAL) && (O_CLOEXEC >= _ast_O_LOCAL)
int c;
#endif
mode_t mode;
@@ -185,7 +185,7 @@
va_start(ap, flags);
mode = (flags & O_CREAT) ? va_arg(ap, mode_t) : (mode_t)0;
va_end(ap);
-#if _ast_O_LOCAL && O_CLOEXEC >= _ast_O_LOCAL
+#if defined(_ast_O_LOCAL) && (O_CLOEXEC >= _ast_O_LOCAL)
if (flags & O_CLOEXEC)
{
flags &= ~O_CLOEXEC;
@@ -198,7 +198,7 @@
RESTART(r, openat(cwd, path, flags&~O_INTERCEPT, mode));
else
RESTART(r, pathopen(cwd, path, NiL, 0, 0, flags|O_INTERCEPT,
mode));
-#if _ast_O_LOCAL && O_CLOEXEC >= _ast_O_LOCAL
+#if defined(_ast_O_LOCAL) && (O_CLOEXEC >= _ast_O_LOCAL)
if (c && r >= 0)
RESTART(c, fcntl(r, F_SETFD, FD_CLOEXEC));
#endif
@@ -723,8 +723,18 @@
ast_socket(int domain, int type, int protocol)
{
int r;
+ int ftype=type;
- RESTART(r, socket(domain, type, protocol));
+/* Filter flags we emulate */
+#if _ast_SOCK_CLOEXEC
+ if (ftype & SOCK_CLOEXEC)
+ ftype &= ~SOCK_CLOEXEC;
+#endif
+#if _ast_SOCK_NONBLOCK
+ if (ftype & SOCK_NONBLOCK)
+ ftype &= ~SOCK_NONBLOCK;
+#endif
+ RESTART(r, socket(domain, ftype, protocol));
SOCKTYPE(r, type, r, -1);
return r;
}
@@ -733,8 +743,19 @@
ast_socketpair(int domain, int type, int protocol, int fds[2])
{
int r;
+ int ftype=type;
+
+/* Filter flags we emulate */
+#if _ast_SOCK_CLOEXEC
+ if (ftype & SOCK_CLOEXEC)
+ ftype &= ~SOCK_CLOEXEC;
+#endif
+#if _ast_SOCK_NONBLOCK
+ if (ftype & SOCK_NONBLOCK)
+ ftype &= ~SOCK_NONBLOCK;
+#endif
- RESTART(r, socketpair(domain, type, protocol, fds));
+ RESTART(r, socketpair(domain, ftype, protocol, fds));
SOCKTYPE(r, type, fds[0], fds[1]);
return r;
}
_______________________________________________
ast-developers mailing list
[email protected]
http://lists.research.att.com/mailman/listinfo/ast-developers