aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Seebach <peter.seebach@windriver.com>2011-03-25 12:38:43 -0500
committerPeter Seebach <peter.seebach@windriver.com>2011-03-25 12:38:43 -0500
commit29e8b8a4cd8f7383c3d851b6255272f1c2a5d286 (patch)
treec9619032a670d06124ef45c392484f4a04f7d0f0
parent96d8e7ce8b483e5cafd0449b9735e4714f41f20b (diff)
downloadpseudo-29e8b8a4cd8f7383c3d851b6255272f1c2a5d286.tar.gz
pseudo-29e8b8a4cd8f7383c3d851b6255272f1c2a5d286.tar.bz2
pseudo-29e8b8a4cd8f7383c3d851b6255272f1c2a5d286.zip
Merge in ports work
This is a spiffied-up rebase of a bunch of intermediate changes, presented as a whole because it is, surprisingly, less confusing that way. The basic idea is to separate the guts code into categories ranging from generic stuff that can be the same everywhere and specific variants. The big scary one is the Darwin support, which actually seems to run okay on 64-bit OS X 10.6. (No other variants were tested.) The other example given is support for the old clone() syscall on RHEL 4, which affects some wrlinux use cases. There's a few minor cleanup bits here, such as a function with inconsistent calling conventions, but nothing really exciting.
-rw-r--r--.gitignore2
-rw-r--r--ChangeLog.txt14
-rw-r--r--Makefile.in13
-rw-r--r--doc/ports23
-rwxr-xr-xmaketables15
-rwxr-xr-xmakewrappers212
-rw-r--r--ports/common/guts/execl.c13
-rw-r--r--ports/common/guts/execle.c13
-rw-r--r--ports/common/guts/execlp.c13
-rw-r--r--ports/common/guts/execv.c (renamed from guts/execv.c)0
-rw-r--r--ports/common/guts/execve.c (renamed from guts/execve.c)0
-rw-r--r--ports/common/guts/execvp.c (renamed from guts/execvp.c)0
-rw-r--r--ports/common/guts/fork.c (renamed from guts/fork.c)0
-rw-r--r--ports/common/pseudo_wrappers.c376
-rw-r--r--ports/common/subports8
-rw-r--r--ports/common/wrapfuncs.in7
-rw-r--r--ports/darwin/guts/COPYRIGHT17
-rw-r--r--ports/darwin/guts/fcntl.c46
-rw-r--r--ports/darwin/guts/fgetgrent_r.c13
-rw-r--r--ports/darwin/guts/fgetpwent_r.c13
-rw-r--r--ports/darwin/guts/fgetxattr.c13
-rw-r--r--ports/darwin/guts/flistxattr.c13
-rw-r--r--ports/darwin/guts/fsetxattr.c13
-rw-r--r--ports/darwin/guts/fstat.c27
-rw-r--r--ports/darwin/guts/getgrent_r.c13
-rw-r--r--ports/darwin/guts/getgrouplist.c42
-rw-r--r--ports/darwin/guts/getgroups.c22
-rw-r--r--ports/darwin/guts/getpwent_r.c13
-rw-r--r--ports/darwin/guts/getxattr.c13
-rw-r--r--ports/darwin/guts/listxattr.c13
-rw-r--r--ports/darwin/guts/lstat.c27
-rw-r--r--ports/darwin/guts/open.c49
-rw-r--r--ports/darwin/guts/scandir.c14
-rw-r--r--ports/darwin/guts/setxattr.c13
-rw-r--r--ports/darwin/guts/stat.c31
-rw-r--r--ports/darwin/portdefs.h10
-rw-r--r--ports/darwin/preports2
-rw-r--r--ports/darwin/pseudo_wrappers.c316
-rw-r--r--ports/darwin/subports3
-rw-r--r--ports/darwin/wrapfuncs.in25
-rw-r--r--ports/linux/guts/COPYRIGHT17
-rw-r--r--ports/linux/guts/__fxstat.c (renamed from guts/__fxstat.c)0
-rw-r--r--ports/linux/guts/__fxstat64.c (renamed from guts/__fxstat64.c)5
-rw-r--r--ports/linux/guts/__fxstatat.c (renamed from guts/__fxstatat.c)0
-rw-r--r--ports/linux/guts/__fxstatat64.c (renamed from guts/__fxstatat64.c)0
-rw-r--r--ports/linux/guts/__lxstat.c (renamed from guts/__lxstat.c)0
-rw-r--r--ports/linux/guts/__lxstat64.c (renamed from guts/__lxstat64.c)0
-rw-r--r--ports/linux/guts/__openat64_2.c (renamed from guts/__openat64_2.c)0
-rw-r--r--ports/linux/guts/__openat_2.c (renamed from guts/__openat_2.c)0
-rw-r--r--ports/linux/guts/__xmknod.c (renamed from guts/__xmknod.c)0
-rw-r--r--ports/linux/guts/__xmknodat.c (renamed from guts/__xmknodat.c)6
-rw-r--r--ports/linux/guts/__xstat.c (renamed from guts/__xstat.c)0
-rw-r--r--ports/linux/guts/__xstat64.c (renamed from guts/__xstat64.c)0
-rw-r--r--ports/linux/guts/canonicalize_file_name.c (renamed from guts/canonicalize_file_name.c)0
-rw-r--r--ports/linux/guts/creat64.c (renamed from guts/creat64.c)0
-rw-r--r--ports/linux/guts/eaccess.c (renamed from guts/eaccess.c)0
-rw-r--r--ports/linux/guts/euidaccess.c (renamed from guts/euidaccess.c)0
-rw-r--r--ports/linux/guts/fcntl.c (renamed from guts/fcntl.c)0
-rw-r--r--ports/linux/guts/fgetxattr.c (renamed from guts/fgetxattr.c)5
-rw-r--r--ports/linux/guts/flistxattr.c (renamed from guts/flistxattr.c)4
-rw-r--r--ports/linux/guts/fopen64.c (renamed from guts/fopen64.c)0
-rw-r--r--ports/linux/guts/fremovexattr.c (renamed from guts/fremovexattr.c)3
-rw-r--r--ports/linux/guts/freopen64.c (renamed from guts/freopen64.c)0
-rw-r--r--ports/linux/guts/fsetxattr.c (renamed from guts/fsetxattr.c)6
-rw-r--r--ports/linux/guts/fstat.c13
-rw-r--r--ports/linux/guts/ftw64.c (renamed from guts/ftw64.c)0
-rw-r--r--ports/linux/guts/get_current_dir_name.c (renamed from guts/get_current_dir_name.c)0
-rw-r--r--ports/linux/guts/getgrent_r.c (renamed from guts/getgrent_r.c)9
-rw-r--r--ports/linux/guts/getgrouplist.c (renamed from guts/getgrouplist.c)0
-rw-r--r--ports/linux/guts/getgroups.c (renamed from guts/getgroups.c)0
-rw-r--r--ports/linux/guts/getpw.c (renamed from guts/getpw.c)0
-rw-r--r--ports/linux/guts/getpwent_r.c (renamed from guts/getpwent_r.c)4
-rw-r--r--ports/linux/guts/getresgid.c (renamed from guts/getresgid.c)0
-rw-r--r--ports/linux/guts/getresuid.c (renamed from guts/getresuid.c)0
-rw-r--r--ports/linux/guts/getxattr.c (renamed from guts/getxattr.c)5
-rw-r--r--ports/linux/guts/glob64.c (renamed from guts/glob64.c)0
-rw-r--r--ports/linux/guts/lchown.c (renamed from guts/lchown.c)0
-rw-r--r--ports/linux/guts/lckpwdf.c (renamed from guts/lckpwdf.c)0
-rw-r--r--ports/linux/guts/lgetxattr.c (renamed from guts/lgetxattr.c)5
-rw-r--r--ports/linux/guts/listxattr.c (renamed from guts/listxattr.c)4
-rw-r--r--ports/linux/guts/llistxattr.c (renamed from guts/llistxattr.c)4
-rw-r--r--ports/linux/guts/lremovexattr.c (renamed from guts/lremovexattr.c)3
-rw-r--r--ports/linux/guts/lsetxattr.c (renamed from guts/lsetxattr.c)6
-rw-r--r--ports/linux/guts/lstat.c13
-rw-r--r--ports/linux/guts/mkstemp64.c (renamed from guts/mkstemp64.c)0
-rw-r--r--ports/linux/guts/nftw64.c (renamed from guts/nftw64.c)0
-rw-r--r--ports/linux/guts/open.c (renamed from guts/open.c)0
-rw-r--r--ports/linux/guts/open64.c (renamed from guts/open64.c)0
-rw-r--r--ports/linux/guts/openat.c (renamed from guts/openat.c)0
-rw-r--r--ports/linux/guts/openat64.c (renamed from guts/openat64.c)0
-rw-r--r--ports/linux/guts/removexattr.c (renamed from guts/removexattr.c)3
-rw-r--r--ports/linux/guts/scandir.c (renamed from guts/scandir.c)0
-rw-r--r--ports/linux/guts/scandir64.c (renamed from guts/scandir64.c)0
-rw-r--r--ports/linux/guts/setfsgid.c (renamed from guts/setfsgid.c)0
-rw-r--r--ports/linux/guts/setfsuid.c (renamed from guts/setfsuid.c)0
-rw-r--r--ports/linux/guts/setgroups.c (renamed from guts/setgroups.c)0
-rw-r--r--ports/linux/guts/setresgid.c (renamed from guts/setresgid.c)0
-rw-r--r--ports/linux/guts/setresuid.c (renamed from guts/setresuid.c)0
-rw-r--r--ports/linux/guts/setxattr.c (renamed from guts/setxattr.c)6
-rw-r--r--ports/linux/guts/stat.c13
-rw-r--r--ports/linux/guts/truncate64.c (renamed from guts/truncate64.c)0
-rw-r--r--ports/linux/guts/ulckpwdf.c (renamed from guts/ulckpwdf.c)0
-rw-r--r--ports/linux/newclone/guts/clone.c (renamed from guts/clone.c)0
-rw-r--r--ports/linux/newclone/pseudo_wrappers.c69
-rw-r--r--ports/linux/newclone/wrapfuncs.in1
-rw-r--r--ports/linux/oldclone/guts/clone.c27
-rw-r--r--ports/linux/oldclone/pseudo_wrappers.c59
-rw-r--r--ports/linux/oldclone/wrapfuncs.in1
-rw-r--r--ports/linux/portdefs.h5
-rw-r--r--ports/linux/preports2
-rw-r--r--ports/linux/pseudo_wrappers.c18
-rw-r--r--ports/linux/subports27
-rw-r--r--ports/linux/wrapfuncs.in64
-rw-r--r--ports/uids_generic/guts/COPYRIGHT17
-rw-r--r--ports/uids_generic/guts/endgrent.c (renamed from guts/endgrent.c)0
-rw-r--r--ports/uids_generic/guts/endpwent.c (renamed from guts/endpwent.c)0
-rw-r--r--ports/uids_generic/guts/getegid.c (renamed from guts/getegid.c)0
-rw-r--r--ports/uids_generic/guts/geteuid.c (renamed from guts/geteuid.c)0
-rw-r--r--ports/uids_generic/guts/getgid.c (renamed from guts/getgid.c)0
-rw-r--r--ports/uids_generic/guts/getgrent.c (renamed from guts/getgrent.c)0
-rw-r--r--ports/uids_generic/guts/getgrgid.c (renamed from guts/getgrgid.c)0
-rw-r--r--ports/uids_generic/guts/getgrgid_r.c (renamed from guts/getgrgid_r.c)0
-rw-r--r--ports/uids_generic/guts/getgrnam.c (renamed from guts/getgrnam.c)0
-rw-r--r--ports/uids_generic/guts/getgrnam_r.c (renamed from guts/getgrnam_r.c)0
-rw-r--r--ports/uids_generic/guts/getpwent.c (renamed from guts/getpwent.c)0
-rw-r--r--ports/uids_generic/guts/getpwnam.c (renamed from guts/getpwnam.c)0
-rw-r--r--ports/uids_generic/guts/getpwnam_r.c (renamed from guts/getpwnam_r.c)0
-rw-r--r--ports/uids_generic/guts/getpwuid.c (renamed from guts/getpwuid.c)0
-rw-r--r--ports/uids_generic/guts/getpwuid_r.c (renamed from guts/getpwuid_r.c)0
-rw-r--r--ports/uids_generic/guts/getuid.c (renamed from guts/getuid.c)0
-rw-r--r--ports/uids_generic/guts/setegid.c (renamed from guts/setegid.c)0
-rw-r--r--ports/uids_generic/guts/seteuid.c (renamed from guts/seteuid.c)0
-rw-r--r--ports/uids_generic/guts/setgid.c (renamed from guts/setgid.c)0
-rw-r--r--ports/uids_generic/guts/setgrent.c (renamed from guts/setgrent.c)0
-rw-r--r--ports/uids_generic/guts/setpwent.c (renamed from guts/setpwent.c)0
-rw-r--r--ports/uids_generic/guts/setregid.c (renamed from guts/setregid.c)0
-rw-r--r--ports/uids_generic/guts/setreuid.c (renamed from guts/setreuid.c)0
-rw-r--r--ports/uids_generic/guts/setuid.c (renamed from guts/setuid.c)0
-rw-r--r--ports/uids_generic/wrapfuncs.in25
-rw-r--r--ports/unix/guts/COPYRIGHT17
-rw-r--r--ports/unix/guts/access.c (renamed from guts/access.c)4
-rw-r--r--ports/unix/guts/acct.c (renamed from guts/acct.c)0
-rw-r--r--ports/unix/guts/chdir.c (renamed from guts/chdir.c)0
-rw-r--r--ports/unix/guts/chmod.c (renamed from guts/chmod.c)0
-rw-r--r--ports/unix/guts/chown.c (renamed from guts/chown.c)0
-rw-r--r--ports/unix/guts/chroot.c (renamed from guts/chroot.c)0
-rw-r--r--ports/unix/guts/close.c (renamed from guts/close.c)0
-rw-r--r--ports/unix/guts/creat.c (renamed from guts/creat.c)2
-rw-r--r--ports/unix/guts/dup.c (renamed from guts/dup.c)0
-rw-r--r--ports/unix/guts/dup2.c (renamed from guts/dup2.c)0
-rw-r--r--ports/unix/guts/fchdir.c (renamed from guts/fchdir.c)0
-rw-r--r--ports/unix/guts/fchmod.c (renamed from guts/fchmod.c)12
-rw-r--r--ports/unix/guts/fchmodat.c (renamed from guts/fchmodat.c)18
-rw-r--r--ports/unix/guts/fchown.c (renamed from guts/fchown.c)18
-rw-r--r--ports/unix/guts/fchownat.c (renamed from guts/fchownat.c)20
-rw-r--r--ports/unix/guts/fclose.c (renamed from guts/fclose.c)0
-rw-r--r--ports/unix/guts/fopen.c (renamed from guts/fopen.c)12
-rw-r--r--ports/unix/guts/freopen.c (renamed from guts/freopen.c)12
-rw-r--r--ports/unix/guts/fts_open.c (renamed from guts/fts_open.c)0
-rw-r--r--ports/unix/guts/ftw.c (renamed from guts/ftw.c)0
-rw-r--r--ports/unix/guts/getcwd.c (renamed from guts/getcwd.c)0
-rw-r--r--ports/unix/guts/getwd.c (renamed from guts/getwd.c)0
-rw-r--r--ports/unix/guts/glob.c (renamed from guts/glob.c)0
-rw-r--r--ports/unix/guts/lchown.c13
-rw-r--r--ports/unix/guts/link.c (renamed from guts/link.c)10
-rw-r--r--ports/unix/guts/lutimes.c (renamed from guts/lutimes.c)0
-rw-r--r--ports/unix/guts/mkdir.c (renamed from guts/mkdir.c)0
-rw-r--r--ports/unix/guts/mkdirat.c (renamed from guts/mkdirat.c)8
-rw-r--r--ports/unix/guts/mkdtemp.c (renamed from guts/mkdtemp.c)6
-rw-r--r--ports/unix/guts/mkfifo.c (renamed from guts/mkfifo.c)0
-rw-r--r--ports/unix/guts/mkfifoat.c (renamed from guts/mkfifoat.c)3
-rw-r--r--ports/unix/guts/mknod.c13
-rw-r--r--ports/unix/guts/mknodat.c66
-rw-r--r--ports/unix/guts/mkstemp.c (renamed from guts/mkstemp.c)10
-rw-r--r--ports/unix/guts/mktemp.c (renamed from guts/mktemp.c)0
-rw-r--r--ports/unix/guts/nftw.c (renamed from guts/nftw.c)0
-rw-r--r--ports/unix/guts/opendir.c (renamed from guts/opendir.c)0
-rw-r--r--ports/unix/guts/pathconf.c (renamed from guts/pathconf.c)0
-rw-r--r--ports/unix/guts/readlink.c (renamed from guts/readlink.c)0
-rw-r--r--ports/unix/guts/readlinkat.c (renamed from guts/readlinkat.c)0
-rw-r--r--ports/unix/guts/realpath.c (renamed from guts/realpath.c)0
-rw-r--r--ports/unix/guts/remove.c (renamed from guts/remove.c)2
-rw-r--r--ports/unix/guts/rename.c (renamed from guts/rename.c)16
-rw-r--r--ports/unix/guts/renameat.c (renamed from guts/renameat.c)0
-rw-r--r--ports/unix/guts/rmdir.c (renamed from guts/rmdir.c)10
-rw-r--r--ports/unix/guts/symlink.c (renamed from guts/symlink.c)0
-rw-r--r--ports/unix/guts/symlinkat.c (renamed from guts/symlinkat.c)8
-rw-r--r--ports/unix/guts/tempnam.c (renamed from guts/tempnam.c)0
-rw-r--r--ports/unix/guts/tmpnam.c (renamed from guts/tmpnam.c)0
-rw-r--r--ports/unix/guts/truncate.c (renamed from guts/truncate.c)0
-rw-r--r--ports/unix/guts/unlink.c (renamed from guts/unlink.c)0
-rw-r--r--ports/unix/guts/unlinkat.c (renamed from guts/unlinkat.c)12
-rw-r--r--ports/unix/guts/utime.c (renamed from guts/utime.c)0
-rw-r--r--ports/unix/guts/utimes.c (renamed from guts/utimes.c)0
-rw-r--r--ports/unix/wrapfuncs.in56
-rw-r--r--pseudo.111
-rw-r--r--pseudo.c22
-rw-r--r--pseudo.h9
-rw-r--r--pseudo_client.c115
-rw-r--r--pseudo_client.h9
-rw-r--r--pseudo_db.c54
-rw-r--r--pseudo_ipc.c24
-rw-r--r--pseudo_ipc.h11
-rw-r--r--pseudo_server.c6
-rw-r--r--pseudo_util.c255
-rw-r--r--pseudo_wrappers.c464
-rw-r--r--templatefile.py26
-rw-r--r--templates/guts3
-rw-r--r--templates/port_wrappers5
-rw-r--r--templates/pseudo_ports6
-rw-r--r--templates/wrapfuncs.c9
-rw-r--r--templates/wrapfuncs.h19
-rw-r--r--templates/wrapper_table28
-rw-r--r--wrapfuncs.in124
-rw-r--r--wrapfuncs64.in16
215 files changed, 2554 insertions, 929 deletions
diff --git a/.gitignore b/.gitignore
index fdaf147..c0e9983 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,4 +8,6 @@ pseudodb
pseudolog
pseudo_tables.c
pseudo_tables.h
+port_wrappers.c
+pseudo_ports.h
templatefile.pyc
diff --git a/ChangeLog.txt b/ChangeLog.txt
index a7efd34..253f596 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,6 +1,20 @@
2011-03-25:
* (seebs) don't try to search path when you don't have one
+ * (seebs) merge in ports branch
+2011-03-24:
+ * (seebs) more work on OS X port.
+ * (seebs) include errno in the verbose debug output
+ * (seebs) fix darwin fcntl.
+ * (seebs) fix *xattr for darwin (they take more arguments)
+
+2011-02-18:
+ * (seebs) moving things to Unix port, cleanup for Darwin
+
+2011-02-14:
+ * (seebs) first pass on splitting out ports
+ * (seebs) various cleanup
+
2011-02-10:
* (seebs) pseudo_client_shutdown(), and the pseudo server, have to
be smart enough to make the local state directory in case the
diff --git a/Makefile.in b/Makefile.in
index 294db44..d30b795 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -24,7 +24,7 @@ SQLITE=@SQLITE@
BITS=@BITS@
MARK64=@MARK64@
RPATH=@RPATH@
-VERSION=0.3
+VERSION=1.0
LIB=lib$(MARK64)
BIN=bin
@@ -47,8 +47,6 @@ GUTS=$(filter-out "$(GLOB_PATTERN)",$(wildcard $(GLOB_PATTERN)))
SOURCES=$(wildcard *.c)
OBJS=$(subst .c,.o,$(SOURCES))
-USE_64=wrapfuncs64.in
-
SHOBJS=pseudo_tables.o pseudo_util.o
DBOBJS=pseudo_db.o
WRAPOBJS=pseudo_wrappers.o
@@ -113,7 +111,9 @@ $(LIBPSEUDO): $(LIB) $(WRAPOBJS) pseudo_client.o pseudo_ipc.o $(SHOBJS)
pseudo_client.o pseudo_ipc.o \
$(WRAPOBJS) $(SHOBJS) $(CLIENT_LDFLAGS)
-%.o: %.c
+# *everything* now relies on stuff that's generated in the
+# wrapper process.
+%.o: %.c pseudo_wrapfuncs.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(CFLAGS_PSEUDO) $<
$(OBJS): pseudo_tables.h
@@ -127,8 +127,8 @@ pseudo_server.o: pseudo_server.h
tables: enums/*.in maketables templatefile.py $(TABLES)
./maketables enums/*.in
-wrappers: wrapfuncs.in $(USE_64) makewrappers templatefile.py $(TEMPLATES)
- ./makewrappers wrapfuncs.in $(USE_64)
+wrappers: makewrappers templatefile.py $(TEMPLATES) ports/*/wrapfuncs.in
+ ./makewrappers
.SECONDARY: tables wrappers
@@ -154,6 +154,7 @@ clean:
pseudo_wrapfuncs.h pseudo_wrapfuncs.c \
pseudo_wrapper_table.c \
pseudo_tables.c pseudo_tables.h \
+ pseudo_ports.h port_wrappers.c \
offsets32 offsets64
distclean: clean
diff --git a/doc/ports b/doc/ports
new file mode 100644
index 0000000..4debb64
--- /dev/null
+++ b/doc/ports
@@ -0,0 +1,23 @@
+The "ports" system provides functionality for porting pseudo to new targets.
+The original motivation was a requirement to support older and newer Linux
+systems on which the signature for clone() differed.
+
+The Darwin port is totally nonfunctional at this point, but it compiles,
+and sufficiently careful hand-tuning of DYLD_INSERT_LIBRARIES and a
+manually-started server can actually pass a simple test. It will get
+worked on in my copious free time.
+
+The basic design of a port is that it provides a wrapfuncs.in list of
+function signatures, guts implementations, and optionally some port-specific
+defines or a block of wrapper code for pseudo_wrappers.c. This is used
+for cases where the default wrapper would not be appropriate, and may
+be combined with the new hand_wrapped=1 flag in wrapfuncs.in.
+
+A port may specify preports or subports. Preports are ports that are
+included and processed *before* the current port -- meaning that functions
+in the current port can override them. Subports are processed *after*
+the current port -- meaning that they can override functions in the
+current port. The preports and subports are specified by scripts,
+which echo a list of port names to standard output. (Be sure any
+diagnostic messages go to standard error.)
+
diff --git a/maketables b/maketables
index 51fb4c8..fe4e62c 100755
--- a/maketables
+++ b/maketables
@@ -108,15 +108,20 @@ class DataType:
return attr
def __repr__(self):
+ column = 0
out = ""
out += "type: %s_t" % self.name
- out += " %s_ENUM\n" % self.prefix
+ out += " (prefix '%s_ENUM')\n" % self.prefix
for col in self.columns:
- out += "\tcol: %s (%s)\n" % (col["name"], col["value"])
+ out += " extra column: %s (default '%s')\n" % (col["name"], col["value"])
+ out += " "
for item in self.data:
- out += "item: %s\n" % item["name"]
- for col in item["cols"]:
- out += "\t%s(%s)\n" % (col["name"], col["value"])
+ column = column + 1
+ if column > 4 and column % 4 == 1:
+ out += "\n "
+ out += "%-19s" % item["name"]
+# for col in item["cols"]:
+# out += "\t%s(%s)\n" % (col["name"], col["value"])
return out
def comment(self):
diff --git a/makewrappers b/makewrappers
index fba2fce..9765cf8 100755
--- a/makewrappers
+++ b/makewrappers
@@ -17,10 +17,13 @@
#
"""convert wrapfuncs.in to wrapper function stubs and tables"""
+import datetime
import glob
import sys
import re
-import datetime
+import os.path
+import string
+import subprocess
from templatefile import TemplateFile
class ArgumentList:
@@ -134,7 +137,7 @@ class Argument:
self.vararg = False
# try for a function pointer
- match = re.match('(.*)\(\*([a-zA-Z0-9_]*)\)\((.*)\)', text)
+ match = re.match('(.*)\(\*([a-zA-Z0-9$_]*)\)\((.*)\)', text)
if match:
self.function_pointer = True
self.args = match.group(3)
@@ -142,7 +145,7 @@ class Argument:
self.name = match.group(2).rstrip()
else:
# plain declaration
- match = re.match('(.*[ *])\(?\*?([a-zA-Z0-9_]*)\)?', text)
+ match = re.match('(.*[ *])\(?\*?([a-zA-Z0-9$_]*)\)?', text)
# there may not be a match, say in the special case
# where an arg is '...'
if match:
@@ -194,7 +197,7 @@ class Argument:
class Function:
"""A function signature and additional data about how the function works"""
- def __init__(self, line):
+ def __init__(self, port, line):
# table of known default values:
default_values = {
'gid_t': '0',
@@ -206,8 +209,14 @@ class Function:
self.dirfd = 'AT_FDCWD'
self.flags = '0'
+ self.port = port
+ self.directory = ''
+ # 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.nowrappers = None
+ self.hand_wrapped = None
# used for the copyright date when creating stub functions
self.date = datetime.date.today().year
@@ -264,6 +273,28 @@ class Function:
value = value.rstrip()
setattr(self, key, value)
+ def maybe_inode64(self):
+ if self.inode64 and os.uname()[0] == 'Darwin':
+ return "$INODE64"
+ else:
+ return ""
+
+ def end_maybe_skip(self):
+ if self.hand_wrapped:
+ return """/* Hand-written wrapper for this function. */
+#endif
+"""
+ else:
+ return ""
+
+ def maybe_skip(self):
+ if self.hand_wrapped:
+ return """/* Hand-written wrapper for this function. */
+#if 0
+"""
+ else:
+ return ""
+
def comment(self):
"""declare self (in a comment)"""
return self.decl(comment = True)
@@ -308,6 +339,18 @@ class Function:
free_paths.append("free((void *) %s);" % path)
return "\n\t\t\t".join(free_paths)
+ def real_predecl(self):
+ if self.real_func:
+ return self.decl().replace(self.name, self.real_func, 1) + ";"
+ else:
+ return ""
+
+ def real_init(self):
+ if self.real_func:
+ return self.real_func
+ else:
+ return "NULL"
+
def rc_return(self):
"""return rc (or just return)"""
if self.type == 'void':
@@ -357,6 +400,133 @@ class Function:
pretty += ' (%s)' % self.comments
return pretty
+class Port:
+ """
+A Port is a set of function declarations and code providing
+details specific to a specific host environment, such as Linux.
+Ports can override each other, and each port can indicate
+additional ports to include.
+"""
+
+ def __init__(self, port, sources):
+ self.name = port
+ self.subports = []
+ self.preports = []
+
+ if os.path.exists(self.portfile("pseudo_wrappers.c")):
+ self.wrappers = self.portfile("pseudo_wrappers.c")
+ else:
+ self.wrappers = None
+
+ if os.path.exists(self.portfile("portdefs.h")):
+ self.portdef_file = self.portfile("portdefs.h")
+ else:
+ self.portdef_file = None
+
+ if os.path.exists(self.portfile("wrapfuncs.in")):
+ self.funcs = process_wrapfuncs(port)
+ else:
+ self.funcs = {}
+
+ for source in sources:
+ source.emit('port', self)
+
+ if os.path.exists(self.portfile("preports")):
+ subport_proc = subprocess.Popen([self.portfile("preports"), self.name], stdout=subprocess.PIPE)
+ portlist = subport_proc.communicate()[0]
+ retcode = subport_proc.poll()
+ if retcode:
+ raise Exception("preports script failed for port %s" % self.name)
+
+ for preport in string.split(portlist):
+ next = Port(preport, sources)
+ self.preports.append(next)
+
+ if os.path.exists(self.portfile("subports")):
+ subport_proc = subprocess.Popen([self.portfile("subports"), self.name], stdout=subprocess.PIPE)
+ portlist = subport_proc.communicate()[0]
+ retcode = subport_proc.poll()
+ if retcode:
+ raise Exception("subports script failed for port %s" % self.name)
+
+ for subport in string.split(portlist):
+ next = Port(subport, sources)
+ self.subports.append(next)
+
+ def functions(self):
+ mergedfuncs = {}
+ for pre in self.preports:
+ prefuncs = pre.functions()
+ for name in prefuncs.keys():
+ if name in mergedfuncs:
+ print "Warning: %s from %s overriding %s" % (name, pre.name, mergedfuncs[name].port)
+ mergedfuncs[name] = prefuncs[name]
+ for name in self.funcs.keys():
+ if name in mergedfuncs:
+ print "Warning: %s from %s overriding %s" % (name, self.name, mergedfuncs[name].port)
+ mergedfuncs[name] = self.funcs[name]
+ for sub in self.subports:
+ subfuncs = sub.functions()
+ for name in subfuncs.keys():
+ if name in mergedfuncs:
+ print "Warning: %s from %s overriding %s" % (name, sub.name, mergedfuncs[name].port)
+ mergedfuncs[name] = subfuncs[name]
+ return mergedfuncs
+
+ def define(self):
+ return '#define PSEUDO_PORT_%s 1' % string.upper(self.name).replace('/', '_')
+
+ def portdefs(self):
+ if self.portdef_file:
+ return '#include "%s"' % self.portdef_file
+ else:
+ return '/* no portdefs for %s */' % self.name
+
+ def include(self):
+ if self.wrappers:
+ return '#include "%s"' % self.wrappers
+ else:
+ return '/* no #include for %s */' % self.name
+
+ def portfile(self, name):
+ return "ports/%s/%s" % (self.name, name)
+
+ def __getitem__(self, key):
+ """Make this object look like a dict for Templates to use"""
+ try:
+ attr = getattr(self, key)
+ except AttributeError:
+ return None
+
+ if callable(attr):
+ return attr()
+ else:
+ return attr
+
+
+def process_wrapfuncs(port):
+ """Process a wrapfuncs.in file, generating a list of prototypes."""
+ filename = "ports/%s/wrapfuncs.in" % port
+ funcs = {}
+ directory = os.path.dirname(filename)
+ sys.stdout.write("%s: " % filename)
+ funclist = open(filename)
+ for line in funclist:
+ line = line.rstrip()
+ if line.startswith('#') or not line:
+ continue
+ try:
+ func = Function(port, line)
+ func.directory = directory
+ funcs[func.name] = func
+ sys.stdout.write(".")
+ except Exception, e:
+ print "Parsing failed:", e
+ exit(1)
+ funclist.close()
+ print ""
+ return funcs
+
def main():
"""Read in function definitions, write out files based on templates."""
funcs = []
@@ -377,30 +547,24 @@ def main():
print "Invalid or malformed template %s. Aborting." % path
exit(1)
- for filename in sys.argv[1:]:
- # parse the list of functions
- sys.stdout.write("%s: " % filename)
- funclist = open(filename)
- for line in funclist:
- line = line.rstrip()
- if line.startswith('#') or not line:
- continue
- try:
- func = Function(line)
- funcs.append(func)
- sys.stdout.write(".")
- except Exception, e:
- print "Parsing failed:", e
- exit(1)
- funclist.close()
- print ""
+ try:
+ port = Port('common', sources)
+
+ except KeyError:
+ print "Unknown uname -s result: '%s'." % uname_s
+ print "Known system types are:"
+ print "%-20s %-10s %s" % ("uname -s", "port name", "description")
+ for key in host_ports:
+ print "%-20s %-10s %s" % (key, host_ports[key],
+ host_descrs[host_ports[key]])
# the per-function stuff
print "Writing functions...",
- for func in funcs:
+ all_funcs = port.functions()
+ for name in sorted(all_funcs.keys()):
# populate various tables and files with each function
for source in sources:
- source.emit('body', func)
+ source.emit('body', all_funcs[name])
print "done. Cleaning up."
for source in sources:
diff --git a/ports/common/guts/execl.c b/ports/common/guts/execl.c
new file mode 100644
index 0000000..ce908ed
--- /dev/null
+++ b/ports/common/guts/execl.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2011 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * int execl(const char *file, const char *arg, va_list ap)
+ * int rc = -1;
+ */
+
+ rc = real_execl(file, arg, ap);
+
+/* return rc;
+ * }
+ */
diff --git a/ports/common/guts/execle.c b/ports/common/guts/execle.c
new file mode 100644
index 0000000..68d8bba
--- /dev/null
+++ b/ports/common/guts/execle.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2011 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * int execle(const char *file, const char *arg, va_list ap)
+ * int rc = -1;
+ */
+
+ rc = real_execle(file, arg, ap);
+
+/* return rc;
+ * }
+ */
diff --git a/ports/common/guts/execlp.c b/ports/common/guts/execlp.c
new file mode 100644
index 0000000..d357986
--- /dev/null
+++ b/ports/common/guts/execlp.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2011 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * int execlp(const char *file, const char *arg, va_list ap)
+ * int rc = -1;
+ */
+
+ rc = real_execlp(file, arg, ap);
+
+/* return rc;
+ * }
+ */
diff --git a/guts/execv.c b/ports/common/guts/execv.c
index 15ad51e..15ad51e 100644
--- a/guts/execv.c
+++ b/ports/common/guts/execv.c
diff --git a/guts/execve.c b/ports/common/guts/execve.c
index a47b9a7..a47b9a7 100644
--- a/guts/execve.c
+++ b/ports/common/guts/execve.c
diff --git a/guts/execvp.c b/ports/common/guts/execvp.c
index 419f41b..419f41b 100644
--- a/guts/execvp.c
+++ b/ports/common/guts/execvp.c
diff --git a/guts/fork.c b/ports/common/guts/fork.c
index 76cac6f..76cac6f 100644
--- a/guts/fork.c
+++ b/ports/common/guts/fork.c
diff --git a/ports/common/pseudo_wrappers.c b/ports/common/pseudo_wrappers.c
new file mode 100644
index 0000000..2cfc400
--- /dev/null
+++ b/ports/common/pseudo_wrappers.c
@@ -0,0 +1,376 @@
+/* these aren't used, but the wrapper table isn't happy unless they
+ * exist
+ */
+static int
+wrap_execl(const char *file, const char *arg, va_list ap) {
+ (void) file;
+ (void) arg;
+ (void) ap;
+ return 0;
+}
+
+static int
+wrap_execle(const char *file, const char *arg, va_list ap) {
+ (void) file;
+ (void) arg;
+ (void) ap;
+ return 0;
+}
+
+static int
+wrap_execlp(const char *file, const char *arg, va_list ap) {
+ (void) file;
+ (void) arg;
+ (void) ap;
+ return 0;
+}
+
+static char **
+execl_to_v(va_list ap, const char *argv0, char *const **envp) {
+ size_t i = 0;
+ size_t alloc_size = 256;
+
+ char **argv = malloc((sizeof *argv) * alloc_size);
+
+ if (!argv) {
+ pseudo_debug(1, "execl failed: couldn't allocate memory for %lu arguments\n",
+ (unsigned long) alloc_size);
+ return NULL;
+ }
+ argv[i++] = (char *) argv0;
+
+ while (argv[i-1]) {
+ argv[i++] = va_arg(ap, char *const);
+ if (i > alloc_size - 1) {
+ alloc_size = alloc_size + 256;
+ argv = realloc(argv, (sizeof *argv) * alloc_size);
+ if (!argv) {
+ pseudo_debug(1, "execl failed: couldn't allocate memory for %lu arguments\n",
+ (unsigned long) alloc_size);
+ return NULL;
+ }
+ }
+ }
+ if (envp) {
+ *envp = va_arg(ap, char **);
+ }
+ return argv;
+}
+
+/* The following wrappers require Special Handling */
+
+int
+execl(const char *file, const char *arg, ...) {
+ sigset_t saved;
+ va_list ap;
+ char **argv;
+
+ int rc = -1;
+
+ if (!pseudo_check_wrappers()) {
+ /* rc was initialized to the "failure" value */
+ pseudo_enosys("execl");
+ return rc;
+ }
+
+ va_start(ap, arg);
+ argv = execl_to_v(ap, arg, 0);
+ va_end(ap);
+ if (!argv) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ pseudo_debug(4, "called: execl\n");
+ pseudo_sigblock(&saved);
+ if (pseudo_getlock()) {
+ errno = EBUSY;
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ return -1;
+ }
+
+ int save_errno;
+
+ /* exec*() use this to restore the sig mask */
+ pseudo_saved_sigmask = saved;
+ rc = wrap_execv(file, argv);
+
+ save_errno = errno;
+ pseudo_droplock();
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ pseudo_debug(4, "completed: execl\n");
+ errno = save_errno;
+ free(argv);
+ return rc;
+}
+
+int
+execlp(const char *file, const char *arg, ...) {
+ sigset_t saved;
+ va_list ap;
+ char **argv;
+
+ int rc = -1;
+
+ if (!pseudo_check_wrappers()) {
+ /* rc was initialized to the "failure" value */
+ pseudo_enosys("execlp");
+ return rc;
+ }
+
+ va_start(ap, arg);
+ argv = execl_to_v(ap, arg, 0);
+ va_end(ap);
+ if (!argv) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ pseudo_debug(4, "called: execlp\n");
+ pseudo_sigblock(&saved);
+ if (pseudo_getlock()) {
+ errno = EBUSY;
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ return -1;
+ }
+
+ int save_errno;
+
+ /* exec*() use this to restore the sig mask */
+ pseudo_saved_sigmask = saved;
+ rc = wrap_execvp(file, argv);
+
+ save_errno = errno;
+ pseudo_droplock();
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ pseudo_debug(4, "completed: execlp\n");
+ errno = save_errno;
+ free(argv);
+ return rc;
+}
+
+int
+execle(const char *file, const char *arg, ...) {
+ sigset_t saved;
+ va_list ap;
+ char **argv;
+ char **envp;
+
+ int rc = -1;
+
+ if (!pseudo_check_wrappers()) {
+ /* rc was initialized to the "failure" value */
+ pseudo_enosys("execle");
+ return rc;
+ }
+
+ va_start(ap, arg);
+ argv = execl_to_v(ap, arg, (char *const **)&envp);
+ va_end(ap);
+ if (!argv) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ pseudo_debug(4, "called: execle\n");
+ pseudo_sigblock(&saved);
+ if (pseudo_getlock()) {
+ errno = EBUSY;
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ return -1;
+ }
+
+ int save_errno;
+
+ /* exec*() use this to restore the sig mask */
+ pseudo_saved_sigmask = saved;
+ rc = wrap_execve(file, argv, envp);
+
+ save_errno = errno;
+ pseudo_droplock();
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ pseudo_debug(4, "completed: execle\n");
+ errno = save_errno;
+ free(argv);
+ return rc;
+}
+
+int
+execv(const char *file, char *const *argv) {
+ sigset_t saved;
+
+ int rc = -1;
+
+ if (!pseudo_check_wrappers() || !real_execv) {
+ /* rc was initialized to the "failure" value */
+ pseudo_enosys("execv");
+ return rc;
+ }
+
+ pseudo_debug(4, "called: execv\n");
+ pseudo_sigblock(&saved);
+ if (pseudo_getlock()) {
+ errno = EBUSY;
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ return -1;
+ }
+
+ int save_errno;
+
+ /* exec*() use this to restore the sig mask */
+ pseudo_saved_sigmask = saved;
+ rc = wrap_execv(file, argv);
+
+ save_errno = errno;
+ pseudo_droplock();
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ pseudo_debug(4, "completed: execv\n");
+ errno = save_errno;
+ return rc;
+}
+
+int
+execve(const char *file, char *const *argv, char *const *envp) {
+ sigset_t saved;
+
+ int rc = -1;
+
+ if (!pseudo_check_wrappers() || !real_execve) {
+ /* rc was initialized to the "failure" value */
+ pseudo_enosys("execve");
+ return rc;
+ }
+
+ pseudo_debug(4, "called: execve\n");
+ pseudo_sigblock(&saved);
+ if (pseudo_getlock()) {
+ errno = EBUSY;
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ return -1;
+ }
+
+ int save_errno;
+
+ /* exec*() use this to restore the sig mask */
+ pseudo_saved_sigmask = saved;
+ rc = wrap_execve(file, argv, envp);
+
+ save_errno = errno;
+ pseudo_droplock();
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ pseudo_debug(4, "completed: execve\n");
+ errno = save_errno;
+ return rc;
+}
+
+int
+execvp(const char *file, char *const *argv) {
+ sigset_t saved;
+
+ int rc = -1;
+
+ if (!pseudo_check_wrappers() || !real_execvp) {
+ /* rc was initialized to the "failure" value */
+ pseudo_enosys("execvp");
+ return rc;
+ }
+
+ pseudo_debug(4, "called: execvp\n");
+ pseudo_sigblock(&saved);
+ if (pseudo_getlock()) {
+ errno = EBUSY;
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ return -1;
+ }
+
+ int save_errno;
+
+ /* exec*() use this to restore the sig mask */
+ pseudo_saved_sigmask = saved;
+ rc = wrap_execvp(file, argv);
+
+ save_errno = errno;
+ pseudo_droplock();
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ pseudo_debug(4, "completed: execvp\n");
+ errno = save_errno;
+ return rc;
+}
+
+int
+fork(void) {
+ sigset_t saved;
+
+ int rc = -1;
+
+ if (!pseudo_check_wrappers() || !real_fork) {
+ /* rc was initialized to the "failure" value */
+ pseudo_enosys("fork");
+ return rc;
+ }
+
+ pseudo_debug(4, "called: fork\n");
+ pseudo_sigblock(&saved);
+ if (pseudo_getlock()) {
+ errno = EBUSY;
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ return -1;
+ }
+
+ int save_errno;
+
+ rc = wrap_fork();
+
+ save_errno = errno;
+
+ pseudo_droplock();
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ pseudo_debug(4, "completed: fork\n");
+ errno = save_errno;
+ return rc;
+}
+
+int
+vfork(void) {
+ /* we don't provide support for the distinct semantics
+ * of vfork()
+ */
+ return fork();
+}
+
+static int
+wrap_execv(const char *file, char *const *argv) {
+ int rc = -1;
+
+#include "guts/execv.c"
+
+ return rc;
+}
+
+static int
+wrap_execve(const char *file, char *const *argv, char *const *envp) {
+ int rc = -1;
+
+#include "guts/execve.c"
+
+ return rc;
+}
+
+static int
+wrap_execvp(const char *file, char *const *argv) {
+ int rc = -1;
+
+#include "guts/execvp.c"
+
+ return rc;
+}
+
+static int
+wrap_fork(void) {
+ int rc = -1;
+
+#include "guts/fork.c"
+
+ return rc;
+}
+
diff --git a/ports/common/subports b/ports/common/subports
new file mode 100644
index 0000000..e2aac56
--- /dev/null
+++ b/ports/common/subports
@@ -0,0 +1,8 @@
+#!/bin/sh
+case $(uname -s) in
+Linux) echo "linux";;
+Darwin) echo "darwin";;
+*) echo >&2 "Unknown result from uname -s: %(uname -s). Aborting."
+ exit 1
+ ;;
+esac
diff --git a/ports/common/wrapfuncs.in b/ports/common/wrapfuncs.in
new file mode 100644
index 0000000..17440f9
--- /dev/null
+++ b/ports/common/wrapfuncs.in
@@ -0,0 +1,7 @@
+int execlp(const char *file, const char *arg, ...); /* hand_wrapped=1 */
+int execl(const char *file, const char *arg, ...); /* hand_wrapped=1 */
+int execle(const char *file, const char *arg, ...); /* hand_wrapped=1 */
+int execv(const char *file, char *const *argv); /* hand_wrapped=1 */
+int execve(const char *file, char *const *argv, char *const *envp); /* hand_wrapped=1 */
+int execvp(const char *file, char *const *argv); /* hand_wrapped=1 */
+int fork(void); /* hand_wrapped=1 */
diff --git a/ports/darwin/guts/COPYRIGHT b/ports/darwin/guts/COPYRIGHT
new file mode 100644
index 0000000..c96e1b1
--- /dev/null
+++ b/ports/darwin/guts/COPYRIGHT
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2008-2010 Wind River Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the Lesser GNU General Public License version 2.1 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the Lesser GNU General Public License for more details.
+ *
+ * You should have received a copy of the Lesser GNU General Public License
+ * version 2.1 along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
diff --git a/ports/darwin/guts/fcntl.c b/ports/darwin/guts/fcntl.c
new file mode 100644
index 0000000..ef42b33
--- /dev/null
+++ b/ports/darwin/guts/fcntl.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2011 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * int fcntl(int fd, int cmd, ... { struct flock *lock })
+ * int rc = -1;
+ */
+ int save_errno;
+ long long flag = 0;
+ void *ptr = 0;
+ off_t off = 0;
+
+ va_start(ap, cmd);
+ flag = va_arg(ap, long long);
+ va_end(ap);
+ rc = real_fcntl(fd, cmd, flag);
+
+ switch (cmd) {
+ case F_DUPFD:
+#ifdef F_DUPFD_CLOEXEC
+ /* it doesn't exist now, but if I take this out they'll add it
+ * just to mess with me.
+ */
+ case F_DUPFD_CLOEXEC:
+#endif
+ /* actually do something */
+ save_errno = errno;
+ if (rc != -1) {
+ pseudo_debug(2, "fcntl_dup: %d->%d\n", fd, rc);
+ pseudo_client_op(OP_DUP, 0, fd, rc, 0, 0);
+ }
+ errno = save_errno;
+ break;
+ default:
+ /* nothing to do, we hope */
+ break;
+ }
+
+ save_errno = errno;
+ pseudo_debug(3, "fcntl(fd %d, cmd %d, %llx) => %d (%s)\n",
+ fd, cmd, flag, rc, strerror(errno));
+ errno = save_errno;
+
+/* return rc;
+ * }
+ */
diff --git a/ports/darwin/guts/fgetgrent_r.c b/ports/darwin/guts/fgetgrent_r.c
new file mode 100644
index 0000000..e760cdd
--- /dev/null
+++ b/ports/darwin/guts/fgetgrent_r.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2011 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * int fgetgrent_r(FILE *fp, struct group*gbuf, char *buf, size_t buflen, struct group **gbufp)
+ * int rc = -1;
+ */
+
+ rc = real_fgetgrent_r(fp, gbuf, buf, buflen, gbufp);
+
+/* return rc;
+ * }
+ */
diff --git a/ports/darwin/guts/fgetpwent_r.c b/ports/darwin/guts/fgetpwent_r.c
new file mode 100644
index 0000000..cfea5b8
--- /dev/null
+++ b/ports/darwin/guts/fgetpwent_r.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2011 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * int fgetpwent_r(FILE *fp, struct passwd *pbuf, char *buf, size_t buflen, struct passwd **pbufp)
+ * int rc = -1;
+ */
+
+ rc = real_fgetpwent_r(fp, pbuf, buf, buflen, pbufp);
+
+/* return rc;
+ * }
+ */
diff --git a/ports/darwin/guts/fgetxattr.c b/ports/darwin/guts/fgetxattr.c
new file mode 100644
index 0000000..1cd8904
--- /dev/null
+++ b/ports/darwin/guts/fgetxattr.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2011 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * ssize_t fgetxattr(int filedes, const char *name, void *value, size_t size, u_int32_t position, int options)
+ * ssize_t rc = -1;
+ */
+
+ rc = real_fgetxattr(filedes, name, value, size, position, options);
+
+/* return rc;
+ * }
+ */
diff --git a/ports/darwin/guts/flistxattr.c b/ports/darwin/guts/flistxattr.c
new file mode 100644
index 0000000..7575f28
--- /dev/null
+++ b/ports/darwin/guts/flistxattr.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2011 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * ssize_t flistxattr(int filedes, char *list, size_t size, int options)
+ * ssize_t rc = -1;
+ */
+
+ rc = real_flistxattr(filedes, list, size, options);
+
+/* return rc;
+ * }
+ */
diff --git a/ports/darwin/guts/fsetxattr.c b/ports/darwin/guts/fsetxattr.c
new file mode 100644
index 0000000..541569a
--- /dev/null
+++ b/ports/darwin/guts/fsetxattr.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2011 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * int fsetxattr(int filedes, const char *name, const void *value, size_t size, u_int32_t position, int options)
+ * int rc = -1;
+ */
+
+ rc = real_fsetxattr(filedes, name, value, size, position, options);
+
+/* return rc;
+ * }
+ */
diff --git a/ports/darwin/guts/fstat.c b/ports/darwin/guts/fstat.c
new file mode 100644
index 0000000..7695147
--- /dev/null
+++ b/ports/darwin/guts/fstat.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2011 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * int fstat(int fd, struct stat *buf)
+ * int rc = -1;
+ */
+ pseudo_msg_t *msg;
+
+ rc = real_fstat(fd, buf);
+
+ if (rc == -1) {
+ return rc;
+ }
+
+ /* query database
+ * note that symlink canonicalizing is now automatic, so we
+ * don't need to check for a symlink on this end
+ */
+ msg = pseudo_client_op(OP_FSTAT, 0, fd, -1, 0, buf);
+ if (msg && msg->result == RESULT_SUCCEED) {
+ pseudo_stat_msg(buf, msg);
+ }
+
+/* return rc;
+ * }
+ */
diff --git a/ports/darwin/guts/getgrent_r.c b/ports/darwin/guts/getgrent_r.c
new file mode 100644
index 0000000..9d5db5a
--- /dev/null
+++ b/ports/darwin/guts/getgrent_r.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2011 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * int getgrent_r(struct group *gbuf, char *buf, size_t buflen, struct group **gbufp)
+ * int rc = -1;
+ */
+
+ rc = real_getgrent_r(gbuf, buf, buflen, gbufp);
+
+/* return rc;
+ * }
+ */
diff --git a/ports/darwin/guts/getgrouplist.c b/ports/darwin/guts/getgrouplist.c
new file mode 100644
index 0000000..85fccc9
--- /dev/null
+++ b/ports/darwin/guts/getgrouplist.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2010 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * static int
+ * wrap_getgrouplist(const char *name, int basegid, int *groups, int *ngroups) {
+ * int rc = -1;
+ */
+
+ int found = 0;
+ int found_group = 0;
+ char buf[PSEUDO_PWD_MAX];
+ struct group grp, *gbuf = &grp;
+
+ setgrent();
+ while ((rc = wrap_getgrent_r(gbuf, buf, PSEUDO_PWD_MAX, &gbuf)) == 0) {
+ int i = 0;
+ for (i = 0; gbuf->gr_mem[i]; ++i) {
+ if (!strcmp(gbuf->gr_mem[i], name)) {
+ if (found < *ngroups)
+ groups[found] = gbuf->gr_gid;
+ ++found;
+ if ((int) gbuf->gr_gid == basegid)
+ found_group = 1;
+ }
+ }
+ }
+ endgrent();
+ if (!found_group) {
+ if (found < *ngroups)
+ groups[found] = basegid;
+ ++found;
+ }
+ if (found >= *ngroups)
+ rc = -1;
+ else
+ rc = found;
+ *ngroups = found;
+
+/* return rc;
+ * }
+ */
diff --git a/ports/darwin/guts/getgroups.c b/ports/darwin/guts/getgroups.c
new file mode 100644
index 0000000..3cbeb76
--- /dev/null
+++ b/ports/darwin/guts/getgroups.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2010 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * static int
+ * wrap_getgroups(int size, gid_t *list) {
+ * int rc = -1;
+ */
+ struct passwd *p = wrap_getpwuid(wrap_getuid());
+ int oldsize = size;
+
+ if (p) {
+ rc = wrap_getgrouplist(p->pw_name, wrap_getgid(), (int *) list, &size);
+ if (oldsize == 0 || size <= oldsize)
+ rc = size;
+ } else {
+ errno = ENOENT;
+ }
+
+/* return rc;
+ * }
+ */
diff --git a/ports/darwin/guts/getpwent_r.c b/ports/darwin/guts/getpwent_r.c
new file mode 100644
index 0000000..3de41b9
--- /dev/null
+++ b/ports/darwin/guts/getpwent_r.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2011 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * int getpwent_r(struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp)
+ * int rc = -1;
+ */
+
+ rc = real_getpwent_r(pwbuf, buf, buflen, pwbufp);
+
+/* return rc;
+ * }
+ */
diff --git a/ports/darwin/guts/getxattr.c b/ports/darwin/guts/getxattr.c
new file mode 100644
index 0000000..16f0993
--- /dev/null
+++ b/ports/darwin/guts/getxattr.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2011 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * ssize_t getxattr(const char *pathname, const char *name, void *value, size_t size, u_int32_t position, int options)
+ * ssize_t rc = -1;
+ */
+
+ rc = real_getxattr(pathname, name, value, size, position, options);
+
+/* return rc;
+ * }
+ */
diff --git a/ports/darwin/guts/listxattr.c b/ports/darwin/guts/listxattr.c
new file mode 100644
index 0000000..0bba451
--- /dev/null
+++ b/ports/darwin/guts/listxattr.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2011 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * ssize_t listxattr(const char *pathname, char *list, size_t size, int options)
+ * ssize_t rc = -1;
+ */
+
+ rc = real_listxattr(pathname, list, size, options);
+
+/* return rc;
+ * }
+ */
diff --git a/ports/darwin/guts/lstat.c b/ports/darwin/guts/lstat.c
new file mode 100644
index 0000000..01e0f30
--- /dev/null
+++ b/ports/darwin/guts/lstat.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2011 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * int lstat(const char *path, struct stat *buf)
+ * int rc = -1;
+ */
+
+ pseudo_msg_t *msg;
+
+ rc = real_lstat(path, buf);
+ if (rc == -1) {
+ return rc;
+ }
+
+ /* query database
+ * note that symlink canonicalizing is now automatic, so we
+ * don't need to check for a symlink on this end
+ */
+ msg = pseudo_client_op(OP_STAT, 0, -1, -1, path, buf);
+ if (msg && msg->result == RESULT_SUCCEED) {
+ pseudo_stat_msg(buf, msg);
+ }
+
+/* return rc;
+ * }
+ */
diff --git a/ports/darwin/guts/open.c b/ports/darwin/guts/open.c
new file mode 100644
index 0000000..64cb6ad
--- /dev/null
+++ b/ports/darwin/guts/open.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2011 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * int open(const char *path, int flags, ... { int mode })
+ * int rc = -1;
+ */
+
+ struct stat buf;
+ int existed = 1;
+ int save_errno;
+
+ /* if a creation has been requested, check whether file exists */
+ if (flags & O_CREAT) {
+ save_errno = errno;
+ rc = real_stat(path, &buf);
+ existed = (rc != -1);
+ if (!existed)
+ pseudo_debug(2, "open_creat: %s -> 0%o\n", path, mode);
+ errno = save_errno;
+ }
+
+ /* because we are not actually root, secretly mask in 0700 to the
+ * underlying mode
+ */
+ rc = real_open(path, flags, PSEUDO_FS_MODE(mode));
+ save_errno = errno;
+
+ if (rc != -1) {
+ int stat_rc;
+ stat_rc = real_stat(path, &buf);
+
+ if (stat_rc != -1) {
+ buf.st_mode = PSEUDO_DB_MODE(buf.st_mode, mode);
+ if (!existed) {
+ pseudo_client_op(OP_CREAT, 0, -1, -1, path, &buf);
+ }
+ pseudo_client_op(OP_OPEN, PSEUDO_ACCESS(flags), rc, -1, path, &buf);
+ } else {
+ pseudo_debug(1, "open (fd %d, path %s, flags %d) succeeded, but stat failed (%s).\n",
+ rc, path, flags, strerror(errno));
+ pseudo_client_op(OP_OPEN, PSEUDO_ACCESS(flags), rc, -1, path, 0);
+ }
+ errno = save_errno;
+ }
+
+/* return rc;
+ * }
+ */
diff --git a/ports/darwin/guts/scandir.c b/ports/darwin/guts/scandir.c
new file mode 100644
index 0000000..6492b1b
--- /dev/null
+++ b/ports/darwin/guts/scandir.c
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2010 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * static int
+ * wrap_scandir(const char *path, struct dirent ***namelist, int (*filter)(struct dirent *), int (*compar)(const void *, const void *)) {
+ * int rc = -1;
+ */
+
+ rc = real_scandir(path, namelist, filter, compar);
+
+/* return rc;
+ * }
+ */
diff --git a/ports/darwin/guts/setxattr.c b/ports/darwin/guts/setxattr.c
new file mode 100644
index 0000000..3c8fd3d
--- /dev/null
+++ b/ports/darwin/guts/setxattr.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2011 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * int setxattr(const char *pathname, const char *name, const void *value, size_t size, u_int32_t position, int options)
+ * int rc = -1;
+ */
+
+ rc = real_setxattr(pathname, name, value, size, position, options);
+
+/* return rc;
+ * }
+ */
diff --git a/ports/darwin/guts/stat.c b/ports/darwin/guts/stat.c
new file mode 100644
index 0000000..1e1cf67
--- /dev/null
+++ b/ports/darwin/guts/stat.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2011 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * int stat(const char *path, struct stat *buf)
+ * int rc = -1;
+ */
+
+ pseudo_msg_t *msg;
+ int save_errno;
+
+ rc = real_stat(path, buf);
+ if (rc == -1) {
+ return rc;
+ }
+ save_errno = errno;
+
+ /* query database
+ * note that symlink canonicalizing is now automatic, so we
+ * don't need to check for a symlink on this end
+ */
+ msg = pseudo_client_op(OP_STAT, 0, -1, AT_FDCWD, path, buf);
+ if (msg) {
+ pseudo_stat_msg(buf, msg);
+ }
+
+ errno = save_errno;
+
+/* return rc;
+ * }
+ */
diff --git a/ports/darwin/portdefs.h b/ports/darwin/portdefs.h
new file mode 100644
index 0000000..f27e28d
--- /dev/null
+++ b/ports/darwin/portdefs.h
@@ -0,0 +1,10 @@
+#define PRELINK_LIBRARIES "DYLD_INSERT_LIBRARIES"
+#define PRELINK_PATH "DYLD_LIBRARY_PATH"
+#define PSEUDO_STATBUF_64 0
+#define PSEUDO_STATBUF struct stat
+#define PSEUDO_LINKPATH_SEPARATOR ":"
+/* hackery to allow sneaky things to be done with getgrent() */
+extern int pseudo_host_etc_passwd_fd;
+extern int pseudo_host_etc_group_fd;
+extern FILE *pseudo_host_etc_passwd_file;
+extern FILE *pseudo_host_etc_group_file;
diff --git a/ports/darwin/preports b/ports/darwin/preports
new file mode 100644
index 0000000..a996c69
--- /dev/null
+++ b/ports/darwin/preports
@@ -0,0 +1,2 @@
+#!/bin/sh
+echo "unix" "uids_generic"
diff --git a/ports/darwin/pseudo_wrappers.c b/ports/darwin/pseudo_wrappers.c
new file mode 100644
index 0000000..36d9172
--- /dev/null
+++ b/ports/darwin/pseudo_wrappers.c
@@ -0,0 +1,316 @@
+/*
+ * pseudo_wrappers.c, darwin pseudo wrappers
+ *
+ * Copyright (c) 2008-2011 Wind River Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the Lesser GNU General Public License version 2.1 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the Lesser GNU General Public License for more details.
+ *
+ * You should have received a copy of the Lesser GNU General Public License
+ * version 2.1 along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+/* there's no fgetgrent_r or fgetpwent_r in Darwin */
+int
+pseudo_getpwent_r(struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp) {
+ /* note that we don't wrap fgetpwent_r, since there's no path
+ * references in it.
+ */
+ if (!pseudo_pwd) {
+ errno = ENOENT;
+ return -1;
+ }
+ return fgetpwent_r(pseudo_pwd, pwbuf, buf, buflen, pwbufp);
+}
+
+int
+pseudo_getgrent_r(struct group *gbuf, char *buf, size_t buflen, struct group **gbufp) {
+ /* note that we don't wrap fgetgrent_r, since there's no path
+ * references in it.
+ */
+ if (!pseudo_grp) {
+ errno = ENOENT;
+ return -1;
+ }
+ return fgetgrent_r(pseudo_grp, gbuf, buf, buflen, gbufp);
+}
+
+#define PLENTY_LONG 2048
+/* the original uid/gid code for Linux was written in terms of the
+ * fget*ent_r() functions... which Darwin doesn't have. But wait! They're
+ * actually pretty easy to implement.
+ */
+int
+pseudo_fgetgrent_r(FILE *fp, struct group *gbuf, char *buf, size_t buflen, struct group **gbufp) {
+ char linebuf[PLENTY_LONG] = { 0 };
+ char *s, *t, *u;
+ size_t max_members;
+ char **members;
+ size_t member = 0;
+ long started_at = -1;
+ gid_t gid;
+ int error = ENOENT;
+ size_t len;
+
+ /* any early exit should set *gbufp to NULL */
+ if (gbufp)
+ *gbufp = NULL;
+
+ if (!gbuf || !fp || !buf)
+ goto error_out;
+
+ if (fp == pseudo_host_etc_group_file) {
+ struct group *g;
+ pseudo_antimagic();
+ g = getgrent();
+ pseudo_magic();
+ if (g) {
+ char *s = linebuf;
+ s += snprintf(linebuf, PLENTY_LONG,
+ "%s:%s:%ld:",
+ g->gr_name,
+ g->gr_passwd,
+ (long) g->gr_gid);
+ if (g->gr_mem) {
+ int i;
+ for (i = 0; g->gr_mem[i]; ++i) {
+ s += snprintf(s,
+ PLENTY_LONG - (s - linebuf),
+ "%s,",
+ g->gr_mem[i]);
+ }
+ if (s[-1] == ',')
+ --s;
+ }
+ strcpy(s, "\n");
+ } else {
+ goto error_out;
+ }
+ } else {
+ started_at = ftell(fp);
+ if (started_at == -1) {
+ goto error_out;
+ }
+ s = fgets(linebuf, PLENTY_LONG, fp);
+ if (!s) {
+ goto error_out;
+ }
+ }
+ /* fgets will have stored a '\0' if there was no error; if there
+ * was an error, though, linebuf was initialized to all zeroes so
+ * the string is null-terminated anyway...
+ */
+ len = strlen(linebuf);
+ if (len > buflen) {
+ error = ERANGE;
+ goto error_out;
+ }
+ memcpy(buf, linebuf, len);
+ /* round up to 8, hope for the best? */
+ len = len + 8 + (((unsigned long long) (buf + len)) % 8);
+ members = (char **) (buf + len);
+ if (len >= buflen) {
+ error = ERANGE;
+ goto error_out;
+ }
+ /* this is how many pointers we have room for... */
+ max_members = (buflen - len) / sizeof(*members);
+
+ t = buf;
+ /* yes, I can assume that Darwin has strsep() */
+ s = strsep(&t, ":");
+ if (!s) {
+ goto error_out;
+ }
+ gbuf->gr_name = s;
+ s = strsep(&t, ":");
+ if (!s) {
+ goto error_out;
+ }
+ gbuf->gr_passwd = s;
+ s = strsep(&t, ":");
+ if (!s) {
+ goto error_out;
+ }
+ gid = (gid_t) strtol(s, &u, 10);
+ /* should be a null byte, otherwise we didn't get a valid number */
+ if (*u)
+ goto error_out;
+ gbuf->gr_gid = gid;
+
+ /* now, s points to a comma-separated list of members, which we
+ * want to stash pointers to in 'members'.
+ */
+ s = strsep(&t, ":");
+ t = s;
+ while ((s = strsep(&t, ",")) != NULL) {
+ if (*s) {
+ if (member + 1 > max_members) {
+ errno = ERANGE;
+ goto error_out;
+ }
+ members[member++] = s;
+ }
+ }
+ if (member + 1 > max_members) {
+ errno = ERANGE;
+ goto error_out;
+ }
+ members[member++] = NULL;
+ *gbufp = gbuf;
+ return 0;
+
+error_out:
+ if (started_at != -1)
+ fseek(fp, started_at, SEEK_SET);
+ return error;
+ return -1;
+}
+
+int
+pseudo_fgetpwent_r(FILE *fp, struct passwd *pbuf, char *buf, size_t buflen, struct passwd **pbufp) {
+ char linebuf[PLENTY_LONG] = { 0 };
+ char *s, *t, *u;
+ long started_at = -1;
+ __darwin_time_t timestamp;
+ uid_t uid;
+ gid_t gid;
+ int error = ENOENT;
+ size_t len;
+
+ /* any early exit should set *gbufp to NULL */
+ if (pbufp)
+ *pbufp = NULL;
+
+ if (!pbuf || !fp || !buf)
+ goto error_out;
+
+ if (fp == pseudo_host_etc_passwd_file) {
+ struct passwd *p;
+
+ pseudo_antimagic();
+ p = getpwent();
+ pseudo_magic();
+ if (p) {
+ snprintf(linebuf, PLENTY_LONG,
+ "%s:%s:%ld:%ld:%s:%ld:%ld:%s:%s:%s\n",
+ p->pw_name,
+ p->pw_passwd,
+ (long) p->pw_uid,
+ (long) p->pw_gid,
+ p->pw_class,
+ (long) p->pw_change,
+ (long) p->pw_expire,
+ p->pw_gecos,
+ p->pw_dir,
+ p->pw_shell);
+ } else {
+ goto error_out;
+ }
+ } else {
+ started_at = ftell(fp);
+ if (started_at == -1) {
+ goto error_out;
+ }
+ s = fgets(linebuf, PLENTY_LONG, fp);
+ if (!s) {
+ goto error_out;
+ }
+ }
+ /* fgets will have stored a '\0' if there was no error; if there
+ * was an error, though, linebuf was initialized to all zeroes so
+ * the string is null-terminated anyway...
+ */
+ len = strlen(linebuf);
+ if (len > buflen) {
+ error = ERANGE;
+ goto error_out;
+ }
+ if (linebuf[len - 1] == '\n') {
+ linebuf[len - 1] = '\0';
+ --len;
+ }
+ memcpy(buf, linebuf, len);
+
+ t = buf;
+ /* yes, I can assume that Darwin has strsep() */
+ s = strsep(&t, ":");
+ if (!s) {
+ goto error_out;
+ }
+ pbuf->pw_name = s;
+
+ s = strsep(&t, ":");
+ if (!s)
+ goto error_out;
+ pbuf->pw_passwd = s;
+
+ s = strsep(&t, ":");
+ if (!s)
+ goto error_out;
+ uid = (uid_t) strtol(s, &u, 10);
+ /* should be a null byte, otherwise we didn't get a valid number */
+ if (*u)
+ goto error_out;
+ pbuf->pw_uid = uid;
+
+ s = strsep(&t, ":");
+ if (!s)
+ goto error_out;
+ gid = (gid_t) strtol(s, &u, 10);
+ /* should be a null byte, otherwise we didn't get a valid number */
+ if (*u)
+ goto error_out;
+ pbuf->pw_gid = gid;
+
+ s = strsep(&t, ":");
+ if (!s)
+ goto error_out;
+ pbuf->pw_class = s;
+
+ s = strsep(&t, ":");
+ if (!s)
+ goto error_out;
+ timestamp = (__darwin_time_t) strtol(s, &u, 10);
+ /* should be a null byte, otherwise we didn't get a valid number */
+ if (*u)
+ goto error_out;
+ pbuf->pw_change = timestamp;
+
+ timestamp = (__darwin_time_t) strtol(s, &u, 10);
+ /* should be a null byte, otherwise we didn't get a valid number */
+ if (*u)
+ goto error_out;
+ pbuf->pw_expire = timestamp;
+
+ s = strsep(&t, ":");
+ if (!s)
+ goto error_out;
+ pbuf->pw_gecos = s;
+
+ s = strsep(&t, ":");
+ if (!s)
+ goto error_out;
+ pbuf->pw_dir = s;
+
+ s = strsep(&t, ":");
+ if (!s)
+ goto error_out;
+ pbuf->pw_shell = s;
+
+ *pbufp = pbuf;
+ return 0;
+
+error_out:
+ if (started_at != -1)
+ fseek(fp, started_at, SEEK_SET);
+ return error;
+ return -1;
+}
diff --git a/ports/darwin/subports b/ports/darwin/subports
new file mode 100644
index 0000000..57bdd6d
--- /dev/null
+++ b/ports/darwin/subports
@@ -0,0 +1,3 @@
+#!/bin/sh
+# no subports at this time
+exit 0
diff --git a/ports/darwin/wrapfuncs.in b/ports/darwin/wrapfuncs.in
new file mode 100644
index 0000000..39d9893
--- /dev/null
+++ b/ports/darwin/wrapfuncs.in
@@ -0,0 +1,25 @@
+# On Darwin, mode_t promotes to int, so you have to use int for va_arg
+int open(const char *path, int flags, ...{int mode}); /* flags=0 */
+int stat(const char *path, struct stat *buf); /* inode64=1 */
+int lstat(const char *path, struct stat *buf); /* flags=AT_SYMLINK_NOFOLLOW, inode64=1 */
+int fstat(int fd, struct stat *buf); /* inode64=1 */
+int fcntl(int fd, int cmd, ...{struct flock *lock});
+# just so we know the inums of symlinks
+# for emulation of passwd utilities
+int getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups);
+# we use "pathname" to avoid canonicalizing paths, because these functions are
+# unimplemented
+ssize_t getxattr(const char *pathname, const char *name, void *value, size_t size, u_int32_t position, int options);
+ssize_t fgetxattr(int filedes, const char *name, void *value, size_t size, u_int32_t position, int options);
+ssize_t listxattr(const char *pathname, char *list, size_t size, int options);
+ssize_t flistxattr(int filedes, char *list, size_t size, int options);
+int setxattr(const char *pathname, const char *name, const void *value, size_t size, u_int32_t position, int options);
+int fsetxattr(int filedes, const char *name, const void *value, size_t size, u_int32_t position, int options);
+# local color UIDs
+int getgrouplist(const char *name, int basegid, int *groups, int *ngroups);
+int scandir(const char *path, struct dirent ***namelist, int (*filter)(struct dirent *), int (*compar)());
+int getgroups(int size, gid_t *list);
+int fgetgrent_r(FILE *fp, struct group *gbuf, char *buf, size_t buflen, struct group **gbufp); /* real_func=pseudo_fgetgrent_r */
+int fgetpwent_r(FILE *fp, struct passwd *pbuf, char *buf, size_t buflen, struct passwd **pbufp); /* real_func=pseudo_fgetpwent_r */
+int getpwent_r(struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp); /* real_func=pseudo_getpwent_r */
+int getgrent_r(struct group *gbuf, char *buf, size_t buflen, struct group **gbufp); /* real_func=pseudo_getgrent_r */
diff --git a/ports/linux/guts/COPYRIGHT b/ports/linux/guts/COPYRIGHT
new file mode 100644
index 0000000..c96e1b1
--- /dev/null
+++ b/ports/linux/guts/COPYRIGHT
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2008-2010 Wind River Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the Lesser GNU General Public License version 2.1 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the Lesser GNU General Public License for more details.
+ *
+ * You should have received a copy of the Lesser GNU General Public License
+ * version 2.1 along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
diff --git a/guts/__fxstat.c b/ports/linux/guts/__fxstat.c
index db9716b..db9716b 100644
--- a/guts/__fxstat.c
+++ b/ports/linux/guts/__fxstat.c
diff --git a/guts/__fxstat64.c b/ports/linux/guts/__fxstat64.c
index 615926e..92c8219 100644
--- a/guts/__fxstat64.c
+++ b/ports/linux/guts/__fxstat64.c
@@ -20,9 +20,8 @@
return rc;
}
msg = pseudo_client_op(OP_FSTAT, 0, fd, -1, 0, buf);
- if (msg) {
- if (msg->result == RESULT_SUCCEED)
- pseudo_stat_msg(buf, msg);
+ if (msg && msg->result == RESULT_SUCCEED) {
+ pseudo_stat_msg(buf, msg);
}
errno = save_errno;
diff --git a/guts/__fxstatat.c b/ports/linux/guts/__fxstatat.c
index 94c5ff6..94c5ff6 100644
--- a/guts/__fxstatat.c
+++ b/ports/linux/guts/__fxstatat.c
diff --git a/guts/__fxstatat64.c b/ports/linux/guts/__fxstatat64.c
index f8a9298..f8a9298 100644
--- a/guts/__fxstatat64.c
+++ b/ports/linux/guts/__fxstatat64.c
diff --git a/guts/__lxstat.c b/ports/linux/guts/__lxstat.c
index 32b0301..32b0301 100644
--- a/guts/__lxstat.c
+++ b/ports/linux/guts/__lxstat.c
diff --git a/guts/__lxstat64.c b/ports/linux/guts/__lxstat64.c
index ac1f782..ac1f782 100644
--- a/guts/__lxstat64.c
+++ b/ports/linux/guts/__lxstat64.c
diff --git a/guts/__openat64_2.c b/ports/linux/guts/__openat64_2.c
index 8772115..8772115 100644
--- a/guts/__openat64_2.c
+++ b/ports/linux/guts/__openat64_2.c
diff --git a/guts/__openat_2.c b/ports/linux/guts/__openat_2.c
index 33ed620..33ed620 100644
--- a/guts/__openat_2.c
+++ b/ports/linux/guts/__openat_2.c
diff --git a/guts/__xmknod.c b/ports/linux/guts/__xmknod.c
index fa31b66..fa31b66 100644
--- a/guts/__xmknod.c
+++ b/ports/linux/guts/__xmknod.c
diff --git a/guts/__xmknodat.c b/ports/linux/guts/__xmknodat.c
index 7b4fc4b..49b2f8f 100644
--- a/guts/__xmknodat.c
+++ b/ports/linux/guts/__xmknodat.c
@@ -51,13 +51,11 @@
(mode & ~07777);
buf.st_rdev = *dev;
msg = pseudo_client_op(OP_MKNOD, 0, -1, dirfd, path, &buf);
- if (!msg) {
- errno = ENOSYS;
- rc = -1;
- } else if (msg->result != RESULT_SUCCEED) {
+ if (msg && msg->result != RESULT_SUCCEED) {
errno = EPERM;
rc = -1;
} else {
+ /* just pretend we worked */
rc = 0;
}
if (rc == -1) {
diff --git a/guts/__xstat.c b/ports/linux/guts/__xstat.c
index ec10abb..ec10abb 100644
--- a/guts/__xstat.c
+++ b/ports/linux/guts/__xstat.c
diff --git a/guts/__xstat64.c b/ports/linux/guts/__xstat64.c
index ed62e7e..ed62e7e 100644
--- a/guts/__xstat64.c
+++ b/ports/linux/guts/__xstat64.c
diff --git a/guts/canonicalize_file_name.c b/ports/linux/guts/canonicalize_file_name.c
index 9a04f33..9a04f33 100644
--- a/guts/canonicalize_file_name.c
+++ b/ports/linux/guts/canonicalize_file_name.c
diff --git a/guts/creat64.c b/ports/linux/guts/creat64.c
index 2d2fc27..2d2fc27 100644
--- a/guts/creat64.c
+++ b/ports/linux/guts/creat64.c
diff --git a/guts/eaccess.c b/ports/linux/guts/eaccess.c
index e2119cc..e2119cc 100644
--- a/guts/eaccess.c
+++ b/ports/linux/guts/eaccess.c
diff --git a/guts/euidaccess.c b/ports/linux/guts/euidaccess.c
index 85433a8..85433a8 100644
--- a/guts/euidaccess.c
+++ b/ports/linux/guts/euidaccess.c
diff --git a/guts/fcntl.c b/ports/linux/guts/fcntl.c
index 2e3e96d..2e3e96d 100644
--- a/guts/fcntl.c
+++ b/ports/linux/guts/fcntl.c
diff --git a/guts/fgetxattr.c b/ports/linux/guts/fgetxattr.c
index a9bd8b0..9d33643 100644
--- a/guts/fgetxattr.c
+++ b/ports/linux/guts/fgetxattr.c
@@ -6,6 +6,11 @@
* ssize_t rc = -1;
*/
+ /* suppress warnings */
+ (void) filedes;
+ (void) name;
+ (void) value;
+ (void) size;
errno = ENOTSUP;
/* return rc;
diff --git a/guts/flistxattr.c b/ports/linux/guts/flistxattr.c
index 62b4173..77db021 100644
--- a/guts/flistxattr.c
+++ b/ports/linux/guts/flistxattr.c
@@ -6,6 +6,10 @@
* ssize_t rc = -1;
*/
+ /* suppress warnings */
+ (void) filedes;
+ (void) list;
+ (void) size;
errno = ENOTSUP;
/* return rc;
diff --git a/guts/fopen64.c b/ports/linux/guts/fopen64.c
index b2724de..b2724de 100644
--- a/guts/fopen64.c
+++ b/ports/linux/guts/fopen64.c
diff --git a/guts/fremovexattr.c b/ports/linux/guts/fremovexattr.c
index fe3681e..529a9de 100644
--- a/guts/fremovexattr.c
+++ b/ports/linux/guts/fremovexattr.c
@@ -6,6 +6,9 @@
* int rc = -1;
*/
+ /* suppress warnings */
+ (void) filedes;
+ (void) name;
errno = ENOTSUP;
/* return rc;
diff --git a/guts/freopen64.c b/ports/linux/guts/freopen64.c
index b8e576b..b8e576b 100644
--- a/guts/freopen64.c
+++ b/ports/linux/guts/freopen64.c
diff --git a/guts/fsetxattr.c b/ports/linux/guts/fsetxattr.c
index a891ffb..3c56ddd 100644
--- a/guts/fsetxattr.c
+++ b/ports/linux/guts/fsetxattr.c
@@ -6,6 +6,12 @@
* int rc = -1;
*/
+ /* suppress warnings */
+ (void) filedes;
+ (void) name;
+ (void) value;
+ (void) size;
+ (void) flags;
errno = ENOTSUP;
/* return rc;
diff --git a/ports/linux/guts/fstat.c b/ports/linux/guts/fstat.c
new file mode 100644
index 0000000..2cf2787
--- /dev/null
+++ b/ports/linux/guts/fstat.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2011 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * int fstat(int fd, struct stat *buf)
+ * int rc = -1;
+ */
+
+ rc = wrap___fxstat(_STAT_VER, fd, buf);
+
+/* return rc;
+ * }
+ */
diff --git a/guts/ftw64.c b/ports/linux/guts/ftw64.c
index a375fbf..a375fbf 100644
--- a/guts/ftw64.c
+++ b/ports/linux/guts/ftw64.c
diff --git a/guts/get_current_dir_name.c b/ports/linux/guts/get_current_dir_name.c
index e07a6ee..e07a6ee 100644
--- a/guts/get_current_dir_name.c
+++ b/ports/linux/guts/get_current_dir_name.c
diff --git a/guts/getgrent_r.c b/ports/linux/guts/getgrent_r.c
index b02466a..b04373d 100644
--- a/guts/getgrent_r.c
+++ b/ports/linux/guts/getgrent_r.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Wind River Systems; see
+ * Copyright (c) 2010-2011 Wind River Systems; see
* guts/COPYRIGHT for information.
*
* static int
@@ -15,13 +15,6 @@
return -1;
}
rc = fgetgrent_r(pseudo_grp, gbuf, buf, buflen, gbufp);
- if (rc == 0 && *gbufp) {
- if (*gbufp == gbuf) {
- pseudo_debug(3, "found group: %d/%s\n", gbuf->gr_gid, gbuf->gr_name);
- } else {
- pseudo_debug(1, "found group (%d), but it's wrong?", gbuf->gr_gid);
- }
- }
/* return rc;
* }
diff --git a/guts/getgrouplist.c b/ports/linux/guts/getgrouplist.c
index 3489ec9..3489ec9 100644
--- a/guts/getgrouplist.c
+++ b/ports/linux/guts/getgrouplist.c
diff --git a/guts/getgroups.c b/ports/linux/guts/getgroups.c
index afb9662..afb9662 100644
--- a/guts/getgroups.c
+++ b/ports/linux/guts/getgroups.c
diff --git a/guts/getpw.c b/ports/linux/guts/getpw.c
index 62b44da..62b44da 100644
--- a/guts/getpw.c
+++ b/ports/linux/guts/getpw.c
diff --git a/guts/getpwent_r.c b/ports/linux/guts/getpwent_r.c
index d55763e..4fd9cc0 100644
--- a/guts/getpwent_r.c
+++ b/ports/linux/guts/getpwent_r.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Wind River Systems; see
+ * Copyright (c) 2010-2011 Wind River Systems; see
* guts/COPYRIGHT for information.
*
* static int
@@ -14,7 +14,7 @@
errno = ENOENT;
return -1;
}
- return fgetpwent_r(pseudo_pwd, pwbuf, buf, buflen, pwbufp);
+ rc = fgetpwent_r(pseudo_pwd, pwbuf, buf, buflen, pwbufp);
/* return rc;
* }
diff --git a/guts/getresgid.c b/ports/linux/guts/getresgid.c
index 13551a4..13551a4 100644
--- a/guts/getresgid.c
+++ b/ports/linux/guts/getresgid.c
diff --git a/guts/getresuid.c b/ports/linux/guts/getresuid.c
index 2e47520..2e47520 100644
--- a/guts/getresuid.c
+++ b/ports/linux/guts/getresuid.c
diff --git a/guts/getxattr.c b/ports/linux/guts/getxattr.c
index 71cfd56..fe8912d 100644
--- a/guts/getxattr.c
+++ b/ports/linux/guts/getxattr.c
@@ -6,6 +6,11 @@
* ssize_t rc = -1;
*/
+ /* suppress warnings */
+ (void) pathname;
+ (void) name;
+ (void) value;
+ (void) size;
errno = ENOTSUP;
/* return rc;
diff --git a/guts/glob64.c b/ports/linux/guts/glob64.c
index ccac6e4..ccac6e4 100644
--- a/guts/glob64.c
+++ b/ports/linux/guts/glob64.c
diff --git a/guts/lchown.c b/ports/linux/guts/lchown.c
index 4eb1202..4eb1202 100644
--- a/guts/lchown.c
+++ b/ports/linux/guts/lchown.c
diff --git a/guts/lckpwdf.c b/ports/linux/guts/lckpwdf.c
index b452ec0..b452ec0 100644
--- a/guts/lckpwdf.c
+++ b/ports/linux/guts/lckpwdf.c
diff --git a/guts/lgetxattr.c b/ports/linux/guts/lgetxattr.c
index 84fe020..404211f 100644
--- a/guts/lgetxattr.c
+++ b/ports/linux/guts/lgetxattr.c
@@ -6,6 +6,11 @@
* ssize_t rc = -1;
*/
+ /* suppress warnings */
+ (void) pathname;
+ (void) name;
+ (void) value;
+ (void) size;
errno = ENOTSUP;
/* return rc;
diff --git a/guts/listxattr.c b/ports/linux/guts/listxattr.c
index cef53fc..1b0b5e7 100644
--- a/guts/listxattr.c
+++ b/ports/linux/guts/listxattr.c
@@ -6,6 +6,10 @@
* ssize_t rc = -1;
*/
+ /* suppress warnings */
+ (void) pathname;
+ (void) list;
+ (void) size;
errno = ENOTSUP;
/* return rc;
diff --git a/guts/llistxattr.c b/ports/linux/guts/llistxattr.c
index 92870b5..a33f970 100644
--- a/guts/llistxattr.c
+++ b/ports/linux/guts/llistxattr.c
@@ -6,6 +6,10 @@
* ssize_t rc = -1;
*/
+ /* suppress warnings */
+ (void) pathname;
+ (void) list;
+ (void) size;
errno = ENOTSUP;
/* return rc;
diff --git a/guts/lremovexattr.c b/ports/linux/guts/lremovexattr.c
index 2ad8a82..38429da 100644
--- a/guts/lremovexattr.c
+++ b/ports/linux/guts/lremovexattr.c
@@ -6,6 +6,9 @@
* int rc = -1;
*/
+ /* suppress warnings */
+ (void) pathname;
+ (void) name;
errno = ENOTSUP;
/* return rc;
diff --git a/guts/lsetxattr.c b/ports/linux/guts/lsetxattr.c
index e5b4cd6..140ae8d 100644
--- a/guts/lsetxattr.c
+++ b/ports/linux/guts/lsetxattr.c
@@ -6,6 +6,12 @@
* int rc = -1;
*/
+ /* suppress warnings */
+ (void) pathname;
+ (void) name;
+ (void) value;
+ (void) size;
+ (void) flags;
errno = ENOTSUP;
/* return rc;
diff --git a/ports/linux/guts/lstat.c b/ports/linux/guts/lstat.c
new file mode 100644
index 0000000..19c202f
--- /dev/null
+++ b/ports/linux/guts/lstat.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2011 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * int lstat(const char *path, struct stat *buf)
+ * int rc = -1;
+ */
+
+ rc = wrap___fxstatat(_STAT_VER, AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW);
+
+/* return rc;
+ * }
+ */
diff --git a/guts/mkstemp64.c b/ports/linux/guts/mkstemp64.c
index def4126..def4126 100644
--- a/guts/mkstemp64.c
+++ b/ports/linux/guts/mkstemp64.c
diff --git a/guts/nftw64.c b/ports/linux/guts/nftw64.c
index 82571cd..82571cd 100644
--- a/guts/nftw64.c
+++ b/ports/linux/guts/nftw64.c
diff --git a/guts/open.c b/ports/linux/guts/open.c
index 0a0596c..0a0596c 100644
--- a/guts/open.c
+++ b/ports/linux/guts/open.c
diff --git a/guts/open64.c b/ports/linux/guts/open64.c
index adeb885..adeb885 100644
--- a/guts/open64.c
+++ b/ports/linux/guts/open64.c
diff --git a/guts/openat.c b/ports/linux/guts/openat.c
index c245796..c245796 100644
--- a/guts/openat.c
+++ b/ports/linux/guts/openat.c
diff --git a/guts/openat64.c b/ports/linux/guts/openat64.c
index 726ec6d..726ec6d 100644
--- a/guts/openat64.c
+++ b/ports/linux/guts/openat64.c
diff --git a/guts/removexattr.c b/ports/linux/guts/removexattr.c
index bf844dd..cd7f486 100644
--- a/guts/removexattr.c
+++ b/ports/linux/guts/removexattr.c
@@ -6,6 +6,9 @@
* int rc = -1;
*/
+ /* suppress warnings */
+ (void) pathname;
+ (void) name;
errno = ENOTSUP;
/* return rc;
diff --git a/guts/scandir.c b/ports/linux/guts/scandir.c
index afcebaf..afcebaf 100644
--- a/guts/scandir.c
+++ b/ports/linux/guts/scandir.c
diff --git a/guts/scandir64.c b/ports/linux/guts/scandir64.c
index 1317b73..1317b73 100644
--- a/guts/scandir64.c
+++ b/ports/linux/guts/scandir64.c
diff --git a/guts/setfsgid.c b/ports/linux/guts/setfsgid.c
index 0e5a10b..0e5a10b 100644
--- a/guts/setfsgid.c
+++ b/ports/linux/guts/setfsgid.c
diff --git a/guts/setfsuid.c b/ports/linux/guts/setfsuid.c
index e52b65e..e52b65e 100644
--- a/guts/setfsuid.c
+++ b/ports/linux/guts/setfsuid.c
diff --git a/guts/setgroups.c b/ports/linux/guts/setgroups.c
index 31b2b57..31b2b57 100644
--- a/guts/setgroups.c
+++ b/ports/linux/guts/setgroups.c
diff --git a/guts/setresgid.c b/ports/linux/guts/setresgid.c
index 2a26405..2a26405 100644
--- a/guts/setresgid.c
+++ b/ports/linux/guts/setresgid.c
diff --git a/guts/setresuid.c b/ports/linux/guts/setresuid.c
index a0a367f..a0a367f 100644
--- a/guts/setresuid.c
+++ b/ports/linux/guts/setresuid.c
diff --git a/guts/setxattr.c b/ports/linux/guts/setxattr.c
index c9a590c..de2de98 100644
--- a/guts/setxattr.c
+++ b/ports/linux/guts/setxattr.c
@@ -6,6 +6,12 @@
* int rc = -1;
*/
+ /* suppress warnings */
+ (void) pathname;
+ (void) name;
+ (void) value;
+ (void) size;
+ (void) flags;
errno = ENOTSUP;
/* return rc;
diff --git a/ports/linux/guts/stat.c b/ports/linux/guts/stat.c
new file mode 100644
index 0000000..1fe800e
--- /dev/null
+++ b/ports/linux/guts/stat.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2011 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * int stat(const char *path, struct stat *buf)
+ * int rc = -1;
+ */
+
+ rc = wrap___fxstatat(_STAT_VER, AT_FDCWD, path, buf, 0);
+
+/* return rc;
+ * }
+ */
diff --git a/guts/truncate64.c b/ports/linux/guts/truncate64.c
index a798984..a798984 100644
--- a/guts/truncate64.c
+++ b/ports/linux/guts/truncate64.c
diff --git a/guts/ulckpwdf.c b/ports/linux/guts/ulckpwdf.c
index bdb6f42..bdb6f42 100644
--- a/guts/ulckpwdf.c
+++ b/ports/linux/guts/ulckpwdf.c
diff --git a/guts/clone.c b/ports/linux/newclone/guts/clone.c
index b3400c7..b3400c7 100644
--- a/guts/clone.c
+++ b/ports/linux/newclone/guts/clone.c
diff --git a/ports/linux/newclone/pseudo_wrappers.c b/ports/linux/newclone/pseudo_wrappers.c
new file mode 100644
index 0000000..dd44408
--- /dev/null
+++ b/ports/linux/newclone/pseudo_wrappers.c
@@ -0,0 +1,69 @@
+static int
+wrap_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, va_list
+ap) {
+ /* unused */
+ (void) fn;
+ (void) child_stack;
+ (void) flags;
+ (void) arg;
+ (void) ap;
+ return 0;
+}
+
+int
+clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...) {
+ sigset_t saved;
+ va_list ap;
+ pid_t *pid;
+ struct user_desc *tls;
+ pid_t *ctid;
+
+ int rc = -1;
+
+ if (!pseudo_check_wrappers() || !real_clone) {
+ /* rc was initialized to the "failure" value */
+ pseudo_enosys("clone");
+ return rc;
+ }
+
+ va_start(ap, arg);
+ pid = va_arg(ap, pid_t *);
+ tls = va_arg(ap, struct user_desc *);
+ ctid = va_arg(ap, pid_t *);
+ va_end(ap);
+
+ pseudo_debug(4, "called: clone\n");
+ pseudo_sigblock(&saved);
+ if (pseudo_getlock()) {
+ errno = EBUSY;
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ return -1;
+ }
+
+ int save_errno;
+ int save_disabled = pseudo_disabled;
+ /* because clone() doesn't actually continue in this function, we
+ * can't check the return and fix up environment variables in the
+ * child. Instead, we have to temporarily do any fixup, then possibly
+ * undo it later. UGH!
+ */
+
+#include "guts/clone.c"
+
+ if (save_disabled != pseudo_disabled) {
+ if (pseudo_disabled) {
+ pseudo_disabled = 0;
+ pseudo_magic();
+ } else {
+ pseudo_disabled = 1;
+ pseudo_antimagic();
+ }
+ }
+
+ save_errno = errno;
+ pseudo_droplock();
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ pseudo_debug(4, "completed: clone\n");
+ errno = save_errno;
+ return rc;
+}
diff --git a/ports/linux/newclone/wrapfuncs.in b/ports/linux/newclone/wrapfuncs.in
new file mode 100644
index 0000000..8849310
--- /dev/null
+++ b/ports/linux/newclone/wrapfuncs.in
@@ -0,0 +1 @@
+int clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...); /* hand_wrapped=1 */
diff --git a/ports/linux/oldclone/guts/clone.c b/ports/linux/oldclone/guts/clone.c
new file mode 100644
index 0000000..58ff4ad
--- /dev/null
+++ b/ports/linux/oldclone/guts/clone.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2008-2010 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * static int
+ * clone(...) {
+ * ....
+ */
+ /* because clone() doesn't actually continue in this function, we
+ * can't check the return and fix up environment variables in the
+ * child. Instead, we have to temporarily do any fixup, then possibly
+ * undo it later. UGH!
+ */
+ pseudo_debug(1, "client resetting for clone(2) call\n");
+ if (!pseudo_get_value("PSEUDO_RELOADED")) {
+ pseudo_setupenv();
+ pseudo_reinit_libpseudo();
+ } else {
+ pseudo_setupenv();
+ pseudo_dropenv();
+ }
+ /* call the real syscall */
+ rc = (*real_clone)(fn, child_stack, flags, arg);
+/* ...
+ * return rc;
+ * }
+ */
diff --git a/ports/linux/oldclone/pseudo_wrappers.c b/ports/linux/oldclone/pseudo_wrappers.c
new file mode 100644
index 0000000..dead493
--- /dev/null
+++ b/ports/linux/oldclone/pseudo_wrappers.c
@@ -0,0 +1,59 @@
+static int (*real_clone)(int (*)(void *), void *, int, void *) = NULL;
+
+int
+wrap_clone(int (*fn)(void *), void *child_stack, int flags, void *arg) {
+ /* unused */
+ return 0;
+}
+
+int
+clone(int (*fn)(void *), void *child_stack, int flags, void *arg) {
+ sigset_t saved;
+ va_list ap;
+ pid_t *pid;
+ struct user_desc *tls;
+ pid_t *ctid;
+
+ int rc = -1;
+
+ if (!pseudo_check_wrappers() || !real_clone) {
+ /* rc was initialized to the "failure" value */
+ pseudo_enosys("clone");
+ return rc;
+ }
+
+ pseudo_debug(4, "called: clone\n");
+ pseudo_sigblock(&saved);
+ if (pseudo_getlock()) {
+ errno = EBUSY;
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ return -1;
+ }
+
+ int save_errno;
+ int save_disabled = pseudo_disabled;
+ /* because clone() doesn't actually continue in this function, we
+ * can't check the return and fix up environment variables in the
+ * child. Instead, we have to temporarily do any fixup, then possibly
+ * undo it later. UGH!
+ */
+
+#include "guts/clone.c"
+
+ if (save_disabled != pseudo_disabled) {
+ if (pseudo_disabled) {
+ pseudo_disabled = 0;
+ pseudo_magic();
+ } else {
+ pseudo_disabled = 1;
+ pseudo_antimagic();
+ }
+ }
+
+ save_errno = errno;
+ pseudo_droplock();
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ pseudo_debug(4, "completed: clone\n");
+ errno = save_errno;
+ return rc;
+}
diff --git a/ports/linux/oldclone/wrapfuncs.in b/ports/linux/oldclone/wrapfuncs.in
new file mode 100644
index 0000000..c915376
--- /dev/null
+++ b/ports/linux/oldclone/wrapfuncs.in
@@ -0,0 +1 @@
+int clone(int (*fn)(void *), void *child_stack, int flags, void *arg); /* hand_wrapped=1 */
diff --git a/ports/linux/portdefs.h b/ports/linux/portdefs.h
new file mode 100644
index 0000000..7e6c2aa
--- /dev/null
+++ b/ports/linux/portdefs.h
@@ -0,0 +1,5 @@
+#define PRELINK_LIBRARIES "LD_PRELOAD"
+#define PRELINK_PATH "LD_LIBRARY_PATH"
+#define PSEUDO_STATBUF_64 1
+#define PSEUDO_STATBUF struct stat64
+#define PSEUDO_LINKPATH_SEPARATOR " "
diff --git a/ports/linux/preports b/ports/linux/preports
new file mode 100644
index 0000000..a996c69
--- /dev/null
+++ b/ports/linux/preports
@@ -0,0 +1,2 @@
+#!/bin/sh
+echo "unix" "uids_generic"
diff --git a/ports/linux/pseudo_wrappers.c b/ports/linux/pseudo_wrappers.c
new file mode 100644
index 0000000..7d3fcd5
--- /dev/null
+++ b/ports/linux/pseudo_wrappers.c
@@ -0,0 +1,18 @@
+
+/* the unix port wants to know that real_stat() and
+ * friends exist. So they do.
+ */
+int
+pseudo_stat(const char *path, struct stat *buf) {
+ return real___xstat(_STAT_VER, path, buf);
+}
+
+int
+pseudo_lstat(const char *path, struct stat *buf) {
+ return real___lxstat(_STAT_VER, path, buf);
+}
+
+int
+pseudo_fstat(int fd, struct stat *buf) {
+ return real___fxstat(_STAT_VER, fd, buf);
+}
diff --git a/ports/linux/subports b/ports/linux/subports
new file mode 100644
index 0000000..02a4688
--- /dev/null
+++ b/ports/linux/subports
@@ -0,0 +1,27 @@
+#!/bin/sh
+found=false
+printf >&2 "Checking for old/new clone mechanics..."
+cat > dummy.c <<EOF
+#include <sched.h>
+int clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...) { return 0; }
+EOF
+if cc -c -o dummy.o dummy.c >/dev/null 2>&1; then
+ rm -f dummy.c dummy.o
+ echo >&2 "New clone."
+ echo "linux/newclone"
+ found=true
+fi
+cat > dummy.c <<EOF
+#include <sched.h>
+int clone(int (*fn)(void *), void *child_stack, int flags, void *arg) { return 0; }
+EOF
+if ! $found && cc -c -o dummy.o dummy.c >/dev/null 2>&1; then
+ rm -f dummy.c dummy.o
+ echo >&2 "Old clone."
+ echo "linux/oldclone"
+ found=true
+fi
+rm -f dummy.c dummy.o
+if ! $found; then
+ echo >&2 "Can't tell, omitting clone(2) support."
+fi
diff --git a/ports/linux/wrapfuncs.in b/ports/linux/wrapfuncs.in
new file mode 100644
index 0000000..2dab39d
--- /dev/null
+++ b/ports/linux/wrapfuncs.in
@@ -0,0 +1,64 @@
+int open(const char *path, int flags, ...{mode_t mode}); /* flags=0 */
+char *get_current_dir_name(void);
+int __xstat(int ver, const char *path, struct stat *buf);
+int __lxstat(int ver, const char *path, struct stat *buf); /* flags=AT_SYMLINK_NOFOLLOW */
+int __fxstat(int ver, int fd, struct stat *buf);
+int lchown(const char *path, uid_t owner, gid_t group); /* flags=AT_SYMLINK_NOFOLLOW */
+int __fxstatat(int ver, int dirfd, const char *path, struct stat *buf, int flags);
+int openat(int dirfd, const char *path, int flags, ...{mode_t mode});
+int __openat_2(int dirfd, const char *path, int flags);
+int __xmknod(int ver, const char *path, mode_t mode, dev_t *dev); /* flags=AT_SYMLINK_NOFOLLOW */
+int __xmknodat(int ver, int dirfd, const char *path, mode_t mode, dev_t *dev); /* flags=AT_SYMLINK_NOFOLLOW */
+int fcntl(int fd, int cmd, ...{struct flock *lock});
+# just so we know the inums of symlinks
+char *canonicalize_file_name(const char *filename);
+int eaccess(const char *path, int mode);
+# we use "pathname" to avoid canonicalizing paths, because these functions are
+# unimplemented
+ssize_t getxattr(const char *pathname, const char *name, void *value, size_t size);
+ssize_t lgetxattr(const char *pathname, const char *name, void *value, size_t size);
+ssize_t fgetxattr(int filedes, const char *name, void *value, size_t size);
+ssize_t listxattr(const char *pathname, char *list, size_t size);
+ssize_t llistxattr(const char *pathname, char *list, size_t size);
+ssize_t flistxattr(int filedes, char *list, size_t size);
+int setxattr(const char *pathname, const char *name, const void *value, size_t size, int flags);
+int lsetxattr(const char *pathname, const char *name, const void *value, size_t size, int flags);
+int fsetxattr(int filedes, const char *name, const void *value, size_t size, int flags);
+int removexattr(const char *pathname, const char *name);
+int lremovexattr(const char *pathname, const char *name);
+int fremovexattr(int filedes, const char *name);
+int open64(const char *path, int flags, ...{mode_t mode}); /* flags=0 */
+int openat64(int dirfd, const char *path, int flags, ...{mode_t mode}); /* flags=0 */
+int __openat64_2(int dirfd, const char *path, int flags); /* flags=0 */
+int creat64(const char *path, mode_t mode);
+int stat(const char *path, struct stat *buf); /* real_func=pseudo_stat */
+int lstat(const char *path, struct stat *buf); /* real_func=pseudo_lstat */
+int fstat(int fd, struct stat *buf); /* real_func=pseudo_fstat */
+int __xstat64(int ver, const char *path, struct stat64 *buf);
+int __lxstat64(int ver, const char *path, struct stat64 *buf); /* flags=AT_SYMLINK_NOFOLLOW */
+int __fxstat64(int ver, int fd, struct stat64 *buf);
+int __fxstatat64(int ver, int dirfd, const char *path, struct stat64 *buf, int flags);
+FILE *fopen64(const char *path, const char *mode);
+int nftw64(const char *path, int (*fn)(const char *, const struct stat64 *, int, struct FTW *), int nopenfd, int flag);
+FILE *freopen64(const char *path, const char *mode, FILE *stream);
+int ftw64(const char *path, int (*fn)(const char *, const struct stat64 *, int), int nopenfd);
+int glob64(const char *pattern, int flags, int (*errfunc)(const char *, int), glob64_t *pglob);
+int scandir64(const char *path, struct dirent64 ***namelist, int (*filter)(const struct dirent64 *), int (*compar)());
+int truncate64(const char *path, off64_t length);
+int mkstemp64(char *template); /* flags=AT_SYMLINK_NOFOLLOW */
+int getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups);
+int setgroups(size_t size, const gid_t *list);
+int setfsgid(gid_t fsgid);
+int setfsuid(uid_t fsuid);
+int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
+int setresuid(uid_t ruid, uid_t euid, uid_t suid);
+int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid);
+int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
+int scandir(const char *path, struct dirent ***namelist, int (*filter)(const struct dirent *), int (*compar)());
+int getgroups(int size, gid_t *list);
+int lckpwdf(void);
+int ulckpwdf(void);
+int euidaccess(const char *path, int mode);
+int getpw(uid_t uid, char *buf);
+int getpwent_r(struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp);
+int getgrent_r(struct group *gbuf, char *buf, size_t buflen, struct group **gbufp);
diff --git a/ports/uids_generic/guts/COPYRIGHT b/ports/uids_generic/guts/COPYRIGHT
new file mode 100644
index 0000000..c96e1b1
--- /dev/null
+++ b/ports/uids_generic/guts/COPYRIGHT
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2008-2010 Wind River Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the Lesser GNU General Public License version 2.1 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the Lesser GNU General Public License for more details.
+ *
+ * You should have received a copy of the Lesser GNU General Public License
+ * version 2.1 along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
diff --git a/guts/endgrent.c b/ports/uids_generic/guts/endgrent.c
index 843cad0..843cad0 100644
--- a/guts/endgrent.c
+++ b/ports/uids_generic/guts/endgrent.c
diff --git a/guts/endpwent.c b/ports/uids_generic/guts/endpwent.c
index f76cf10..f76cf10 100644
--- a/guts/endpwent.c
+++ b/ports/uids_generic/guts/endpwent.c
diff --git a/guts/getegid.c b/ports/uids_generic/guts/getegid.c
index 7c14f48..7c14f48 100644
--- a/guts/getegid.c
+++ b/ports/uids_generic/guts/getegid.c
diff --git a/guts/geteuid.c b/ports/uids_generic/guts/geteuid.c
index 1745e13..1745e13 100644
--- a/guts/geteuid.c
+++ b/ports/uids_generic/guts/geteuid.c
diff --git a/guts/getgid.c b/ports/uids_generic/guts/getgid.c
index ca8bad3..ca8bad3 100644
--- a/guts/getgid.c
+++ b/ports/uids_generic/guts/getgid.c
diff --git a/guts/getgrent.c b/ports/uids_generic/guts/getgrent.c
index e8e07f5..e8e07f5 100644
--- a/guts/getgrent.c
+++ b/ports/uids_generic/guts/getgrent.c
diff --git a/guts/getgrgid.c b/ports/uids_generic/guts/getgrgid.c
index c1824e7..c1824e7 100644
--- a/guts/getgrgid.c
+++ b/ports/uids_generic/guts/getgrgid.c
diff --git a/guts/getgrgid_r.c b/ports/uids_generic/guts/getgrgid_r.c
index 06a91c9..06a91c9 100644
--- a/guts/getgrgid_r.c
+++ b/ports/uids_generic/guts/getgrgid_r.c
diff --git a/guts/getgrnam.c b/ports/uids_generic/guts/getgrnam.c
index 0e26444..0e26444 100644
--- a/guts/getgrnam.c
+++ b/ports/uids_generic/guts/getgrnam.c
diff --git a/guts/getgrnam_r.c b/ports/uids_generic/guts/getgrnam_r.c
index 39de641..39de641 100644
--- a/guts/getgrnam_r.c
+++ b/ports/uids_generic/guts/getgrnam_r.c
diff --git a/guts/getpwent.c b/ports/uids_generic/guts/getpwent.c
index 3b1f837..3b1f837 100644
--- a/guts/getpwent.c
+++ b/ports/uids_generic/guts/getpwent.c
diff --git a/guts/getpwnam.c b/ports/uids_generic/guts/getpwnam.c
index 024b3d8..024b3d8 100644
--- a/guts/getpwnam.c
+++ b/ports/uids_generic/guts/getpwnam.c
diff --git a/guts/getpwnam_r.c b/ports/uids_generic/guts/getpwnam_r.c
index 5d7a4ea..5d7a4ea 100644
--- a/guts/getpwnam_r.c
+++ b/ports/uids_generic/guts/getpwnam_r.c
diff --git a/guts/getpwuid.c b/ports/uids_generic/guts/getpwuid.c
index 11142de..11142de 100644
--- a/guts/getpwuid.c
+++ b/ports/uids_generic/guts/getpwuid.c
diff --git a/guts/getpwuid_r.c b/ports/uids_generic/guts/getpwuid_r.c
index 06b920e..06b920e 100644
--- a/guts/getpwuid_r.c
+++ b/ports/uids_generic/guts/getpwuid_r.c
diff --git a/guts/getuid.c b/ports/uids_generic/guts/getuid.c
index e783cc8..e783cc8 100644
--- a/guts/getuid.c
+++ b/ports/uids_generic/guts/getuid.c
diff --git a/guts/setegid.c b/ports/uids_generic/guts/setegid.c
index ff777a0..ff777a0 100644
--- a/guts/setegid.c
+++ b/ports/uids_generic/guts/setegid.c
diff --git a/guts/seteuid.c b/ports/uids_generic/guts/seteuid.c
index 430768f..430768f 100644
--- a/guts/seteuid.c
+++ b/ports/uids_generic/guts/seteuid.c
diff --git a/guts/setgid.c b/ports/uids_generic/guts/setgid.c
index b94db1a..b94db1a 100644
--- a/guts/setgid.c
+++ b/ports/uids_generic/guts/setgid.c
diff --git a/guts/setgrent.c b/ports/uids_generic/guts/setgrent.c
index 75aab61..75aab61 100644
--- a/guts/setgrent.c
+++ b/ports/uids_generic/guts/setgrent.c
diff --git a/guts/setpwent.c b/ports/uids_generic/guts/setpwent.c
index fb35e07..fb35e07 100644
--- a/guts/setpwent.c
+++ b/ports/uids_generic/guts/setpwent.c
diff --git a/guts/setregid.c b/ports/uids_generic/guts/setregid.c
index 78b2037..78b2037 100644
--- a/guts/setregid.c
+++ b/ports/uids_generic/guts/setregid.c
diff --git a/guts/setreuid.c b/ports/uids_generic/guts/setreuid.c
index 3ff82ab..3ff82ab 100644
--- a/guts/setreuid.c
+++ b/ports/uids_generic/guts/setreuid.c
diff --git a/guts/setuid.c b/ports/uids_generic/guts/setuid.c
index 6bfdf6c..6bfdf6c 100644
--- a/guts/setuid.c
+++ b/ports/uids_generic/guts/setuid.c
diff --git a/ports/uids_generic/wrapfuncs.in b/ports/uids_generic/wrapfuncs.in
new file mode 100644
index 0000000..38aa558
--- /dev/null
+++ b/ports/uids_generic/wrapfuncs.in
@@ -0,0 +1,25 @@
+# I bet you never knew there were this many of these!
+gid_t getegid(void);
+gid_t getgid(void);
+int getgrgid_r(gid_t gid, struct group *gbuf, char *buf, size_t buflen, struct group **gbufp);
+int getgrnam_r(const char *name, struct group *gbuf, char *buf, size_t buflen, struct group **gbufp);
+int getpwnam_r(const char *name, struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp);
+int getpwuid_r(uid_t uid, struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp);
+int setegid(gid_t egid);
+int seteuid(uid_t euid);
+int setgid(gid_t gid);
+int setregid(gid_t rgid, gid_t egid);
+int setreuid(uid_t ruid, uid_t euid);
+int setuid(uid_t uid);
+struct group *getgrent(void);
+struct group *getgrgid(gid_t gid);
+struct group *getgrnam(const char *name);
+struct passwd *getpwent(void);
+struct passwd *getpwnam(const char *name);
+struct passwd *getpwuid(uid_t uid);
+uid_t geteuid(void);
+uid_t getuid(void);
+void endgrent(void);
+void endpwent(void);
+void setgrent(void);
+void setpwent(void);
diff --git a/ports/unix/guts/COPYRIGHT b/ports/unix/guts/COPYRIGHT
new file mode 100644
index 0000000..c96e1b1
--- /dev/null
+++ b/ports/unix/guts/COPYRIGHT
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2008-2010 Wind River Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the Lesser GNU General Public License version 2.1 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the Lesser GNU General Public License for more details.
+ *
+ * You should have received a copy of the Lesser GNU General Public License
+ * version 2.1 along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
diff --git a/guts/access.c b/ports/unix/guts/access.c
index c250c2e..5a92957 100644
--- a/guts/access.c
+++ b/ports/unix/guts/access.c
@@ -6,12 +6,12 @@
* wrap_access(const char *path, int mode) {
* int rc = -1;
*/
- struct stat64 buf;
+ struct stat buf;
/* note: no attempt to handle the case where user isn't
* root.
*/
- rc = wrap___fxstatat64(_STAT_VER, AT_FDCWD, path, &buf, 0);
+ rc = real_stat(path, &buf);
if (rc == -1)
return rc;
diff --git a/guts/acct.c b/ports/unix/guts/acct.c
index b8dca5d..b8dca5d 100644
--- a/guts/acct.c
+++ b/ports/unix/guts/acct.c
diff --git a/guts/chdir.c b/ports/unix/guts/chdir.c
index 59a262f..59a262f 100644
--- a/guts/chdir.c
+++ b/ports/unix/guts/chdir.c
diff --git a/guts/chmod.c b/ports/unix/guts/chmod.c
index a157335..a157335 100644
--- a/guts/chmod.c
+++ b/ports/unix/guts/chmod.c
diff --git a/guts/chown.c b/ports/unix/guts/chown.c
index 4fcbdda..4fcbdda 100644
--- a/guts/chown.c
+++ b/ports/unix/guts/chown.c
diff --git a/guts/chroot.c b/ports/unix/guts/chroot.c
index c5b6f2f..c5b6f2f 100644
--- a/guts/chroot.c
+++ b/ports/unix/guts/chroot.c
diff --git a/guts/close.c b/ports/unix/guts/close.c
index 09c73e6..09c73e6 100644
--- a/guts/close.c
+++ b/ports/unix/guts/close.c
diff --git a/guts/creat.c b/ports/unix/guts/creat.c
index d46e4d5..8593cd4 100644
--- a/guts/creat.c
+++ b/ports/unix/guts/creat.c
@@ -7,7 +7,7 @@
* int rc = -1;
*/
- rc = wrap_openat(AT_FDCWD, path, O_CREAT|O_WRONLY|O_TRUNC, mode);
+ rc = wrap_open(path, O_CREAT|O_WRONLY|O_TRUNC, mode);
/* return rc;
* }
diff --git a/guts/dup.c b/ports/unix/guts/dup.c
index 13612b1..13612b1 100644
--- a/guts/dup.c
+++ b/ports/unix/guts/dup.c
diff --git a/guts/dup2.c b/ports/unix/guts/dup2.c
index 04666d1..04666d1 100644
--- a/guts/dup2.c
+++ b/ports/unix/guts/dup2.c
diff --git a/guts/fchdir.c b/ports/unix/guts/fchdir.c
index ba77ebf..ba77ebf 100644
--- a/guts/fchdir.c
+++ b/ports/unix/guts/fchdir.c
diff --git a/guts/fchmod.c b/ports/unix/guts/fchmod.c
index c06f677..40f62ba 100644
--- a/guts/fchmod.c
+++ b/ports/unix/guts/fchmod.c
@@ -7,23 +7,21 @@
* int rc = -1;
*/
pseudo_msg_t *msg;
- struct stat64 buf;
+ struct stat buf;
int save_errno = errno;
- if (real___fxstat64(_STAT_VER, fd, &buf) == -1) {
+ if (real_fstat(fd, &buf) == -1) {
/* can't stat it, can't chmod it */
return -1;
}
buf.st_mode = (buf.st_mode & ~07777) | (mode & 07777);
- msg = pseudo_client_op(OP_FCHMOD, 0, fd, -1, 0, &buf);
+ msg = pseudo_client_op_plain(OP_FCHMOD, 0, fd, -1, 0, &buf);
real_fchmod(fd, PSEUDO_FS_MODE(mode));
- if (!msg) {
- errno = ENOSYS;
- rc = -1;
- } else if (msg->result != RESULT_SUCCEED) {
+ if (msg && msg->result != RESULT_SUCCEED) {
errno = EPERM;
rc = -1;
} else {
+ /* just pretend we worked */
errno = save_errno;
rc = 0;
}
diff --git a/guts/fchmodat.c b/ports/unix/guts/fchmodat.c
index f58f55a..531345d 100644
--- a/guts/fchmodat.c
+++ b/ports/unix/guts/fchmodat.c
@@ -7,7 +7,7 @@
* int rc = -1;
*/
pseudo_msg_t *msg;
- struct stat64 buf;
+ struct stat buf;
int save_errno;
#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
@@ -16,12 +16,12 @@
return -1;
}
if (flags & AT_SYMLINK_NOFOLLOW) {
- rc = real___lxstat64(_STAT_VER, path, &buf);
+ rc = real_lstat(path, &buf);
} else {
- rc = real___xstat64(_STAT_VER, path, &buf);
+ rc = real_stat(path, &buf);
}
#else
- rc = real___fxstatat64(_STAT_VER, dirfd, path, &buf, flags);
+ rc = real___fxstatat(_STAT_VER, dirfd, path, &buf, flags);
#endif
if (rc == -1) {
return rc;
@@ -36,7 +36,7 @@
/* purely for debugging purposes: check whether file
* is already in database.
*/
- msg = pseudo_client_op(OP_STAT, 0, -1, -1, path, &buf);
+ msg = pseudo_client_op_plain(OP_STAT, 0, -1, -1, path, &buf);
if (!msg || msg->result != RESULT_SUCCEED) {
pseudo_debug(2, "chmodat to 0%o on %d/%s, ino %llu, new file.\n",
mode, dirfd, path, (unsigned long long) buf.st_ino);
@@ -57,14 +57,12 @@
*/
buf.st_mode = (buf.st_mode & ~07777) | (mode & 07777);
- msg = pseudo_client_op(OP_CHMOD, 0, -1, dirfd, path, &buf);
- if (!msg) {
- errno = ENOSYS;
- rc = -1;
- } else if (msg->result != RESULT_SUCCEED) {
+ msg = pseudo_client_op_plain(OP_CHMOD, 0, -1, dirfd, path, &buf);
+ if (msg && msg->result != RESULT_SUCCEED) {
errno = EPERM;
rc = -1;
} else {
+ /* if server is down, just pretend we worked */
rc = 0;
}
diff --git a/guts/fchown.c b/ports/unix/guts/fchown.c
index 7d0da85..c36a869 100644
--- a/guts/fchown.c
+++ b/ports/unix/guts/fchown.c
@@ -7,22 +7,22 @@
* int rc = -1;
*/
pseudo_msg_t *msg;
- struct stat64 buf;
+ struct stat buf;
int save_errno;
- if (real___fxstat64(_STAT_VER, fd, &buf) == -1) {
+ if (real_fstat(fd, &buf) == -1) {
save_errno = errno;
- pseudo_debug(2, "fchown failing because fxstat failed: %s\n",
+ pseudo_debug(2, "fchown failing because fstat failed: %s\n",
strerror(errno));
errno = save_errno;
return -1;
}
if (owner == (uid_t) -1 || group == (gid_t) -1) {
- msg = pseudo_client_op(OP_STAT, 0, fd, -1, NULL, &buf);
+ msg = pseudo_client_op_plain(OP_STAT, 0, fd, -1, NULL, &buf);
/* copy in any existing values... */
if (msg) {
if (msg->result == RESULT_SUCCEED) {
- pseudo_stat_msg(&buf, msg);
+ pseudo_stat_msg_plain(&buf, msg);
} else {
pseudo_debug(2, "fchown fd %d, ino %llu, unknown file.\n",
fd, (unsigned long long) buf.st_ino);
@@ -41,14 +41,12 @@
}
pseudo_debug(2, "fchown, fd %d: %d:%d -> %d:%d\n",
fd, owner, group, buf.st_uid, buf.st_gid);
- msg = pseudo_client_op(OP_FCHOWN, 0, fd, -1, 0, &buf);
- if (!msg) {
- errno = ENOSYS;
- rc = -1;
- } else if (msg->result != RESULT_SUCCEED) {
+ msg = pseudo_client_op_plain(OP_FCHOWN, 0, fd, -1, 0, &buf);
+ if (msg && msg->result != RESULT_SUCCEED) {
errno = EPERM;
rc = -1;
} else {
+ /* just pretend we worked */
rc = 0;
}
diff --git a/guts/fchownat.c b/ports/unix/guts/fchownat.c
index f006efe..9585fb0 100644
--- a/guts/fchownat.c
+++ b/ports/unix/guts/fchownat.c
@@ -7,7 +7,7 @@
* int rc = -1;
*/
pseudo_msg_t *msg;
- struct stat64 buf;
+ struct stat buf;
int save_errno;
int doing_link = 0;
@@ -17,12 +17,12 @@
return -1;
}
if (flags & AT_SYMLINK_NOFOLLOW) {
- rc = real___lxstat64(_STAT_VER, path, &buf);
+ rc = real_lstat(path, &buf);
} else {
- rc = real___xstat64(_STAT_VER, path, &buf);
+ rc = real_stat(path, &buf);
}
#else
- rc = real___fxstatat64(_STAT_VER, dirfd, path, &buf, flags);
+ rc = real___fxstatat(_STAT_VER, dirfd, path, &buf, flags);
#endif
if (rc == -1) {
return rc;
@@ -34,11 +34,11 @@
save_errno = errno;
if (owner == (uid_t) -1 || group == (gid_t) -1) {
- msg = pseudo_client_op(OP_STAT, 0, -1, -1, path, &buf);
+ msg = pseudo_client_op_plain(OP_STAT, 0, -1, -1, path, &buf);
/* copy in any existing values... */
if (msg) {
if (msg->result == RESULT_SUCCEED) {
- pseudo_stat_msg(&buf, msg);
+ pseudo_stat_msg_plain(&buf, msg);
} else {
pseudo_debug(2, "chownat to %d:%d on %d/%s, ino %llu, new file.\n",
owner, group, dirfd, path,
@@ -53,14 +53,12 @@
if (group != (gid_t) -1) {
buf.st_gid = group;
}
- msg = pseudo_client_op(OP_CHOWN, 0, -1, dirfd, path, &buf);
- if (!msg) {
- errno = ENOSYS;
- rc = -1;
- } else if (msg->result != RESULT_SUCCEED) {
+ msg = pseudo_client_op_plain(OP_CHOWN, 0, -1, dirfd, path, &buf);
+ if (msg && msg->result != RESULT_SUCCEED) {
errno = EPERM;
rc = -1;
} else {
+ /* just pretend we worked */
rc = 0;
}
diff --git a/guts/fclose.c b/ports/unix/guts/fclose.c
index 4469f5b..4469f5b 100644
--- a/guts/fclose.c
+++ b/ports/unix/guts/fclose.c
diff --git a/guts/fopen.c b/ports/unix/guts/fopen.c
index c8a3f98..9dd6c33 100644
--- a/guts/fopen.c
+++ b/ports/unix/guts/fopen.c
@@ -6,9 +6,9 @@
* wrap_fopen(const char *path, const char *mode) {
* FILE * rc = 0;
*/
- struct stat64 buf;
+ struct stat buf;
int save_errno;
- int existed = (real___xstat64(_STAT_VER, path, &buf) != -1);
+ int existed = (real_stat(path, &buf) != -1);
rc = real_fopen(path, mode);
save_errno = errno;
@@ -17,15 +17,15 @@
int fd = fileno(rc);
pseudo_debug(2, "fopen '%s': fd %d <FILE %p>\n", path, fd, (void *) rc);
- if (real___fxstat64(_STAT_VER, fd, &buf) != -1) {
+ if (real_fstat(fd, &buf) != -1) {
if (!existed) {
- pseudo_client_op(OP_CREAT, 0, -1, -1, path, &buf);
+ pseudo_client_op_plain(OP_CREAT, 0, -1, -1, path, &buf);
}
- pseudo_client_op(OP_OPEN, pseudo_access_fopen(mode), fd, -1, path, &buf);
+ pseudo_client_op_plain(OP_OPEN, pseudo_access_fopen(mode), fd, -1, path, &buf);
} else {
pseudo_debug(1, "fopen (fd %d) succeeded, but fstat failed (%s).\n",
fd, strerror(errno));
- pseudo_client_op(OP_OPEN, pseudo_access_fopen(mode), fd, -1, path, 0);
+ pseudo_client_op_plain(OP_OPEN, pseudo_access_fopen(mode), fd, -1, path, 0);
}
errno = save_errno;
}
diff --git a/guts/freopen.c b/ports/unix/guts/freopen.c
index bd50b29..b5a7bfc 100644
--- a/guts/freopen.c
+++ b/ports/unix/guts/freopen.c
@@ -6,9 +6,9 @@
* wrap_freopen(const char *path, const char *mode, FILE *stream) {
* FILE * rc = NULL;
*/
- struct stat64 buf;
+ struct stat buf;
int save_errno;
- int existed = (real___xstat64(_STAT_VER, path, &buf) != -1);
+ int existed = (real_stat(path, &buf) != -1);
rc = real_freopen(path, mode, stream);
save_errno = errno;
@@ -17,15 +17,15 @@
int fd = fileno(rc);
pseudo_debug(2, "freopen '%s': fd %d\n", path, fd);
- if (real___fxstat64(_STAT_VER, fd, &buf) != -1) {
+ if (real_fstat(fd, &buf) != -1) {
if (!existed) {
- pseudo_client_op(OP_CREAT, 0, -1, -1, path, &buf);
+ pseudo_client_op_plain(OP_CREAT, 0, -1, -1, path, &buf);
}
- pseudo_client_op(OP_OPEN, pseudo_access_fopen(mode), fd, -1, path, &buf);
+ pseudo_client_op_plain(OP_OPEN, pseudo_access_fopen(mode), fd, -1, path, &buf);
} else {
pseudo_debug(1, "fopen (fd %d) succeeded, but stat failed (%s).\n",
fd, strerror(errno));
- pseudo_client_op(OP_OPEN, pseudo_access_fopen(mode), fd, -1, path, 0);
+ pseudo_client_op_plain(OP_OPEN, pseudo_access_fopen(mode), fd, -1, path, 0);
}
errno = save_errno;
}
diff --git a/guts/fts_open.c b/ports/unix/guts/fts_open.c
index 8b3ce19..8b3ce19 100644
--- a/guts/fts_open.c
+++ b/ports/unix/guts/fts_open.c
diff --git a/guts/ftw.c b/ports/unix/guts/ftw.c
index 0861194..0861194 100644
--- a/guts/ftw.c
+++ b/ports/unix/guts/ftw.c
diff --git a/guts/getcwd.c b/ports/unix/guts/getcwd.c
index b3f552c..b3f552c 100644
--- a/guts/getcwd.c
+++ b/ports/unix/guts/getcwd.c
diff --git a/guts/getwd.c b/ports/unix/guts/getwd.c
index 836301e..836301e 100644
--- a/guts/getwd.c
+++ b/ports/unix/guts/getwd.c
diff --git a/guts/glob.c b/ports/unix/guts/glob.c
index 0012179..0012179 100644
--- a/guts/glob.c
+++ b/ports/unix/guts/glob.c
diff --git a/ports/unix/guts/lchown.c b/ports/unix/guts/lchown.c
new file mode 100644
index 0000000..60727d0
--- /dev/null
+++ b/ports/unix/guts/lchown.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2008,2011 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * int lchown(const char *path, uid_t owner, gid_t group)
+ * int rc = -1;
+ */
+
+ rc = wrap_chown(path, owner, group);
+
+/* return rc;
+ * }
+ */
diff --git a/guts/link.c b/ports/unix/guts/link.c
index e528d53..81316e2 100644
--- a/guts/link.c
+++ b/ports/unix/guts/link.c
@@ -7,7 +7,7 @@
* int rc = -1;
*/
pseudo_msg_t *msg;
- struct stat64 buf;
+ struct stat buf;
rc = real_link(oldpath, newpath);
if (rc == 0) {
@@ -19,16 +19,16 @@
* files they link to. This is contraPOSIX, but
* it's apparently useful.
*/
- real___lxstat64(_STAT_VER, oldpath, &buf);
+ real_lstat(oldpath, &buf);
/* a link should copy the existing database entry, if
* there is one. OP_LINK is also used to insert unseen
* files, though, so it can't be implicit.
*/
- msg = pseudo_client_op(OP_STAT, 0, -1, -1, oldpath, &buf);
+ msg = pseudo_client_op_plain(OP_STAT, 0, -1, -1, oldpath, &buf);
if (msg) {
- pseudo_stat_msg(&buf, msg);
+ pseudo_stat_msg_plain(&buf, msg);
}
- pseudo_client_op(OP_LINK, 0, -1, -1, newpath, &buf);
+ pseudo_client_op_plain(OP_LINK, 0, -1, -1, newpath, &buf);
}
/* return rc;
diff --git a/guts/lutimes.c b/ports/unix/guts/lutimes.c
index cdadbbd..cdadbbd 100644
--- a/guts/lutimes.c
+++ b/ports/unix/guts/lutimes.c
diff --git a/guts/mkdir.c b/ports/unix/guts/mkdir.c
index 9f116e2..9f116e2 100644
--- a/guts/mkdir.c
+++ b/ports/unix/guts/mkdir.c
diff --git a/guts/mkdirat.c b/ports/unix/guts/mkdirat.c
index 988e3f4..a3d3ca7 100644
--- a/guts/mkdirat.c
+++ b/ports/unix/guts/mkdirat.c
@@ -16,16 +16,16 @@
rc = real_mkdirat(dirfd, path, PSEUDO_FS_MODE(mode));
#endif
if (rc != -1) {
- struct stat64 buf;
+ struct stat buf;
int stat_rc;
#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
- stat_rc = real___lxstat64(_STAT_VER, path, &buf);
+ stat_rc = real_lstat(path, &buf);
#else
- stat_rc = real___fxstatat64(_STAT_VER, dirfd, path, &buf, AT_SYMLINK_NOFOLLOW);
+ stat_rc = real___fxstatat(_STAT_VER, dirfd, path, &buf, AT_SYMLINK_NOFOLLOW);
#endif
if (stat_rc != -1) {
- pseudo_client_op(OP_MKDIR, 0, -1, dirfd, path, &buf);
+ pseudo_client_op_plain(OP_MKDIR, 0, -1, dirfd, path, &buf);
} else {
pseudo_debug(1, "mkdir of %s succeeded, but stat failed: %s\n",
path, strerror(errno));
diff --git a/guts/mkdtemp.c b/ports/unix/guts/mkdtemp.c
index fb23bc3..92d4da7 100644
--- a/guts/mkdtemp.c
+++ b/ports/unix/guts/mkdtemp.c
@@ -6,7 +6,7 @@
* wrap_mkdtemp(char *template) {
* char * rc = NULL;
*/
- struct stat64 buf;
+ struct stat buf;
int save_errno;
size_t len;
char *tmp_template;
@@ -29,8 +29,8 @@
if (rc != NULL) {
save_errno = errno;
- if (real___xstat64(_STAT_VER, rc, &buf) != -1) {
- pseudo_client_op(OP_CREAT, 0, -1, -1, tmp_template, &buf);
+ if (real_stat(rc, &buf) != -1) {
+ pseudo_client_op_plain(OP_CREAT, 0, -1, -1, tmp_template, &buf);
} else {
pseudo_debug(1, "mkdtemp (path %s) succeeded, but fstat failed (%s).\n",
rc, strerror(errno));
diff --git a/guts/mkfifo.c b/ports/unix/guts/mkfifo.c
index 32f79fb..32f79fb 100644
--- a/guts/mkfifo.c
+++ b/ports/unix/guts/mkfifo.c
diff --git a/guts/mkfifoat.c b/ports/unix/guts/mkfifoat.c
index 26fcba3..3497f37 100644
--- a/guts/mkfifoat.c
+++ b/ports/unix/guts/mkfifoat.c
@@ -6,9 +6,8 @@
* wrap_mkfifoat(int dirfd, const char *path, mode_t mode) {
* int rc = -1;
*/
- dev_t unused = 0;
- rc = wrap___xmknodat(_STAT_VER, dirfd, path, (mode & 07777) | S_IFIFO, &unused);
+ rc = wrap_mknodat(dirfd, path, (mode & 07777) | S_IFIFO, (dev_t) 0);
/* return rc;
* }
diff --git a/ports/unix/guts/mknod.c b/ports/unix/guts/mknod.c
new file mode 100644
index 0000000..25c2962
--- /dev/null
+++ b/ports/unix/guts/mknod.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2011 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * int mknod(const char *path, mode_t mode, dev_t dev)
+ * int rc = -1;
+ */
+
+ rc = real_mknod(path, mode, dev);
+
+/* return rc;
+ * }
+ */
diff --git a/ports/unix/guts/mknodat.c b/ports/unix/guts/mknodat.c
new file mode 100644
index 0000000..22fe5ce
--- /dev/null
+++ b/ports/unix/guts/mknodat.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2011 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * int mknodat(int dirfd, const char *path, mode_t mode, dev_t dev)
+ * int rc = -1;
+ */
+
+ pseudo_msg_t *msg;
+ struct stat buf;
+
+#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
+ if (dirfd != AT_FDCWD) {
+ errno = ENOSYS;
+ return -1;
+ }
+ rc = real_stat(path, &buf);
+#else
+ rc = real___fxstatat(_STAT_VER, dirfd, path, &buf, AT_SYMLINK_NOFOLLOW);
+#endif
+ if (rc != -1) {
+ /* if we can stat the file, you can't mknod it */
+ errno = EEXIST;
+ return -1;
+ }
+#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
+ rc = real_open(path, O_CREAT | O_WRONLY | O_EXCL, PSEUDO_FS_MODE(mode));
+#else
+ rc = real_openat(dirfd, path, O_CREAT | O_WRONLY | O_EXCL,
+ PSEUDO_FS_MODE(mode));
+#endif
+ if (rc == -1) {
+ return -1;
+ }
+ real_fstat(rc, &buf);
+ /* mknod does not really open the file. We don't have
+ * to use wrap_close because we've never exposed this file
+ * descriptor to the client code.
+ */
+ real_close(rc);
+
+ /* mask in the mode type bits again */
+ buf.st_mode = (PSEUDO_DB_MODE(buf.st_mode, mode) & 07777) |
+ (mode & ~07777);
+ buf.st_rdev = dev;
+ msg = pseudo_client_op_plain(OP_MKNOD, 0, -1, dirfd, path, &buf);
+ if (msg && msg->result != RESULT_SUCCEED) {
+ errno = EPERM;
+ rc = -1;
+ } else {
+ /* just pretend we worked */
+ rc = 0;
+ }
+ if (rc == -1) {
+ int save_errno = errno;
+#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
+ real_unlink(path);
+#else
+ real_unlinkat(dirfd, path, AT_SYMLINK_NOFOLLOW);
+#endif
+ errno = save_errno;
+ }
+
+/* return rc;
+ * }
+ */
diff --git a/guts/mkstemp.c b/ports/unix/guts/mkstemp.c
index 83f7bfe..46c0be1 100644
--- a/guts/mkstemp.c
+++ b/ports/unix/guts/mkstemp.c
@@ -6,7 +6,7 @@
* wrap_mkstemp(char *template) {
* int rc = -1;
*/
- struct stat64 buf;
+ struct stat buf;
int save_errno;
size_t len;
char *tmp_template;
@@ -29,13 +29,13 @@
if (rc != -1) {
save_errno = errno;
- if (real___fxstat64(_STAT_VER, rc, &buf) != -1) {
- pseudo_client_op(OP_CREAT, 0, -1, -1, tmp_template, &buf);
- pseudo_client_op(OP_OPEN, PSA_READ | PSA_WRITE, rc, -1, tmp_template, &buf);
+ if (real_fstat(rc, &buf) != -1) {
+ pseudo_client_op_plain(OP_CREAT, 0, -1, -1, tmp_template, &buf);
+ pseudo_client_op_plain(OP_OPEN, PSA_READ | PSA_WRITE, rc, -1, tmp_template, &buf);
} else {
pseudo_debug(1, "mkstemp (fd %d) succeeded, but fstat failed (%s).\n",
rc, strerror(errno));
- pseudo_client_op(OP_OPEN, PSA_READ | PSA_WRITE, rc, -1, tmp_template, 0);
+ pseudo_client_op_plain(OP_OPEN, PSA_READ | PSA_WRITE, rc, -1, tmp_template, 0);
}
errno = save_errno;
}
diff --git a/guts/mktemp.c b/ports/unix/guts/mktemp.c
index 7cf594a..7cf594a 100644
--- a/guts/mktemp.c
+++ b/ports/unix/guts/mktemp.c
diff --git a/guts/nftw.c b/ports/unix/guts/nftw.c
index 73daec8..73daec8 100644
--- a/guts/nftw.c
+++ b/ports/unix/guts/nftw.c
diff --git a/guts/opendir.c b/ports/unix/guts/opendir.c
index 8eaa71f..8eaa71f 100644
--- a/guts/opendir.c
+++ b/ports/unix/guts/opendir.c
diff --git a/guts/pathconf.c b/ports/unix/guts/pathconf.c
index c6caa34..c6caa34 100644
--- a/guts/pathconf.c
+++ b/ports/unix/guts/pathconf.c
diff --git a/guts/readlink.c b/ports/unix/guts/readlink.c
index 18d9dc7..18d9dc7 100644
--- a/guts/readlink.c
+++ b/ports/unix/guts/readlink.c
diff --git a/guts/readlinkat.c b/ports/unix/guts/readlinkat.c
index 5282e2b..5282e2b 100644
--- a/guts/readlinkat.c
+++ b/ports/unix/guts/readlinkat.c
diff --git a/guts/realpath.c b/ports/unix/guts/realpath.c
index 8059f5e..8059f5e 100644
--- a/guts/realpath.c
+++ b/ports/unix/guts/realpath.c
diff --git a/guts/remove.c b/ports/unix/guts/remove.c
index 47f8752..902a640 100644
--- a/guts/remove.c
+++ b/ports/unix/guts/remove.c
@@ -7,7 +7,7 @@
* int rc = -1;
*/
struct stat buf;
- if (real___lxstat(_STAT_VER, path, &buf) == -1) {
+ if (real_lstat(path, &buf) == -1) {
errno = ENOENT;
return -1;
}
diff --git a/guts/rename.c b/ports/unix/guts/rename.c
index 8d4106b..04892c1 100644
--- a/guts/rename.c
+++ b/ports/unix/guts/rename.c
@@ -7,7 +7,7 @@
* int rc = -1;
*/
pseudo_msg_t *msg;
- struct stat64 oldbuf, newbuf;
+ struct stat oldbuf, newbuf;
int oldrc, newrc;
int save_errno;
int old_db_entry = 0;
@@ -23,14 +23,14 @@
save_errno = errno;
- newrc = real___lxstat64(_STAT_VER, newpath, &newbuf);
- oldrc = real___lxstat64(_STAT_VER, oldpath, &oldbuf);
+ newrc = real_lstat(newpath, &newbuf);
+ oldrc = real_lstat(oldpath, &oldbuf);
errno = save_errno;
/* newpath must be removed. */
/* as with unlink, we have to mark that the file may get deleted */
- msg = pseudo_client_op(OP_MAY_UNLINK, 0, -1, -1, newpath, newrc ? NULL : &newbuf);
+ msg = pseudo_client_op_plain(OP_MAY_UNLINK, 0, -1, -1, newpath, newrc ? NULL : &newbuf);
if (msg && msg->result == RESULT_SUCCEED)
old_db_entry = 1;
rc = real_rename(oldpath, newpath);
@@ -40,10 +40,10 @@
/* since we failed, that wasn't really unlinked -- put
* it back.
*/
- pseudo_client_op(OP_CANCEL_UNLINK, 0, -1, -1, newpath, &newbuf);
+ pseudo_client_op_plain(OP_CANCEL_UNLINK, 0, -1, -1, newpath, &newbuf);
} else {
/* confirm that the file was removed */
- pseudo_client_op(OP_DID_UNLINK, 0, -1, -1, newpath, &newbuf);
+ pseudo_client_op_plain(OP_DID_UNLINK, 0, -1, -1, newpath, &newbuf);
}
}
if (rc == -1) {
@@ -86,9 +86,9 @@
}
pseudo_debug(1, "creating new '%s' [%llu] to rename\n",
oldpath, (unsigned long long) oldbuf.st_ino);
- pseudo_client_op(OP_LINK, 0, -1, -1, oldpath, &oldbuf);
+ pseudo_client_op_plain(OP_LINK, 0, -1, -1, oldpath, &oldbuf);
}
- pseudo_client_op(OP_RENAME, 0, -1, -1, newpath, &oldbuf, oldpath);
+ pseudo_client_op_plain(OP_RENAME, 0, -1, -1, newpath, &oldbuf, oldpath);
errno = save_errno;
/* return rc;
diff --git a/guts/renameat.c b/ports/unix/guts/renameat.c
index c8203b7..c8203b7 100644
--- a/guts/renameat.c
+++ b/ports/unix/guts/renameat.c
diff --git a/guts/rmdir.c b/ports/unix/guts/rmdir.c
index af7fb7e..7307fcd 100644
--- a/guts/rmdir.c
+++ b/ports/unix/guts/rmdir.c
@@ -7,25 +7,25 @@
* int rc = -1;
*/
pseudo_msg_t *msg;
- struct stat64 buf;
+ struct stat buf;
int save_errno;
int old_db_entry = 0;
- rc = real___lxstat64(_STAT_VER, path, &buf);
+ rc = real_lstat(path, &buf);
if (rc == -1) {
return rc;
}
- msg = pseudo_client_op(OP_MAY_UNLINK, 0, -1, -1, path, &buf);
+ msg = pseudo_client_op_plain(OP_MAY_UNLINK, 0, -1, -1, path, &buf);
if (msg && msg->result == RESULT_SUCCEED)
old_db_entry = 1;
rc = real_rmdir(path);
if (old_db_entry) {
if (rc == -1) {
save_errno = errno;
- pseudo_client_op(OP_CANCEL_UNLINK, 0, -1, -1, path, &buf);
+ pseudo_client_op_plain(OP_CANCEL_UNLINK, 0, -1, -1, path, &buf);
errno = save_errno;
} else {
- pseudo_client_op(OP_DID_UNLINK, 0, -1, -1, path, &buf);
+ pseudo_client_op_plain(OP_DID_UNLINK, 0, -1, -1, path, &buf);
}
} else {
pseudo_debug(1, "rmdir on <%s>, not in database, no effect.\n", path);
diff --git a/guts/symlink.c b/ports/unix/guts/symlink.c
index 487c135..487c135 100644
--- a/guts/symlink.c
+++ b/ports/unix/guts/symlink.c
diff --git a/guts/symlinkat.c b/ports/unix/guts/symlinkat.c
index b70d500..9912c31 100644
--- a/guts/symlinkat.c
+++ b/ports/unix/guts/symlinkat.c
@@ -6,7 +6,7 @@
* wrap_symlinkat(const char *oldname, int dirfd, const char *newpath) {
* int rc = -1;
*/
- struct stat64 buf;
+ struct stat buf;
char *roldname = 0;
if (oldname[0] == '/' && pseudo_chroot_len && !pseudo_nosymlinkexp) {
@@ -30,9 +30,9 @@
return rc;
}
#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
- rc = real___lxstat64(_STAT_VER, newpath, &buf);
+ rc = real_lstat(newpath, &buf);
#else
- rc = real___fxstatat64(_STAT_VER, dirfd, newpath, &buf, AT_SYMLINK_NOFOLLOW);
+ rc = real___fxstatat(_STAT_VER, dirfd, newpath, &buf, AT_SYMLINK_NOFOLLOW);
#endif
if (rc == -1) {
int save_errno = errno;
@@ -43,7 +43,7 @@
return rc;
}
/* just record the entry */
- pseudo_client_op(OP_SYMLINK, 0, -1, dirfd, newpath, &buf);
+ pseudo_client_op_plain(OP_SYMLINK, 0, -1, dirfd, newpath, &buf);
free(roldname);
diff --git a/guts/tempnam.c b/ports/unix/guts/tempnam.c
index 9b0257f..9b0257f 100644
--- a/guts/tempnam.c
+++ b/ports/unix/guts/tempnam.c
diff --git a/guts/tmpnam.c b/ports/unix/guts/tmpnam.c
index 3fece57..3fece57 100644
--- a/guts/tmpnam.c
+++ b/ports/unix/guts/tmpnam.c
diff --git a/guts/truncate.c b/ports/unix/guts/truncate.c
index 6a19a50..6a19a50 100644
--- a/guts/truncate.c
+++ b/ports/unix/guts/truncate.c
diff --git a/guts/unlink.c b/ports/unix/guts/unlink.c
index d8a5d01..d8a5d01 100644
--- a/guts/unlink.c
+++ b/ports/unix/guts/unlink.c
diff --git a/guts/unlinkat.c b/ports/unix/guts/unlinkat.c
index 3bfda81..7b51ab9 100644
--- a/guts/unlinkat.c
+++ b/ports/unix/guts/unlinkat.c
@@ -8,7 +8,7 @@
*/
pseudo_msg_t *msg;
int save_errno;
- struct stat64 buf;
+ struct stat buf;
int old_db_entry;
#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
@@ -29,14 +29,14 @@
#endif
#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
- rc = real___lxstat64(_STAT_VER, path, &buf);
+ rc = real_lstat(path, &buf);
#else
- rc = real___fxstatat64(_STAT_VER, dirfd, path, &buf, AT_SYMLINK_NOFOLLOW);
+ rc = real___fxstatat(_STAT_VER, dirfd, path, &buf, AT_SYMLINK_NOFOLLOW);
#endif
if (rc == -1) {
return rc;
}
- msg = pseudo_client_op(OP_MAY_UNLINK, 0, -1, dirfd, path, &buf);
+ msg = pseudo_client_op_plain(OP_MAY_UNLINK, 0, -1, dirfd, path, &buf);
if (msg && msg->result == RESULT_SUCCEED)
old_db_entry = 1;
#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
@@ -47,10 +47,10 @@
if (old_db_entry) {
if (rc == -1) {
save_errno = errno;
- pseudo_client_op(OP_CANCEL_UNLINK, 0, -1, -1, path, &buf);
+ pseudo_client_op_plain(OP_CANCEL_UNLINK, 0, -1, -1, path, &buf);
errno = save_errno;
} else {
- pseudo_client_op(OP_DID_UNLINK, 0, -1, -1, path, &buf);
+ pseudo_client_op_plain(OP_DID_UNLINK, 0, -1, -1, path, &buf);
}
} else {
pseudo_debug(1, "unlink on <%s>, not in database, no effect.\n", path);
diff --git a/guts/utime.c b/ports/unix/guts/utime.c
index ff65237..ff65237 100644
--- a/guts/utime.c
+++ b/ports/unix/guts/utime.c
diff --git a/guts/utimes.c b/ports/unix/guts/utimes.c
index 69ad949..69ad949 100644
--- a/guts/utimes.c
+++ b/ports/unix/guts/utimes.c
diff --git a/ports/unix/wrapfuncs.in b/ports/unix/wrapfuncs.in
new file mode 100644
index 0000000..b0fdb2c
--- /dev/null
+++ b/ports/unix/wrapfuncs.in
@@ -0,0 +1,56 @@
+int creat(const char *path, mode_t mode);
+char *getcwd(char *buf, size_t size);
+char *getwd(char *buf);
+int close(int fd);
+int fchmod(int fd, mode_t mode);
+int fchown(int fd, uid_t owner, gid_t group);
+int lchown(const char *path, uid_t owner, gid_t group); /* flags=AT_SYMLINK_NOFOLLOW */
+int dup2(int oldfd, int newfd);
+int dup(int fd);
+int chdir(const char *path);
+int fchdir(int dirfd);
+int access(const char *path, int mode);
+FTS *fts_open(char * const *path_argv, int options, int (*compar)(const FTSENT **, const FTSENT **)); /* inode64=1 */
+int ftw(const char *path, int (*fn)(const char *, const struct stat *, int), int nopenfd);
+int nftw(const char *path, int (*fn)(const char *, const struct stat *, int, struct FTW *), int nopenfd, int flag);
+int glob(const char *pattern, int flags, int (*errfunc)(const char *, int), glob_t *pglob);
+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);
+int remove(const char *path); /* flags=AT_SYMLINK_NOFOLLOW */
+DIR *opendir(const char *path);
+char *tempnam(const char *template, const char *pfx);
+char *tmpnam(char *s);
+int truncate(const char *path, off_t length);
+int utime(const char *path, const struct utimbuf *buf);
+int utimes(const char *path, const struct timeval *times);
+# needed because libc stdio does horrible things with inline asm syscalls
+FILE *fopen(const char *path, const char *mode);
+int fclose(FILE *fp);
+FILE *freopen(const char *path, const char *mode, FILE *stream);
+int chroot(const char *path);
+int acct(const char *path);
+int chmod(const char *path, mode_t mode);
+int chown(const char *path, uid_t owner, gid_t group);
+int fchmodat(int dirfd, const char *path, mode_t mode, int flags);
+int fchownat(int dirfd, const char *path, uid_t owner, gid_t group, int flags);
+int link(const char *oldpath, const char *newpath); /* flags=AT_SYMLINK_NOFOLLOW */
+int mkdir(const char *path, mode_t mode); /* flags=AT_SYMLINK_NOFOLLOW */
+int mkdirat(int dirfd, const char *path, mode_t mode); /* flags=AT_SYMLINK_NOFOLLOW */
+int mkfifo(const char *path, mode_t mode); /* flags=AT_SYMLINK_NOFOLLOW */
+int mkfifoat(int dirfd, const char *path, mode_t mode); /* flags=AT_SYMLINK_NOFOLLOW */
+int mknod(const char *path, mode_t mode, dev_t dev); /* flags=AT_SYMLINK_NOFOLLOW */
+int mknodat(int dirfd, const char *path, mode_t mode, dev_t dev); /* flags=AT_SYMLINK_NOFOLLOW */
+int mkstemp(char *template); /* flags=AT_SYMLINK_NOFOLLOW */
+int rename(const char *oldpath, const char *newpath); /* flags=AT_SYMLINK_NOFOLLOW */
+int renameat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath); /* flags=AT_SYMLINK_NOFOLLOW */
+int rmdir(const char *path); /* flags=AT_SYMLINK_NOFOLLOW */
+int symlink(const char *oldname, const char *newpath); /* flags=AT_SYMLINK_NOFOLLOW */
+int symlinkat(const char *oldname, int dirfd, const char *newpath); /* flags=AT_SYMLINK_NOFOLLOW */
+int unlink(const char *path); /* flags=AT_SYMLINK_NOFOLLOW */
+int unlinkat(int dirfd, const char *path, int rflags); /* flags=AT_SYMLINK_NOFOLLOW */
+# primarily for use with chroot()
+ssize_t readlink(const char *path, char *buf, size_t bufsiz); /* flags=AT_SYMLINK_NOFOLLOW */
+ssize_t readlinkat(int dirfd, const char *path, char *buf, size_t bufsiz); /* flags=AT_SYMLINK_NOFOLLOW */
diff --git a/pseudo.1 b/pseudo.1
index a9f37a6..aa32bbe 100644
--- a/pseudo.1
+++ b/pseudo.1
@@ -401,14 +401,21 @@ in the
directory, while clients log to standard error.
.TP 8
.B PSEUDO_DISABLED
-If this variable is set to a value that doesn't look like f, F, n, N, or
+If this variable is set to a value that doesn't look like f, F, n, N, s, S, or
a numeric zero, the
.I pseudo
client library does not modify the behavior of called functions, though it
continues to intercept them and block signals while processing them. This
variable is reevaluated on every call to
.IR fork(2) ,\ clone(2)
-or related functions.
+or related functions. If the value starts with a lowercase or uppercase s,
+the pseudo client disables all server spawning and communications, but still
+operates locally. This means that no filesystem mode or permissions changes
+are actually recorded or reported, but functions like
+.I chown()
+will still report success, even though nothing happens. This function is
+intended for debugging of issues which are complicated by the server's
+involvement.
.TP 8
.B PSEUDO_ENOSYS_ABORT
If this variable is set, the
diff --git a/pseudo.c b/pseudo.c
index 7d3c90a..99ad1f1 100644
--- a/pseudo.c
+++ b/pseudo.c
@@ -94,8 +94,8 @@ main(int argc, char *argv[]) {
int o;
char *s;
int lockfd, newfd;
- char *ld_env = getenv("LD_PRELOAD");
- int rc;
+ char *ld_env = getenv(PRELINK_LIBRARIES);
+ int rc = 0;
char opts[pseudo_path_max()], *optptr = opts;
char *lockname;
char *lockpath;
@@ -105,17 +105,17 @@ main(int argc, char *argv[]) {
pseudo_init_util();
if (ld_env && strstr(ld_env, "libpseudo")) {
- pseudo_debug(2, "can't run daemon with libpseudo in LD_PRELOAD\n");
+ pseudo_debug(2, "can't run daemon with libpseudo in %s\n", PRELINK_LIBRARIES);
s = pseudo_get_value("PSEUDO_RELOADED");
if (s) {
- pseudo_diag("I can't seem to make LD_PRELOAD go away. Sorry.\n");
- pseudo_diag("LD_PRELOAD: %s\n", ld_env);
+ pseudo_diag("I can't seem to make %s go away. Sorry.\n", PRELINK_LIBRARIES);
+ pseudo_diag("%s: %s\n", PRELINK_LIBRARIES, ld_env);
exit(EXIT_FAILURE);
}
free(s);
pseudo_set_value("PSEUDO_RELOADED", "YES");
pseudo_setupenv();
- pseudo_dropenv(); /* Drop LD_PRELOAD */
+ pseudo_dropenv(); /* Drop PRELINK_LIBRARIES */
execv(argv[0], argv);
exit(EXIT_FAILURE);
@@ -359,14 +359,14 @@ main(int argc, char *argv[]) {
if ((path = getenv("PATH")) == NULL)
path = "/bin:/usr/bin";
while (*path) {
- struct stat64 buf;
+ struct stat buf;
int len = strcspn(path, ":");
snprintf(fullpath, pseudo_path_max(), "%.*s/%s",
len, path, argv[0]);
path += len;
if (*path == ':')
++path;
- if (!stat64(fullpath, &buf)) {
+ if (!stat(fullpath, &buf)) {
if (buf.st_mode & 0111) {
found = 1;
break;
@@ -937,14 +937,14 @@ pseudo_server_response(pseudo_msg_t *msg, const char *program, const char *tag)
int
pseudo_db_check(int fix) {
- struct stat64 buf;
+ struct stat buf;
pseudo_msg_t *m;
pdb_file_list l;
int errors = 0;
int delete_some = 0;
/* magic cookie used to show who's deleting the files */
int magic_cookie = (int) getpid();
- int rc;
+ int rc = 0;
l = pdb_files();
if (!l) {
@@ -959,7 +959,7 @@ pseudo_db_check(int fix) {
if (m->pathlen > 0) {
int fixup_needed = 0;
pseudo_debug(1, "Checking <%s>\n", m->path);
- if (lstat64(m->path, &buf)) {
+ if (lstat(m->path, &buf)) {
errors = EXIT_FAILURE;
pseudo_diag("can't stat <%s>\n", m->path);
continue;
diff --git a/pseudo.h b/pseudo.h
index a101597..297d6d8 100644
--- a/pseudo.h
+++ b/pseudo.h
@@ -56,15 +56,17 @@ extern char *pseudo_bindir_path(char *);
extern char *pseudo_libdir_path(char *);
extern char *pseudo_localstatedir_path(char *);
extern char *pseudo_get_prefix(char *);
-extern char *pseudo_get_bindir();
-extern char *pseudo_get_libdir();
-extern char *pseudo_get_localstatedir();
+extern char *pseudo_get_bindir(void);
+extern char *pseudo_get_libdir(void);
+extern char *pseudo_get_localstatedir(void);
extern int pseudo_logfile(char *defname);
extern ssize_t pseudo_sys_path_max(void);
extern ssize_t pseudo_path_max(void);
#define PSEUDO_PWD_MAX 4096
extern int pseudo_etc_file(const char *filename, char *realname, int flags, char **search, int dircount);
#define PSEUDO_ETC_FILE(name, realname, flags) pseudo_etc_file((name), (realname), (flags), (char *[]) { pseudo_chroot, pseudo_passwd }, 2)
+extern void pseudo_stat32_from64(struct stat *, const struct stat64 *);
+extern void pseudo_stat64_from32(struct stat64 *, const struct stat *);
extern char *pseudo_version;
@@ -111,3 +113,4 @@ extern char *pseudo_version;
#define O_LARGEFILE 0
#endif
+#include "pseudo_ports.h"
diff --git a/pseudo_client.c b/pseudo_client.c
index 319fa05..b53ee25 100644
--- a/pseudo_client.c
+++ b/pseudo_client.c
@@ -32,13 +32,19 @@
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
+#include <pwd.h>
+#include <grp.h>
#include "pseudo.h"
#include "pseudo_ipc.h"
#include "pseudo_client.h"
/* GNU extension */
+#if PSEUDO_PORT_LINUX
extern char *program_invocation_name;
+#else
+static char *program_invocation_name = "unknown";
+#endif
static char *base_path(int dirfd, const char *path, int leave_last);
@@ -60,6 +66,7 @@ size_t pseudo_chroot_len = 0;
char *pseudo_cwd_rel = NULL;
/* used for PSEUDO_DISABLED */
int pseudo_disabled = 0;
+static int pseudo_local_only = 0;
static char **fd_paths = NULL;
static int nfds = 0;
@@ -117,7 +124,9 @@ pseudo_init_client(void) {
* pseudo (and cause it to reinit the defaults).
*/
env = getenv("PSEUDO_DISABLED");
- if (!env) pseudo_get_value("PSEUDO_DISABLED");
+ if (!env) {
+ env = pseudo_get_value("PSEUDO_DISABLED");
+ }
if (env) {
int actually_disabled = 1;
switch (*env) {
@@ -128,6 +137,11 @@ pseudo_init_client(void) {
case 'N':
actually_disabled = 0;
break;
+ case 's':
+ case 'S':
+ actually_disabled = 0;
+ pseudo_local_only = 1;
+ break;
}
if (actually_disabled) {
if (!pseudo_disabled) {
@@ -287,10 +301,26 @@ pseudo_file_close(int *fd, FILE **fp) {
}
pseudo_antimagic();
if (*fp) {
+#if PSEUDO_PORT_DARWIN
+ if (*fp == pseudo_host_etc_passwd_file) {
+ endpwent();
+ } else if (*fp != pseudo_host_etc_group_file) {
+ endgrent();
+ } else {
+ fclose(*fp);
+ }
+#else
fclose(*fp);
+#endif
*fd = -1;
*fp = 0;
}
+#if PSEUDO_PORT_DARWIN
+ if (*fd == pseudo_host_etc_passwd_fd ||
+ *fd == pseudo_host_etc_group_fd) {
+ *fd = -1;
+ }
+#endif
/* this should be impossible */
if (*fd >= 0) {
close(*fd);
@@ -308,6 +338,15 @@ pseudo_file_open(char *name, int *fd, FILE **fp) {
pseudo_file_close(fd, fp);
pseudo_antimagic();
*fd = PSEUDO_ETC_FILE(name, NULL, O_RDONLY);
+#if PSEUDO_PORT_DARWIN
+ if (*fd == pseudo_host_etc_passwd_fd) {
+ *fp = pseudo_host_etc_passwd_file;
+ setpwent();
+ } else if (*fd == pseudo_host_etc_group_fd) {
+ *fp = pseudo_host_etc_group_file;
+ setgrent();
+ }
+#endif
if (*fd >= 0) {
*fd = pseudo_fd(*fd, MOVE_FD);
*fp = fdopen(*fd, "r");
@@ -601,7 +640,7 @@ client_spawn_server(void) {
pseudo_set_value("PSEUDO_RELOADED", "YES");
pseudo_setupenv();
- pseudo_dropenv(); /* drop LD_PRELOAD */
+ pseudo_dropenv(); /* drop PRELINK_LIBRARIES */
pseudo_debug(4, "calling execv on %s\n", argv[0]);
@@ -679,9 +718,13 @@ pseudo_fd(int fd, int how) {
static int
client_connect(void) {
/* we have a server pid, is it responsive? */
- struct sockaddr_un sun = { AF_UNIX, PSEUDO_SOCKET };
+ struct sockaddr_un sun = { .sun_family = AF_UNIX, .sun_path = PSEUDO_SOCKET };
int cwd_fd;
+#if PSEUDO_PORT_DARWIN
+ sun.sun_len = strlen(PSEUDO_SOCKET) + 1;
+#endif
+
connect_fd = socket(PF_UNIX, SOCK_STREAM, 0);
connect_fd = pseudo_fd(connect_fd, MOVE_FD);
if (connect_fd == -1) {
@@ -959,8 +1002,29 @@ base_path(int dirfd, const char *path, int leave_last) {
return newpath;
}
+#if PSEUDO_STATBUF_64
+pseudo_msg_t *
+pseudo_client_op_plain(pseudo_op_t op, int access, int fd, int dirfd, const char *path, const struct stat *buf, ...) {
+ char *oldpath = NULL;
+ PSEUDO_STATBUF buf64;
+
+ if (op == OP_RENAME) {
+ va_list ap;
+ va_start(ap, buf);
+ oldpath = va_arg(ap, char *);
+ va_end(ap);
+ }
+ if (buf) {
+ pseudo_stat64_from32(&buf64, buf);
+ return pseudo_client_op(op, access, fd, dirfd, path, &buf64, oldpath);
+ } else {
+ return pseudo_client_op(op, access, fd, dirfd, path, NULL, oldpath);
+ }
+}
+#endif
+
pseudo_msg_t *
-pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path, const struct stat64 *buf, ...) {
+pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path, const PSEUDO_STATBUF *buf, ...) {
pseudo_msg_t *result = 0;
pseudo_msg_t msg = { .type = PSEUDO_MSG_OP };
size_t pathlen = -1;
@@ -1156,7 +1220,12 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path
struct timeval tv1, tv2;
pseudo_debug(4, "sending request [ino %llu]\n", (unsigned long long) msg.ino);
gettimeofday(&tv1, NULL);
- result = pseudo_client_request(&msg, pathlen, path);
+ if (pseudo_local_only) {
+ /* disable server */
+ result = NULL;
+ } else {
+ result = pseudo_client_request(&msg, pathlen, path);
+ }
gettimeofday(&tv2, NULL);
++messages;
message_time.tv_sec += (tv2.tv_sec - tv1.tv_sec);
@@ -1208,40 +1277,6 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path
return result;
}
-void
-pseudo_stat32_from64(struct stat *buf32, struct stat64 *buf) {
- buf32->st_dev = buf->st_dev;
- buf32->st_ino = buf->st_ino;
- buf32->st_mode = buf->st_mode;
- buf32->st_nlink = buf->st_nlink;
- buf32->st_uid = buf->st_uid;
- buf32->st_gid = buf->st_gid;
- buf32->st_rdev = buf->st_rdev;
- buf32->st_size = buf->st_size;
- buf32->st_blksize = buf->st_blksize;
- buf32->st_blocks = buf->st_blocks;
- buf32->st_atime = buf->st_atime;
- buf32->st_mtime = buf->st_mtime;
- buf32->st_ctime = buf->st_ctime;
-}
-
-void
-pseudo_stat64_from32(struct stat64 *buf64, struct stat *buf) {
- buf64->st_dev = buf->st_dev;
- buf64->st_ino = buf->st_ino;
- buf64->st_mode = buf->st_mode;
- buf64->st_nlink = buf->st_nlink;
- buf64->st_uid = buf->st_uid;
- buf64->st_gid = buf->st_gid;
- buf64->st_rdev = buf->st_rdev;
- buf64->st_size = buf->st_size;
- buf64->st_blksize = buf->st_blksize;
- buf64->st_blocks = buf->st_blocks;
- buf64->st_atime = buf->st_atime;
- buf64->st_mtime = buf->st_mtime;
- buf64->st_ctime = buf->st_ctime;
-}
-
/* stuff for handling paths and execs */
static char *previous_path;
static char *previous_path_segs;
@@ -1257,7 +1292,7 @@ static void
populate_path_segs(void) {
size_t len = 0;
char *s;
- int c;
+ int c = 0;
free(path_segs);
free(previous_path_segs);
diff --git a/pseudo_client.h b/pseudo_client.h
index 44d697b..58ad875 100644
--- a/pseudo_client.h
+++ b/pseudo_client.h
@@ -17,7 +17,12 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
-extern pseudo_msg_t *pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path, const struct stat64 *buf, ...);
+extern pseudo_msg_t *pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path, const PSEUDO_STATBUF *buf, ...);
+#if PSEUDO_STATBUF_64
+extern pseudo_msg_t *pseudo_client_op_plain(pseudo_op_t op, int access, int fd, int dirfd, const char *path, const struct stat *buf, ...);
+#else
+#define pseudo_client_op_plain pseudo_client_op
+#endif
extern void pseudo_antimagic(void);
extern void pseudo_magic(void);
extern void pseudo_client_touchuid(void);
@@ -25,8 +30,6 @@ extern void pseudo_client_touchgid(void);
extern char *pseudo_client_fdpath(int fd);
extern int pseudo_client_shutdown(void);
extern int pseudo_fd(int fd, int how);
-extern void pseudo_stat32_from64(struct stat *, struct stat64 *);
-extern void pseudo_stat64_from32(struct stat64 *, struct stat *);
#define MOVE_FD 0
#define COPY_FD 1
#define PSEUDO_MIN_FD 20
diff --git a/pseudo_db.c b/pseudo_db.c
index 575fd72..540a3c2 100644
--- a/pseudo_db.c
+++ b/pseudo_db.c
@@ -529,11 +529,13 @@ get_dbs(void) {
int err = 0;
int i;
for (i = 0; db_infos[i].db; ++i) {
- if (get_db(&db_infos[i]))
+ if (get_db(&db_infos[i])) {
+ pseudo_diag("Error getting '%s' database.\n",
+ db_infos[i].pathname);
err = 1;
-
+ }
}
- return !err;
+ return err;
}
/* put a prepared log entry into the database */
@@ -544,7 +546,7 @@ pdb_log_traits(pseudo_query_t *traits) {
int rc;
if (!log_db && get_dbs()) {
- pseudo_diag("database error.\n");
+ pseudo_diag("%s: database error.\n", __func__);
return 1;
}
e = calloc(sizeof(*e), 1);
@@ -642,7 +644,7 @@ pdb_log_entry(log_entry *e) {
int rc;
if (!log_db && get_dbs()) {
- pseudo_diag("database error.\n");
+ pseudo_diag("%s: database error.\n", __func__);
return 1;
}
@@ -740,7 +742,7 @@ pdb_log_msg(pseudo_sev_t severity, pseudo_msg_t *msg, const char *program, const
}
if (!log_db && get_dbs()) {
- pseudo_diag("database error.\n");
+ pseudo_diag("%s: database error.\n", __func__);
return 1;
}
@@ -874,7 +876,7 @@ pdb_query(char *stmt_type, pseudo_query_t *traits, unsigned long fields, int uni
static buffer *sql;
if (!log_db && get_dbs()) {
- pseudo_diag("database error.\n");
+ pseudo_diag("%s: database error.\n", __func__);
return NULL;
}
@@ -1262,7 +1264,7 @@ pdb_link_file(pseudo_msg_t *msg) {
" VALUES (?, ?, ?, ?, ?, ?, ?, 0);";
if (!file_db && get_dbs()) {
- pseudo_diag("database error.\n");
+ pseudo_diag("%s: database error.\n", __func__);
return 0;
}
if (!insert) {
@@ -1307,7 +1309,7 @@ pdb_unlink_file_dev(pseudo_msg_t *msg) {
char *sql = "DELETE FROM files WHERE dev = ? AND ino = ?;";
if (!file_db && get_dbs()) {
- pseudo_diag("database error.\n");
+ pseudo_diag("%s: database error.\n", __func__);
return 0;
}
if (!sql_delete) {
@@ -1340,7 +1342,7 @@ pdb_update_file_path(pseudo_msg_t *msg) {
"WHERE path = 'NAMELESS FILE' and dev = ? AND ino = ?;";
if (!file_db && get_dbs()) {
- pseudo_diag("database error.\n");
+ pseudo_diag("%s: database error.\n", __func__);
return 0;
}
if (!update) {
@@ -1374,7 +1376,7 @@ pdb_may_unlink_file(pseudo_msg_t *msg, int deleting) {
char *sql_mark_file = "UPDATE files SET deleting = ? WHERE path = ?;";
if (!file_db && get_dbs()) {
- pseudo_diag("database error.\n");
+ pseudo_diag("%s: database error.\n", __func__);
return 0;
}
if (!mark_file) {
@@ -1418,7 +1420,7 @@ pdb_cancel_unlink_file(pseudo_msg_t *msg) {
char *sql_mark_file = "UPDATE files SET deleting = 0 WHERE path = ?;";
if (!file_db && get_dbs()) {
- pseudo_diag("database error.\n");
+ pseudo_diag("%s: database error.\n", __func__);
return 0;
}
if (!mark_file) {
@@ -1458,7 +1460,7 @@ pdb_did_unlink_files(int deleting) {
char *sql_delete_exact = "DELETE FROM files WHERE deleting = ?;";
if (!file_db && get_dbs()) {
- pseudo_diag("database error.\n");
+ pseudo_diag("%s: database error.\n", __func__);
return 0;
}
if (!delete_exact) {
@@ -1492,7 +1494,7 @@ pdb_did_unlink_file(char *path, int deleting) {
char *sql_delete_exact = "DELETE FROM files WHERE path = ? AND deleting = ?;";
if (!file_db && get_dbs()) {
- pseudo_diag("database error.\n");
+ pseudo_diag("%s: database error.\n", __func__);
return 0;
}
if (!delete_exact) {
@@ -1527,7 +1529,7 @@ pdb_unlink_file(pseudo_msg_t *msg) {
char *sql_delete_exact = "DELETE FROM files WHERE path = ?;";
if (!file_db && get_dbs()) {
- pseudo_diag("database error.\n");
+ pseudo_diag("%s: database error.\n", __func__);
return 0;
}
if (!delete_exact) {
@@ -1573,7 +1575,7 @@ pdb_unlink_contents(pseudo_msg_t *msg) {
"(path > (? || '/') AND path < (? || '0'));";
if (!file_db && get_dbs()) {
- pseudo_diag("database error.\n");
+ pseudo_diag("%s: database error.\n", __func__);
return 0;
}
if (!delete_sub) {
@@ -1622,7 +1624,7 @@ pdb_rename_file(const char *oldpath, pseudo_msg_t *msg) {
"WHERE (path > (? || '/') AND path < (? || '0'));";
if (!file_db && get_dbs()) {
- pseudo_diag("database error.\n");
+ pseudo_diag("%s: database error.\n", __func__);
return 0;
}
if (!update_exact) {
@@ -1691,7 +1693,7 @@ pdb_renumber_all(dev_t from, dev_t to) {
" WHERE dev = ?;";
if (!file_db && get_dbs()) {
- pseudo_diag("database error.\n");
+ pseudo_diag("%s: database error.\n", __func__);
return 0;
}
if (!update) {
@@ -1732,7 +1734,7 @@ pdb_update_inode(pseudo_msg_t *msg) {
" WHERE path = ?;";
if (!file_db && get_dbs()) {
- pseudo_diag("database error.\n");
+ pseudo_diag("%s: database error.\n", __func__);
return 0;
}
if (!update) {
@@ -1784,7 +1786,7 @@ pdb_update_file(pseudo_msg_t *msg) {
" WHERE dev = ? AND ino = ?;";
if (!file_db && get_dbs()) {
- pseudo_diag("database error.\n");
+ pseudo_diag("%s: database error.\n", __func__);
return 0;
}
if (!update) {
@@ -1824,7 +1826,7 @@ pdb_find_file_exact(pseudo_msg_t *msg) {
char *sql = "SELECT * FROM files WHERE path = ? AND dev = ? AND ino = ?;";
if (!file_db && get_dbs()) {
- pseudo_diag("database error.\n");
+ pseudo_diag("%s: database error.\n", __func__);
return 0;
}
if (!select) {
@@ -1875,7 +1877,7 @@ pdb_find_file_path(pseudo_msg_t *msg) {
char *sql = "SELECT * FROM files WHERE path = ?;";
if (!file_db && get_dbs()) {
- pseudo_diag("database error.\n");
+ pseudo_diag("%s: database error.\n", __func__);
return 1;
}
if (!select) {
@@ -1932,7 +1934,7 @@ pdb_get_file_path(pseudo_msg_t *msg) {
char *response;
if (!file_db && get_dbs()) {
- pseudo_diag("database error.\n");
+ pseudo_diag("%s: database error.\n", __func__);
return 0;
}
if (!select) {
@@ -1981,7 +1983,7 @@ pdb_find_file_dev(pseudo_msg_t *msg) {
char *sql = "SELECT * FROM files WHERE dev = ? AND ino = ?;";
if (!file_db && get_dbs()) {
- pseudo_diag("database error.\n");
+ pseudo_diag("%s: database error.\n", __func__);
return 0;
}
if (!select) {
@@ -2030,7 +2032,7 @@ pdb_find_file_ino(pseudo_msg_t *msg) {
char *sql = "SELECT * FROM files WHERE ino = ?;";
if (!file_db && get_dbs()) {
- pseudo_diag("database error.\n");
+ pseudo_diag("%s: database error.\n", __func__);
return 0;
}
if (!select) {
@@ -2074,7 +2076,7 @@ pdb_files(void) {
pdb_file_list l;
if (!file_db && get_dbs()) {
- pseudo_diag("database error.\n");
+ pseudo_diag("%s: database error.\n", __func__);
return 0;
}
diff --git a/pseudo_ipc.c b/pseudo_ipc.c
index 61e00b8..341c647 100644
--- a/pseudo_ipc.c
+++ b/pseudo_ipc.c
@@ -220,7 +220,7 @@ pseudo_msg_new(size_t pathlen, const char *path) {
*/
void
-pseudo_msg_stat(pseudo_msg_t *msg, const struct stat64 *buf) {
+pseudo_msg_stat(pseudo_msg_t *msg, const PSEUDO_STATBUF *buf) {
if (!msg || !buf)
return;
msg->uid = buf->st_uid;
@@ -233,7 +233,7 @@ pseudo_msg_stat(pseudo_msg_t *msg, const struct stat64 *buf) {
}
void
-pseudo_stat_msg(struct stat64 *buf, const pseudo_msg_t *msg) {
+pseudo_stat_msg(PSEUDO_STATBUF *buf, const pseudo_msg_t *msg) {
if (!msg || !buf)
return;
buf->st_uid = msg->uid;
@@ -242,3 +242,23 @@ pseudo_stat_msg(struct stat64 *buf, const pseudo_msg_t *msg) {
buf->st_rdev = msg->rdev;
}
+#if PSEUDO_STATBUF_64
+void
+pseudo_msg_stat_plain(pseudo_msg_t *msg, const struct stat *buf) {
+ PSEUDO_STATBUF buf64;
+ if (buf) {
+ pseudo_stat64_from32(&buf64, buf);
+ pseudo_msg_stat(msg, &buf64);
+ }
+}
+
+void
+pseudo_stat_msg_plain(struct stat *buf, const pseudo_msg_t *msg) {
+ PSEUDO_STATBUF buf64;
+ if (buf) {
+ pseudo_stat64_from32(&buf64, buf);
+ pseudo_stat_msg(&buf64, msg);
+ pseudo_stat32_from64(buf, &buf64);
+ }
+}
+#endif
diff --git a/pseudo_ipc.h b/pseudo_ipc.h
index b65c7fb..48aaa38 100644
--- a/pseudo_ipc.h
+++ b/pseudo_ipc.h
@@ -64,5 +64,12 @@ extern pseudo_msg_t *pseudo_msg_dupheader(pseudo_msg_t *);
extern pseudo_msg_t *pseudo_msg_new(size_t, const char *);
extern int pseudo_msg_send(int fd, pseudo_msg_t *, size_t, const char *);
-void pseudo_msg_stat(pseudo_msg_t *msg, const struct stat64 *buf);
-void pseudo_stat_msg(struct stat64 *buf, const pseudo_msg_t *msg);
+void pseudo_msg_stat(pseudo_msg_t *msg, const PSEUDO_STATBUF *buf);
+void pseudo_stat_msg(PSEUDO_STATBUF *buf, const pseudo_msg_t *msg);
+#if PSEUDO_STATBUF_64
+void pseudo_stat_msg_plain(struct stat *buf, const pseudo_msg_t *msg);
+void pseudo_msg_stat_plain(pseudo_msg_t *msg, const struct stat *buf);
+#else
+#define pseudo_stat_msg_plain pseudo_stat_msg
+#define pseudo_msg_stat_plain pseudo_msg_stat
+#endif
diff --git a/pseudo_server.c b/pseudo_server.c
index 50425de..e64c68c 100644
--- a/pseudo_server.c
+++ b/pseudo_server.c
@@ -105,10 +105,14 @@ pseudo_server_write_pid(pid_t pid) {
int
pseudo_server_start(int daemonize) {
- struct sockaddr_un sun = { AF_UNIX, PSEUDO_SOCKET };
+ struct sockaddr_un sun = { .sun_family = AF_UNIX, .sun_path = PSEUDO_SOCKET };
char *pseudo_path;
int rc, newfd;
+#if PSEUDO_PORT_DARWIN
+ sun.sun_len = strlen(PSEUDO_SOCKET) + 1;
+#endif
+
listen_fd = socket(PF_UNIX, SOCK_STREAM, 0);
if (listen_fd < 0) {
pseudo_diag("couldn't create listening socket: %s\n", strerror(errno));
diff --git a/pseudo_util.c b/pseudo_util.c
index 704655e..d19bd0c 100644
--- a/pseudo_util.c
+++ b/pseudo_util.c
@@ -204,7 +204,7 @@ static ssize_t pseudo_sys_max_pathlen = -1;
* libc.so -- this forces rebuilds of the library when the C library
* changes. The problem is that the pseudo binary may be
* a prebuilt, in which case it doesn't know about CHECKSUM, so it
- * has to determine whether a given LD_PRELOAD contains libpseudo.so
+ * has to determine whether a given PRELINK_LIBRARIES contains libpseudo.so
* or libpseudoCHECKSUM.so, without prior knowledge... Fancy!
*
* We search for anything matching libpseudo*.so, where * is any
@@ -213,9 +213,13 @@ static ssize_t pseudo_sys_max_pathlen = -1;
* the end of the string or a space after it.
*/
static char *libpseudo_name = "libpseudo.so";
-static char *libpseudo_pattern = "(^|=| )libpseudo[^ ]*\\.so($| )";
+/* this used to look for a "libpseudo*.so", but it turns out you can
+ * specify a path even on Linux.
+ */
+static char *libpseudo_pattern = "(^|=| )[^ ]*libpseudo[^ ]*\\.so($| )";
static regex_t libpseudo_regex;
static int libpseudo_regex_compiled = 0;
+
/* Okay, so, there's a funny story behind this. On one of the systems
* we need to run on, /usr/bin/find happens to provide its own
* definitions of regcomp and regexec which are INCOMPATIBLE with the
@@ -226,8 +230,13 @@ static int libpseudo_regex_compiled = 0;
* no one called us from a program with incompatible variants.
*
*/
+#if PSEUDO_PORT_LINUX
static int (*real_regcomp)(regex_t *__restrict __preg, const char *__restrict __pattern, int __cflags);
static int (*real_regexec)(const regex_t *__restrict __preg, const char *__restrict __string, size_t __nmatch, regmatch_t __pmatch[__restrict_arr], int __eflags);
+#else
+#define real_regcomp regcomp
+#define real_regexec regexec
+#endif /* PSEUDO_PORT_LINUX */
static int
libpseudo_regex_init(void) {
@@ -235,20 +244,22 @@ libpseudo_regex_init(void) {
if (libpseudo_regex_compiled)
return 0;
+#if PSEUDO_PORT_LINUX
real_regcomp = dlsym(RTLD_NEXT, "regcomp");
if (!real_regcomp)
real_regcomp = regcomp;
real_regexec = dlsym(RTLD_NEXT, "regexec");
if (!real_regexec)
real_regexec = regexec;
+#endif
rc = (*real_regcomp)(&libpseudo_regex, libpseudo_pattern, REG_EXTENDED);
if (rc == 0)
libpseudo_regex_compiled = 1;
return rc;
}
-/* given a space-separated list of files, ala LD_PRELOAD, return that
- * list without any variants of libpseudo*.so.
+/* given a space-or-colon-separated list of files, ala PRELINK_LIBRARIES,
+ # return that list without any variants of libpseudo*.so.
*/
static char *
without_libpseudo(char *list) {
@@ -259,7 +270,7 @@ without_libpseudo(char *list) {
if (libpseudo_regex_init())
return NULL;
- if (list[0] == '=' || list[0] == ' ')
+ if (list[0] == '=' || list[0] == PSEUDO_LINKPATH_SEPARATOR[0])
skip_start = 1;
if ((*real_regexec)(&libpseudo_regex, list, 1, pmatch, 0)) {
@@ -282,20 +293,42 @@ without_libpseudo(char *list) {
}
static char *
-with_libpseudo(char *list) {
+with_libpseudo(char *list, char *libdir_path) {
regmatch_t pmatch[1];
+
if (libpseudo_regex_init())
return NULL;
if ((*real_regexec)(&libpseudo_regex, list, 1, pmatch, 0)) {
+ size_t len;
+#if PSEUDO_PORT_DARWIN
+ /* <%s:%s/%s\0> */
+ len = strlen(list) + 1 + strlen(libdir_path) + 1 + strlen(libpseudo_name) + 1;
+#else
+ /* suppress warning */
+ (void) libdir_path;
/* <%s %s\0> */
- size_t len = strlen(list) + 1 + strlen(libpseudo_name) + 1;
+ len = strlen(list) + 1 + strlen(libpseudo_name) + 1;
+#endif
char *new = malloc(len);
- if (new)
- snprintf(new, len, "%s %s", list,
+ if (new) {
+ /* insert space only if there were previous bits */
+ /* on Darwin, we have to provide the full path to
+ * libpseudo
+ */
+#if PSEUDO_PORT_DARWIN
+ snprintf(new, len, "%s%s%s/%s", list,
+ *list ? PSEUDO_LINKPATH_SEPARATOR : "",
+ libdir_path ? libdir_path : "",
libpseudo_name);
+#else
+ snprintf(new, len, "%s%s%s", list,
+ *list ? PSEUDO_LINKPATH_SEPARATOR : "",
+ libpseudo_name);
+#endif
+ }
return new;
} else {
- return list;
+ return strdup(list);
}
}
@@ -399,7 +432,7 @@ pseudo_append_element(char **pnewpath, char **proot, size_t *pallocated, char **
static int link_recursion = 0;
size_t curlen, allocated;
char *newpath, *current, *root;
- struct stat64 buf;
+ struct stat buf;
if (!pnewpath || !*pnewpath ||
!pcurrent || !*pcurrent ||
!proot || !*proot ||
@@ -461,7 +494,7 @@ pseudo_append_element(char **pnewpath, char **proot, size_t *pallocated, char **
/* if lstat fails, that's fine -- nonexistent files aren't symlinks */
if (!leave_this) {
int is_link;
- is_link = (lstat64(newpath, &buf) != -1) && S_ISLNK(buf.st_mode);
+ is_link = (lstat(newpath, &buf) != -1) && S_ISLNK(buf.st_mode);
if (link_recursion >= PSEUDO_MAX_LINK_RECURSION && is_link) {
pseudo_diag("link recursion too deep, not expanding path '%s'.\n", newpath);
is_link = 0;
@@ -621,17 +654,19 @@ pseudo_fix_path(const char *base, const char *path, size_t rootlen, size_t basel
* we don't try to fix the library path.
*/
void pseudo_dropenv() {
- char * ld_preload = getenv("LD_PRELOAD");
+ char *ld_preload = getenv(PRELINK_LIBRARIES);
if (ld_preload) {
ld_preload = without_libpseudo(ld_preload);
if (!ld_preload) {
- pseudo_diag("fatal: can't allocate new LD_PRELOAD variable.\n");
+ pseudo_diag("fatal: can't allocate new %s variable.\n", PRELINK_LIBRARIES);
+ }
+ if (ld_preload && strlen(ld_preload)) {
+ pseudo_diag("ld_preload without: <%s>\n", ld_preload);
+ setenv(PRELINK_LIBRARIES, ld_preload, 1);
+ } else {
+ unsetenv(PRELINK_LIBRARIES);
}
- if (ld_preload && strlen(ld_preload))
- setenv("LD_PRELOAD", ld_preload, 1);
- else
- unsetenv("LD_PRELOAD");
}
}
@@ -650,15 +685,15 @@ pseudo_dropenvp(char * const *envp) {
j = 0;
for (i = 0; envp[i]; ++i) {
- if (STARTSWITH(envp[i], "LD_PRELOAD=")) {
+ if (STARTSWITH(envp[i], PRELINK_LIBRARIES "=")) {
char *new_val = without_libpseudo(envp[i]);
if (!new_val) {
pseudo_diag("fatal: can't allocate new environment variable.\n");
return 0;
} else {
/* don't keep an empty value; if the whole string is
- * LD_PRELOAD=, we just drop it. */
- if (strcmp(new_val, "LD_PRELOAD=")) {
+ * PRELINK_LIRBARIES=, we just drop it. */
+ if (strcmp(new_val, PRELINK_LIBRARIES "=")) {
new_envp[j++] = new_val;
}
}
@@ -690,40 +725,58 @@ pseudo_setupenv() {
i++;
}
- char * ld_preload = getenv("LD_PRELOAD");
- if (ld_preload) {
- ld_preload = with_libpseudo(ld_preload);
- if (!ld_preload) {
- pseudo_diag("fatal: can't allocate new LD_PRELOAD variable.\n");
- }
- setenv("LD_PRELOAD", ld_preload, 1);
- } else {
- setenv("LD_PRELOAD", libpseudo_name, 1);
- }
-
- const char *ld_library_path = getenv("LD_LIBRARY_PATH");
- char * libdir_path = pseudo_libdir_path(NULL);
+ const char *ld_library_path = getenv(PRELINK_PATH);
+ char *libdir_path = pseudo_libdir_path(NULL);
if (!ld_library_path) {
size_t len = strlen(libdir_path) + 1 + (strlen(libdir_path) + 2) + 1;
char *newenv = malloc(len);
if (!newenv) {
- pseudo_diag("fatal: can't allocate new LD_LIBRARY_PATH variable.\n");
+ pseudo_diag("fatal: can't allocate new %s variable.\n", PRELINK_PATH);
}
snprintf(newenv, len, "%s:%s64", libdir_path, libdir_path);
- setenv("LD_LIBRARY_PATH", newenv, 1);
+ setenv(PRELINK_PATH, newenv, 1);
} else if (!strstr(ld_library_path, libdir_path)) {
size_t len = strlen(ld_library_path) + 1 + strlen(libdir_path) + 1 + (strlen(libdir_path) + 2) + 1;
char *newenv = malloc(len);
if (!newenv) {
- pseudo_diag("fatal: can't allocate new LD_LIBRARY_PATH variable.\n");
+ pseudo_diag("fatal: can't allocate new %s variable.\n", PRELINK_PATH);
}
snprintf(newenv, len, "%s:%s:%s64", ld_library_path, libdir_path, libdir_path);
- setenv("LD_LIBRARY_PATH", newenv, 1);
+ setenv(PRELINK_PATH, newenv, 1);
} else {
/* nothing to do, ld_library_path exists and contains
* our preferred path */
}
+
+ char *ld_preload = getenv(PRELINK_LIBRARIES);
+ if (ld_preload) {
+ ld_preload = with_libpseudo(ld_preload, libdir_path);
+ if (!ld_preload) {
+ pseudo_diag("fatal: can't allocate new %s variable.\n", PRELINK_LIBRARIES);
+ }
+ setenv(PRELINK_LIBRARIES, ld_preload, 1);
+ free(ld_preload);
+ } else {
+ ld_preload = with_libpseudo("", libdir_path);
+ if (!ld_preload) {
+ pseudo_diag("fatal: can't allocate new %s variable.\n", PRELINK_LIBRARIES);
+ }
+ setenv(PRELINK_LIBRARIES, ld_preload, 1);
+ free(ld_preload);
+ }
+
+ /* we kept libdir path until now because with_libpseudo might
+ * need it
+ */
free(libdir_path);
+
+
+#if PSEUDO_PORT_DARWIN
+ char *force_flat = getenv("DYLD_FORCE_FLAT_NAMESPACE");
+ if (!force_flat) {
+ setenv("DYLD_FORCE_FLAT_NAMESPACE", "1", 1);
+ }
+#endif
}
/* add pseudo stuff to the environment.
@@ -751,10 +804,10 @@ pseudo_setupenvp(char * const *envp) {
free(pseudo_get_localstatedir());
for (i = 0; envp[i]; ++i) {
- if (STARTSWITH(envp[i], "LD_PRELOAD=")) {
+ if (STARTSWITH(envp[i], PRELINK_LIBRARIES "=")) {
ld_preload = envp[i];
}
- if (STARTSWITH(envp[i], "LD_LIBRARY_PATH=")) {
+ if (STARTSWITH(envp[i], PRELINK_PATH "=")) {
ld_library_path = envp[i];
}
++env_count;
@@ -773,33 +826,20 @@ pseudo_setupenvp(char * const *envp) {
return NULL;
}
- if (ld_preload) {
- ld_preload = with_libpseudo(ld_preload);
- if (!ld_preload) {
- pseudo_diag("fatal: can't allocate new LD_PRELOAD variable.\n");
- }
- new_envp[j++] = ld_preload;
- } else {
- size_t len = strlen("LD_PRELOAD=") + strlen(libpseudo_name) + 1;
- char *newenv = malloc(len);
- snprintf(newenv, len, "LD_PRELOAD=%s", libpseudo_name);
- new_envp[j++] = newenv;
- }
-
char *libdir_path = pseudo_libdir_path(NULL);
if (!ld_library_path) {
- size_t len = strlen("LD_LIBRARY_PATH=") + strlen(libdir_path) + 1 + (strlen(libdir_path) + 2) + 1;
+ size_t len = strlen(PRELINK_PATH "=") + strlen(libdir_path) + 1 + (strlen(libdir_path) + 2) + 1;
char *newenv = malloc(len);
if (!newenv) {
- pseudo_diag("fatal: can't allocate new LD_LIBRARY_PATH variable.\n");
+ pseudo_diag("fatal: can't allocate new %s variable.\n", PRELINK_PATH);
}
- snprintf(newenv, len, "LD_LIBRARY_PATH=%s:%s64", libdir_path, libdir_path);
+ snprintf(newenv, len, PRELINK_PATH "=%s:%s64", libdir_path, libdir_path);
new_envp[j++] = newenv;
} else if (!strstr(ld_library_path, libdir_path)) {
size_t len = strlen(ld_library_path) + 1 + strlen(libdir_path) + 1 + (strlen(libdir_path) + 2) + 1;
char *newenv = malloc(len);
if (!newenv) {
- pseudo_diag("fatal: can't allocate new LD_LIBRARY_PATH variable.\n");
+ pseudo_diag("fatal: can't allocate new %s variable.\n", PRELINK_PATH);
}
snprintf(newenv, len, "%s:%s:%s64", ld_library_path, libdir_path, libdir_path);
new_envp[j++] = newenv;
@@ -807,11 +847,27 @@ pseudo_setupenvp(char * const *envp) {
/* keep old value */
new_envp[j++] = ld_library_path;
}
+
+ if (ld_preload) {
+ ld_preload = with_libpseudo(ld_preload, libdir_path);
+ if (!ld_preload) {
+ pseudo_diag("fatal: can't allocate new %s variable.\n", PRELINK_LIBRARIES);
+ }
+ new_envp[j++] = ld_preload;
+ } else {
+ ld_preload = with_libpseudo("", libdir_path);
+ size_t len = strlen(PRELINK_LIBRARIES "=") + strlen(ld_preload) + 1;
+ char *newenv = malloc(len);
+ snprintf(newenv, len, PRELINK_LIBRARIES "=%s", ld_preload);
+ new_envp[j++] = newenv;
+ free(ld_preload);
+ }
+
free(libdir_path);
for (i = 0; envp[i]; ++i) {
- if (STARTSWITH(envp[i], "LD_PRELOAD=")) continue;
- if (STARTSWITH(envp[i], "LD_LIBRARY_PATH=")) continue;
+ if (STARTSWITH(envp[i], PRELINK_LIBRARIES "=")) continue;
+ if (STARTSWITH(envp[i], PRELINK_PATH "=")) continue;
new_envp[j++] = envp[i];
}
@@ -892,7 +948,7 @@ pseudo_prefix_path(char *file) {
char *
pseudo_bindir_path(char *file) {
char * rc;
- char * bindir = pseudo_get_bindir(NULL);
+ char * bindir = pseudo_get_bindir();
if (!bindir) {
pseudo_diag("You must set the PSEUDO_BINDIR environment variable to run pseudo.\n");
@@ -909,7 +965,7 @@ pseudo_bindir_path(char *file) {
char *
pseudo_libdir_path(char *file) {
char * rc;
- char * libdir = pseudo_get_libdir(NULL);
+ char * libdir = pseudo_get_libdir();
if (!libdir) {
pseudo_diag("You must set the PSEUDO_LIBDIR environment variable to run pseudo.\n");
@@ -926,7 +982,7 @@ pseudo_libdir_path(char *file) {
char *
pseudo_localstatedir_path(char *file) {
char * rc;
- char * localstatedir = pseudo_get_localstatedir(NULL);
+ char * localstatedir = pseudo_get_localstatedir();
if (!localstatedir) {
pseudo_diag("You must set the PSEUDO_LOCALSTATEDIR environment variable to run pseudo.\n");
@@ -996,7 +1052,7 @@ pseudo_get_prefix(char *pathname) {
}
char *
-pseudo_get_bindir() {
+pseudo_get_bindir(void) {
char *s = pseudo_get_value("PSEUDO_BINDIR");
if (!s) {
char *pseudo_bindir = pseudo_prefix_path(PSEUDO_BINDIR);;
@@ -1009,15 +1065,19 @@ pseudo_get_bindir() {
}
char *
-pseudo_get_libdir() {
+pseudo_get_libdir(void) {
char *s = pseudo_get_value("PSEUDO_LIBDIR");
if (!s) {
- char *pseudo_libdir = pseudo_prefix_path(PSEUDO_LIBDIR);
+ char *pseudo_libdir;
+ pseudo_libdir = pseudo_prefix_path(PSEUDO_LIBDIR);
if (pseudo_libdir) {
pseudo_set_value("PSEUDO_LIBDIR", pseudo_libdir);
s = pseudo_libdir;
}
}
+#if PSEUDO_PORT_DARWIN
+ /* on Darwin, we need lib64, because dyld won't search */
+#else
/* If we somehow got lib64 in there, clean it down to just lib... */
if (s) {
size_t len = strlen(s);
@@ -1026,6 +1086,7 @@ pseudo_get_libdir() {
pseudo_set_value("PSEUDO_LIBDIR", s);
}
}
+#endif
return s;
}
@@ -1144,6 +1205,23 @@ pseudo_access_fopen(const char *mode) {
* - /etc/<file>
*/
+#if PSEUDO_PORT_DARWIN
+/* on Darwin, you can't just use /etc/passwd for system lookups,
+ * you have to use the real library calls because they know about
+ * Directory Services. So...
+ *
+ * We make up fake fds and FILE * objects that can't possibly be
+ * valid.
+ */
+int pseudo_host_etc_passwd_fd = -3;
+int pseudo_host_etc_group_fd = -4;
+static FILE pseudo_fake_passwd_file;
+static FILE pseudo_fake_group_file;
+FILE *pseudo_host_etc_passwd_file = &pseudo_fake_passwd_file;
+FILE *pseudo_host_etc_group_file = &pseudo_fake_group_file;
+
+#endif
+
int
pseudo_etc_file(const char *file, char *realname, int flags, char **search_dirs, int dircount) {
char filename[pseudo_path_max()];
@@ -1181,6 +1259,15 @@ pseudo_etc_file(const char *file, char *realname, int flags, char **search_dirs,
} else {
pseudo_debug(2, "pseudo_etc_file: no search dirs.\n");
}
+#if PSEUDO_PORT_DARWIN
+ if (!strcmp("passwd", file)) {
+ pseudo_debug(2, "Darwin hackery: pseudo_etc_passwd returning magic passwd fd\n");
+ return pseudo_host_etc_passwd_fd;
+ } else if (!strcmp("group", file)) {
+ pseudo_debug(2, "Darwin hackery: pseudo_etc_passwd returning magic group fd\n");
+ return pseudo_host_etc_group_fd;
+ }
+#endif
snprintf(filename, pseudo_path_max(), "/etc/%s", file);
pseudo_debug(2, "falling back on <%s> for <%s>\n",
filename, file);
@@ -1200,7 +1287,11 @@ pseudo_logfile(char *defname) {
char *pseudo_path;
char *filename = pseudo_get_value("PSEUDO_DEBUG_FILE");
char *s;
+#if PSEUDO_PORT_LINUX
extern char *program_invocation_short_name; /* glibcism */
+#else
+ char *program_invocation_short_name = "unknown";
+#endif
int fd;
if (!filename) {
@@ -1288,3 +1379,37 @@ pseudo_logfile(char *defname) {
else
return 0;
}
+
+void
+pseudo_stat32_from64(struct stat *buf32, const struct stat64 *buf) {
+ buf32->st_dev = buf->st_dev;
+ buf32->st_ino = buf->st_ino;
+ buf32->st_mode = buf->st_mode;
+ buf32->st_nlink = buf->st_nlink;
+ buf32->st_uid = buf->st_uid;
+ buf32->st_gid = buf->st_gid;
+ buf32->st_rdev = buf->st_rdev;
+ buf32->st_size = buf->st_size;
+ buf32->st_blksize = buf->st_blksize;
+ buf32->st_blocks = buf->st_blocks;
+ buf32->st_atime = buf->st_atime;
+ buf32->st_mtime = buf->st_mtime;
+ buf32->st_ctime = buf->st_ctime;
+}
+
+void
+pseudo_stat64_from32(struct stat64 *buf64, const struct stat *buf) {
+ buf64->st_dev = buf->st_dev;
+ buf64->st_ino = buf->st_ino;
+ buf64->st_mode = buf->st_mode;
+ buf64->st_nlink = buf->st_nlink;
+ buf64->st_uid = buf->st_uid;
+ buf64->st_gid = buf->st_gid;
+ buf64->st_rdev = buf->st_rdev;
+ buf64->st_size = buf->st_size;
+ buf64->st_blksize = buf->st_blksize;
+ buf64->st_blocks = buf->st_blocks;
+ buf64->st_atime = buf->st_atime;
+ buf64->st_mtime = buf->st_mtime;
+ buf64->st_ctime = buf->st_ctime;
+}
diff --git a/pseudo_wrappers.c b/pseudo_wrappers.c
index 470206a..dd4a800 100644
--- a/pseudo_wrappers.c
+++ b/pseudo_wrappers.c
@@ -1,5 +1,21 @@
-/* wrapper code -- this is the shared code used around the pseduo
- * wrapper functions, which are in pseudo_wrapfuncs.c.
+/*
+ * pseudo_wrappers.c, shared code for wrapper functions
+ *
+ * Copyright (c) 2008-2011 Wind River Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the Lesser GNU General Public License version 2.1 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the Lesser GNU General Public License for more details.
+ *
+ * You should have received a copy of the Lesser GNU General Public License
+ * version 2.1 along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
*/
#include <assert.h>
#include <stdlib.h>
@@ -91,12 +107,22 @@ pseudo_init_wrappers(void) {
char *e;
dlerror();
f = dlsym(RTLD_NEXT, pseudo_functions[i].name);
- if ((e = dlerror()) != NULL) {
- /* leave it NULL, which our implementation checks for */
- pseudo_diag("No wrapper for %s: %s\n", pseudo_functions[i].name, e);
+ if (f) {
+ *pseudo_functions[i].real = f;
} else {
- if (f)
- *pseudo_functions[i].real = f;
+ 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
}
}
}
@@ -210,426 +236,4 @@ pseudo_check_wrappers(void) {
return _libpseudo_initted;
}
-static char **
-execl_to_v(va_list ap, const char *argv0, char *const **envp) {
- size_t i = 0;
- size_t alloc_size = 256;
-
- char **argv = malloc((sizeof *argv) * alloc_size);
-
- if (!argv) {
- pseudo_debug(1, "execl failed: couldn't allocate memory for %lu arguments\n",
- (unsigned long) alloc_size);
- return NULL;
- }
- argv[i++] = (char *) argv0;
-
- while (argv[i-1]) {
- argv[i++] = va_arg(ap, char *const);
- if (i > alloc_size - 1) {
- alloc_size = alloc_size + 256;
- argv = realloc(argv, (sizeof *argv) * alloc_size);
- if (!argv) {
- pseudo_debug(1, "execl failed: couldn't allocate memory for %lu arguments\n",
- (unsigned long) alloc_size);
- return NULL;
- }
- }
- }
- if (envp) {
- *envp = va_arg(ap, char **);
- }
- return argv;
-}
-
-/* The following wrappers require Special Handling */
-
-int
-execl(const char *file, const char *arg, ...) {
- sigset_t saved;
- va_list ap;
- char **argv;
-
- int rc = -1;
-
- if (!pseudo_check_wrappers()) {
- /* rc was initialized to the "failure" value */
- pseudo_enosys("execl");
- return rc;
- }
-
- va_start(ap, arg);
- argv = execl_to_v(ap, arg, 0);
- va_end(ap);
- if (!argv) {
- errno = ENOMEM;
- return -1;
- }
-
- pseudo_debug(4, "called: execl\n");
- pseudo_sigblock(&saved);
- if (pseudo_getlock()) {
- errno = EBUSY;
- sigprocmask(SIG_SETMASK, &saved, NULL);
- return -1;
- }
-
- int save_errno;
-
- /* exec*() use this to restore the sig mask */
- pseudo_saved_sigmask = saved;
- rc = wrap_execv(file, argv);
-
- save_errno = errno;
- pseudo_droplock();
- sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: execl\n");
- errno = save_errno;
- free(argv);
- return rc;
-}
-
-int
-execlp(const char *file, const char *arg, ...) {
- sigset_t saved;
- va_list ap;
- char **argv;
-
- int rc = -1;
-
- if (!pseudo_check_wrappers()) {
- /* rc was initialized to the "failure" value */
- pseudo_enosys("execlp");
- return rc;
- }
-
- va_start(ap, arg);
- argv = execl_to_v(ap, arg, 0);
- va_end(ap);
- if (!argv) {
- errno = ENOMEM;
- return -1;
- }
-
- pseudo_debug(4, "called: execlp\n");
- pseudo_sigblock(&saved);
- if (pseudo_getlock()) {
- errno = EBUSY;
- sigprocmask(SIG_SETMASK, &saved, NULL);
- return -1;
- }
-
- int save_errno;
-
- /* exec*() use this to restore the sig mask */
- pseudo_saved_sigmask = saved;
- rc = wrap_execvp(file, argv);
-
- save_errno = errno;
- pseudo_droplock();
- sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: execlp\n");
- errno = save_errno;
- free(argv);
- return rc;
-}
-
-int
-execle(const char *file, const char *arg, ...) {
- sigset_t saved;
- va_list ap;
- char **argv;
- char **envp;
-
- int rc = -1;
-
- if (!pseudo_check_wrappers()) {
- /* rc was initialized to the "failure" value */
- pseudo_enosys("execle");
- return rc;
- }
-
- va_start(ap, arg);
- argv = execl_to_v(ap, arg, (char *const **)&envp);
- va_end(ap);
- if (!argv) {
- errno = ENOMEM;
- return -1;
- }
-
- pseudo_debug(4, "called: execle\n");
- pseudo_sigblock(&saved);
- if (pseudo_getlock()) {
- errno = EBUSY;
- sigprocmask(SIG_SETMASK, &saved, NULL);
- return -1;
- }
-
- int save_errno;
-
- /* exec*() use this to restore the sig mask */
- pseudo_saved_sigmask = saved;
- rc = wrap_execve(file, argv, envp);
-
- save_errno = errno;
- pseudo_droplock();
- sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: execle\n");
- errno = save_errno;
- free(argv);
- return rc;
-}
-
-int
-execv(const char *file, char *const *argv) {
- sigset_t saved;
-
- int rc = -1;
-
- if (!pseudo_check_wrappers() || !real_execv) {
- /* rc was initialized to the "failure" value */
- pseudo_enosys("execv");
- return rc;
- }
-
- pseudo_debug(4, "called: execv\n");
- pseudo_sigblock(&saved);
- if (pseudo_getlock()) {
- errno = EBUSY;
- sigprocmask(SIG_SETMASK, &saved, NULL);
- return -1;
- }
-
- int save_errno;
-
- /* exec*() use this to restore the sig mask */
- pseudo_saved_sigmask = saved;
- rc = wrap_execv(file, argv);
-
- save_errno = errno;
- pseudo_droplock();
- sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: execv\n");
- errno = save_errno;
- return rc;
-}
-
-int
-execve(const char *file, char *const *argv, char *const *envp) {
- sigset_t saved;
-
- int rc = -1;
-
- if (!pseudo_check_wrappers() || !real_execve) {
- /* rc was initialized to the "failure" value */
- pseudo_enosys("execve");
- return rc;
- }
-
- pseudo_debug(4, "called: execve\n");
- pseudo_sigblock(&saved);
- if (pseudo_getlock()) {
- errno = EBUSY;
- sigprocmask(SIG_SETMASK, &saved, NULL);
- return -1;
- }
-
- int save_errno;
-
- /* exec*() use this to restore the sig mask */
- pseudo_saved_sigmask = saved;
- rc = wrap_execve(file, argv, envp);
-
- save_errno = errno;
- pseudo_droplock();
- sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: execve\n");
- errno = save_errno;
- return rc;
-}
-
-int
-execvp(const char *file, char *const *argv) {
- sigset_t saved;
-
- int rc = -1;
-
- if (!pseudo_check_wrappers() || !real_execvp) {
- /* rc was initialized to the "failure" value */
- pseudo_enosys("execvp");
- return rc;
- }
-
- pseudo_debug(4, "called: execvp\n");
- pseudo_sigblock(&saved);
- if (pseudo_getlock()) {
- errno = EBUSY;
- sigprocmask(SIG_SETMASK, &saved, NULL);
- return -1;
- }
-
- int save_errno;
-
- /* exec*() use this to restore the sig mask */
- pseudo_saved_sigmask = saved;
- rc = wrap_execvp(file, argv);
-
- save_errno = errno;
- pseudo_droplock();
- sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: execvp\n");
- errno = save_errno;
- return rc;
-}
-
-int
-fork(void) {
- sigset_t saved;
-
- int rc = -1;
-
- if (!pseudo_check_wrappers() || !real_fork) {
- /* rc was initialized to the "failure" value */
- pseudo_enosys("fork");
- return rc;
- }
-
- pseudo_debug(4, "called: fork\n");
- pseudo_sigblock(&saved);
- if (pseudo_getlock()) {
- errno = EBUSY;
- sigprocmask(SIG_SETMASK, &saved, NULL);
- return -1;
- }
-
- int save_errno;
-
- rc = wrap_fork();
-
- save_errno = errno;
-
- pseudo_droplock();
- sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: fork\n");
- errno = save_errno;
- return rc;
-}
-
-int
-vfork(void) {
- /* we don't provide support for the distinct semantics
- * of vfork()
- */
- return fork();
-}
-
-int
-clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...) {
- sigset_t saved;
- va_list ap;
- pid_t *pid;
- struct user_desc *tls;
- pid_t *ctid;
-
- int rc = -1;
-
- if (!pseudo_check_wrappers() || !real_clone) {
- /* rc was initialized to the "failure" value */
- pseudo_enosys("clone");
- return rc;
- }
-
- va_start(ap, arg);
- pid = va_arg(ap, pid_t *);
- tls = va_arg(ap, struct user_desc *);
- ctid = va_arg(ap, pid_t *);
- va_end(ap);
-
- pseudo_debug(4, "called: clone\n");
- pseudo_sigblock(&saved);
- if (pseudo_getlock()) {
- errno = EBUSY;
- sigprocmask(SIG_SETMASK, &saved, NULL);
- return -1;
- }
-
- int save_errno;
- int save_disabled = pseudo_disabled;
- /* because clone() doesn't actually continue in this function, we
- * can't check the return and fix up environment variables in the
- * child. Instead, we have to temporarily do any fixup, then possibly
- * undo it later. UGH!
- */
-
-#include "guts/clone.c"
-
- if (save_disabled != pseudo_disabled) {
- if (pseudo_disabled) {
- pseudo_disabled = 0;
- pseudo_magic();
- } else {
- pseudo_disabled = 1;
- pseudo_antimagic();
- }
- }
-
- save_errno = errno;
- pseudo_droplock();
- sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: clone\n");
- errno = save_errno;
- return rc;
-}
-
-#if 0
-static int (*real_execlp)(const char *file, const char *arg, ...) = NULL;
-static int (*real_execl)(const char *file, const char *arg, ...) = NULL;
-static int (*real_execle)(const char *file, const char *arg, ...) = NULL;
-#endif
-static int (*real_execv)(const char *file, char *const *argv) = NULL;
-static int (*real_execve)(const char *file, char *const *argv, char *const *envp) = NULL;
-static int (*real_execvp)(const char *file, char *const *argv) = NULL;
-static int (*real_fork)(void) = NULL;
-static int (*real_clone)(int (*)(void *), void *, int, void *, ...) = NULL;
-
-static int
-wrap_execv(const char *file, char *const *argv) {
- int rc = -1;
-
-#include "guts/execv.c"
-
- return rc;
-}
-
-static int
-wrap_execve(const char *file, char *const *argv, char *const *envp) {
- int rc = -1;
-
-#include "guts/execve.c"
-
- return rc;
-}
-
-static int
-wrap_execvp(const char *file, char *const *argv) {
- int rc = -1;
-
-#include "guts/execvp.c"
-
- return rc;
-}
-
-static int
-wrap_fork(void) {
- int rc = -1;
-
-#include "guts/fork.c"
-
- return rc;
-}
-
-int
-wrap_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...) {
- /* unused */
- return 0;
-}
+#include "port_wrappers.c"
diff --git a/templatefile.py b/templatefile.py
index e08bc64..11e002c 100644
--- a/templatefile.py
+++ b/templatefile.py
@@ -16,6 +16,8 @@ class TemplateFile:
# empty footer if none specified:
self.sections['footer'] = []
+ # empty per-port if none specified:
+ self.sections['port'] = []
# lines appended to body by default
self.sections['body'] = []
@@ -45,7 +47,10 @@ class TemplateFile:
current.append(line)
self.template.close()
for section, data in self.sections.items():
- self.sections[section] = Template("\n".join(data))
+ if len(data) > 0:
+ self.sections[section] = Template("\n".join(data))
+ else:
+ self.sections[section] = None
# You need a file if this isn't a file-per-item
if not self.file_per_item:
@@ -68,8 +73,7 @@ class TemplateFile:
strings.append(data.safe_substitute({}))
return "\n".join(strings)
- def emit(self, template, item=None):
- """Emit a template, with optional interpolation of an item."""
+ def get_file(self, item):
if self.file_per_item:
if not item:
return
@@ -84,16 +88,24 @@ class TemplateFile:
(path, self.path, template)
return
+ def emit(self, template, item=None):
+ """Emit a template, with optional interpolation of an item."""
if template == "copyright":
# hey, at least it's not a global variable, amirite?
- self.file.write(TemplateFile.copyright)
+ self.get_file(item)
+ if self.file:
+ self.file.write(TemplateFile.copyright)
elif template in self.sections:
templ = self.sections[template]
- self.file.write(templ.safe_substitute(item))
- self.file.write("\n")
+ if templ:
+ self.get_file(item)
+ if self.file:
+ self.file.write(templ.safe_substitute(item))
+ self.file.write("\n")
else:
print "Warning: Unknown template '%s'." % template
if self.file_per_item:
- self.file.close()
+ if self.file:
+ self.file.close()
self.file = None
diff --git a/templates/guts b/templates/guts
index 3e32fb2..e2c9880 100644
--- a/templates/guts
+++ b/templates/guts
@@ -1,4 +1,5 @@
-@name guts/${name}.c
+@name ports/${port}/guts/${name}.c
+@header
@body
/*
* Copyright (c) ${date} Wind River Systems; see
diff --git a/templates/port_wrappers b/templates/port_wrappers
new file mode 100644
index 0000000..7ff7ff8
--- /dev/null
+++ b/templates/port_wrappers
@@ -0,0 +1,5 @@
+@name port_wrappers.c
+@header
+/* additional hand-written wrappers for ports which provide them */
+@port
+${include}
diff --git a/templates/pseudo_ports b/templates/pseudo_ports
new file mode 100644
index 0000000..113a2b6
--- /dev/null
+++ b/templates/pseudo_ports
@@ -0,0 +1,6 @@
+@name pseudo_ports.h
+@header
+/* #defines for port-specific hackery */
+@port
+${define}
+${portdefs}
diff --git a/templates/wrapfuncs.c b/templates/wrapfuncs.c
index 0a90efd..61b52ff 100644
--- a/templates/wrapfuncs.c
+++ b/templates/wrapfuncs.c
@@ -13,7 +13,9 @@
* script if you want to modify this. */
@body
-static ${type} (*real_${name})(${decl_args}) = NULL;
+static ${type} (*real_${name})(${decl_args}) = ${real_init};
+
+${maybe_skip}
${type}
${name}(${decl_args}) {
@@ -58,7 +60,7 @@ ${name}(${decl_args}) {
save_errno = errno;
pseudo_droplock();
sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: $name\n");
+ pseudo_debug(4, "completed: $name (maybe: %s)\n", strerror(save_errno));
errno = save_errno;
${rc_return}
}
@@ -69,8 +71,9 @@ wrap_${name}(${wrap_args}) {
${maybe_variadic_decl}
${maybe_variadic_start}
-#include "guts/${name}.c"
+#include "ports/${port}/guts/${name}.c"
${rc_return}
}
+${end_maybe_skip}
diff --git a/templates/wrapfuncs.h b/templates/wrapfuncs.h
index 403d261..1ce4fcc 100644
--- a/templates/wrapfuncs.h
+++ b/templates/wrapfuncs.h
@@ -8,22 +8,5 @@
/* ${comment} */
static ${type} wrap_${name}(${wrap_args});
static ${type} (*real_${name})(${decl_args});
+${real_predecl}
@footer
-/* special cases: functions with manually-written wrappers */
-
-/* int fork(void) */
-static int wrap_fork(void);
-static int (*real_fork)(void);
-/* int clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...) */
-static int wrap_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...);
-static int (*real_clone)(int (*fn)(void *), void *child_stack, int flags, void *arg, ...);
-/* int execv(const char *file, char *const *argv) */
-static int wrap_execv(const char *file, char *const *argv);
-static int (*real_execv)(const char *file, char *const *argv);
-/* int execve(const char *file, char *const *argv, char *const *envp) */
-static int wrap_execve(const char *file, char *const *argv, char *const *envp);
-static int (*real_execve)(const char *file, char *const *argv, char *const *envp);
-/* int execvp(const char *file, char *const *argv) */
-static int wrap_execvp(const char *file, char *const *argv);
-static int (*real_execvp)(const char *file, char *const *argv);
-
diff --git a/templates/wrapper_table b/templates/wrapper_table
index dd9c249..2e79fcd 100644
--- a/templates/wrapper_table
+++ b/templates/wrapper_table
@@ -11,36 +11,10 @@ static struct {
} pseudo_functions[] = {
@body
{ /* ${comment}; */
- "${name}",
+ "${name}${maybe_inode64}",
(int (**)(void)) &real_${name},
(int (*)(void)) wrap_${name}
},
@footer
- /* special cases: Functions which need manually-coded wrappers */
- { /* int fork(void); */
- "fork",
- (int (**)(void)) &real_fork,
- (int (*)(void)) wrap_fork
- },
- { /* int clone(int (*fn)(void *), void *, int, void, ...); */
- "clone",
- (int (**)(void)) &real_clone,
- (int (*)(void)) wrap_clone
- },
- { /* int execv(const char *file, char *const *argv); */
- "execv",
- (int (**)(void)) &real_execv,
- (int (*)(void)) wrap_execv
- },
- { /* int execve(const char *file, char *const *argv, char *const *envp); */
- "execve",
- (int (**)(void)) &real_execve,
- (int (*)(void)) wrap_execve
- },
- { /* int execvp(const char *file, char *const *argv); */
- "execvp",
- (int (**)(void)) &real_execvp,
- (int (*)(void)) wrap_execvp
- },
{ NULL, NULL, NULL },
};
diff --git a/wrapfuncs.in b/wrapfuncs.in
deleted file mode 100644
index a30486b..0000000
--- a/wrapfuncs.in
+++ /dev/null
@@ -1,124 +0,0 @@
-int open(const char *path, int flags, ...{mode_t mode}); /* flags=0 */
-char *getcwd(char *buf, size_t size);
-char *getwd(char *buf);
-char *get_current_dir_name(void);
-int close(int fd);
-int link(const char *oldpath, const char *newpath); /* flags=AT_SYMLINK_NOFOLLOW */
-int rename(const char *oldpath, const char *newpath); /* flags=AT_SYMLINK_NOFOLLOW */
-int renameat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath); /* flags=AT_SYMLINK_NOFOLLOW */
-int unlink(const char *path); /* flags=AT_SYMLINK_NOFOLLOW */
-int unlinkat(int dirfd, const char *path, int rflags); /* flags=AT_SYMLINK_NOFOLLOW */
-int creat(const char *path, mode_t mode);
-int __xstat(int ver, const char *path, struct stat *buf);
-int __lxstat(int ver, const char *path, struct stat *buf); /* flags=AT_SYMLINK_NOFOLLOW */
-int __fxstat(int ver, int fd, struct stat *buf);
-int chmod(const char *path, mode_t mode);
-int fchmod(int fd, mode_t mode);
-int chown(const char *path, uid_t owner, gid_t group);
-int fchown(int fd, uid_t owner, gid_t group);
-int lchown(const char *path, uid_t owner, gid_t group); /* flags=AT_SYMLINK_NOFOLLOW */
-int __fxstatat(int ver, int dirfd, const char *path, struct stat *buf, int flags);
-int fchownat(int dirfd, const char *path, uid_t owner, gid_t group, int flags);
-int fchmodat(int dirfd, const char *path, mode_t mode, int flags);
-int openat(int dirfd, const char *path, int flags, ...{mode_t mode});
-int __openat_2(int dirfd, const char *path, int flags);
-int __xmknod(int ver, const char *path, mode_t mode, dev_t *dev); /* flags=AT_SYMLINK_NOFOLLOW */
-int __xmknodat(int ver, int dirfd, const char *path, mode_t mode, dev_t *dev); /* flags=AT_SYMLINK_NOFOLLOW */
-int dup2(int oldfd, int newfd);
-int dup(int fd);
-int mkdir(const char *path, mode_t mode); /* flags=AT_SYMLINK_NOFOLLOW */
-int mkdirat(int dirfd, const char *path, mode_t mode); /* flags=AT_SYMLINK_NOFOLLOW */
-int rmdir(const char *path); /* flags=AT_SYMLINK_NOFOLLOW */
-int chdir(const char *path);
-int fchdir(int dirfd);
-int fcntl(int fd, int cmd, ...{struct flock *lock});
-# just so we know the inums of symlinks
-int symlink(const char *oldname, const char *newpath); /* flags=AT_SYMLINK_NOFOLLOW */
-int symlinkat(const char *oldname, int dirfd, const char *newpath); /* flags=AT_SYMLINK_NOFOLLOW */
-# needed because glibc stdio does horrible things with inline asm syscalls
-FILE *fopen(const char *path, const char *mode);
-int fclose(FILE *fp);
-FILE *freopen(const char *path, const char *mode, FILE *stream);
-int mkstemp(char *template); /* flags=AT_SYMLINK_NOFOLLOW */
-# I bet you never knew there were this many of these!
-int setfsuid(uid_t fsuid);
-int setfsgid(gid_t fsgid);
-int seteuid(uid_t euid);
-int setegid(gid_t egid);
-uid_t getuid(void);
-uid_t geteuid(void);
-gid_t getgid(void);
-gid_t getegid(void);
-int setresuid(uid_t ruid, uid_t euid, uid_t suid);
-int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
-int setuid(uid_t uid);
-int setgid(gid_t gid);
-int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
-int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid);
-int setreuid(uid_t ruid, uid_t euid);
-int setregid(gid_t rgid, gid_t egid);
-int setgroups(size_t size, const gid_t *list);
-# primarily for use with chroot()
-int chroot(const char *path);
-ssize_t readlink(const char *path, char *buf, size_t bufsiz); /* flags=AT_SYMLINK_NOFOLLOW */
-ssize_t readlinkat(int dirfd, const char *path, char *buf, size_t bufsiz); /* flags=AT_SYMLINK_NOFOLLOW */
-int access(const char *path, int mode);
-int acct(const char *path);
-char *canonicalize_file_name(const char *filename);
-int eaccess(const char *path, int mode);
-int euidaccess(const char *path, int mode);
-FTS *fts_open(char * const *path_argv, int options, int (*compar)(const FTSENT **, const FTSENT **));
-int ftw(const char *path, int (*fn)(const char *, const struct stat *, int), int nopenfd);
-int nftw(const char *path, int (*fn)(const char *, const struct stat *, int, struct FTW *), int nopenfd, int flag);
-int glob(const char *pattern, int flags, int (*errfunc)(const char *, int), glob_t *pglob);
-int lutimes(const char *path, const struct timeval *tv);
-char *mkdtemp(char *template);
-int mkfifo(const char *path, mode_t mode); /* flags=AT_SYMLINK_NOFOLLOW */
-int mkfifoat(int dirfd, const char *path, mode_t mode); /* flags=AT_SYMLINK_NOFOLLOW */
-char *mktemp(char *template);
-long pathconf(const char *path, int name);
-char *realpath(const char *name, char *resolved_name);
-int remove(const char *path); /* flags=AT_SYMLINK_NOFOLLOW */
-DIR *opendir(const char *path);
-int scandir(const char *path, struct dirent ***namelist, int (*filter)(const struct dirent *), int (*compar)());
-char *tempnam(const char *template, const char *pfx);
-char *tmpnam(char *s);
-int truncate(const char *path, off_t length);
-int utime(const char *path, const struct utimbuf *buf);
-int utimes(const char *path, const struct timeval *times);
-# for emulation of passwd utilities
-struct passwd *getpwnam(const char *name);
-struct passwd *getpwuid(uid_t uid);
-int getpwnam_r(const char *name, struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp);
-int getpwuid_r(uid_t uid, struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp);
-int getpwent_r(struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp);
-struct passwd *getpwent(void);
-void setpwent(void);
-void endpwent(void);
-int lckpwdf(void);
-int ulckpwdf(void);
-int getpw(uid_t uid, char *buf);
-struct group *getgrnam(const char *name);
-struct group *getgrgid(gid_t gid);
-int getgrnam_r(const char *name, struct group *gbuf, char *buf, size_t buflen, struct group **gbufp);
-int getgrgid_r(gid_t gid, struct group *gbuf, char *buf, size_t buflen, struct group **gbufp);
-struct group *getgrent(void);
-int getgrent_r(struct group *gbuf, char *buf, size_t buflen, struct group **gbufp);
-void setgrent(void);
-void endgrent(void);
-int getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups);
-int getgroups(int size, gid_t *list);
-# we use "pathname" to avoid canonicalizing paths, because these functions are
-# unimplemented
-ssize_t getxattr(const char *pathname, const char *name, void *value, size_t size);
-ssize_t lgetxattr(const char *pathname, const char *name, void *value, size_t size);
-ssize_t fgetxattr(int filedes, const char *name, void *value, size_t size);
-ssize_t listxattr(const char *pathname, char *list, size_t size);
-ssize_t llistxattr(const char *pathname, char *list, size_t size);
-ssize_t flistxattr(int filedes, char *list, size_t size);
-int setxattr(const char *pathname, const char *name, const void *value, size_t size, int flags);
-int lsetxattr(const char *pathname, const char *name, const void *value, size_t size, int flags);
-int fsetxattr(int filedes, const char *name, const void *value, size_t size, int flags);
-int removexattr(const char *pathname, const char *name);
-int lremovexattr(const char *pathname, const char *name);
-int fremovexattr(int filedes, const char *name);
diff --git a/wrapfuncs64.in b/wrapfuncs64.in
deleted file mode 100644
index 71ab0a6..0000000
--- a/wrapfuncs64.in
+++ /dev/null
@@ -1,16 +0,0 @@
-int open64(const char *path, int flags, ...{mode_t mode}); /* flags=0 */
-int openat64(int dirfd, const char *path, int flags, ...{mode_t mode}); /* flags=0 */
-int __openat64_2(int dirfd, const char *path, int flags); /* flags=0 */
-int creat64(const char *path, mode_t mode);
-int __xstat64(int ver, const char *path, struct stat64 *buf);
-int __lxstat64(int ver, const char *path, struct stat64 *buf); /* flags=AT_SYMLINK_NOFOLLOW */
-int __fxstat64(int ver, int fd, struct stat64 *buf);
-int __fxstatat64(int ver, int dirfd, const char *path, struct stat64 *buf, int flags);
-FILE *fopen64(const char *path, const char *mode);
-int nftw64(const char *path, int (*fn)(const char *, const struct stat64 *, int, struct FTW *), int nopenfd, int flag);
-FILE *freopen64(const char *path, const char *mode, FILE *stream);
-int ftw64(const char *path, int (*fn)(const char *, const struct stat64 *, int), int nopenfd);
-int glob64(const char *pattern, int flags, int (*errfunc)(const char *, int), glob64_t *pglob);
-int scandir64(const char *path, struct dirent64 ***namelist, int (*filter)(const struct dirent64 *), int (*compar)());
-int truncate64(const char *path, off64_t length);
-int mkstemp64(char *template); /* flags=AT_SYMLINK_NOFOLLOW */