summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKhem Raj <raj.khem@gmail.com>2012-02-03 00:03:33 -0800
committerRichard Purdie <richard.purdie@linuxfoundation.org>2012-02-08 00:50:28 +0000
commit41936cd5bcfddfbf3374174c1e3cdea951d2d10f (patch)
treeb0cdd347a41a848821c16812c98c3823280ff454
parentbdc50cbfbba0148a09f78e49b658f195295f3f80 (diff)
downloadpoky-41936cd5bcfddfbf3374174c1e3cdea951d2d10f.tar.gz
pseudo: Wrap renameat and opendir
(From OE-Core rev: f6056cf0e7c76f2f3df650b088ce84df41ec14ca) Signed-off-by: Khem Raj <raj.khem@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-devtools/pseudo/pseudo/opendir.patch94
-rw-r--r--meta/recipes-devtools/pseudo/pseudo/renameat.patch229
-rw-r--r--meta/recipes-devtools/pseudo/pseudo_1.2.bb6
3 files changed, 327 insertions, 2 deletions
diff --git a/meta/recipes-devtools/pseudo/pseudo/opendir.patch b/meta/recipes-devtools/pseudo/pseudo/opendir.patch
new file mode 100644
index 0000000000..bc6cec8e7e
--- /dev/null
+++ b/meta/recipes-devtools/pseudo/pseudo/opendir.patch
@@ -0,0 +1,94 @@
1commit 162f2692c399b93311652201a940fdaf9c9e6924
2Author: Peter Seebach <peter.seebach@windriver.com>
3Date: Thu Feb 2 11:45:42 2012 -0600
4
5 Make opendir/closedir stash and forget directory names.
6
7 The dirfd(DIR *) interface allows you to get the fd for a DIR *,
8 meaning you can use it with openat(), meaning you can need its
9 path. This causes a segfault. Also gonna fix the base_path
10 code not to segfault in that case, but first fix the underlying
11 problem.
12
13Upstream-Status: Backport
14
15diff --git a/ChangeLog.txt b/ChangeLog.txt
16index 4de488c..9625b38 100644
17--- a/ChangeLog.txt
18+++ b/ChangeLog.txt
19@@ -1,3 +1,7 @@
20+2012-02-02:
21+ * (seebs) stash dir name for DIR * from opendir using dirfd.
22+ * (seebs) add closedir.
23+
24 2011-11-02:
25 * (seebs) Call this 1.2 because the UNLOAD change is moderately
26 significant, and so's the clone change.
27diff --git a/ports/unix/guts/closedir.c b/ports/unix/guts/closedir.c
28new file mode 100644
29index 0000000..1085361
30--- /dev/null
31+++ b/ports/unix/guts/closedir.c
32@@ -0,0 +1,20 @@
33+/*
34+ * Copyright (c) 2012 Wind River Systems; see
35+ * guts/COPYRIGHT for information.
36+ *
37+ * static int
38+ * wrap_closedir(DIR *dirp) {
39+ * int rc = -1;
40+ */
41+ if (!dirp) {
42+ errno = EFAULT;
43+ return -1;
44+ }
45+
46+ int fd = dirfd(dirp);
47+ pseudo_client_op(OP_CLOSE, 0, fd, -1, 0, 0);
48+ rc = real_closedir(dirp);
49+
50+/* return rc;
51+ * }
52+ */
53diff --git a/ports/unix/guts/opendir.c b/ports/unix/guts/opendir.c
54index 8eaa71f..e69717e 100644
55--- a/ports/unix/guts/opendir.c
56+++ b/ports/unix/guts/opendir.c
57@@ -6,8 +6,25 @@
58 * wrap_opendir(const char *path) {
59 * DIR * rc = NULL;
60 */
61+ struct stat buf;
62+ int save_errno;
63
64 rc = real_opendir(path);
65+ if (rc) {
66+ int fd;
67+ save_errno = errno;
68+ fd = dirfd(rc);
69+ if (real_fstat(fd, &buf) == -1) {
70+ pseudo_debug(1, "diropen (fd %d) succeeded, but fstat failed (%s).\n",
71+ fd, strerror(errno));
72+ pseudo_client_op_plain(OP_OPEN, PSA_READ, fd, -1, path, 0);
73+ } else {
74+ pseudo_client_op_plain(OP_OPEN, PSA_READ, fd, -1, path, &buf);
75+ }
76+
77+
78+ errno = save_errno;
79+ }
80
81 /* return rc;
82 * }
83diff --git a/ports/unix/wrapfuncs.in b/ports/unix/wrapfuncs.in
84index e06e404..32250c4 100644
85--- a/ports/unix/wrapfuncs.in
86+++ b/ports/unix/wrapfuncs.in
87@@ -21,6 +21,7 @@ long pathconf(const char *path, int name);
88 char *realpath(const char *name, char *resolved_name); /* version="GLIBC_2.3" */
89 int remove(const char *path); /* flags=AT_SYMLINK_NOFOLLOW */
90 DIR *opendir(const char *path);
91+int closedir(DIR *dirp);
92 char *tempnam(const char *template, const char *pfx);
93 char *tmpnam(char *s);
94 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 0000000000..a2b2cbc78c
--- /dev/null
+++ b/meta/recipes-devtools/pseudo/pseudo/renameat.patch
@@ -0,0 +1,229 @@
1commit 795f2b44b7f692151556782f142a4a6e7d45d892
2Author: Peter Seebach <peter.seebach@windriver.com>
3Date: Thu Feb 2 15:49:21 2012 -0600
4
5 Implement renameat()
6
7 After three long years, someone tried to use this. This was impossibly
8 hard back when pseudo was written, because there was only one dirfd
9 provided for. Thing is, now, the canonicalization happens in wrapfuncs,
10 so a small tweak to makewrappers to recognize that oldpath should use
11 olddirfd if it exists is enough to get us fully canonicalized paths
12 when needed.
13
14 Also fix the crash if base_path gets called with an fd for which we have
15 no path.
16
17Upstream-Status: Backport
18
19diff --git a/ChangeLog.txt b/ChangeLog.txt
20index 9625b38..25bd463 100644
21--- a/ChangeLog.txt
22+++ b/ChangeLog.txt
23@@ -1,6 +1,9 @@
24 2012-02-02:
25 * (seebs) stash dir name for DIR * from opendir using dirfd.
26 * (seebs) add closedir.
27+ * (seebs) add initial pass at renameat()
28+ * (seebs) in base_path, don't try to strlen the result if
29+ fd_path() returns NULL.
30
31 2011-11-02:
32 * (seebs) Call this 1.2 because the UNLOAD change is moderately
33diff --git a/makewrappers b/makewrappers
34index 20bbf2b..bf344d6 100755
35--- a/makewrappers
36+++ b/makewrappers
37@@ -211,12 +211,13 @@ class Function:
38 self.flags = '0'
39 self.port = port
40 self.directory = ''
41- self.version = 'NULL'
42+ self.version = 'NULL'
43 # On Darwin, some functions are SECRETLY converted to foo$INODE64
44 # when called. So we have to look those up for real_*
45 self.inode64 = None
46 self.real_func = None
47 self.paths_to_munge = []
48+ self.dirfds = {}
49 self.hand_wrapped = None
50 # used for the copyright date when creating stub functions
51 self.date = datetime.date.today().year
52@@ -239,6 +240,7 @@ class Function:
53 # * If the arg has a name ending in 'path', we will canonicalize it.
54 # * If the arg is named 'dirfd' or 'flags', it becomes the default
55 # values for the dirfd and flags arguments when canonicalizing.
56+ # * If the name ends in dirfd, we do the same fancy stuff.
57 # * Note that the "comments" field (/* ... */ after the decl) can
58 # override the dirfd/flags values.
59 self.args = ArgumentList(bits.group(2))
60@@ -246,7 +248,9 @@ class Function:
61 # ignore varargs, they never get these special treatments
62 if arg.vararg:
63 pass
64- elif arg.name == 'dirfd':
65+ elif arg.name[-5:] == 'dirfd':
66+ if len(arg.name) > 5:
67+ self.dirfds[arg.name[:-5]] = True
68 self.dirfd = 'dirfd'
69 elif arg.name == 'flags':
70 self.flags = 'flags'
71@@ -325,9 +329,13 @@ class Function:
72 """create/allocate canonical paths"""
73 alloc_paths = []
74 for path in self.paths_to_munge:
75+ prefix = path[:-4]
76+ if not prefix in self.dirfds:
77+ prefix = ''
78+ print "for path %s: prefix <%s>" % ( path, prefix )
79 alloc_paths.append(
80- "%s = pseudo_root_path(__func__, __LINE__, %s, %s, %s);" %
81- (path, self.dirfd, path, self.flags))
82+ "%s = pseudo_root_path(__func__, __LINE__, %s%s, %s, %s);" %
83+ (path, prefix, self.dirfd, path, self.flags))
84 return "\n\t\t\t".join(alloc_paths)
85
86 def free_paths(self):
87diff --git a/ports/unix/guts/renameat.c b/ports/unix/guts/renameat.c
88index c8203b7..f13cd1e 100644
89--- a/ports/unix/guts/renameat.c
90+++ b/ports/unix/guts/renameat.c
91@@ -1,15 +1,111 @@
92 /*
93- * Copyright (c) 2008-2010 Wind River Systems; see
94+ * Copyright (c) 2008-2012 Wind River Systems; see
95 * guts/COPYRIGHT for information.
96 *
97 * static int
98 * wrap_renameat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) {
99 * int rc = -1;
100 */
101+ pseudo_msg_t *msg;
102+ struct stat oldbuf, newbuf;
103+ int oldrc, newrc;
104+ int save_errno;
105+ int old_db_entry = 0;
106
107- pseudo_diag("help! unimplemented renameat [%s -> %s].\n", oldpath, newpath);
108+ pseudo_debug(2, "renameat: %d,%s->%d,%s\n",
109+ olddirfd, oldpath ? oldpath : "<nil>",
110+ newdirfd, newpath ? newpath : "<nil>");
111+
112+#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
113+ if (olddirfd != AT_FDCWD || newdirfd != AT_FDCWD) {
114+ errno = ENOSYS;
115+ return -1;
116+ }
117+#endif
118+
119+ if (!oldpath || !newpath) {
120+ errno = EFAULT;
121+ return -1;
122+ }
123+
124+ save_errno = errno;
125+
126+#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
127+ newrc = real_lstat(newpath, &newbuf);
128+ oldrc = real_lstat(oldpath, &oldbuf);
129+#else
130+ oldrc = real___fxstatat(_STAT_VER, olddirfd, oldpath, &oldbuf, AT_SYMLINK_NOFOLLOW);
131+ newrc = real___fxstatat(_STAT_VER, newdirfd, newpath, &newbuf, AT_SYMLINK_NOFOLLOW);
132+#endif
133+
134+ errno = save_errno;
135+
136+ /* newpath must be removed. */
137+ /* as with unlink, we have to mark that the file may get deleted */
138+ msg = pseudo_client_op_plain(OP_MAY_UNLINK, 0, -1, newdirfd, newpath, newrc ? NULL : &newbuf);
139+ if (msg && msg->result == RESULT_SUCCEED)
140+ old_db_entry = 1;
141 rc = real_renameat(olddirfd, oldpath, newdirfd, newpath);
142+ save_errno = errno;
143+ if (old_db_entry) {
144+ if (rc == -1) {
145+ /* since we failed, that wasn't really unlinked -- put
146+ * it back.
147+ */
148+ pseudo_client_op_plain(OP_CANCEL_UNLINK, 0, -1, newdirfd, newpath, &newbuf);
149+ } else {
150+ /* confirm that the file was removed */
151+ pseudo_client_op_plain(OP_DID_UNLINK, 0, -1, newdirfd, newpath, &newbuf);
152+ }
153+ }
154+ if (rc == -1) {
155+ /* and we're done. */
156+ errno = save_errno;
157+ return rc;
158+ }
159+ save_errno = errno;
160+ /* nothing to do for a "rename" of a link to itself */
161+ if (newrc != -1 && oldrc != -1 &&
162+ newbuf.st_dev == oldbuf.st_dev &&
163+ newbuf.st_ino == oldbuf.st_ino) {
164+ return rc;
165+ }
166+
167+ /* rename(3) is not mv(1). rename(file, dir) fails; you must provide
168+ * the corrected path yourself. You can rename over a directory only
169+ * if the source is a directory. Symlinks are simply removed.
170+ *
171+ * If we got here, the real rename call succeeded. That means newpath
172+ * has been unlinked and oldpath has been linked to it.
173+ *
174+ * There are a ton of special cases to error check. I don't check
175+ * for any of them, because in every such case, the underlying rename
176+ * failed, and there is nothing to do.
177+ * The only tricky part is that, because we used to ignore symlinks,
178+ * we may have to rename or remove directory trees even though in
179+ * theory rename can never destroy a directory tree.
180+ */
181+ if (!old_db_entry) {
182+ /* create an entry under the old name, which will then be
183+ * renamed; this way, children would get renamed too, if there
184+ * were any.
185+ */
186+ if (newrc == 0) {
187+ if (newbuf.st_dev != oldbuf.st_dev) {
188+ oldbuf.st_dev = newbuf.st_dev;
189+ oldbuf.st_ino = newbuf.st_ino;
190+ }
191+ }
192+ pseudo_debug(1, "creating new '%s' [%llu] to rename\n",
193+ oldpath, (unsigned long long) oldbuf.st_ino);
194+ pseudo_client_op_plain(OP_LINK, 0, -1, olddirfd, oldpath, &oldbuf);
195+ }
196+ /* special case: use 'fd' for olddirfd, because
197+ * we know it has no other meaning for RENAME
198+ */
199+ pseudo_client_op_plain(OP_RENAME, 0, olddirfd, newdirfd, newpath, &oldbuf, oldpath);
200
201+ errno = save_errno;
202 /* return rc;
203 * }
204 */
205diff --git a/pseudo_client.c b/pseudo_client.c
206index 48607c2..4a30420 100644
207--- a/pseudo_client.c
208+++ b/pseudo_client.c
209@@ -988,6 +988,8 @@ base_path(int dirfd, const char *path, int leave_last) {
210 if (dirfd != -1 && dirfd != AT_FDCWD) {
211 if (dirfd >= 0) {
212 basepath = fd_path(dirfd);
213+ }
214+ if (basepath) {
215 baselen = strlen(basepath);
216 } else {
217 pseudo_diag("got *at() syscall for unknown directory, fd %d\n", dirfd);
218@@ -1128,7 +1130,10 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path
219 if (path) {
220 pseudo_debug(2, " %s", path);
221 }
222- if (fd != -1) {
223+ /* for OP_RENAME in renameat, "fd" is also used for the
224+ * second dirfd.
225+ */
226+ if (fd != -1 && op != OP_RENAME) {
227 pseudo_debug(2, " [fd %d]", fd);
228 }
229 if (buf) {
diff --git a/meta/recipes-devtools/pseudo/pseudo_1.2.bb b/meta/recipes-devtools/pseudo/pseudo_1.2.bb
index f2ebc228d9..04bcbce1ea 100644
--- a/meta/recipes-devtools/pseudo/pseudo_1.2.bb
+++ b/meta/recipes-devtools/pseudo/pseudo_1.2.bb
@@ -1,10 +1,12 @@
1require pseudo.inc 1require pseudo.inc
2 2
3PR = "r4" 3PR = "r5"
4 4
5SRC_URI = "http://www.yoctoproject.org/downloads/${BPN}/${BPN}-${PV}.tar.bz2 \ 5SRC_URI = "http://www.yoctoproject.org/downloads/${BPN}/${BPN}-${PV}.tar.bz2 \
6 file://oe-config.patch \ 6 file://oe-config.patch \
7 file://static_sqlite.patch" 7 file://static_sqlite.patch \
8 file://opendir.patch \
9 file://renameat.patch"
8 10
9SRC_URI[md5sum] = "a2819084bab7e991f06626d02cf55048" 11SRC_URI[md5sum] = "a2819084bab7e991f06626d02cf55048"
10SRC_URI[sha256sum] = "4749a22df687f44d24c26e97170d4781a1bd52d5ee092364a40877e4d96ff058" 12SRC_URI[sha256sum] = "4749a22df687f44d24c26e97170d4781a1bd52d5ee092364a40877e4d96ff058"