| Submitter | Khem Raj |
|---|---|
| Date | Feb. 6, 2012, 6:40 a.m. |
| Message ID | <633b2b23bbddb8cb2b0aa1d75ee82b9826d1de55.1328510188.git.raj.khem@gmail.com> |
| Download | mbox | patch |
| Permalink | /patch/20759/ |
| State | New |
| Headers | show |
Comments
On 02/05/2012 10:40 PM, Khem Raj wrote: > Signed-off-by: Khem Raj<raj.khem@gmail.com> > --- > meta/recipes-devtools/pseudo/pseudo/opendir.patch | 92 ++++++++ > meta/recipes-devtools/pseudo/pseudo/renameat.patch | 227 ++++++++++++++++++++ > meta/recipes-devtools/pseudo/pseudo_1.2.bb | 6 +- > 3 files changed, 323 insertions(+), 2 deletions(-) > create mode 100644 meta/recipes-devtools/pseudo/pseudo/opendir.patch > create mode 100644 meta/recipes-devtools/pseudo/pseudo/renameat.patch > > diff --git a/meta/recipes-devtools/pseudo/pseudo/opendir.patch b/meta/recipes-devtools/pseudo/pseudo/opendir.patch > new file mode 100644 > index 0000000..d20f717 > --- /dev/null > +++ b/meta/recipes-devtools/pseudo/pseudo/opendir.patch > @@ -0,0 +1,92 @@ > +commit 162f2692c399b93311652201a940fdaf9c9e6924 > +Author: Peter Seebach<peter.seebach@windriver.com> > +Date: Thu Feb 2 11:45:42 2012 -0600 > + > + Make opendir/closedir stash and forget directory names. > + > + The dirfd(DIR *) interface allows you to get the fd for a DIR *, > + meaning you can use it with openat(), meaning you can need its > + path. This causes a segfault. Also gonna fix the base_path > + code not to segfault in that case, but first fix the underlying > + problem. > + Missing Upstream-Status: and Signed-off-by (yes I know we have an email header). Thanks Sau! > +diff --git a/ChangeLog.txt b/ChangeLog.txt > +index 4de488c..9625b38 100644 > +--- a/ChangeLog.txt > ++++ b/ChangeLog.txt > +@@ -1,3 +1,7 @@ > ++2012-02-02: > ++ * (seebs) stash dir name for DIR * from opendir using dirfd. > ++ * (seebs) add closedir. > ++ > + 2011-11-02: > + * (seebs) Call this 1.2 because the UNLOAD change is moderately > + significant, and so's the clone change. > +diff --git a/ports/unix/guts/closedir.c b/ports/unix/guts/closedir.c > +new file mode 100644 > +index 0000000..1085361 > +--- /dev/null > ++++ b/ports/unix/guts/closedir.c > +@@ -0,0 +1,20 @@ > ++/* > ++ * Copyright (c) 2012 Wind River Systems; see > ++ * guts/COPYRIGHT for information. > ++ * > ++ * static int > ++ * wrap_closedir(DIR *dirp) { > ++ * int rc = -1; > ++ */ > ++ if (!dirp) { > ++ errno = EFAULT; > ++ return -1; > ++ } > ++ > ++ int fd = dirfd(dirp); > ++ pseudo_client_op(OP_CLOSE, 0, fd, -1, 0, 0); > ++ rc = real_closedir(dirp); > ++ > ++/* return rc; > ++ * } > ++ */ > +diff --git a/ports/unix/guts/opendir.c b/ports/unix/guts/opendir.c > +index 8eaa71f..e69717e 100644 > +--- a/ports/unix/guts/opendir.c > ++++ b/ports/unix/guts/opendir.c > +@@ -6,8 +6,25 @@ > + * wrap_opendir(const char *path) { > + * DIR * rc = NULL; > + */ > ++ struct stat buf; > ++ int save_errno; > + > + rc = real_opendir(path); > ++ if (rc) { > ++ int fd; > ++ save_errno = errno; > ++ fd = dirfd(rc); > ++ if (real_fstat(fd,&buf) == -1) { > ++ pseudo_debug(1, "diropen (fd %d) succeeded, but fstat failed (%s).\n", > ++ fd, strerror(errno)); > ++ pseudo_client_op_plain(OP_OPEN, PSA_READ, fd, -1, path, 0); > ++ } else { > ++ pseudo_client_op_plain(OP_OPEN, PSA_READ, fd, -1, path,&buf); > ++ } > ++ > ++ > ++ errno = save_errno; > ++ } > + > + /* return rc; > + * } > +diff --git a/ports/unix/wrapfuncs.in b/ports/unix/wrapfuncs.in > +index e06e404..32250c4 100644 > +--- a/ports/unix/wrapfuncs.in > ++++ b/ports/unix/wrapfuncs.in > +@@ -21,6 +21,7 @@ long pathconf(const char *path, int name); > + char *realpath(const char *name, char *resolved_name); /* version="GLIBC_2.3" */ > + int remove(const char *path); /* flags=AT_SYMLINK_NOFOLLOW */ > + DIR *opendir(const char *path); > ++int closedir(DIR *dirp); > + char *tempnam(const char *template, const char *pfx); > + char *tmpnam(char *s); > + int truncate(const char *path, off_t length); > diff --git a/meta/recipes-devtools/pseudo/pseudo/renameat.patch b/meta/recipes-devtools/pseudo/pseudo/renameat.patch > new file mode 100644 > index 0000000..74c8585 > --- /dev/null > +++ b/meta/recipes-devtools/pseudo/pseudo/renameat.patch > @@ -0,0 +1,227 @@ > +commit 795f2b44b7f692151556782f142a4a6e7d45d892 > +Author: Peter Seebach<peter.seebach@windriver.com> > +Date: Thu Feb 2 15:49:21 2012 -0600 > + > + Implement renameat() > + > + After three long years, someone tried to use this. This was impossibly > + hard back when pseudo was written, because there was only one dirfd > + provided for. Thing is, now, the canonicalization happens in wrapfuncs, > + so a small tweak to makewrappers to recognize that oldpath should use > + olddirfd if it exists is enough to get us fully canonicalized paths > + when needed. > + > + Also fix the crash if base_path gets called with an fd for which we have > + no path. > + > +diff --git a/ChangeLog.txt b/ChangeLog.txt > +index 9625b38..25bd463 100644 > +--- a/ChangeLog.txt > ++++ b/ChangeLog.txt > +@@ -1,6 +1,9 @@ > + 2012-02-02: > + * (seebs) stash dir name for DIR * from opendir using dirfd. > + * (seebs) add closedir. > ++ * (seebs) add initial pass at renameat() > ++ * (seebs) in base_path, don't try to strlen the result if > ++ fd_path() returns NULL. > + > + 2011-11-02: > + * (seebs) Call this 1.2 because the UNLOAD change is moderately > +diff --git a/makewrappers b/makewrappers > +index 20bbf2b..bf344d6 100755 > +--- a/makewrappers > ++++ b/makewrappers > +@@ -211,12 +211,13 @@ class Function: > + self.flags = '0' > + self.port = port > + self.directory = '' > +- self.version = 'NULL' > ++ self.version = 'NULL' > + # On Darwin, some functions are SECRETLY converted to foo$INODE64 > + # when called. So we have to look those up for real_* > + self.inode64 = None > + self.real_func = None > + self.paths_to_munge = [] > ++ self.dirfds = {} > + self.hand_wrapped = None > + # used for the copyright date when creating stub functions > + self.date = datetime.date.today().year > +@@ -239,6 +240,7 @@ class Function: > + # * If the arg has a name ending in 'path', we will canonicalize it. > + # * If the arg is named 'dirfd' or 'flags', it becomes the default > + # values for the dirfd and flags arguments when canonicalizing. > ++ # * If the name ends in dirfd, we do the same fancy stuff. > + # * Note that the "comments" field (/* ... */ after the decl) can > + # override the dirfd/flags values. > + self.args = ArgumentList(bits.group(2)) > +@@ -246,7 +248,9 @@ class Function: > + # ignore varargs, they never get these special treatments > + if arg.vararg: > + pass > +- elif arg.name == 'dirfd': > ++ elif arg.name[-5:] == 'dirfd': > ++ if len(arg.name)> 5: > ++ self.dirfds[arg.name[:-5]] = True > + self.dirfd = 'dirfd' > + elif arg.name == 'flags': > + self.flags = 'flags' > +@@ -325,9 +329,13 @@ class Function: > + """create/allocate canonical paths""" > + alloc_paths = [] > + for path in self.paths_to_munge: > ++ prefix = path[:-4] > ++ if not prefix in self.dirfds: > ++ prefix = '' > ++ print "for path %s: prefix<%s>" % ( path, prefix ) > + alloc_paths.append( > +- "%s = pseudo_root_path(__func__, __LINE__, %s, %s, %s);" % > +- (path, self.dirfd, path, self.flags)) > ++ "%s = pseudo_root_path(__func__, __LINE__, %s%s, %s, %s);" % > ++ (path, prefix, self.dirfd, path, self.flags)) > + return "\n\t\t\t".join(alloc_paths) > + > + def free_paths(self): > +diff --git a/ports/unix/guts/renameat.c b/ports/unix/guts/renameat.c > +index c8203b7..f13cd1e 100644 > +--- a/ports/unix/guts/renameat.c > ++++ b/ports/unix/guts/renameat.c > +@@ -1,15 +1,111 @@ > + /* > +- * Copyright (c) 2008-2010 Wind River Systems; see > ++ * Copyright (c) 2008-2012 Wind River Systems; see > + * guts/COPYRIGHT for information. > + * > + * static int > + * wrap_renameat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) { > + * int rc = -1; > + */ > ++ pseudo_msg_t *msg; > ++ struct stat oldbuf, newbuf; > ++ int oldrc, newrc; > ++ int save_errno; > ++ int old_db_entry = 0; > + > +- pseudo_diag("help! unimplemented renameat [%s -> %s].\n", oldpath, newpath); > ++ pseudo_debug(2, "renameat: %d,%s->%d,%s\n", > ++ olddirfd, oldpath ? oldpath : "<nil>", > ++ newdirfd, newpath ? newpath : "<nil>"); > ++ > ++#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS > ++ if (olddirfd != AT_FDCWD || newdirfd != AT_FDCWD) { > ++ errno = ENOSYS; > ++ return -1; > ++ } > ++#endif > ++ > ++ if (!oldpath || !newpath) { > ++ errno = EFAULT; > ++ return -1; > ++ } > ++ > ++ save_errno = errno; > ++ > ++#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS > ++ newrc = real_lstat(newpath,&newbuf); > ++ oldrc = real_lstat(oldpath,&oldbuf); > ++#else > ++ oldrc = real___fxstatat(_STAT_VER, olddirfd, oldpath,&oldbuf, AT_SYMLINK_NOFOLLOW); > ++ newrc = real___fxstatat(_STAT_VER, newdirfd, newpath,&newbuf, AT_SYMLINK_NOFOLLOW); > ++#endif > ++ > ++ errno = save_errno; > ++ > ++ /* newpath must be removed. */ > ++ /* as with unlink, we have to mark that the file may get deleted */ > ++ msg = pseudo_client_op_plain(OP_MAY_UNLINK, 0, -1, newdirfd, newpath, newrc ? NULL :&newbuf); > ++ if (msg&& msg->result == RESULT_SUCCEED) > ++ old_db_entry = 1; > + rc = real_renameat(olddirfd, oldpath, newdirfd, newpath); > ++ save_errno = errno; > ++ if (old_db_entry) { > ++ if (rc == -1) { > ++ /* since we failed, that wasn't really unlinked -- put > ++ * it back. > ++ */ > ++ pseudo_client_op_plain(OP_CANCEL_UNLINK, 0, -1, newdirfd, newpath,&newbuf); > ++ } else { > ++ /* confirm that the file was removed */ > ++ pseudo_client_op_plain(OP_DID_UNLINK, 0, -1, newdirfd, newpath,&newbuf); > ++ } > ++ } > ++ if (rc == -1) { > ++ /* and we're done. */ > ++ errno = save_errno; > ++ return rc; > ++ } > ++ save_errno = errno; > ++ /* nothing to do for a "rename" of a link to itself */ > ++ if (newrc != -1&& oldrc != -1&& > ++ newbuf.st_dev == oldbuf.st_dev&& > ++ newbuf.st_ino == oldbuf.st_ino) { > ++ return rc; > ++ } > ++ > ++ /* rename(3) is not mv(1). rename(file, dir) fails; you must provide > ++ * the corrected path yourself. You can rename over a directory only > ++ * if the source is a directory. Symlinks are simply removed. > ++ * > ++ * If we got here, the real rename call succeeded. That means newpath > ++ * has been unlinked and oldpath has been linked to it. > ++ * > ++ * There are a ton of special cases to error check. I don't check > ++ * for any of them, because in every such case, the underlying rename > ++ * failed, and there is nothing to do. > ++ * The only tricky part is that, because we used to ignore symlinks, > ++ * we may have to rename or remove directory trees even though in > ++ * theory rename can never destroy a directory tree. > ++ */ > ++ if (!old_db_entry) { > ++ /* create an entry under the old name, which will then be > ++ * renamed; this way, children would get renamed too, if there > ++ * were any. > ++ */ > ++ if (newrc == 0) { > ++ if (newbuf.st_dev != oldbuf.st_dev) { > ++ oldbuf.st_dev = newbuf.st_dev; > ++ oldbuf.st_ino = newbuf.st_ino; > ++ } > ++ } > ++ pseudo_debug(1, "creating new '%s' [%llu] to rename\n", > ++ oldpath, (unsigned long long) oldbuf.st_ino); > ++ pseudo_client_op_plain(OP_LINK, 0, -1, olddirfd, oldpath,&oldbuf); > ++ } > ++ /* special case: use 'fd' for olddirfd, because > ++ * we know it has no other meaning for RENAME > ++ */ > ++ pseudo_client_op_plain(OP_RENAME, 0, olddirfd, newdirfd, newpath,&oldbuf, oldpath); > + > ++ errno = save_errno; > + /* return rc; > + * } > + */ > +diff --git a/pseudo_client.c b/pseudo_client.c > +index 48607c2..4a30420 100644 > +--- a/pseudo_client.c > ++++ b/pseudo_client.c > +@@ -988,6 +988,8 @@ base_path(int dirfd, const char *path, int leave_last) { > + if (dirfd != -1&& dirfd != AT_FDCWD) { > + if (dirfd>= 0) { > + basepath = fd_path(dirfd); > ++ } > ++ if (basepath) { > + baselen = strlen(basepath); > + } else { > + pseudo_diag("got *at() syscall for unknown directory, fd %d\n", dirfd); > +@@ -1128,7 +1130,10 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path > + if (path) { > + pseudo_debug(2, " %s", path); > + } > +- if (fd != -1) { > ++ /* for OP_RENAME in renameat, "fd" is also used for the > ++ * second dirfd. > ++ */ > ++ if (fd != -1&& op != OP_RENAME) { > + pseudo_debug(2, " [fd %d]", fd); > + } > + if (buf) { > diff --git a/meta/recipes-devtools/pseudo/pseudo_1.2.bb b/meta/recipes-devtools/pseudo/pseudo_1.2.bb > index f2ebc22..04bcbce 100644 > --- a/meta/recipes-devtools/pseudo/pseudo_1.2.bb > +++ b/meta/recipes-devtools/pseudo/pseudo_1.2.bb > @@ -1,10 +1,12 @@ > require pseudo.inc > > -PR = "r4" > +PR = "r5" > > SRC_URI = "http://www.yoctoproject.org/downloads/${BPN}/${BPN}-${PV}.tar.bz2 \ > file://oe-config.patch \ > - file://static_sqlite.patch" > + file://static_sqlite.patch \ > + file://opendir.patch \ > + file://renameat.patch" > > SRC_URI[md5sum] = "a2819084bab7e991f06626d02cf55048" > SRC_URI[sha256sum] = "4749a22df687f44d24c26e97170d4781a1bd52d5ee092364a40877e4d96ff058"
On Tue, Feb 7, 2012 at 8:21 AM, Saul Wold <sgw@linux.intel.com> wrote: > On 02/05/2012 10:40 PM, Khem Raj wrote: >> >> Signed-off-by: Khem Raj<raj.khem@gmail.com> >> --- >> meta/recipes-devtools/pseudo/pseudo/opendir.patch | 92 ++++++++ >> meta/recipes-devtools/pseudo/pseudo/renameat.patch | 227 >> ++++++++++++++++++++ >> meta/recipes-devtools/pseudo/pseudo_1.2.bb | 6 +- >> 3 files changed, 323 insertions(+), 2 deletions(-) >> create mode 100644 meta/recipes-devtools/pseudo/pseudo/opendir.patch >> create mode 100644 meta/recipes-devtools/pseudo/pseudo/renameat.patch >> >> diff --git a/meta/recipes-devtools/pseudo/pseudo/opendir.patch >> b/meta/recipes-devtools/pseudo/pseudo/opendir.patch >> new file mode 100644 >> index 0000000..d20f717 >> --- /dev/null >> +++ b/meta/recipes-devtools/pseudo/pseudo/opendir.patch >> @@ -0,0 +1,92 @@ >> +commit 162f2692c399b93311652201a940fdaf9c9e6924 >> +Author: Peter Seebach<peter.seebach@windriver.com> >> +Date: Thu Feb 2 11:45:42 2012 -0600 >> + >> + Make opendir/closedir stash and forget directory names. >> + >> + The dirfd(DIR *) interface allows you to get the fd for a DIR *, >> + meaning you can use it with openat(), meaning you can need its >> + path. This causes a segfault. Also gonna fix the base_path >> + code not to segfault in that case, but first fix the underlying >> + problem. >> + > > > Missing Upstream-Status: and Signed-off-by (yes I know we have an email > header). they are backports > > Thanks > Sau! > >> +diff --git a/ChangeLog.txt b/ChangeLog.txt >> +index 4de488c..9625b38 100644 >> +--- a/ChangeLog.txt >> ++++ b/ChangeLog.txt >> +@@ -1,3 +1,7 @@ >> ++2012-02-02: >> ++ * (seebs) stash dir name for DIR * from opendir using dirfd. >> ++ * (seebs) add closedir. >> ++ >> + 2011-11-02: >> + * (seebs) Call this 1.2 because the UNLOAD change is moderately >> + significant, and so's the clone change. >> +diff --git a/ports/unix/guts/closedir.c b/ports/unix/guts/closedir.c >> +new file mode 100644 >> +index 0000000..1085361 >> +--- /dev/null >> ++++ b/ports/unix/guts/closedir.c >> +@@ -0,0 +1,20 @@ >> ++/* >> ++ * Copyright (c) 2012 Wind River Systems; see >> ++ * guts/COPYRIGHT for information. >> ++ * >> ++ * static int >> ++ * wrap_closedir(DIR *dirp) { >> ++ * int rc = -1; >> ++ */ >> ++ if (!dirp) { >> ++ errno = EFAULT; >> ++ return -1; >> ++ } >> ++ >> ++ int fd = dirfd(dirp); >> ++ pseudo_client_op(OP_CLOSE, 0, fd, -1, 0, 0); >> ++ rc = real_closedir(dirp); >> ++ >> ++/* return rc; >> ++ * } >> ++ */ >> +diff --git a/ports/unix/guts/opendir.c b/ports/unix/guts/opendir.c >> +index 8eaa71f..e69717e 100644 >> +--- a/ports/unix/guts/opendir.c >> ++++ b/ports/unix/guts/opendir.c >> +@@ -6,8 +6,25 @@ >> + * wrap_opendir(const char *path) { >> + * DIR * rc = NULL; >> + */ >> ++ struct stat buf; >> ++ int save_errno; >> + >> + rc = real_opendir(path); >> ++ if (rc) { >> ++ int fd; >> ++ save_errno = errno; >> ++ fd = dirfd(rc); >> ++ if (real_fstat(fd,&buf) == -1) { >> >> ++ pseudo_debug(1, "diropen (fd %d) succeeded, but >> fstat failed (%s).\n", >> ++ fd, strerror(errno)); >> ++ pseudo_client_op_plain(OP_OPEN, PSA_READ, fd, -1, >> path, 0); >> ++ } else { >> ++ pseudo_client_op_plain(OP_OPEN, PSA_READ, fd, -1, >> path,&buf); >> ++ } >> ++ >> ++ >> ++ errno = save_errno; >> ++ } >> + >> + /* return rc; >> + * } >> +diff --git a/ports/unix/wrapfuncs.in b/ports/unix/wrapfuncs.in >> +index e06e404..32250c4 100644 >> +--- a/ports/unix/wrapfuncs.in >> ++++ b/ports/unix/wrapfuncs.in >> +@@ -21,6 +21,7 @@ long pathconf(const char *path, int name); >> + char *realpath(const char *name, char *resolved_name); /* >> version="GLIBC_2.3" */ >> + int remove(const char *path); /* flags=AT_SYMLINK_NOFOLLOW */ >> + DIR *opendir(const char *path); >> ++int closedir(DIR *dirp); >> + char *tempnam(const char *template, const char *pfx); >> + char *tmpnam(char *s); >> + int truncate(const char *path, off_t length); >> diff --git a/meta/recipes-devtools/pseudo/pseudo/renameat.patch >> b/meta/recipes-devtools/pseudo/pseudo/renameat.patch >> new file mode 100644 >> index 0000000..74c8585 >> --- /dev/null >> +++ b/meta/recipes-devtools/pseudo/pseudo/renameat.patch >> @@ -0,0 +1,227 @@ >> +commit 795f2b44b7f692151556782f142a4a6e7d45d892 >> +Author: Peter Seebach<peter.seebach@windriver.com> >> +Date: Thu Feb 2 15:49:21 2012 -0600 >> + >> + Implement renameat() >> + >> + After three long years, someone tried to use this. This was >> impossibly >> + hard back when pseudo was written, because there was only one dirfd >> + provided for. Thing is, now, the canonicalization happens in >> wrapfuncs, >> + so a small tweak to makewrappers to recognize that oldpath should use >> + olddirfd if it exists is enough to get us fully canonicalized paths >> + when needed. >> + >> + Also fix the crash if base_path gets called with an fd for which we >> have >> + no path. >> + >> +diff --git a/ChangeLog.txt b/ChangeLog.txt >> +index 9625b38..25bd463 100644 >> +--- a/ChangeLog.txt >> ++++ b/ChangeLog.txt >> +@@ -1,6 +1,9 @@ >> + 2012-02-02: >> + * (seebs) stash dir name for DIR * from opendir using dirfd. >> + * (seebs) add closedir. >> ++ * (seebs) add initial pass at renameat() >> ++ * (seebs) in base_path, don't try to strlen the result if >> ++ fd_path() returns NULL. >> + >> + 2011-11-02: >> + * (seebs) Call this 1.2 because the UNLOAD change is moderately >> +diff --git a/makewrappers b/makewrappers >> +index 20bbf2b..bf344d6 100755 >> +--- a/makewrappers >> ++++ b/makewrappers >> +@@ -211,12 +211,13 @@ class Function: >> + self.flags = '0' >> + self.port = port >> + self.directory = '' >> +- self.version = 'NULL' >> ++ self.version = 'NULL' >> + # On Darwin, some functions are SECRETLY converted to >> foo$INODE64 >> + # when called. So we have to look those up for real_* >> + self.inode64 = None >> + self.real_func = None >> + self.paths_to_munge = [] >> ++ self.dirfds = {} >> + self.hand_wrapped = None >> + # used for the copyright date when creating stub functions >> + self.date = datetime.date.today().year >> +@@ -239,6 +240,7 @@ class Function: >> + # * If the arg has a name ending in 'path', we will canonicalize >> it. >> + # * If the arg is named 'dirfd' or 'flags', it becomes the >> default >> + # values for the dirfd and flags arguments when >> canonicalizing. >> ++ # * If the name ends in dirfd, we do the same fancy stuff. >> + # * Note that the "comments" field (/* ... */ after the decl) >> can >> + # override the dirfd/flags values. >> + self.args = ArgumentList(bits.group(2)) >> +@@ -246,7 +248,9 @@ class Function: >> + # ignore varargs, they never get these special treatments >> + if arg.vararg: >> + pass >> +- elif arg.name == 'dirfd': >> ++ elif arg.name[-5:] == 'dirfd': >> ++ if len(arg.name)> 5: >> ++ self.dirfds[arg.name[:-5]] = True >> + self.dirfd = 'dirfd' >> + elif arg.name == 'flags': >> + self.flags = 'flags' >> +@@ -325,9 +329,13 @@ class Function: >> + """create/allocate canonical paths""" >> + alloc_paths = [] >> + for path in self.paths_to_munge: >> ++ prefix = path[:-4] >> ++ if not prefix in self.dirfds: >> ++ prefix = '' >> ++ print "for path %s: prefix<%s>" % ( path, prefix ) >> + alloc_paths.append( >> +- "%s = pseudo_root_path(__func__, __LINE__, %s, %s, %s);" >> % >> +- (path, self.dirfd, path, self.flags)) >> ++ "%s = pseudo_root_path(__func__, __LINE__, %s%s, %s, >> %s);" % >> ++ (path, prefix, self.dirfd, path, self.flags)) >> + return "\n\t\t\t".join(alloc_paths) >> + >> + def free_paths(self): >> +diff --git a/ports/unix/guts/renameat.c b/ports/unix/guts/renameat.c >> +index c8203b7..f13cd1e 100644 >> +--- a/ports/unix/guts/renameat.c >> ++++ b/ports/unix/guts/renameat.c >> +@@ -1,15 +1,111 @@ >> + /* >> +- * Copyright (c) 2008-2010 Wind River Systems; see >> ++ * Copyright (c) 2008-2012 Wind River Systems; see >> + * guts/COPYRIGHT for information. >> + * >> + * static int >> + * wrap_renameat(int olddirfd, const char *oldpath, int newdirfd, const >> char *newpath) { >> + * int rc = -1; >> + */ >> ++ pseudo_msg_t *msg; >> ++ struct stat oldbuf, newbuf; >> ++ int oldrc, newrc; >> ++ int save_errno; >> ++ int old_db_entry = 0; >> + >> +- pseudo_diag("help! unimplemented renameat [%s -> %s].\n", >> oldpath, newpath); >> ++ pseudo_debug(2, "renameat: %d,%s->%d,%s\n", >> ++ olddirfd, oldpath ? oldpath : "<nil>", >> ++ newdirfd, newpath ? newpath : "<nil>"); >> ++ >> ++#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS >> ++ if (olddirfd != AT_FDCWD || newdirfd != AT_FDCWD) { >> ++ errno = ENOSYS; >> ++ return -1; >> ++ } >> ++#endif >> ++ >> ++ if (!oldpath || !newpath) { >> ++ errno = EFAULT; >> ++ return -1; >> ++ } >> ++ >> ++ save_errno = errno; >> ++ >> ++#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS >> ++ newrc = real_lstat(newpath,&newbuf); >> ++ oldrc = real_lstat(oldpath,&oldbuf); >> ++#else >> ++ oldrc = real___fxstatat(_STAT_VER, olddirfd, oldpath,&oldbuf, >> AT_SYMLINK_NOFOLLOW); >> ++ newrc = real___fxstatat(_STAT_VER, newdirfd, newpath,&newbuf, >> AT_SYMLINK_NOFOLLOW); >> >> ++#endif >> ++ >> ++ errno = save_errno; >> ++ >> ++ /* newpath must be removed. */ >> ++ /* as with unlink, we have to mark that the file may get deleted >> */ >> ++ msg = pseudo_client_op_plain(OP_MAY_UNLINK, 0, -1, newdirfd, >> newpath, newrc ? NULL :&newbuf); >> ++ if (msg&& msg->result == RESULT_SUCCEED) >> >> ++ old_db_entry = 1; >> + rc = real_renameat(olddirfd, oldpath, newdirfd, newpath); >> ++ save_errno = errno; >> ++ if (old_db_entry) { >> ++ if (rc == -1) { >> ++ /* since we failed, that wasn't really unlinked -- >> put >> ++ * it back. >> ++ */ >> ++ pseudo_client_op_plain(OP_CANCEL_UNLINK, 0, -1, >> newdirfd, newpath,&newbuf); >> ++ } else { >> ++ /* confirm that the file was removed */ >> ++ pseudo_client_op_plain(OP_DID_UNLINK, 0, -1, >> newdirfd, newpath,&newbuf); >> ++ } >> ++ } >> ++ if (rc == -1) { >> ++ /* and we're done. */ >> ++ errno = save_errno; >> ++ return rc; >> ++ } >> ++ save_errno = errno; >> ++ /* nothing to do for a "rename" of a link to itself */ >> ++ if (newrc != -1&& oldrc != -1&& >> ++ newbuf.st_dev == oldbuf.st_dev&& >> ++ newbuf.st_ino == oldbuf.st_ino) { >> ++ return rc; >> ++ } >> ++ >> ++ /* rename(3) is not mv(1). rename(file, dir) fails; you must >> provide >> ++ * the corrected path yourself. You can rename over a directory >> only >> ++ * if the source is a directory. Symlinks are simply removed. >> ++ * >> ++ * If we got here, the real rename call succeeded. That means >> newpath >> ++ * has been unlinked and oldpath has been linked to it. >> ++ * >> ++ * There are a ton of special cases to error check. I don't check >> ++ * for any of them, because in every such case, the underlying >> rename >> ++ * failed, and there is nothing to do. >> ++ * The only tricky part is that, because we used to ignore >> symlinks, >> ++ * we may have to rename or remove directory trees even though in >> ++ * theory rename can never destroy a directory tree. >> ++ */ >> ++ if (!old_db_entry) { >> ++ /* create an entry under the old name, which will then be >> ++ * renamed; this way, children would get renamed too, if >> there >> ++ * were any. >> ++ */ >> ++ if (newrc == 0) { >> ++ if (newbuf.st_dev != oldbuf.st_dev) { >> ++ oldbuf.st_dev = newbuf.st_dev; >> ++ oldbuf.st_ino = newbuf.st_ino; >> ++ } >> ++ } >> ++ pseudo_debug(1, "creating new '%s' [%llu] to rename\n", >> ++ oldpath, (unsigned long long) oldbuf.st_ino); >> ++ pseudo_client_op_plain(OP_LINK, 0, -1, olddirfd, >> oldpath,&oldbuf); >> ++ } >> ++ /* special case: use 'fd' for olddirfd, because >> ++ * we know it has no other meaning for RENAME >> ++ */ >> ++ pseudo_client_op_plain(OP_RENAME, 0, olddirfd, newdirfd, >> newpath,&oldbuf, oldpath); >> >> + >> ++ errno = save_errno; >> + /* return rc; >> + * } >> + */ >> +diff --git a/pseudo_client.c b/pseudo_client.c >> +index 48607c2..4a30420 100644 >> +--- a/pseudo_client.c >> ++++ b/pseudo_client.c >> +@@ -988,6 +988,8 @@ base_path(int dirfd, const char *path, int >> leave_last) { >> + if (dirfd != -1&& dirfd != AT_FDCWD) { >> >> + if (dirfd>= 0) { >> + basepath = fd_path(dirfd); >> ++ } >> ++ if (basepath) { >> + baselen = strlen(basepath); >> + } else { >> + pseudo_diag("got *at() syscall for unknown >> directory, fd %d\n", dirfd); >> +@@ -1128,7 +1130,10 @@ pseudo_client_op(pseudo_op_t op, int access, int >> fd, int dirfd, const char *path >> + if (path) { >> + pseudo_debug(2, " %s", path); >> + } >> +- if (fd != -1) { >> ++ /* for OP_RENAME in renameat, "fd" is also used for the >> ++ * second dirfd. >> ++ */ >> ++ if (fd != -1&& op != OP_RENAME) { >> >> + pseudo_debug(2, " [fd %d]", fd); >> + } >> + if (buf) { >> diff --git a/meta/recipes-devtools/pseudo/pseudo_1.2.bb >> b/meta/recipes-devtools/pseudo/pseudo_1.2.bb >> index f2ebc22..04bcbce 100644 >> --- a/meta/recipes-devtools/pseudo/pseudo_1.2.bb >> +++ b/meta/recipes-devtools/pseudo/pseudo_1.2.bb >> @@ -1,10 +1,12 @@ >> require pseudo.inc >> >> -PR = "r4" >> +PR = "r5" >> >> SRC_URI = >> "http://www.yoctoproject.org/downloads/${BPN}/${BPN}-${PV}.tar.bz2 \ >> file://oe-config.patch \ >> - file://static_sqlite.patch" >> + file://static_sqlite.patch \ >> + file://opendir.patch \ >> + file://renameat.patch" >> >> SRC_URI[md5sum] = "a2819084bab7e991f06626d02cf55048" >> SRC_URI[sha256sum] = >> "4749a22df687f44d24c26e97170d4781a1bd52d5ee092364a40877e4d96ff058"
On 02/07/2012 08:31 AM, Khem Raj wrote: > On Tue, Feb 7, 2012 at 8:21 AM, Saul Wold<sgw@linux.intel.com> wrote: >> On 02/05/2012 10:40 PM, Khem Raj wrote: >>> >>> Signed-off-by: Khem Raj<raj.khem@gmail.com> >>> --- >>> meta/recipes-devtools/pseudo/pseudo/opendir.patch | 92 ++++++++ >>> meta/recipes-devtools/pseudo/pseudo/renameat.patch | 227 >>> ++++++++++++++++++++ >>> meta/recipes-devtools/pseudo/pseudo_1.2.bb | 6 +- >>> 3 files changed, 323 insertions(+), 2 deletions(-) >>> create mode 100644 meta/recipes-devtools/pseudo/pseudo/opendir.patch >>> create mode 100644 meta/recipes-devtools/pseudo/pseudo/renameat.patch >>> >>> diff --git a/meta/recipes-devtools/pseudo/pseudo/opendir.patch >>> b/meta/recipes-devtools/pseudo/pseudo/opendir.patch >>> new file mode 100644 >>> index 0000000..d20f717 >>> --- /dev/null >>> +++ b/meta/recipes-devtools/pseudo/pseudo/opendir.patch >>> @@ -0,0 +1,92 @@ >>> +commit 162f2692c399b93311652201a940fdaf9c9e6924 >>> +Author: Peter Seebach<peter.seebach@windriver.com> >>> +Date: Thu Feb 2 11:45:42 2012 -0600 >>> + >>> + Make opendir/closedir stash and forget directory names. >>> + >>> + The dirfd(DIR *) interface allows you to get the fd for a DIR *, >>> + meaning you can use it with openat(), meaning you can need its >>> + path. This causes a segfault. Also gonna fix the base_path >>> + code not to segfault in that case, but first fix the underlying >>> + problem. >>> + >> >> >> Missing Upstream-Status: and Signed-off-by (yes I know we have an email >> header). > > they are backports > Please update the patch! Thanks Sau! >> >> Thanks >> Sau! >> >>> +diff --git a/ChangeLog.txt b/ChangeLog.txt >>> +index 4de488c..9625b38 100644 >>> +--- a/ChangeLog.txt >>> ++++ b/ChangeLog.txt >>> +@@ -1,3 +1,7 @@ >>> ++2012-02-02: >>> ++ * (seebs) stash dir name for DIR * from opendir using dirfd. >>> ++ * (seebs) add closedir. >>> ++ >>> + 2011-11-02: >>> + * (seebs) Call this 1.2 because the UNLOAD change is moderately >>> + significant, and so's the clone change. >>> +diff --git a/ports/unix/guts/closedir.c b/ports/unix/guts/closedir.c >>> +new file mode 100644 >>> +index 0000000..1085361 >>> +--- /dev/null >>> ++++ b/ports/unix/guts/closedir.c >>> +@@ -0,0 +1,20 @@ >>> ++/* >>> ++ * Copyright (c) 2012 Wind River Systems; see >>> ++ * guts/COPYRIGHT for information. >>> ++ * >>> ++ * static int >>> ++ * wrap_closedir(DIR *dirp) { >>> ++ * int rc = -1; >>> ++ */ >>> ++ if (!dirp) { >>> ++ errno = EFAULT; >>> ++ return -1; >>> ++ } >>> ++ >>> ++ int fd = dirfd(dirp); >>> ++ pseudo_client_op(OP_CLOSE, 0, fd, -1, 0, 0); >>> ++ rc = real_closedir(dirp); >>> ++ >>> ++/* return rc; >>> ++ * } >>> ++ */ >>> +diff --git a/ports/unix/guts/opendir.c b/ports/unix/guts/opendir.c >>> +index 8eaa71f..e69717e 100644 >>> +--- a/ports/unix/guts/opendir.c >>> ++++ b/ports/unix/guts/opendir.c >>> +@@ -6,8 +6,25 @@ >>> + * wrap_opendir(const char *path) { >>> + * DIR * rc = NULL; >>> + */ >>> ++ struct stat buf; >>> ++ int save_errno; >>> + >>> + rc = real_opendir(path); >>> ++ if (rc) { >>> ++ int fd; >>> ++ save_errno = errno; >>> ++ fd = dirfd(rc); >>> ++ if (real_fstat(fd,&buf) == -1) { >>> >>> ++ pseudo_debug(1, "diropen (fd %d) succeeded, but >>> fstat failed (%s).\n", >>> ++ fd, strerror(errno)); >>> ++ pseudo_client_op_plain(OP_OPEN, PSA_READ, fd, -1, >>> path, 0); >>> ++ } else { >>> ++ pseudo_client_op_plain(OP_OPEN, PSA_READ, fd, -1, >>> path,&buf); >>> ++ } >>> ++ >>> ++ >>> ++ errno = save_errno; >>> ++ } >>> + >>> + /* return rc; >>> + * } >>> +diff --git a/ports/unix/wrapfuncs.in b/ports/unix/wrapfuncs.in >>> +index e06e404..32250c4 100644 >>> +--- a/ports/unix/wrapfuncs.in >>> ++++ b/ports/unix/wrapfuncs.in >>> +@@ -21,6 +21,7 @@ long pathconf(const char *path, int name); >>> + char *realpath(const char *name, char *resolved_name); /* >>> version="GLIBC_2.3" */ >>> + int remove(const char *path); /* flags=AT_SYMLINK_NOFOLLOW */ >>> + DIR *opendir(const char *path); >>> ++int closedir(DIR *dirp); >>> + char *tempnam(const char *template, const char *pfx); >>> + char *tmpnam(char *s); >>> + int truncate(const char *path, off_t length); >>> diff --git a/meta/recipes-devtools/pseudo/pseudo/renameat.patch >>> b/meta/recipes-devtools/pseudo/pseudo/renameat.patch >>> new file mode 100644 >>> index 0000000..74c8585 >>> --- /dev/null >>> +++ b/meta/recipes-devtools/pseudo/pseudo/renameat.patch >>> @@ -0,0 +1,227 @@ >>> +commit 795f2b44b7f692151556782f142a4a6e7d45d892 >>> +Author: Peter Seebach<peter.seebach@windriver.com> >>> +Date: Thu Feb 2 15:49:21 2012 -0600 >>> + >>> + Implement renameat() >>> + >>> + After three long years, someone tried to use this. This was >>> impossibly >>> + hard back when pseudo was written, because there was only one dirfd >>> + provided for. Thing is, now, the canonicalization happens in >>> wrapfuncs, >>> + so a small tweak to makewrappers to recognize that oldpath should use >>> + olddirfd if it exists is enough to get us fully canonicalized paths >>> + when needed. >>> + >>> + Also fix the crash if base_path gets called with an fd for which we >>> have >>> + no path. >>> + >>> +diff --git a/ChangeLog.txt b/ChangeLog.txt >>> +index 9625b38..25bd463 100644 >>> +--- a/ChangeLog.txt >>> ++++ b/ChangeLog.txt >>> +@@ -1,6 +1,9 @@ >>> + 2012-02-02: >>> + * (seebs) stash dir name for DIR * from opendir using dirfd. >>> + * (seebs) add closedir. >>> ++ * (seebs) add initial pass at renameat() >>> ++ * (seebs) in base_path, don't try to strlen the result if >>> ++ fd_path() returns NULL. >>> + >>> + 2011-11-02: >>> + * (seebs) Call this 1.2 because the UNLOAD change is moderately >>> +diff --git a/makewrappers b/makewrappers >>> +index 20bbf2b..bf344d6 100755 >>> +--- a/makewrappers >>> ++++ b/makewrappers >>> +@@ -211,12 +211,13 @@ class Function: >>> + self.flags = '0' >>> + self.port = port >>> + self.directory = '' >>> +- self.version = 'NULL' >>> ++ self.version = 'NULL' >>> + # On Darwin, some functions are SECRETLY converted to >>> foo$INODE64 >>> + # when called. So we have to look those up for real_* >>> + self.inode64 = None >>> + self.real_func = None >>> + self.paths_to_munge = [] >>> ++ self.dirfds = {} >>> + self.hand_wrapped = None >>> + # used for the copyright date when creating stub functions >>> + self.date = datetime.date.today().year >>> +@@ -239,6 +240,7 @@ class Function: >>> + # * If the arg has a name ending in 'path', we will canonicalize >>> it. >>> + # * If the arg is named 'dirfd' or 'flags', it becomes the >>> default >>> + # values for the dirfd and flags arguments when >>> canonicalizing. >>> ++ # * If the name ends in dirfd, we do the same fancy stuff. >>> + # * Note that the "comments" field (/* ... */ after the decl) >>> can >>> + # override the dirfd/flags values. >>> + self.args = ArgumentList(bits.group(2)) >>> +@@ -246,7 +248,9 @@ class Function: >>> + # ignore varargs, they never get these special treatments >>> + if arg.vararg: >>> + pass >>> +- elif arg.name == 'dirfd': >>> ++ elif arg.name[-5:] == 'dirfd': >>> ++ if len(arg.name)> 5: >>> ++ self.dirfds[arg.name[:-5]] = True >>> + self.dirfd = 'dirfd' >>> + elif arg.name == 'flags': >>> + self.flags = 'flags' >>> +@@ -325,9 +329,13 @@ class Function: >>> + """create/allocate canonical paths""" >>> + alloc_paths = [] >>> + for path in self.paths_to_munge: >>> ++ prefix = path[:-4] >>> ++ if not prefix in self.dirfds: >>> ++ prefix = '' >>> ++ print "for path %s: prefix<%s>" % ( path, prefix ) >>> + alloc_paths.append( >>> +- "%s = pseudo_root_path(__func__, __LINE__, %s, %s, %s);" >>> % >>> +- (path, self.dirfd, path, self.flags)) >>> ++ "%s = pseudo_root_path(__func__, __LINE__, %s%s, %s, >>> %s);" % >>> ++ (path, prefix, self.dirfd, path, self.flags)) >>> + return "\n\t\t\t".join(alloc_paths) >>> + >>> + def free_paths(self): >>> +diff --git a/ports/unix/guts/renameat.c b/ports/unix/guts/renameat.c >>> +index c8203b7..f13cd1e 100644 >>> +--- a/ports/unix/guts/renameat.c >>> ++++ b/ports/unix/guts/renameat.c >>> +@@ -1,15 +1,111 @@ >>> + /* >>> +- * Copyright (c) 2008-2010 Wind River Systems; see >>> ++ * Copyright (c) 2008-2012 Wind River Systems; see >>> + * guts/COPYRIGHT for information. >>> + * >>> + * static int >>> + * wrap_renameat(int olddirfd, const char *oldpath, int newdirfd, const >>> char *newpath) { >>> + * int rc = -1; >>> + */ >>> ++ pseudo_msg_t *msg; >>> ++ struct stat oldbuf, newbuf; >>> ++ int oldrc, newrc; >>> ++ int save_errno; >>> ++ int old_db_entry = 0; >>> + >>> +- pseudo_diag("help! unimplemented renameat [%s -> %s].\n", >>> oldpath, newpath); >>> ++ pseudo_debug(2, "renameat: %d,%s->%d,%s\n", >>> ++ olddirfd, oldpath ? oldpath : "<nil>", >>> ++ newdirfd, newpath ? newpath : "<nil>"); >>> ++ >>> ++#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS >>> ++ if (olddirfd != AT_FDCWD || newdirfd != AT_FDCWD) { >>> ++ errno = ENOSYS; >>> ++ return -1; >>> ++ } >>> ++#endif >>> ++ >>> ++ if (!oldpath || !newpath) { >>> ++ errno = EFAULT; >>> ++ return -1; >>> ++ } >>> ++ >>> ++ save_errno = errno; >>> ++ >>> ++#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS >>> ++ newrc = real_lstat(newpath,&newbuf); >>> ++ oldrc = real_lstat(oldpath,&oldbuf); >>> ++#else >>> ++ oldrc = real___fxstatat(_STAT_VER, olddirfd, oldpath,&oldbuf, >>> AT_SYMLINK_NOFOLLOW); >>> ++ newrc = real___fxstatat(_STAT_VER, newdirfd, newpath,&newbuf, >>> AT_SYMLINK_NOFOLLOW); >>> >>> ++#endif >>> ++ >>> ++ errno = save_errno; >>> ++ >>> ++ /* newpath must be removed. */ >>> ++ /* as with unlink, we have to mark that the file may get deleted >>> */ >>> ++ msg = pseudo_client_op_plain(OP_MAY_UNLINK, 0, -1, newdirfd, >>> newpath, newrc ? NULL :&newbuf); >>> ++ if (msg&& msg->result == RESULT_SUCCEED) >>> >>> ++ old_db_entry = 1; >>> + rc = real_renameat(olddirfd, oldpath, newdirfd, newpath); >>> ++ save_errno = errno; >>> ++ if (old_db_entry) { >>> ++ if (rc == -1) { >>> ++ /* since we failed, that wasn't really unlinked -- >>> put >>> ++ * it back. >>> ++ */ >>> ++ pseudo_client_op_plain(OP_CANCEL_UNLINK, 0, -1, >>> newdirfd, newpath,&newbuf); >>> ++ } else { >>> ++ /* confirm that the file was removed */ >>> ++ pseudo_client_op_plain(OP_DID_UNLINK, 0, -1, >>> newdirfd, newpath,&newbuf); >>> ++ } >>> ++ } >>> ++ if (rc == -1) { >>> ++ /* and we're done. */ >>> ++ errno = save_errno; >>> ++ return rc; >>> ++ } >>> ++ save_errno = errno; >>> ++ /* nothing to do for a "rename" of a link to itself */ >>> ++ if (newrc != -1&& oldrc != -1&& >>> ++ newbuf.st_dev == oldbuf.st_dev&& >>> ++ newbuf.st_ino == oldbuf.st_ino) { >>> ++ return rc; >>> ++ } >>> ++ >>> ++ /* rename(3) is not mv(1). rename(file, dir) fails; you must >>> provide >>> ++ * the corrected path yourself. You can rename over a directory >>> only >>> ++ * if the source is a directory. Symlinks are simply removed. >>> ++ * >>> ++ * If we got here, the real rename call succeeded. That means >>> newpath >>> ++ * has been unlinked and oldpath has been linked to it. >>> ++ * >>> ++ * There are a ton of special cases to error check. I don't check >>> ++ * for any of them, because in every such case, the underlying >>> rename >>> ++ * failed, and there is nothing to do. >>> ++ * The only tricky part is that, because we used to ignore >>> symlinks, >>> ++ * we may have to rename or remove directory trees even though in >>> ++ * theory rename can never destroy a directory tree. >>> ++ */ >>> ++ if (!old_db_entry) { >>> ++ /* create an entry under the old name, which will then be >>> ++ * renamed; this way, children would get renamed too, if >>> there >>> ++ * were any. >>> ++ */ >>> ++ if (newrc == 0) { >>> ++ if (newbuf.st_dev != oldbuf.st_dev) { >>> ++ oldbuf.st_dev = newbuf.st_dev; >>> ++ oldbuf.st_ino = newbuf.st_ino; >>> ++ } >>> ++ } >>> ++ pseudo_debug(1, "creating new '%s' [%llu] to rename\n", >>> ++ oldpath, (unsigned long long) oldbuf.st_ino); >>> ++ pseudo_client_op_plain(OP_LINK, 0, -1, olddirfd, >>> oldpath,&oldbuf); >>> ++ } >>> ++ /* special case: use 'fd' for olddirfd, because >>> ++ * we know it has no other meaning for RENAME >>> ++ */ >>> ++ pseudo_client_op_plain(OP_RENAME, 0, olddirfd, newdirfd, >>> newpath,&oldbuf, oldpath); >>> >>> + >>> ++ errno = save_errno; >>> + /* return rc; >>> + * } >>> + */ >>> +diff --git a/pseudo_client.c b/pseudo_client.c >>> +index 48607c2..4a30420 100644 >>> +--- a/pseudo_client.c >>> ++++ b/pseudo_client.c >>> +@@ -988,6 +988,8 @@ base_path(int dirfd, const char *path, int >>> leave_last) { >>> + if (dirfd != -1&& dirfd != AT_FDCWD) { >>> >>> + if (dirfd>= 0) { >>> + basepath = fd_path(dirfd); >>> ++ } >>> ++ if (basepath) { >>> + baselen = strlen(basepath); >>> + } else { >>> + pseudo_diag("got *at() syscall for unknown >>> directory, fd %d\n", dirfd); >>> +@@ -1128,7 +1130,10 @@ pseudo_client_op(pseudo_op_t op, int access, int >>> fd, int dirfd, const char *path >>> + if (path) { >>> + pseudo_debug(2, " %s", path); >>> + } >>> +- if (fd != -1) { >>> ++ /* for OP_RENAME in renameat, "fd" is also used for the >>> ++ * second dirfd. >>> ++ */ >>> ++ if (fd != -1&& op != OP_RENAME) { >>> >>> + pseudo_debug(2, " [fd %d]", fd); >>> + } >>> + if (buf) { >>> diff --git a/meta/recipes-devtools/pseudo/pseudo_1.2.bb >>> b/meta/recipes-devtools/pseudo/pseudo_1.2.bb >>> index f2ebc22..04bcbce 100644 >>> --- a/meta/recipes-devtools/pseudo/pseudo_1.2.bb >>> +++ b/meta/recipes-devtools/pseudo/pseudo_1.2.bb >>> @@ -1,10 +1,12 @@ >>> require pseudo.inc >>> >>> -PR = "r4" >>> +PR = "r5" >>> >>> SRC_URI = >>> "http://www.yoctoproject.org/downloads/${BPN}/${BPN}-${PV}.tar.bz2 \ >>> file://oe-config.patch \ >>> - file://static_sqlite.patch" >>> + file://static_sqlite.patch \ >>> + file://opendir.patch \ >>> + file://renameat.patch" >>> >>> SRC_URI[md5sum] = "a2819084bab7e991f06626d02cf55048" >>> SRC_URI[sha256sum] = >>> "4749a22df687f44d24c26e97170d4781a1bd52d5ee092364a40877e4d96ff058" >
On Tue, Feb 7, 2012 at 8:43 AM, Saul Wold <sgw@linux.intel.com> wrote: > On 02/07/2012 08:31 AM, Khem Raj wrote: >> >> On Tue, Feb 7, 2012 at 8:21 AM, Saul Wold<sgw@linux.intel.com> wrote: >>> >>> On 02/05/2012 10:40 PM, Khem Raj wrote: >>>> >>>> >>>> Signed-off-by: Khem Raj<raj.khem@gmail.com> >>>> --- >>>> meta/recipes-devtools/pseudo/pseudo/opendir.patch | 92 ++++++++ >>>> meta/recipes-devtools/pseudo/pseudo/renameat.patch | 227 >>>> ++++++++++++++++++++ >>>> meta/recipes-devtools/pseudo/pseudo_1.2.bb | 6 +- >>>> 3 files changed, 323 insertions(+), 2 deletions(-) >>>> create mode 100644 meta/recipes-devtools/pseudo/pseudo/opendir.patch >>>> create mode 100644 meta/recipes-devtools/pseudo/pseudo/renameat.patch >>>> >>>> diff --git a/meta/recipes-devtools/pseudo/pseudo/opendir.patch >>>> b/meta/recipes-devtools/pseudo/pseudo/opendir.patch >>>> new file mode 100644 >>>> index 0000000..d20f717 >>>> --- /dev/null >>>> +++ b/meta/recipes-devtools/pseudo/pseudo/opendir.patch >>>> @@ -0,0 +1,92 @@ >>>> +commit 162f2692c399b93311652201a940fdaf9c9e6924 >>>> +Author: Peter Seebach<peter.seebach@windriver.com> >>>> +Date: Thu Feb 2 11:45:42 2012 -0600 >>>> + >>>> + Make opendir/closedir stash and forget directory names. >>>> + >>>> + The dirfd(DIR *) interface allows you to get the fd for a DIR *, >>>> + meaning you can use it with openat(), meaning you can need its >>>> + path. This causes a segfault. Also gonna fix the base_path >>>> + code not to segfault in that case, but first fix the underlying >>>> + problem. >>>> + >>> >>> >>> >>> Missing Upstream-Status: and Signed-off-by (yes I know we have an email >>> header). >> >> >> they are backports >> > Please update the patch! should be there now.
The pseudo upstream has been updated. We should like just update the recipe to use git commit: 9461b2a88ba672c533a331f95dd5ba7eba683c77 --Mark On 2/7/12 11:43 AM, Saul Wold wrote: > On 02/07/2012 08:31 AM, Khem Raj wrote: >> On Tue, Feb 7, 2012 at 8:21 AM, Saul Wold<sgw@linux.intel.com> wrote: >>> On 02/05/2012 10:40 PM, Khem Raj wrote: >>>> >>>> Signed-off-by: Khem Raj<raj.khem@gmail.com> >>>> --- >>>> meta/recipes-devtools/pseudo/pseudo/opendir.patch | 92 ++++++++ >>>> meta/recipes-devtools/pseudo/pseudo/renameat.patch | 227 >>>> ++++++++++++++++++++ >>>> meta/recipes-devtools/pseudo/pseudo_1.2.bb | 6 +- >>>> 3 files changed, 323 insertions(+), 2 deletions(-) >>>> create mode 100644 meta/recipes-devtools/pseudo/pseudo/opendir.patch >>>> create mode 100644 meta/recipes-devtools/pseudo/pseudo/renameat.patch >>>> >>>> diff --git a/meta/recipes-devtools/pseudo/pseudo/opendir.patch >>>> b/meta/recipes-devtools/pseudo/pseudo/opendir.patch >>>> new file mode 100644 >>>> index 0000000..d20f717 >>>> --- /dev/null >>>> +++ b/meta/recipes-devtools/pseudo/pseudo/opendir.patch >>>> @@ -0,0 +1,92 @@ >>>> +commit 162f2692c399b93311652201a940fdaf9c9e6924 >>>> +Author: Peter Seebach<peter.seebach@windriver.com> >>>> +Date: Thu Feb 2 11:45:42 2012 -0600 >>>> + >>>> + Make opendir/closedir stash and forget directory names. >>>> + >>>> + The dirfd(DIR *) interface allows you to get the fd for a DIR *, >>>> + meaning you can use it with openat(), meaning you can need its >>>> + path. This causes a segfault. Also gonna fix the base_path >>>> + code not to segfault in that case, but first fix the underlying >>>> + problem. >>>> + >>> >>> >>> Missing Upstream-Status: and Signed-off-by (yes I know we have an email >>> header). >> >> they are backports >> > Please update the patch! > > Thanks > Sau! > >>> >>> Thanks >>> Sau! >>> >>>> +diff --git a/ChangeLog.txt b/ChangeLog.txt >>>> +index 4de488c..9625b38 100644 >>>> +--- a/ChangeLog.txt >>>> ++++ b/ChangeLog.txt >>>> +@@ -1,3 +1,7 @@ >>>> ++2012-02-02: >>>> ++ * (seebs) stash dir name for DIR * from opendir using dirfd. >>>> ++ * (seebs) add closedir. >>>> ++ >>>> + 2011-11-02: >>>> + * (seebs) Call this 1.2 because the UNLOAD change is moderately >>>> + significant, and so's the clone change. >>>> +diff --git a/ports/unix/guts/closedir.c b/ports/unix/guts/closedir.c >>>> +new file mode 100644 >>>> +index 0000000..1085361 >>>> +--- /dev/null >>>> ++++ b/ports/unix/guts/closedir.c >>>> +@@ -0,0 +1,20 @@ >>>> ++/* >>>> ++ * Copyright (c) 2012 Wind River Systems; see >>>> ++ * guts/COPYRIGHT for information. >>>> ++ * >>>> ++ * static int >>>> ++ * wrap_closedir(DIR *dirp) { >>>> ++ * int rc = -1; >>>> ++ */ >>>> ++ if (!dirp) { >>>> ++ errno = EFAULT; >>>> ++ return -1; >>>> ++ } >>>> ++ >>>> ++ int fd = dirfd(dirp); >>>> ++ pseudo_client_op(OP_CLOSE, 0, fd, -1, 0, 0); >>>> ++ rc = real_closedir(dirp); >>>> ++ >>>> ++/* return rc; >>>> ++ * } >>>> ++ */ >>>> +diff --git a/ports/unix/guts/opendir.c b/ports/unix/guts/opendir.c >>>> +index 8eaa71f..e69717e 100644 >>>> +--- a/ports/unix/guts/opendir.c >>>> ++++ b/ports/unix/guts/opendir.c >>>> +@@ -6,8 +6,25 @@ >>>> + * wrap_opendir(const char *path) { >>>> + * DIR * rc = NULL; >>>> + */ >>>> ++ struct stat buf; >>>> ++ int save_errno; >>>> + >>>> + rc = real_opendir(path); >>>> ++ if (rc) { >>>> ++ int fd; >>>> ++ save_errno = errno; >>>> ++ fd = dirfd(rc); >>>> ++ if (real_fstat(fd,&buf) == -1) { >>>> >>>> ++ pseudo_debug(1, "diropen (fd %d) succeeded, but >>>> fstat failed (%s).\n", >>>> ++ fd, strerror(errno)); >>>> ++ pseudo_client_op_plain(OP_OPEN, PSA_READ, fd, -1, >>>> path, 0); >>>> ++ } else { >>>> ++ pseudo_client_op_plain(OP_OPEN, PSA_READ, fd, -1, >>>> path,&buf); >>>> ++ } >>>> ++ >>>> ++ >>>> ++ errno = save_errno; >>>> ++ } >>>> + >>>> + /* return rc; >>>> + * } >>>> +diff --git a/ports/unix/wrapfuncs.in b/ports/unix/wrapfuncs.in >>>> +index e06e404..32250c4 100644 >>>> +--- a/ports/unix/wrapfuncs.in >>>> ++++ b/ports/unix/wrapfuncs.in >>>> +@@ -21,6 +21,7 @@ long pathconf(const char *path, int name); >>>> + char *realpath(const char *name, char *resolved_name); /* >>>> version="GLIBC_2.3" */ >>>> + int remove(const char *path); /* flags=AT_SYMLINK_NOFOLLOW */ >>>> + DIR *opendir(const char *path); >>>> ++int closedir(DIR *dirp); >>>> + char *tempnam(const char *template, const char *pfx); >>>> + char *tmpnam(char *s); >>>> + int truncate(const char *path, off_t length); >>>> diff --git a/meta/recipes-devtools/pseudo/pseudo/renameat.patch >>>> b/meta/recipes-devtools/pseudo/pseudo/renameat.patch >>>> new file mode 100644 >>>> index 0000000..74c8585 >>>> --- /dev/null >>>> +++ b/meta/recipes-devtools/pseudo/pseudo/renameat.patch >>>> @@ -0,0 +1,227 @@ >>>> +commit 795f2b44b7f692151556782f142a4a6e7d45d892 >>>> +Author: Peter Seebach<peter.seebach@windriver.com> >>>> +Date: Thu Feb 2 15:49:21 2012 -0600 >>>> + >>>> + Implement renameat() >>>> + >>>> + After three long years, someone tried to use this. This was >>>> impossibly >>>> + hard back when pseudo was written, because there was only one dirfd >>>> + provided for. Thing is, now, the canonicalization happens in >>>> wrapfuncs, >>>> + so a small tweak to makewrappers to recognize that oldpath should use >>>> + olddirfd if it exists is enough to get us fully canonicalized paths >>>> + when needed. >>>> + >>>> + Also fix the crash if base_path gets called with an fd for which we >>>> have >>>> + no path. >>>> + >>>> +diff --git a/ChangeLog.txt b/ChangeLog.txt >>>> +index 9625b38..25bd463 100644 >>>> +--- a/ChangeLog.txt >>>> ++++ b/ChangeLog.txt >>>> +@@ -1,6 +1,9 @@ >>>> + 2012-02-02: >>>> + * (seebs) stash dir name for DIR * from opendir using dirfd. >>>> + * (seebs) add closedir. >>>> ++ * (seebs) add initial pass at renameat() >>>> ++ * (seebs) in base_path, don't try to strlen the result if >>>> ++ fd_path() returns NULL. >>>> + >>>> + 2011-11-02: >>>> + * (seebs) Call this 1.2 because the UNLOAD change is moderately >>>> +diff --git a/makewrappers b/makewrappers >>>> +index 20bbf2b..bf344d6 100755 >>>> +--- a/makewrappers >>>> ++++ b/makewrappers >>>> +@@ -211,12 +211,13 @@ class Function: >>>> + self.flags = '0' >>>> + self.port = port >>>> + self.directory = '' >>>> +- self.version = 'NULL' >>>> ++ self.version = 'NULL' >>>> + # On Darwin, some functions are SECRETLY converted to >>>> foo$INODE64 >>>> + # when called. So we have to look those up for real_* >>>> + self.inode64 = None >>>> + self.real_func = None >>>> + self.paths_to_munge = [] >>>> ++ self.dirfds = {} >>>> + self.hand_wrapped = None >>>> + # used for the copyright date when creating stub functions >>>> + self.date = datetime.date.today().year >>>> +@@ -239,6 +240,7 @@ class Function: >>>> + # * If the arg has a name ending in 'path', we will canonicalize >>>> it. >>>> + # * If the arg is named 'dirfd' or 'flags', it becomes the >>>> default >>>> + # values for the dirfd and flags arguments when >>>> canonicalizing. >>>> ++ # * If the name ends in dirfd, we do the same fancy stuff. >>>> + # * Note that the "comments" field (/* ... */ after the decl) >>>> can >>>> + # override the dirfd/flags values. >>>> + self.args = ArgumentList(bits.group(2)) >>>> +@@ -246,7 +248,9 @@ class Function: >>>> + # ignore varargs, they never get these special treatments >>>> + if arg.vararg: >>>> + pass >>>> +- elif arg.name == 'dirfd': >>>> ++ elif arg.name[-5:] == 'dirfd': >>>> ++ if len(arg.name)> 5: >>>> ++ self.dirfds[arg.name[:-5]] = True >>>> + self.dirfd = 'dirfd' >>>> + elif arg.name == 'flags': >>>> + self.flags = 'flags' >>>> +@@ -325,9 +329,13 @@ class Function: >>>> + """create/allocate canonical paths""" >>>> + alloc_paths = [] >>>> + for path in self.paths_to_munge: >>>> ++ prefix = path[:-4] >>>> ++ if not prefix in self.dirfds: >>>> ++ prefix = '' >>>> ++ print "for path %s: prefix<%s>" % ( path, prefix ) >>>> + alloc_paths.append( >>>> +- "%s = pseudo_root_path(__func__, __LINE__, %s, %s, %s);" >>>> % >>>> +- (path, self.dirfd, path, self.flags)) >>>> ++ "%s = pseudo_root_path(__func__, __LINE__, %s%s, %s, >>>> %s);" % >>>> ++ (path, prefix, self.dirfd, path, self.flags)) >>>> + return "\n\t\t\t".join(alloc_paths) >>>> + >>>> + def free_paths(self): >>>> +diff --git a/ports/unix/guts/renameat.c b/ports/unix/guts/renameat.c >>>> +index c8203b7..f13cd1e 100644 >>>> +--- a/ports/unix/guts/renameat.c >>>> ++++ b/ports/unix/guts/renameat.c >>>> +@@ -1,15 +1,111 @@ >>>> + /* >>>> +- * Copyright (c) 2008-2010 Wind River Systems; see >>>> ++ * Copyright (c) 2008-2012 Wind River Systems; see >>>> + * guts/COPYRIGHT for information. >>>> + * >>>> + * static int >>>> + * wrap_renameat(int olddirfd, const char *oldpath, int newdirfd, const >>>> char *newpath) { >>>> + * int rc = -1; >>>> + */ >>>> ++ pseudo_msg_t *msg; >>>> ++ struct stat oldbuf, newbuf; >>>> ++ int oldrc, newrc; >>>> ++ int save_errno; >>>> ++ int old_db_entry = 0; >>>> + >>>> +- pseudo_diag("help! unimplemented renameat [%s -> %s].\n", >>>> oldpath, newpath); >>>> ++ pseudo_debug(2, "renameat: %d,%s->%d,%s\n", >>>> ++ olddirfd, oldpath ? oldpath : "<nil>", >>>> ++ newdirfd, newpath ? newpath : "<nil>"); >>>> ++ >>>> ++#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS >>>> ++ if (olddirfd != AT_FDCWD || newdirfd != AT_FDCWD) { >>>> ++ errno = ENOSYS; >>>> ++ return -1; >>>> ++ } >>>> ++#endif >>>> ++ >>>> ++ if (!oldpath || !newpath) { >>>> ++ errno = EFAULT; >>>> ++ return -1; >>>> ++ } >>>> ++ >>>> ++ save_errno = errno; >>>> ++ >>>> ++#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS >>>> ++ newrc = real_lstat(newpath,&newbuf); >>>> ++ oldrc = real_lstat(oldpath,&oldbuf); >>>> ++#else >>>> ++ oldrc = real___fxstatat(_STAT_VER, olddirfd, oldpath,&oldbuf, >>>> AT_SYMLINK_NOFOLLOW); >>>> ++ newrc = real___fxstatat(_STAT_VER, newdirfd, newpath,&newbuf, >>>> AT_SYMLINK_NOFOLLOW); >>>> >>>> ++#endif >>>> ++ >>>> ++ errno = save_errno; >>>> ++ >>>> ++ /* newpath must be removed. */ >>>> ++ /* as with unlink, we have to mark that the file may get deleted >>>> */ >>>> ++ msg = pseudo_client_op_plain(OP_MAY_UNLINK, 0, -1, newdirfd, >>>> newpath, newrc ? NULL :&newbuf); >>>> ++ if (msg&& msg->result == RESULT_SUCCEED) >>>> >>>> ++ old_db_entry = 1; >>>> + rc = real_renameat(olddirfd, oldpath, newdirfd, newpath); >>>> ++ save_errno = errno; >>>> ++ if (old_db_entry) { >>>> ++ if (rc == -1) { >>>> ++ /* since we failed, that wasn't really unlinked -- >>>> put >>>> ++ * it back. >>>> ++ */ >>>> ++ pseudo_client_op_plain(OP_CANCEL_UNLINK, 0, -1, >>>> newdirfd, newpath,&newbuf); >>>> ++ } else { >>>> ++ /* confirm that the file was removed */ >>>> ++ pseudo_client_op_plain(OP_DID_UNLINK, 0, -1, >>>> newdirfd, newpath,&newbuf); >>>> ++ } >>>> ++ } >>>> ++ if (rc == -1) { >>>> ++ /* and we're done. */ >>>> ++ errno = save_errno; >>>> ++ return rc; >>>> ++ } >>>> ++ save_errno = errno; >>>> ++ /* nothing to do for a "rename" of a link to itself */ >>>> ++ if (newrc != -1&& oldrc != -1&& >>>> ++ newbuf.st_dev == oldbuf.st_dev&& >>>> ++ newbuf.st_ino == oldbuf.st_ino) { >>>> ++ return rc; >>>> ++ } >>>> ++ >>>> ++ /* rename(3) is not mv(1). rename(file, dir) fails; you must >>>> provide >>>> ++ * the corrected path yourself. You can rename over a directory >>>> only >>>> ++ * if the source is a directory. Symlinks are simply removed. >>>> ++ * >>>> ++ * If we got here, the real rename call succeeded. That means >>>> newpath >>>> ++ * has been unlinked and oldpath has been linked to it. >>>> ++ * >>>> ++ * There are a ton of special cases to error check. I don't check >>>> ++ * for any of them, because in every such case, the underlying >>>> rename >>>> ++ * failed, and there is nothing to do. >>>> ++ * The only tricky part is that, because we used to ignore >>>> symlinks, >>>> ++ * we may have to rename or remove directory trees even though in >>>> ++ * theory rename can never destroy a directory tree. >>>> ++ */ >>>> ++ if (!old_db_entry) { >>>> ++ /* create an entry under the old name, which will then be >>>> ++ * renamed; this way, children would get renamed too, if >>>> there >>>> ++ * were any. >>>> ++ */ >>>> ++ if (newrc == 0) { >>>> ++ if (newbuf.st_dev != oldbuf.st_dev) { >>>> ++ oldbuf.st_dev = newbuf.st_dev; >>>> ++ oldbuf.st_ino = newbuf.st_ino; >>>> ++ } >>>> ++ } >>>> ++ pseudo_debug(1, "creating new '%s' [%llu] to rename\n", >>>> ++ oldpath, (unsigned long long) oldbuf.st_ino); >>>> ++ pseudo_client_op_plain(OP_LINK, 0, -1, olddirfd, >>>> oldpath,&oldbuf); >>>> ++ } >>>> ++ /* special case: use 'fd' for olddirfd, because >>>> ++ * we know it has no other meaning for RENAME >>>> ++ */ >>>> ++ pseudo_client_op_plain(OP_RENAME, 0, olddirfd, newdirfd, >>>> newpath,&oldbuf, oldpath); >>>> >>>> + >>>> ++ errno = save_errno; >>>> + /* return rc; >>>> + * } >>>> + */ >>>> +diff --git a/pseudo_client.c b/pseudo_client.c >>>> +index 48607c2..4a30420 100644 >>>> +--- a/pseudo_client.c >>>> ++++ b/pseudo_client.c >>>> +@@ -988,6 +988,8 @@ base_path(int dirfd, const char *path, int >>>> leave_last) { >>>> + if (dirfd != -1&& dirfd != AT_FDCWD) { >>>> >>>> + if (dirfd>= 0) { >>>> + basepath = fd_path(dirfd); >>>> ++ } >>>> ++ if (basepath) { >>>> + baselen = strlen(basepath); >>>> + } else { >>>> + pseudo_diag("got *at() syscall for unknown >>>> directory, fd %d\n", dirfd); >>>> +@@ -1128,7 +1130,10 @@ pseudo_client_op(pseudo_op_t op, int access, int >>>> fd, int dirfd, const char *path >>>> + if (path) { >>>> + pseudo_debug(2, " %s", path); >>>> + } >>>> +- if (fd != -1) { >>>> ++ /* for OP_RENAME in renameat, "fd" is also used for the >>>> ++ * second dirfd. >>>> ++ */ >>>> ++ if (fd != -1&& op != OP_RENAME) { >>>> >>>> + pseudo_debug(2, " [fd %d]", fd); >>>> + } >>>> + if (buf) { >>>> diff --git a/meta/recipes-devtools/pseudo/pseudo_1.2.bb >>>> b/meta/recipes-devtools/pseudo/pseudo_1.2.bb >>>> index f2ebc22..04bcbce 100644 >>>> --- a/meta/recipes-devtools/pseudo/pseudo_1.2.bb >>>> +++ b/meta/recipes-devtools/pseudo/pseudo_1.2.bb >>>> @@ -1,10 +1,12 @@ >>>> require pseudo.inc >>>> >>>> -PR = "r4" >>>> +PR = "r5" >>>> >>>> SRC_URI = >>>> "http://www.yoctoproject.org/downloads/${BPN}/${BPN}-${PV}.tar.bz2 \ >>>> file://oe-config.patch \ >>>> - file://static_sqlite.patch" >>>> + file://static_sqlite.patch \ >>>> + file://opendir.patch \ >>>> + file://renameat.patch" >>>> >>>> SRC_URI[md5sum] = "a2819084bab7e991f06626d02cf55048" >>>> SRC_URI[sha256sum] = >>>> "4749a22df687f44d24c26e97170d4781a1bd52d5ee092364a40877e4d96ff058" >> > > _______________________________________________ > Openembedded-core mailing list > Openembedded-core@lists.openembedded.org > http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/openembedded-core
On Tue, Feb 7, 2012 at 3:21 PM, Mark Hatle <mark.hatle@windriver.com> wrote: > The pseudo upstream has been updated. We should like just update the recipe > to use git commit: 9461b2a88ba672c533a331f95dd5ba7eba683c77 > yes that is for git recipe we still need patches for 1.2 recipe and default is to use 1.2 > --Mark > > > On 2/7/12 11:43 AM, Saul Wold wrote: >> >> On 02/07/2012 08:31 AM, Khem Raj wrote: >>> >>> On Tue, Feb 7, 2012 at 8:21 AM, Saul Wold<sgw@linux.intel.com> wrote: >>>> >>>> On 02/05/2012 10:40 PM, Khem Raj wrote: >>>>> >>>>> >>>>> Signed-off-by: Khem Raj<raj.khem@gmail.com> >>>>> --- >>>>> meta/recipes-devtools/pseudo/pseudo/opendir.patch | 92 ++++++++ >>>>> meta/recipes-devtools/pseudo/pseudo/renameat.patch | 227 >>>>> ++++++++++++++++++++ >>>>> meta/recipes-devtools/pseudo/pseudo_1.2.bb | 6 +- >>>>> 3 files changed, 323 insertions(+), 2 deletions(-) >>>>> create mode 100644 meta/recipes-devtools/pseudo/pseudo/opendir.patch >>>>> create mode 100644 meta/recipes-devtools/pseudo/pseudo/renameat.patch >>>>> >>>>> diff --git a/meta/recipes-devtools/pseudo/pseudo/opendir.patch >>>>> b/meta/recipes-devtools/pseudo/pseudo/opendir.patch >>>>> new file mode 100644 >>>>> index 0000000..d20f717 >>>>> --- /dev/null >>>>> +++ b/meta/recipes-devtools/pseudo/pseudo/opendir.patch >>>>> @@ -0,0 +1,92 @@ >>>>> +commit 162f2692c399b93311652201a940fdaf9c9e6924 >>>>> +Author: Peter Seebach<peter.seebach@windriver.com> >>>>> +Date: Thu Feb 2 11:45:42 2012 -0600 >>>>> + >>>>> + Make opendir/closedir stash and forget directory names. >>>>> + >>>>> + The dirfd(DIR *) interface allows you to get the fd for a DIR *, >>>>> + meaning you can use it with openat(), meaning you can need its >>>>> + path. This causes a segfault. Also gonna fix the base_path >>>>> + code not to segfault in that case, but first fix the underlying >>>>> + problem. >>>>> + >>>> >>>> >>>> >>>> Missing Upstream-Status: and Signed-off-by (yes I know we have an email >>>> header). >>> >>> >>> they are backports >>> >> Please update the patch! >> >> Thanks >> Sau! >> >>>> >>>> Thanks >>>> Sau! >>>> >>>>> +diff --git a/ChangeLog.txt b/ChangeLog.txt >>>>> +index 4de488c..9625b38 100644 >>>>> +--- a/ChangeLog.txt >>>>> ++++ b/ChangeLog.txt >>>>> +@@ -1,3 +1,7 @@ >>>>> ++2012-02-02: >>>>> ++ * (seebs) stash dir name for DIR * from opendir using dirfd. >>>>> ++ * (seebs) add closedir. >>>>> ++ >>>>> + 2011-11-02: >>>>> + * (seebs) Call this 1.2 because the UNLOAD change is moderately >>>>> + significant, and so's the clone change. >>>>> +diff --git a/ports/unix/guts/closedir.c b/ports/unix/guts/closedir.c >>>>> +new file mode 100644 >>>>> +index 0000000..1085361 >>>>> +--- /dev/null >>>>> ++++ b/ports/unix/guts/closedir.c >>>>> +@@ -0,0 +1,20 @@ >>>>> ++/* >>>>> ++ * Copyright (c) 2012 Wind River Systems; see >>>>> ++ * guts/COPYRIGHT for information. >>>>> ++ * >>>>> ++ * static int >>>>> ++ * wrap_closedir(DIR *dirp) { >>>>> ++ * int rc = -1; >>>>> ++ */ >>>>> ++ if (!dirp) { >>>>> ++ errno = EFAULT; >>>>> ++ return -1; >>>>> ++ } >>>>> ++ >>>>> ++ int fd = dirfd(dirp); >>>>> ++ pseudo_client_op(OP_CLOSE, 0, fd, -1, 0, 0); >>>>> ++ rc = real_closedir(dirp); >>>>> ++ >>>>> ++/* return rc; >>>>> ++ * } >>>>> ++ */ >>>>> +diff --git a/ports/unix/guts/opendir.c b/ports/unix/guts/opendir.c >>>>> +index 8eaa71f..e69717e 100644 >>>>> +--- a/ports/unix/guts/opendir.c >>>>> ++++ b/ports/unix/guts/opendir.c >>>>> +@@ -6,8 +6,25 @@ >>>>> + * wrap_opendir(const char *path) { >>>>> + * DIR * rc = NULL; >>>>> + */ >>>>> ++ struct stat buf; >>>>> ++ int save_errno; >>>>> + >>>>> + rc = real_opendir(path); >>>>> ++ if (rc) { >>>>> ++ int fd; >>>>> ++ save_errno = errno; >>>>> ++ fd = dirfd(rc); >>>>> ++ if (real_fstat(fd,&buf) == -1) { >>>>> >>>>> ++ pseudo_debug(1, "diropen (fd %d) succeeded, but >>>>> fstat failed (%s).\n", >>>>> ++ fd, strerror(errno)); >>>>> ++ pseudo_client_op_plain(OP_OPEN, PSA_READ, fd, >>>>> -1, >>>>> path, 0); >>>>> ++ } else { >>>>> ++ pseudo_client_op_plain(OP_OPEN, PSA_READ, fd, >>>>> -1, >>>>> path,&buf); >>>>> ++ } >>>>> ++ >>>>> ++ >>>>> ++ errno = save_errno; >>>>> ++ } >>>>> + >>>>> + /* return rc; >>>>> + * } >>>>> +diff --git a/ports/unix/wrapfuncs.in b/ports/unix/wrapfuncs.in >>>>> +index e06e404..32250c4 100644 >>>>> +--- a/ports/unix/wrapfuncs.in >>>>> ++++ b/ports/unix/wrapfuncs.in >>>>> +@@ -21,6 +21,7 @@ long pathconf(const char *path, int name); >>>>> + char *realpath(const char *name, char *resolved_name); /* >>>>> version="GLIBC_2.3" */ >>>>> + int remove(const char *path); /* flags=AT_SYMLINK_NOFOLLOW */ >>>>> + DIR *opendir(const char *path); >>>>> ++int closedir(DIR *dirp); >>>>> + char *tempnam(const char *template, const char *pfx); >>>>> + char *tmpnam(char *s); >>>>> + int truncate(const char *path, off_t length); >>>>> diff --git a/meta/recipes-devtools/pseudo/pseudo/renameat.patch >>>>> b/meta/recipes-devtools/pseudo/pseudo/renameat.patch >>>>> new file mode 100644 >>>>> index 0000000..74c8585 >>>>> --- /dev/null >>>>> +++ b/meta/recipes-devtools/pseudo/pseudo/renameat.patch >>>>> @@ -0,0 +1,227 @@ >>>>> +commit 795f2b44b7f692151556782f142a4a6e7d45d892 >>>>> +Author: Peter Seebach<peter.seebach@windriver.com> >>>>> +Date: Thu Feb 2 15:49:21 2012 -0600 >>>>> + >>>>> + Implement renameat() >>>>> + >>>>> + After three long years, someone tried to use this. This was >>>>> impossibly >>>>> + hard back when pseudo was written, because there was only one >>>>> dirfd >>>>> + provided for. Thing is, now, the canonicalization happens in >>>>> wrapfuncs, >>>>> + so a small tweak to makewrappers to recognize that oldpath should >>>>> use >>>>> + olddirfd if it exists is enough to get us fully canonicalized >>>>> paths >>>>> + when needed. >>>>> + >>>>> + Also fix the crash if base_path gets called with an fd for which >>>>> we >>>>> have >>>>> + no path. >>>>> + >>>>> +diff --git a/ChangeLog.txt b/ChangeLog.txt >>>>> +index 9625b38..25bd463 100644 >>>>> +--- a/ChangeLog.txt >>>>> ++++ b/ChangeLog.txt >>>>> +@@ -1,6 +1,9 @@ >>>>> + 2012-02-02: >>>>> + * (seebs) stash dir name for DIR * from opendir using dirfd. >>>>> + * (seebs) add closedir. >>>>> ++ * (seebs) add initial pass at renameat() >>>>> ++ * (seebs) in base_path, don't try to strlen the result if >>>>> ++ fd_path() returns NULL. >>>>> + >>>>> + 2011-11-02: >>>>> + * (seebs) Call this 1.2 because the UNLOAD change is moderately >>>>> +diff --git a/makewrappers b/makewrappers >>>>> +index 20bbf2b..bf344d6 100755 >>>>> +--- a/makewrappers >>>>> ++++ b/makewrappers >>>>> +@@ -211,12 +211,13 @@ class Function: >>>>> + self.flags = '0' >>>>> + self.port = port >>>>> + self.directory = '' >>>>> +- self.version = 'NULL' >>>>> ++ self.version = 'NULL' >>>>> + # On Darwin, some functions are SECRETLY converted to >>>>> foo$INODE64 >>>>> + # when called. So we have to look those up for real_* >>>>> + self.inode64 = None >>>>> + self.real_func = None >>>>> + self.paths_to_munge = [] >>>>> ++ self.dirfds = {} >>>>> + self.hand_wrapped = None >>>>> + # used for the copyright date when creating stub functions >>>>> + self.date = datetime.date.today().year >>>>> +@@ -239,6 +240,7 @@ class Function: >>>>> + # * If the arg has a name ending in 'path', we will >>>>> canonicalize >>>>> it. >>>>> + # * If the arg is named 'dirfd' or 'flags', it becomes the >>>>> default >>>>> + # values for the dirfd and flags arguments when >>>>> canonicalizing. >>>>> ++ # * If the name ends in dirfd, we do the same fancy stuff. >>>>> + # * Note that the "comments" field (/* ... */ after the decl) >>>>> can >>>>> + # override the dirfd/flags values. >>>>> + self.args = ArgumentList(bits.group(2)) >>>>> +@@ -246,7 +248,9 @@ class Function: >>>>> + # ignore varargs, they never get these special treatments >>>>> + if arg.vararg: >>>>> + pass >>>>> +- elif arg.name == 'dirfd': >>>>> ++ elif arg.name[-5:] == 'dirfd': >>>>> ++ if len(arg.name)> 5: >>>>> ++ self.dirfds[arg.name[:-5]] = True >>>>> + self.dirfd = 'dirfd' >>>>> + elif arg.name == 'flags': >>>>> + self.flags = 'flags' >>>>> +@@ -325,9 +329,13 @@ class Function: >>>>> + """create/allocate canonical paths""" >>>>> + alloc_paths = [] >>>>> + for path in self.paths_to_munge: >>>>> ++ prefix = path[:-4] >>>>> ++ if not prefix in self.dirfds: >>>>> ++ prefix = '' >>>>> ++ print "for path %s: prefix<%s>" % ( path, prefix ) >>>>> + alloc_paths.append( >>>>> +- "%s = pseudo_root_path(__func__, __LINE__, %s, %s, >>>>> %s);" >>>>> % >>>>> +- (path, self.dirfd, path, self.flags)) >>>>> ++ "%s = pseudo_root_path(__func__, __LINE__, %s%s, %s, >>>>> %s);" % >>>>> ++ (path, prefix, self.dirfd, path, self.flags)) >>>>> + return "\n\t\t\t".join(alloc_paths) >>>>> + >>>>> + def free_paths(self): >>>>> +diff --git a/ports/unix/guts/renameat.c b/ports/unix/guts/renameat.c >>>>> +index c8203b7..f13cd1e 100644 >>>>> +--- a/ports/unix/guts/renameat.c >>>>> ++++ b/ports/unix/guts/renameat.c >>>>> +@@ -1,15 +1,111 @@ >>>>> + /* >>>>> +- * Copyright (c) 2008-2010 Wind River Systems; see >>>>> ++ * Copyright (c) 2008-2012 Wind River Systems; see >>>>> + * guts/COPYRIGHT for information. >>>>> + * >>>>> + * static int >>>>> + * wrap_renameat(int olddirfd, const char *oldpath, int newdirfd, >>>>> const >>>>> char *newpath) { >>>>> + * int rc = -1; >>>>> + */ >>>>> ++ pseudo_msg_t *msg; >>>>> ++ struct stat oldbuf, newbuf; >>>>> ++ int oldrc, newrc; >>>>> ++ int save_errno; >>>>> ++ int old_db_entry = 0; >>>>> + >>>>> +- pseudo_diag("help! unimplemented renameat [%s -> %s].\n", >>>>> oldpath, newpath); >>>>> ++ pseudo_debug(2, "renameat: %d,%s->%d,%s\n", >>>>> ++ olddirfd, oldpath ? oldpath : "<nil>", >>>>> ++ newdirfd, newpath ? newpath : "<nil>"); >>>>> ++ >>>>> ++#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS >>>>> ++ if (olddirfd != AT_FDCWD || newdirfd != AT_FDCWD) { >>>>> ++ errno = ENOSYS; >>>>> ++ return -1; >>>>> ++ } >>>>> ++#endif >>>>> ++ >>>>> ++ if (!oldpath || !newpath) { >>>>> ++ errno = EFAULT; >>>>> ++ return -1; >>>>> ++ } >>>>> ++ >>>>> ++ save_errno = errno; >>>>> ++ >>>>> ++#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS >>>>> ++ newrc = real_lstat(newpath,&newbuf); >>>>> ++ oldrc = real_lstat(oldpath,&oldbuf); >>>>> ++#else >>>>> ++ oldrc = real___fxstatat(_STAT_VER, olddirfd, oldpath,&oldbuf, >>>>> AT_SYMLINK_NOFOLLOW); >>>>> ++ newrc = real___fxstatat(_STAT_VER, newdirfd, newpath,&newbuf, >>>>> AT_SYMLINK_NOFOLLOW); >>>>> >>>>> ++#endif >>>>> ++ >>>>> ++ errno = save_errno; >>>>> ++ >>>>> ++ /* newpath must be removed. */ >>>>> ++ /* as with unlink, we have to mark that the file may get >>>>> deleted >>>>> */ >>>>> ++ msg = pseudo_client_op_plain(OP_MAY_UNLINK, 0, -1, newdirfd, >>>>> newpath, newrc ? NULL :&newbuf); >>>>> ++ if (msg&& msg->result == RESULT_SUCCEED) >>>>> >>>>> ++ old_db_entry = 1; >>>>> + rc = real_renameat(olddirfd, oldpath, newdirfd, newpath); >>>>> ++ save_errno = errno; >>>>> ++ if (old_db_entry) { >>>>> ++ if (rc == -1) { >>>>> ++ /* since we failed, that wasn't really unlinked >>>>> -- >>>>> put >>>>> ++ * it back. >>>>> ++ */ >>>>> ++ pseudo_client_op_plain(OP_CANCEL_UNLINK, 0, -1, >>>>> newdirfd, newpath,&newbuf); >>>>> ++ } else { >>>>> ++ /* confirm that the file was removed */ >>>>> ++ pseudo_client_op_plain(OP_DID_UNLINK, 0, -1, >>>>> newdirfd, newpath,&newbuf); >>>>> ++ } >>>>> ++ } >>>>> ++ if (rc == -1) { >>>>> ++ /* and we're done. */ >>>>> ++ errno = save_errno; >>>>> ++ return rc; >>>>> ++ } >>>>> ++ save_errno = errno; >>>>> ++ /* nothing to do for a "rename" of a link to itself */ >>>>> ++ if (newrc != -1&& oldrc != -1&& >>>>> ++ newbuf.st_dev == oldbuf.st_dev&& >>>>> ++ newbuf.st_ino == oldbuf.st_ino) { >>>>> ++ return rc; >>>>> ++ } >>>>> ++ >>>>> ++ /* rename(3) is not mv(1). rename(file, dir) fails; you must >>>>> provide >>>>> ++ * the corrected path yourself. You can rename over a >>>>> directory >>>>> only >>>>> ++ * if the source is a directory. Symlinks are simply removed. >>>>> ++ * >>>>> ++ * If we got here, the real rename call succeeded. That means >>>>> newpath >>>>> ++ * has been unlinked and oldpath has been linked to it. >>>>> ++ * >>>>> ++ * There are a ton of special cases to error check. I don't >>>>> check >>>>> ++ * for any of them, because in every such case, the underlying >>>>> rename >>>>> ++ * failed, and there is nothing to do. >>>>> ++ * The only tricky part is that, because we used to ignore >>>>> symlinks, >>>>> ++ * we may have to rename or remove directory trees even though >>>>> in >>>>> ++ * theory rename can never destroy a directory tree. >>>>> ++ */ >>>>> ++ if (!old_db_entry) { >>>>> ++ /* create an entry under the old name, which will then >>>>> be >>>>> ++ * renamed; this way, children would get renamed too, >>>>> if >>>>> there >>>>> ++ * were any. >>>>> ++ */ >>>>> ++ if (newrc == 0) { >>>>> ++ if (newbuf.st_dev != oldbuf.st_dev) { >>>>> ++ oldbuf.st_dev = newbuf.st_dev; >>>>> ++ oldbuf.st_ino = newbuf.st_ino; >>>>> ++ } >>>>> ++ } >>>>> ++ pseudo_debug(1, "creating new '%s' [%llu] to rename\n", >>>>> ++ oldpath, (unsigned long long) oldbuf.st_ino); >>>>> ++ pseudo_client_op_plain(OP_LINK, 0, -1, olddirfd, >>>>> oldpath,&oldbuf); >>>>> ++ } >>>>> ++ /* special case: use 'fd' for olddirfd, because >>>>> ++ * we know it has no other meaning for RENAME >>>>> ++ */ >>>>> ++ pseudo_client_op_plain(OP_RENAME, 0, olddirfd, newdirfd, >>>>> newpath,&oldbuf, oldpath); >>>>> >>>>> + >>>>> ++ errno = save_errno; >>>>> + /* return rc; >>>>> + * } >>>>> + */ >>>>> +diff --git a/pseudo_client.c b/pseudo_client.c >>>>> +index 48607c2..4a30420 100644 >>>>> +--- a/pseudo_client.c >>>>> ++++ b/pseudo_client.c >>>>> +@@ -988,6 +988,8 @@ base_path(int dirfd, const char *path, int >>>>> leave_last) { >>>>> + if (dirfd != -1&& dirfd != AT_FDCWD) { >>>>> >>>>> + if (dirfd>= 0) { >>>>> + basepath = fd_path(dirfd); >>>>> ++ } >>>>> ++ if (basepath) { >>>>> + baselen = strlen(basepath); >>>>> + } else { >>>>> + pseudo_diag("got *at() syscall for >>>>> unknown >>>>> directory, fd %d\n", dirfd); >>>>> +@@ -1128,7 +1130,10 @@ pseudo_client_op(pseudo_op_t op, int access, >>>>> int >>>>> fd, int dirfd, const char *path >>>>> + if (path) { >>>>> + pseudo_debug(2, " %s", path); >>>>> + } >>>>> +- if (fd != -1) { >>>>> ++ /* for OP_RENAME in renameat, "fd" is also used for the >>>>> ++ * second dirfd. >>>>> ++ */ >>>>> ++ if (fd != -1&& op != OP_RENAME) { >>>>> >>>>> + pseudo_debug(2, " [fd %d]", fd); >>>>> + } >>>>> + if (buf) { >>>>> diff --git a/meta/recipes-devtools/pseudo/pseudo_1.2.bb >>>>> b/meta/recipes-devtools/pseudo/pseudo_1.2.bb >>>>> index f2ebc22..04bcbce 100644 >>>>> --- a/meta/recipes-devtools/pseudo/pseudo_1.2.bb >>>>> +++ b/meta/recipes-devtools/pseudo/pseudo_1.2.bb >>>>> @@ -1,10 +1,12 @@ >>>>> require pseudo.inc >>>>> >>>>> -PR = "r4" >>>>> +PR = "r5" >>>>> >>>>> SRC_URI = >>>>> "http://www.yoctoproject.org/downloads/${BPN}/${BPN}-${PV}.tar.bz2 \ >>>>> file://oe-config.patch \ >>>>> - file://static_sqlite.patch" >>>>> + file://static_sqlite.patch \ >>>>> + file://opendir.patch \ >>>>> + file://renameat.patch" >>>>> >>>>> SRC_URI[md5sum] = "a2819084bab7e991f06626d02cf55048" >>>>> SRC_URI[sha256sum] = >>>>> "4749a22df687f44d24c26e97170d4781a1bd52d5ee092364a40877e4d96ff058" >>> >>> >> >> _______________________________________________ >> Openembedded-core mailing list >> Openembedded-core@lists.openembedded.org >> http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/openembedded-core > >
Patch
diff --git a/meta/recipes-devtools/pseudo/pseudo/opendir.patch b/meta/recipes-devtools/pseudo/pseudo/opendir.patch new file mode 100644 index 0000000..d20f717 --- /dev/null +++ b/meta/recipes-devtools/pseudo/pseudo/opendir.patch @@ -0,0 +1,92 @@ +commit 162f2692c399b93311652201a940fdaf9c9e6924 +Author: Peter Seebach <peter.seebach@windriver.com> +Date: Thu Feb 2 11:45:42 2012 -0600 + + Make opendir/closedir stash and forget directory names. + + The dirfd(DIR *) interface allows you to get the fd for a DIR *, + meaning you can use it with openat(), meaning you can need its + path. This causes a segfault. Also gonna fix the base_path + code not to segfault in that case, but first fix the underlying + problem. + +diff --git a/ChangeLog.txt b/ChangeLog.txt +index 4de488c..9625b38 100644 +--- a/ChangeLog.txt ++++ b/ChangeLog.txt +@@ -1,3 +1,7 @@ ++2012-02-02: ++ * (seebs) stash dir name for DIR * from opendir using dirfd. ++ * (seebs) add closedir. ++ + 2011-11-02: + * (seebs) Call this 1.2 because the UNLOAD change is moderately + significant, and so's the clone change. +diff --git a/ports/unix/guts/closedir.c b/ports/unix/guts/closedir.c +new file mode 100644 +index 0000000..1085361 +--- /dev/null ++++ b/ports/unix/guts/closedir.c +@@ -0,0 +1,20 @@ ++/* ++ * Copyright (c) 2012 Wind River Systems; see ++ * guts/COPYRIGHT for information. ++ * ++ * static int ++ * wrap_closedir(DIR *dirp) { ++ * int rc = -1; ++ */ ++ if (!dirp) { ++ errno = EFAULT; ++ return -1; ++ } ++ ++ int fd = dirfd(dirp); ++ pseudo_client_op(OP_CLOSE, 0, fd, -1, 0, 0); ++ rc = real_closedir(dirp); ++ ++/* return rc; ++ * } ++ */ +diff --git a/ports/unix/guts/opendir.c b/ports/unix/guts/opendir.c +index 8eaa71f..e69717e 100644 +--- a/ports/unix/guts/opendir.c ++++ b/ports/unix/guts/opendir.c +@@ -6,8 +6,25 @@ + * wrap_opendir(const char *path) { + * DIR * rc = NULL; + */ ++ struct stat buf; ++ int save_errno; + + rc = real_opendir(path); ++ if (rc) { ++ int fd; ++ save_errno = errno; ++ fd = dirfd(rc); ++ if (real_fstat(fd, &buf) == -1) { ++ pseudo_debug(1, "diropen (fd %d) succeeded, but fstat failed (%s).\n", ++ fd, strerror(errno)); ++ pseudo_client_op_plain(OP_OPEN, PSA_READ, fd, -1, path, 0); ++ } else { ++ pseudo_client_op_plain(OP_OPEN, PSA_READ, fd, -1, path, &buf); ++ } ++ ++ ++ errno = save_errno; ++ } + + /* return rc; + * } +diff --git a/ports/unix/wrapfuncs.in b/ports/unix/wrapfuncs.in +index e06e404..32250c4 100644 +--- a/ports/unix/wrapfuncs.in ++++ b/ports/unix/wrapfuncs.in +@@ -21,6 +21,7 @@ long pathconf(const char *path, int name); + char *realpath(const char *name, char *resolved_name); /* version="GLIBC_2.3" */ + int remove(const char *path); /* flags=AT_SYMLINK_NOFOLLOW */ + DIR *opendir(const char *path); ++int closedir(DIR *dirp); + char *tempnam(const char *template, const char *pfx); + char *tmpnam(char *s); + int truncate(const char *path, off_t length); diff --git a/meta/recipes-devtools/pseudo/pseudo/renameat.patch b/meta/recipes-devtools/pseudo/pseudo/renameat.patch new file mode 100644 index 0000000..74c8585 --- /dev/null +++ b/meta/recipes-devtools/pseudo/pseudo/renameat.patch @@ -0,0 +1,227 @@ +commit 795f2b44b7f692151556782f142a4a6e7d45d892 +Author: Peter Seebach <peter.seebach@windriver.com> +Date: Thu Feb 2 15:49:21 2012 -0600 + + Implement renameat() + + After three long years, someone tried to use this. This was impossibly + hard back when pseudo was written, because there was only one dirfd + provided for. Thing is, now, the canonicalization happens in wrapfuncs, + so a small tweak to makewrappers to recognize that oldpath should use + olddirfd if it exists is enough to get us fully canonicalized paths + when needed. + + Also fix the crash if base_path gets called with an fd for which we have + no path. + +diff --git a/ChangeLog.txt b/ChangeLog.txt +index 9625b38..25bd463 100644 +--- a/ChangeLog.txt ++++ b/ChangeLog.txt +@@ -1,6 +1,9 @@ + 2012-02-02: + * (seebs) stash dir name for DIR * from opendir using dirfd. + * (seebs) add closedir. ++ * (seebs) add initial pass at renameat() ++ * (seebs) in base_path, don't try to strlen the result if ++ fd_path() returns NULL. + + 2011-11-02: + * (seebs) Call this 1.2 because the UNLOAD change is moderately +diff --git a/makewrappers b/makewrappers +index 20bbf2b..bf344d6 100755 +--- a/makewrappers ++++ b/makewrappers +@@ -211,12 +211,13 @@ class Function: + self.flags = '0' + self.port = port + self.directory = '' +- self.version = 'NULL' ++ self.version = 'NULL' + # On Darwin, some functions are SECRETLY converted to foo$INODE64 + # when called. So we have to look those up for real_* + self.inode64 = None + self.real_func = None + self.paths_to_munge = [] ++ self.dirfds = {} + self.hand_wrapped = None + # used for the copyright date when creating stub functions + self.date = datetime.date.today().year +@@ -239,6 +240,7 @@ class Function: + # * If the arg has a name ending in 'path', we will canonicalize it. + # * If the arg is named 'dirfd' or 'flags', it becomes the default + # values for the dirfd and flags arguments when canonicalizing. ++ # * If the name ends in dirfd, we do the same fancy stuff. + # * Note that the "comments" field (/* ... */ after the decl) can + # override the dirfd/flags values. + self.args = ArgumentList(bits.group(2)) +@@ -246,7 +248,9 @@ class Function: + # ignore varargs, they never get these special treatments + if arg.vararg: + pass +- elif arg.name == 'dirfd': ++ elif arg.name[-5:] == 'dirfd': ++ if len(arg.name) > 5: ++ self.dirfds[arg.name[:-5]] = True + self.dirfd = 'dirfd' + elif arg.name == 'flags': + self.flags = 'flags' +@@ -325,9 +329,13 @@ class Function: + """create/allocate canonical paths""" + alloc_paths = [] + for path in self.paths_to_munge: ++ prefix = path[:-4] ++ if not prefix in self.dirfds: ++ prefix = '' ++ print "for path %s: prefix <%s>" % ( path, prefix ) + alloc_paths.append( +- "%s = pseudo_root_path(__func__, __LINE__, %s, %s, %s);" % +- (path, self.dirfd, path, self.flags)) ++ "%s = pseudo_root_path(__func__, __LINE__, %s%s, %s, %s);" % ++ (path, prefix, self.dirfd, path, self.flags)) + return "\n\t\t\t".join(alloc_paths) + + def free_paths(self): +diff --git a/ports/unix/guts/renameat.c b/ports/unix/guts/renameat.c +index c8203b7..f13cd1e 100644 +--- a/ports/unix/guts/renameat.c ++++ b/ports/unix/guts/renameat.c +@@ -1,15 +1,111 @@ + /* +- * Copyright (c) 2008-2010 Wind River Systems; see ++ * Copyright (c) 2008-2012 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_renameat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) { + * int rc = -1; + */ ++ pseudo_msg_t *msg; ++ struct stat oldbuf, newbuf; ++ int oldrc, newrc; ++ int save_errno; ++ int old_db_entry = 0; + +- pseudo_diag("help! unimplemented renameat [%s -> %s].\n", oldpath, newpath); ++ pseudo_debug(2, "renameat: %d,%s->%d,%s\n", ++ olddirfd, oldpath ? oldpath : "<nil>", ++ newdirfd, newpath ? newpath : "<nil>"); ++ ++#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS ++ if (olddirfd != AT_FDCWD || newdirfd != AT_FDCWD) { ++ errno = ENOSYS; ++ return -1; ++ } ++#endif ++ ++ if (!oldpath || !newpath) { ++ errno = EFAULT; ++ return -1; ++ } ++ ++ save_errno = errno; ++ ++#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS ++ newrc = real_lstat(newpath, &newbuf); ++ oldrc = real_lstat(oldpath, &oldbuf); ++#else ++ oldrc = real___fxstatat(_STAT_VER, olddirfd, oldpath, &oldbuf, AT_SYMLINK_NOFOLLOW); ++ newrc = real___fxstatat(_STAT_VER, newdirfd, newpath, &newbuf, AT_SYMLINK_NOFOLLOW); ++#endif ++ ++ errno = save_errno; ++ ++ /* newpath must be removed. */ ++ /* as with unlink, we have to mark that the file may get deleted */ ++ msg = pseudo_client_op_plain(OP_MAY_UNLINK, 0, -1, newdirfd, newpath, newrc ? NULL : &newbuf); ++ if (msg && msg->result == RESULT_SUCCEED) ++ old_db_entry = 1; + rc = real_renameat(olddirfd, oldpath, newdirfd, newpath); ++ save_errno = errno; ++ if (old_db_entry) { ++ if (rc == -1) { ++ /* since we failed, that wasn't really unlinked -- put ++ * it back. ++ */ ++ pseudo_client_op_plain(OP_CANCEL_UNLINK, 0, -1, newdirfd, newpath, &newbuf); ++ } else { ++ /* confirm that the file was removed */ ++ pseudo_client_op_plain(OP_DID_UNLINK, 0, -1, newdirfd, newpath, &newbuf); ++ } ++ } ++ if (rc == -1) { ++ /* and we're done. */ ++ errno = save_errno; ++ return rc; ++ } ++ save_errno = errno; ++ /* nothing to do for a "rename" of a link to itself */ ++ if (newrc != -1 && oldrc != -1 && ++ newbuf.st_dev == oldbuf.st_dev && ++ newbuf.st_ino == oldbuf.st_ino) { ++ return rc; ++ } ++ ++ /* rename(3) is not mv(1). rename(file, dir) fails; you must provide ++ * the corrected path yourself. You can rename over a directory only ++ * if the source is a directory. Symlinks are simply removed. ++ * ++ * If we got here, the real rename call succeeded. That means newpath ++ * has been unlinked and oldpath has been linked to it. ++ * ++ * There are a ton of special cases to error check. I don't check ++ * for any of them, because in every such case, the underlying rename ++ * failed, and there is nothing to do. ++ * The only tricky part is that, because we used to ignore symlinks, ++ * we may have to rename or remove directory trees even though in ++ * theory rename can never destroy a directory tree. ++ */ ++ if (!old_db_entry) { ++ /* create an entry under the old name, which will then be ++ * renamed; this way, children would get renamed too, if there ++ * were any. ++ */ ++ if (newrc == 0) { ++ if (newbuf.st_dev != oldbuf.st_dev) { ++ oldbuf.st_dev = newbuf.st_dev; ++ oldbuf.st_ino = newbuf.st_ino; ++ } ++ } ++ pseudo_debug(1, "creating new '%s' [%llu] to rename\n", ++ oldpath, (unsigned long long) oldbuf.st_ino); ++ pseudo_client_op_plain(OP_LINK, 0, -1, olddirfd, oldpath, &oldbuf); ++ } ++ /* special case: use 'fd' for olddirfd, because ++ * we know it has no other meaning for RENAME ++ */ ++ pseudo_client_op_plain(OP_RENAME, 0, olddirfd, newdirfd, newpath, &oldbuf, oldpath); + ++ errno = save_errno; + /* return rc; + * } + */ +diff --git a/pseudo_client.c b/pseudo_client.c +index 48607c2..4a30420 100644 +--- a/pseudo_client.c ++++ b/pseudo_client.c +@@ -988,6 +988,8 @@ base_path(int dirfd, const char *path, int leave_last) { + if (dirfd != -1 && dirfd != AT_FDCWD) { + if (dirfd >= 0) { + basepath = fd_path(dirfd); ++ } ++ if (basepath) { + baselen = strlen(basepath); + } else { + pseudo_diag("got *at() syscall for unknown directory, fd %d\n", dirfd); +@@ -1128,7 +1130,10 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path + if (path) { + pseudo_debug(2, " %s", path); + } +- if (fd != -1) { ++ /* for OP_RENAME in renameat, "fd" is also used for the ++ * second dirfd. ++ */ ++ if (fd != -1 && op != OP_RENAME) { + pseudo_debug(2, " [fd %d]", fd); + } + if (buf) { diff --git a/meta/recipes-devtools/pseudo/pseudo_1.2.bb b/meta/recipes-devtools/pseudo/pseudo_1.2.bb index f2ebc22..04bcbce 100644 --- a/meta/recipes-devtools/pseudo/pseudo_1.2.bb +++ b/meta/recipes-devtools/pseudo/pseudo_1.2.bb @@ -1,10 +1,12 @@ require pseudo.inc -PR = "r4" +PR = "r5" SRC_URI = "http://www.yoctoproject.org/downloads/${BPN}/${BPN}-${PV}.tar.bz2 \ file://oe-config.patch \ - file://static_sqlite.patch" + file://static_sqlite.patch \ + file://opendir.patch \ + file://renameat.patch" SRC_URI[md5sum] = "a2819084bab7e991f06626d02cf55048" SRC_URI[sha256sum] = "4749a22df687f44d24c26e97170d4781a1bd52d5ee092364a40877e4d96ff058"
Signed-off-by: Khem Raj <raj.khem@gmail.com> --- meta/recipes-devtools/pseudo/pseudo/opendir.patch | 92 ++++++++ meta/recipes-devtools/pseudo/pseudo/renameat.patch | 227 ++++++++++++++++++++ meta/recipes-devtools/pseudo/pseudo_1.2.bb | 6 +- 3 files changed, 323 insertions(+), 2 deletions(-) create mode 100644 meta/recipes-devtools/pseudo/pseudo/opendir.patch create mode 100644 meta/recipes-devtools/pseudo/pseudo/renameat.patch