aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog.txt5
-rwxr-xr-xmakewrappers1
-rw-r--r--ports/unix/wrapfuncs.in2
-rw-r--r--pseudo_wrappers.c60
-rw-r--r--templates/wrapper_table12
5 files changed, 52 insertions, 28 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt
index 7ffb74a..a2bbb61 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,3 +1,8 @@
+2011-06-08:
+ * (seebs) Get the modern realpath from glibc instead of the old
+ one inexplicably proferred by RTLD_NEXT. Fixes realpath(path, NULL)
+ when PSEUDO_DISABLED=1.
+
2011-06-06:
* (seebs) revise system() handler substantially. It now
pollutes the environment but works.
diff --git a/makewrappers b/makewrappers
index 6dcf889..20bbf2b 100755
--- a/makewrappers
+++ b/makewrappers
@@ -211,6 +211,7 @@ class Function:
self.flags = '0'
self.port = port
self.directory = ''
+ 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
diff --git a/ports/unix/wrapfuncs.in b/ports/unix/wrapfuncs.in
index 74bad89..e06e404 100644
--- a/ports/unix/wrapfuncs.in
+++ b/ports/unix/wrapfuncs.in
@@ -18,7 +18,7 @@ int lutimes(const char *path, const struct timeval *tv);
char *mkdtemp(char *template);
char *mktemp(char *template);
long pathconf(const char *path, int name);
-char *realpath(const char *name, char *resolved_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);
char *tempnam(const char *template, const char *pfx);
diff --git a/pseudo_wrappers.c b/pseudo_wrappers.c
index 600a918..07a4429 100644
--- a/pseudo_wrappers.c
+++ b/pseudo_wrappers.c
@@ -90,6 +90,42 @@ pseudo_reinit_libpseudo(void) {
_libpseudo_init();
}
+static void
+pseudo_init_one_wrapper(pseudo_function *func) {
+ int (*f)(void);
+ char *e;
+ if (*func->real != NULL) {
+ /* already initialized */
+ return;
+ }
+ dlerror();
+
+#if PSEUDO_PORT_LINUX
+ if (func->version)
+ f = dlvsym(RTLD_NEXT, func->name, func->version);
+ /* fall through to the general case, if that failed */
+ if (!f)
+#endif
+ f = dlsym(RTLD_NEXT, func->name);
+ if (f) {
+ *func->real = f;
+ } else {
+ e = dlerror();
+#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
+ char *s = func->name;
+ s += strlen(s) - 2;
+ /* *at() don't have to exist */
+ if (!strcmp(s, "at")) {
+ continue;
+ }
+#else
+ if (e != NULL) {
+ pseudo_diag("No real function for %s: %s\n", func->name, e);
+ }
+#endif
+ }
+}
+
void
pseudo_init_wrappers(void) {
int i;
@@ -103,29 +139,7 @@ pseudo_init_wrappers(void) {
*/
if (!done) {
for (i = 0; pseudo_functions[i].name; ++i) {
- if (*pseudo_functions[i].real == NULL) {
- int (*f)(void);
- char *e;
- dlerror();
- f = dlsym(RTLD_NEXT, pseudo_functions[i].name);
- if (f) {
- *pseudo_functions[i].real = f;
- } else {
- e = dlerror();
-#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
- char *s = pseudo_functions[i].name;
- s += strlen(s) - 2;
- /* *at() don't have to exist */
- if (!strcmp(s, "at")) {
- continue;
- }
-#else
- if (e != NULL) {
- pseudo_diag("No real function for %s: %s\n", pseudo_functions[i].name, e);
- }
-#endif
- }
- }
+ pseudo_init_one_wrapper(&pseudo_functions[i]);
}
done = 1;
}
diff --git a/templates/wrapper_table b/templates/wrapper_table
index 2e79fcd..bb30530 100644
--- a/templates/wrapper_table
+++ b/templates/wrapper_table
@@ -4,17 +4,21 @@
/* This file is generated and should not be modified. See the makewrappers
* script if you want to modify this. */
-static struct {
+typedef struct {
char *name; /* the name */
int (**real)(void); /* the underlying syscall */
int (*wrapper)(void); /* the wrapper from guts/name.c */
-} pseudo_functions[] = {
+ char *version; /* the version, if we know and care */
+} pseudo_function;
+
+static pseudo_function pseudo_functions[] = {
@body
{ /* ${comment}; */
"${name}${maybe_inode64}",
(int (**)(void)) &real_${name},
- (int (*)(void)) wrap_${name}
+ (int (*)(void)) wrap_${name},
+ ${version}
},
@footer
- { NULL, NULL, NULL },
+ { NULL, NULL, NULL, NULL },
};