diff options
Diffstat (limited to 'ports/linux')
73 files changed, 1730 insertions, 0 deletions
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/ports/linux/guts/__fxstat.c b/ports/linux/guts/__fxstat.c new file mode 100644 index 0000000..db9716b --- /dev/null +++ b/ports/linux/guts/__fxstat.c @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * int + * wrap___fxstat(int ver, int fd, struct stat *buf) { + * int rc = -1; + */ + + struct stat64 buf64; + /* populate buffer with complete data */ + real___fxstat(ver, fd, buf); + /* obtain fake data */ + rc = wrap___fxstat64(ver, fd, &buf64); + /* overwrite */ + pseudo_stat32_from64(buf, &buf64); + +/* return rc; + * } + */ diff --git a/ports/linux/guts/__fxstat64.c b/ports/linux/guts/__fxstat64.c new file mode 100644 index 0000000..92c8219 --- /dev/null +++ b/ports/linux/guts/__fxstat64.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * int + * wrap___fxstat64(int ver, int fd, struct stat64 *buf) { + * int rc = -1; + */ + pseudo_msg_t *msg; + int save_errno; + + rc = real___fxstat64(ver, fd, buf); + save_errno = errno; + if (rc == -1) { + return rc; + } + if (ver != _STAT_VER) { + pseudo_debug(1, "version mismatch: got stat version %d, only supporting %d\n", ver, _STAT_VER); + errno = save_errno; + return rc; + } + msg = pseudo_client_op(OP_FSTAT, 0, fd, -1, 0, buf); + if (msg && msg->result == RESULT_SUCCEED) { + pseudo_stat_msg(buf, msg); + } + + errno = save_errno; +/* return rc; + * } + */ diff --git a/ports/linux/guts/__fxstatat.c b/ports/linux/guts/__fxstatat.c new file mode 100644 index 0000000..94c5ff6 --- /dev/null +++ b/ports/linux/guts/__fxstatat.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap___fxstatat(int ver, int dirfd, const char *path, struct stat *buf, int flags) { + * int rc = -1; + */ + + struct stat64 buf64; + /* populate buffer with complete data */ +#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS + if (dirfd != AT_FDCWD) { + errno = ENOSYS; + return -1; + } + if (flags & AT_SYMLINK_NOFOLLOW) { + rc = real___lxstat(ver, path, buf); + } else { + rc = real___xstat(ver, path, buf); + } +#else + real___fxstatat(ver, dirfd, path, buf, flags); +#endif + /* obtain fake data */ + rc = wrap___fxstatat64(ver, dirfd, path, &buf64, flags); + /* overwrite */ + pseudo_stat32_from64(buf, &buf64); + +/* return rc; + * } + */ diff --git a/ports/linux/guts/__fxstatat64.c b/ports/linux/guts/__fxstatat64.c new file mode 100644 index 0000000..f8a9298 --- /dev/null +++ b/ports/linux/guts/__fxstatat64.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap___fxstatat64(int ver, int dirfd, const char *path, struct stat64 *buf, int flags) { + * int rc = -1; + */ + pseudo_msg_t *msg; + int save_errno; + +#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS + if (dirfd != AT_FDCWD) { + errno = ENOSYS; + return -1; + } +#endif + if (flags & AT_SYMLINK_NOFOLLOW) { +#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS + rc = real___lxstat64(ver, path, buf); +#else + rc = real___fxstatat64(ver, dirfd, path, buf, flags); +#endif + if (rc == -1) { + return rc; + } + } else { +#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS + rc = real___xstat64(ver, path, buf); +#else + rc = real___fxstatat64(ver, dirfd, path, buf, flags); +#endif + if (rc == -1) { + return rc; + } + } + save_errno = errno; + + if (ver != _STAT_VER) { + pseudo_debug(1, "version mismatch: got stat version %d, only supporting %d\n", ver, _STAT_VER); + errno = save_errno; + 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, dirfd, path, buf); + if (msg) { + pseudo_stat_msg(buf, msg); + } + + errno = save_errno; + +/* return rc; + * } + */ diff --git a/ports/linux/guts/__lxstat.c b/ports/linux/guts/__lxstat.c new file mode 100644 index 0000000..32b0301 --- /dev/null +++ b/ports/linux/guts/__lxstat.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap___lxstat(int ver, const char *path, struct stat *buf) { + * int rc = -1; + */ + + rc = wrap___fxstatat(ver, AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW); + +/* + * } + */ diff --git a/ports/linux/guts/__lxstat64.c b/ports/linux/guts/__lxstat64.c new file mode 100644 index 0000000..ac1f782 --- /dev/null +++ b/ports/linux/guts/__lxstat64.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap___lxstat64(int ver, const char *path, struct stat64 *buf) { + * int rc = -1; + */ + + rc = wrap___fxstatat64(ver, AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW); + +/* + * } + */ diff --git a/ports/linux/guts/__openat64_2.c b/ports/linux/guts/__openat64_2.c new file mode 100644 index 0000000..8772115 --- /dev/null +++ b/ports/linux/guts/__openat64_2.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap___openat64_2(int dirfd, const char *path, int flags) { + * int rc = -1; + */ + + rc = wrap_openat(dirfd, path, flags, O_LARGEFILE); + +/* return rc; + * } + */ diff --git a/ports/linux/guts/__openat_2.c b/ports/linux/guts/__openat_2.c new file mode 100644 index 0000000..33ed620 --- /dev/null +++ b/ports/linux/guts/__openat_2.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap___openat_2(int dirfd, const char *path, int flags) { + * int rc = -1; + */ + + rc = wrap_openat(dirfd, path, flags, 0); + +/* return rc; + * } + */ diff --git a/ports/linux/guts/__xmknod.c b/ports/linux/guts/__xmknod.c new file mode 100644 index 0000000..fa31b66 --- /dev/null +++ b/ports/linux/guts/__xmknod.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap___xmknod(int ver, const char *path, mode_t mode, dev_t *dev) { + * int rc = -1; + */ + + rc = wrap___xmknodat(ver, AT_FDCWD, path, mode, dev); + +/* return rc; + * } + */ diff --git a/ports/linux/guts/__xmknodat.c b/ports/linux/guts/__xmknodat.c new file mode 100644 index 0000000..49b2f8f --- /dev/null +++ b/ports/linux/guts/__xmknodat.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap___xmknodat(int ver, int dirfd, const char *path, mode_t mode, dev_t *dev) { + * int rc = -1; + */ + pseudo_msg_t *msg; + struct stat64 buf; + + /* we don't use underlying call, so _ver is irrelevant to us */ + (void) ver; + +#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS + if (dirfd != AT_FDCWD) { + errno = ENOSYS; + return -1; + } + rc = real___xstat64(_STAT_VER, path, &buf); +#else + rc = real___fxstatat64(_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; + } + if (!dev) { + errno = EINVAL; + 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___fxstat64(_STAT_VER, 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(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/ports/linux/guts/__xstat.c b/ports/linux/guts/__xstat.c new file mode 100644 index 0000000..ec10abb --- /dev/null +++ b/ports/linux/guts/__xstat.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap___xstat(int ver, const char *path, struct stat *buf) { + * int rc = -1; + */ + + rc = wrap___fxstatat(ver, AT_FDCWD, path, buf, 0); + +/* return rc; + * } + */ diff --git a/ports/linux/guts/__xstat64.c b/ports/linux/guts/__xstat64.c new file mode 100644 index 0000000..ed62e7e --- /dev/null +++ b/ports/linux/guts/__xstat64.c @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap___xstat64(int ver, const char *path, struct stat64 *buf) { + * int rc = -1; + */ + rc = wrap___fxstatat64(ver, AT_FDCWD, path, buf, 0); + +/* return rc; + * } + */ diff --git a/ports/linux/guts/canonicalize_file_name.c b/ports/linux/guts/canonicalize_file_name.c new file mode 100644 index 0000000..9a04f33 --- /dev/null +++ b/ports/linux/guts/canonicalize_file_name.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static char * + * wrap_canonicalize_file_name(const char *filename) { + * char * rc = NULL; + */ + + rc = wrap_realpath(filename, NULL); + +/* return rc; + * } + */ diff --git a/ports/linux/guts/creat64.c b/ports/linux/guts/creat64.c new file mode 100644 index 0000000..2d2fc27 --- /dev/null +++ b/ports/linux/guts/creat64.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_creat64(const char *path, ...mode_t mode) { + * int rc = -1; + */ + + rc = wrap_openat(AT_FDCWD, path, O_CREAT|O_WRONLY|O_TRUNC|O_LARGEFILE, mode); + +/* return rc; + * } + */ diff --git a/ports/linux/guts/eaccess.c b/ports/linux/guts/eaccess.c new file mode 100644 index 0000000..e2119cc --- /dev/null +++ b/ports/linux/guts/eaccess.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_eaccess(const char *path, int mode) { + * int rc = -1; + */ + + rc = wrap_access(path, mode); + +/* return rc; + * } + */ diff --git a/ports/linux/guts/euidaccess.c b/ports/linux/guts/euidaccess.c new file mode 100644 index 0000000..85433a8 --- /dev/null +++ b/ports/linux/guts/euidaccess.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_euidaccess(const char *path, int mode) { + * int rc = -1; + */ + + rc = wrap_access(path, mode); + +/* return rc; + * } + */ diff --git a/ports/linux/guts/fcntl.c b/ports/linux/guts/fcntl.c new file mode 100644 index 0000000..2e3e96d --- /dev/null +++ b/ports/linux/guts/fcntl.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_fcntl(int fd, int cmd, ...struct flock *lock) { + * int rc = -1; + */ + long arg; + int save_errno; + + /* we don't know whether we need lock or arg; grab both, which + * should be safe enough on Linuxy systems. */ + va_start(ap, cmd); + arg = va_arg(ap, long); + va_end(ap); + + switch (cmd) { + case F_DUPFD: +#ifdef F_DUPFD_CLOEXEC + case F_DUPFD_CLOEXEC: +#endif + /* actually do something */ + rc = real_fcntl(fd, cmd, arg); + 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; + /* no argument: */ + case F_GETFD: + case F_GETFL: + case F_GETOWN: + case F_GETSIG: + case F_GETLEASE: + rc = real_fcntl(fd, cmd); + break; + /* long argument */ + case F_SETFD: + case F_SETFL: + case F_SETOWN: + case F_SETSIG: + case F_SETLEASE: + case F_NOTIFY: + rc = real_fcntl(fd, cmd, arg); + break; + /* struct flock * argument */ + case F_GETLK: + case F_SETLK: + case F_SETLKW: + rc = real_fcntl(fd, cmd, lock); + break; +#if defined(F_GETLK64) && (F_GETLK64 != F_GETLK) + /* the cast is safe, all struct pointers must smell the same */ + case F_GETLK64: + case F_SETLK64: + case F_SETLKW64: + rc = real_fcntl(fd, cmd, (struct flock64 *) lock); + break; +#endif + default: + pseudo_diag("unknown fcntl argument %d, assuming long argument.\n", + cmd); + rc = real_fcntl(fd, cmd, arg); + break; + } +/* return rc; + * } + */ diff --git a/ports/linux/guts/fgetxattr.c b/ports/linux/guts/fgetxattr.c new file mode 100644 index 0000000..9d33643 --- /dev/null +++ b/ports/linux/guts/fgetxattr.c @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * ssize_t fgetxattr(int filedes, const char *name, void *value, size_t size) + * ssize_t rc = -1; + */ + + /* suppress warnings */ + (void) filedes; + (void) name; + (void) value; + (void) size; + errno = ENOTSUP; + +/* return rc; + * } + */ diff --git a/ports/linux/guts/flistxattr.c b/ports/linux/guts/flistxattr.c new file mode 100644 index 0000000..77db021 --- /dev/null +++ b/ports/linux/guts/flistxattr.c @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * ssize_t flistxattr(int filedes, char *list, size_t size) + * ssize_t rc = -1; + */ + + /* suppress warnings */ + (void) filedes; + (void) list; + (void) size; + errno = ENOTSUP; + +/* return rc; + * } + */ diff --git a/ports/linux/guts/fopen64.c b/ports/linux/guts/fopen64.c new file mode 100644 index 0000000..b2724de --- /dev/null +++ b/ports/linux/guts/fopen64.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static FILE * + * wrap_fopen64(const char *path, const char *mode) { + * FILE * rc = 0; + */ + struct stat64 buf; + int save_errno; + + int existed = (real___xstat64(_STAT_VER, path, &buf) != -1); + + rc = real_fopen64(path, mode); + save_errno = errno; + + if (rc) { + int fd = fileno(rc); + + pseudo_debug(2, "fopen64 '%s': fd %d <FILE %p>\n", path, fd, (void *) rc); + if (real___fxstat64(_STAT_VER, fd, &buf) != -1) { + if (!existed) { + pseudo_client_op(OP_CREAT, 0, -1, -1, path, &buf); + } + pseudo_client_op(OP_OPEN, pseudo_access_fopen(mode), fd, -1, path, &buf); + } else { + pseudo_debug(1, "fopen64 (fd %d) succeeded, but fstat failed (%s).\n", + fd, strerror(errno)); + pseudo_client_op(OP_OPEN, pseudo_access_fopen(mode), fd, -1, path, 0); + } + errno = save_errno; + } + +/* return rc; + * } + */ diff --git a/ports/linux/guts/fremovexattr.c b/ports/linux/guts/fremovexattr.c new file mode 100644 index 0000000..529a9de --- /dev/null +++ b/ports/linux/guts/fremovexattr.c @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * int fremovexattr(int filedes, const char *name) + * int rc = -1; + */ + + /* suppress warnings */ + (void) filedes; + (void) name; + errno = ENOTSUP; + +/* return rc; + * } + */ diff --git a/ports/linux/guts/freopen64.c b/ports/linux/guts/freopen64.c new file mode 100644 index 0000000..b8e576b --- /dev/null +++ b/ports/linux/guts/freopen64.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static FILE * + * wrap_freopen64(const char *path, const char *mode, FILE *stream) { + * FILE * rc = NULL; + */ + struct stat64 buf; + int save_errno; + int existed = (real___xstat64(_STAT_VER, path, &buf) != -1); + + rc = real_freopen64(path, mode, stream); + save_errno = errno; + + if (rc) { + int fd = fileno(rc); + + pseudo_debug(2, "freopen64 '%s': fd %d\n", path, fd); + if (real___fxstat64(_STAT_VER, fd, &buf) != -1) { + if (!existed) { + pseudo_client_op(OP_CREAT, 0, -1, -1, path, &buf); + } + pseudo_client_op(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); + } + errno = save_errno; + } + +/* return rc; + * } + */ diff --git a/ports/linux/guts/fsetxattr.c b/ports/linux/guts/fsetxattr.c new file mode 100644 index 0000000..3c56ddd --- /dev/null +++ b/ports/linux/guts/fsetxattr.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * int fsetxattr(int filedes, const char *name, const void *value, size_t size, int flags) + * 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/ports/linux/guts/ftw64.c b/ports/linux/guts/ftw64.c new file mode 100644 index 0000000..a375fbf --- /dev/null +++ b/ports/linux/guts/ftw64.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_ftw64(const char *path, int (*fn)(const char *, const struct stat64 *, int), int nopenfd) { + * int rc = -1; + */ + + rc = real_ftw64(path, fn, nopenfd); + +/* return rc; + * } + */ diff --git a/ports/linux/guts/get_current_dir_name.c b/ports/linux/guts/get_current_dir_name.c new file mode 100644 index 0000000..e07a6ee --- /dev/null +++ b/ports/linux/guts/get_current_dir_name.c @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static char * + * wrap_get_current_dir_name(void) { + * char * rc = NULL; + */ + + pseudo_debug(3, "get_current_dir_name (getcwd)\n"); + /* this relies on a Linux extension, but we dutifully + * emulated that extension. + */ + rc = wrap_getcwd(NULL, 0); + +/* return rc; + * } + */ diff --git a/ports/linux/guts/getgrent_r.c b/ports/linux/guts/getgrent_r.c new file mode 100644 index 0000000..b04373d --- /dev/null +++ b/ports/linux/guts/getgrent_r.c @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2010-2011 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_getgrent_r(struct group *gbuf, char *buf, size_t buflen, struct group **gbufp) { + * int rc = -1; + */ + + /* note that we don't wrap fgetgrent_r, since there's no path + * references in it. + */ + if (!pseudo_grp) { + errno = ENOENT; + return -1; + } + rc = fgetgrent_r(pseudo_grp, gbuf, buf, buflen, gbufp); + +/* return rc; + * } + */ diff --git a/ports/linux/guts/getgrouplist.c b/ports/linux/guts/getgrouplist.c new file mode 100644 index 0000000..3489ec9 --- /dev/null +++ b/ports/linux/guts/getgrouplist.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_getgrouplist(const char *user, gid_t group, gid_t *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], user)) { + if (found < *ngroups) + groups[found] = gbuf->gr_gid; + ++found; + if (gbuf->gr_gid == group) + found_group = 1; + } + } + } + endgrent(); + if (!found_group) { + if (found < *ngroups) + groups[found] = group; + ++found; + } + if (found >= *ngroups) + rc = -1; + else + rc = found; + *ngroups = found; + +/* return rc; + * } + */ diff --git a/ports/linux/guts/getgroups.c b/ports/linux/guts/getgroups.c new file mode 100644 index 0000000..afb9662 --- /dev/null +++ b/ports/linux/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(), list, &size); + if (oldsize == 0 || size <= oldsize) + rc = size; + } else { + errno = ENOENT; + } + +/* return rc; + * } + */ diff --git a/ports/linux/guts/getpw.c b/ports/linux/guts/getpw.c new file mode 100644 index 0000000..62b44da --- /dev/null +++ b/ports/linux/guts/getpw.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_getpw(uid_t uid, char *buf) { + * int rc = -1; + */ + static struct passwd pwd; + static char pwbuf[PSEUDO_PWD_MAX]; + struct passwd *pwp; + + pseudo_diag("warning: unsafe getpw() called. hoping buf has at least %d chars.\n", + PSEUDO_PWD_MAX); + rc = wrap_getpwuid_r(uid, &pwd, pwbuf, PSEUDO_PWD_MAX, &pwp); + /* different error return conventions */ + if (rc != 0) { + errno = rc; + rc = -1; + } else { + snprintf(buf, PSEUDO_PWD_MAX, "%s:%s:%d:%d:%s:%s:%s", + pwd.pw_name, + pwd.pw_passwd, + pwd.pw_uid, + pwd.pw_gid, + pwd.pw_gecos, + pwd.pw_dir, + pwd.pw_shell); + } + +/* return rc; + * } + */ diff --git a/ports/linux/guts/getpwent_r.c b/ports/linux/guts/getpwent_r.c new file mode 100644 index 0000000..4fd9cc0 --- /dev/null +++ b/ports/linux/guts/getpwent_r.c @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2010-2011 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_getpwent_r(struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp) { + * int rc = -1; + */ + + /* note that we don't wrap fgetpwent_r, since there's no path + * references in it. + */ + if (!pseudo_pwd) { + errno = ENOENT; + return -1; + } + rc = fgetpwent_r(pseudo_pwd, pwbuf, buf, buflen, pwbufp); + +/* return rc; + * } + */ diff --git a/ports/linux/guts/getresgid.c b/ports/linux/guts/getresgid.c new file mode 100644 index 0000000..13551a4 --- /dev/null +++ b/ports/linux/guts/getresgid.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid) { + * int rc = -1; + */ + if (rgid) + *rgid = pseudo_rgid; + if (egid) + *egid = pseudo_egid; + if (sgid) + *sgid = pseudo_sgid; + if (rgid && egid && sgid) { + rc = 0; + } else { + rc = -1; + errno = EFAULT; + } +/* return rc; + * } + */ diff --git a/ports/linux/guts/getresuid.c b/ports/linux/guts/getresuid.c new file mode 100644 index 0000000..2e47520 --- /dev/null +++ b/ports/linux/guts/getresuid.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid) { + * int rc = -1; + */ + if (ruid) + *ruid = pseudo_ruid; + if (euid) + *euid = pseudo_euid; + if (suid) + *suid = pseudo_suid; + if (ruid && euid && suid) { + rc = 0; + } else { + rc = -1; + errno = EFAULT; + } +/* return rc; + * } + */ diff --git a/ports/linux/guts/getxattr.c b/ports/linux/guts/getxattr.c new file mode 100644 index 0000000..fe8912d --- /dev/null +++ b/ports/linux/guts/getxattr.c @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * ssize_t getxattr(const char *pathname, const char *name, void *value, size_t size) + * ssize_t rc = -1; + */ + + /* suppress warnings */ + (void) pathname; + (void) name; + (void) value; + (void) size; + errno = ENOTSUP; + +/* return rc; + * } + */ diff --git a/ports/linux/guts/glob64.c b/ports/linux/guts/glob64.c new file mode 100644 index 0000000..ccac6e4 --- /dev/null +++ b/ports/linux/guts/glob64.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_glob64(const char *pattern, int flags, int (*errfunc)(const char *, int), glob64_t *pglob) { + * int rc = -1; + */ + char *rpattern = NULL; + int alloced = 0; + + /* note: no canonicalization */ + if (pattern && (*pattern == '/') && pseudo_chroot_len) { + size_t len = strlen(pattern) + pseudo_chroot_len + 2; + rpattern = malloc(len); + if (!rpattern) { + errno = ENOMEM; + return GLOB_NOSPACE; + } + snprintf(rpattern, len, "%s/%s", pseudo_chroot, pattern); + alloced = 1; + } + + rc = real_glob64(alloced ? rpattern : pattern, flags, errfunc, pglob); + + free(rpattern); + + if (rc == 0) { + unsigned int i; + for (i = 0; i < pglob->gl_pathc; ++i) { + pseudo_dechroot(pglob->gl_pathv[i], (size_t) -1); + } + } +/* return rc; + * } + */ diff --git a/ports/linux/guts/lchown.c b/ports/linux/guts/lchown.c new file mode 100644 index 0000000..4eb1202 --- /dev/null +++ b/ports/linux/guts/lchown.c @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_lchown(const char *path, uid_t owner, gid_t group) { + */ + + rc = wrap_fchownat(AT_FDCWD, path, owner, group, AT_SYMLINK_NOFOLLOW); + +/* return rc; + * } + */ diff --git a/ports/linux/guts/lckpwdf.c b/ports/linux/guts/lckpwdf.c new file mode 100644 index 0000000..b452ec0 --- /dev/null +++ b/ports/linux/guts/lckpwdf.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_lckpwdf(void) { + * int rc = -1; + */ + rc = pseudo_pwd_lck_open(); + if (rc != -1) { + struct flock lck = { + .l_type = F_RDLCK, + .l_whence = SEEK_SET, + .l_start = 0, + .l_len = 1 + }; + /* I don't really care whether this works. */ + fcntl(rc, F_SETFD, FD_CLOEXEC); + /* Now lock it. */ + alarm(15); /* magic number from man page */ + rc = fcntl(rc, F_SETLKW, &lck); + alarm(0); + if (rc == -1) { + int save_errno = errno; + pseudo_pwd_lck_close(); + errno = save_errno; + } + } + +/* return rc; + * } + */ diff --git a/ports/linux/guts/lgetxattr.c b/ports/linux/guts/lgetxattr.c new file mode 100644 index 0000000..404211f --- /dev/null +++ b/ports/linux/guts/lgetxattr.c @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * ssize_t lgetxattr(const char *pathname, const char *name, void *value, size_t size) + * ssize_t rc = -1; + */ + + /* suppress warnings */ + (void) pathname; + (void) name; + (void) value; + (void) size; + errno = ENOTSUP; + +/* return rc; + * } + */ diff --git a/ports/linux/guts/listxattr.c b/ports/linux/guts/listxattr.c new file mode 100644 index 0000000..1b0b5e7 --- /dev/null +++ b/ports/linux/guts/listxattr.c @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * ssize_t listxattr(const char *pathname, char *list, size_t size) + * ssize_t rc = -1; + */ + + /* suppress warnings */ + (void) pathname; + (void) list; + (void) size; + errno = ENOTSUP; + +/* return rc; + * } + */ diff --git a/ports/linux/guts/llistxattr.c b/ports/linux/guts/llistxattr.c new file mode 100644 index 0000000..a33f970 --- /dev/null +++ b/ports/linux/guts/llistxattr.c @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * ssize_t llistxattr(const char *pathname, char *list, size_t size) + * ssize_t rc = -1; + */ + + /* suppress warnings */ + (void) pathname; + (void) list; + (void) size; + errno = ENOTSUP; + +/* return rc; + * } + */ diff --git a/ports/linux/guts/lremovexattr.c b/ports/linux/guts/lremovexattr.c new file mode 100644 index 0000000..38429da --- /dev/null +++ b/ports/linux/guts/lremovexattr.c @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * int lremovexattr(const char *pathname, const char *name) + * int rc = -1; + */ + + /* suppress warnings */ + (void) pathname; + (void) name; + errno = ENOTSUP; + +/* return rc; + * } + */ diff --git a/ports/linux/guts/lsetxattr.c b/ports/linux/guts/lsetxattr.c new file mode 100644 index 0000000..140ae8d --- /dev/null +++ b/ports/linux/guts/lsetxattr.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * int lsetxattr(const char *pathname, const char *name, const void *value, size_t size, int flags) + * 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/ports/linux/guts/mkstemp64.c b/ports/linux/guts/mkstemp64.c new file mode 100644 index 0000000..def4126 --- /dev/null +++ b/ports/linux/guts/mkstemp64.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_mkstemp64(char *template) { + * int rc = -1; + */ + struct stat64 buf; + int save_errno; + size_t len; + char *tmp_template; + + if (!template) { + errno = EFAULT; + return 0; + } + + len = strlen(template); + tmp_template = PSEUDO_ROOT_PATH(AT_FDCWD, template, AT_SYMLINK_NOFOLLOW); + + if (!tmp_template) { + errno = ENOENT; + return -1; + } + + rc = real_mkstemp64(tmp_template); + + 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); + } 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); + } + errno = save_errno; + } + /* mkstemp only changes the XXXXXX at the end. */ + memcpy(template + len - 6, tmp_template + strlen(tmp_template) - 6, 6); + free(tmp_template); +/* return rc; + * } + */ diff --git a/ports/linux/guts/nftw64.c b/ports/linux/guts/nftw64.c new file mode 100644 index 0000000..82571cd --- /dev/null +++ b/ports/linux/guts/nftw64.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_nftw64(const char *path, int (*fn)(const char *, const struct stat64 *, int, struct FTW *), int nopenfd, int flag) { + * int rc = -1; + */ + + rc = real_nftw64(path, fn, nopenfd, flag); + +/* return rc; + * } + */ diff --git a/ports/linux/guts/open.c b/ports/linux/guts/open.c new file mode 100644 index 0000000..0a0596c --- /dev/null +++ b/ports/linux/guts/open.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_open(const char *path, int flags, ...mode_t mode) { + * int rc = -1; + */ + + return wrap_openat(AT_FDCWD, path, flags, mode); + +/* return rc; + * } + */ diff --git a/ports/linux/guts/open64.c b/ports/linux/guts/open64.c new file mode 100644 index 0000000..adeb885 --- /dev/null +++ b/ports/linux/guts/open64.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_open64(const char *path, int flags, ...mode_t mode) { + * int rc = -1; + */ + + rc = wrap_openat(AT_FDCWD, path, flags, mode | O_LARGEFILE); + +/* return rc; + * } + */ diff --git a/ports/linux/guts/openat.c b/ports/linux/guts/openat.c new file mode 100644 index 0000000..c245796 --- /dev/null +++ b/ports/linux/guts/openat.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_openat(int dirfd, const char *path, int flags, ...mode_t mode) { + * int rc = -1; + */ + struct stat64 buf; + int existed = 1; + int save_errno; + +#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS + if (dirfd != AT_FDCWD) { + errno = ENOSYS; + return -1; + } +#endif + /* if a creation has been requested, check whether file exists */ + if (flags & O_CREAT) { + save_errno = errno; +#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS + rc = real___xstat64(_STAT_VER, path, &buf); +#else + rc = real___fxstatat64(_STAT_VER, dirfd, path, &buf, 0); +#endif + existed = (rc != -1); + if (!existed) + pseudo_debug(2, "openat_creat: %s -> 0%o\n", path, mode); + errno = save_errno; + } + + /* because we are not actually root, secretly mask in 0700 to the + * underlying mode + */ +#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS + rc = real_open(path, flags, PSEUDO_FS_MODE(mode)); +#else + rc = real_openat(dirfd, path, flags, PSEUDO_FS_MODE(mode)); +#endif + save_errno = errno; + + if (rc != -1) { + int stat_rc; +#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS + stat_rc = real___xstat64(_STAT_VER, path, &buf); +#else + stat_rc = real___fxstatat64(_STAT_VER, dirfd, path, &buf, 0); +#endif + + if (stat_rc != -1) { + buf.st_mode = PSEUDO_DB_MODE(buf.st_mode, mode); + if (!existed) { + pseudo_client_op(OP_CREAT, 0, -1, dirfd, path, &buf); + } + pseudo_client_op(OP_OPEN, PSEUDO_ACCESS(flags), rc, dirfd, path, &buf); + } else { + pseudo_debug(1, "openat (fd %d, path %d/%s, flags %d) succeeded, but stat failed (%s).\n", + rc, dirfd, path, flags, strerror(errno)); + pseudo_client_op(OP_OPEN, PSEUDO_ACCESS(flags), rc, dirfd, path, 0); + } + errno = save_errno; + } + +/* return rc; + * } + */ diff --git a/ports/linux/guts/openat64.c b/ports/linux/guts/openat64.c new file mode 100644 index 0000000..726ec6d --- /dev/null +++ b/ports/linux/guts/openat64.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_openat64(int dirfd, const char *path, int flags, ...mode_t mode) { + * int rc = -1; + */ + + rc = wrap_openat(dirfd, path, flags, mode | O_LARGEFILE); + +/* return rc; + * } + */ diff --git a/ports/linux/guts/removexattr.c b/ports/linux/guts/removexattr.c new file mode 100644 index 0000000..cd7f486 --- /dev/null +++ b/ports/linux/guts/removexattr.c @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * int removexattr(const char *pathname, const char *name) + * int rc = -1; + */ + + /* suppress warnings */ + (void) pathname; + (void) name; + errno = ENOTSUP; + +/* return rc; + * } + */ diff --git a/ports/linux/guts/scandir.c b/ports/linux/guts/scandir.c new file mode 100644 index 0000000..afcebaf --- /dev/null +++ b/ports/linux/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)(const struct dirent *), int (*compar)(const void *, const void *)) { + * int rc = -1; + */ + + rc = real_scandir(path, namelist, filter, compar); + +/* return rc; + * } + */ diff --git a/ports/linux/guts/scandir64.c b/ports/linux/guts/scandir64.c new file mode 100644 index 0000000..1317b73 --- /dev/null +++ b/ports/linux/guts/scandir64.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_scandir64(const char *path, struct dirent64 ***namelist, int (*filter)(const struct dirent64 *), int (*compar)(const void *, const void *)) { + * int rc = -1; + */ + + rc = real_scandir64(path, namelist, filter, compar); + +/* return rc; + * } + */ diff --git a/ports/linux/guts/setfsgid.c b/ports/linux/guts/setfsgid.c new file mode 100644 index 0000000..0e5a10b --- /dev/null +++ b/ports/linux/guts/setfsgid.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_setfsgid(gid_t fsgid) { + * int rc = -1; + */ + if (pseudo_euid == 0 || + pseudo_egid == fsgid || pseudo_rgid == fsgid || pseudo_sgid == fsgid) { + pseudo_fgid = fsgid; + rc = 0; + } else { + rc = -1; + errno = EPERM; + } +/* return rc; + * } + */ diff --git a/ports/linux/guts/setfsuid.c b/ports/linux/guts/setfsuid.c new file mode 100644 index 0000000..e52b65e --- /dev/null +++ b/ports/linux/guts/setfsuid.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_setfsuid(uid_t fsuid) { + * int rc = -1; + */ + if (pseudo_euid == 0 || + pseudo_euid == fsuid || pseudo_ruid == fsuid || pseudo_suid == fsuid) { + pseudo_fuid = fsuid; + rc = 0; + } else { + rc = -1; + errno = EPERM; + } +/* return rc; + * } + */ diff --git a/ports/linux/guts/setgroups.c b/ports/linux/guts/setgroups.c new file mode 100644 index 0000000..31b2b57 --- /dev/null +++ b/ports/linux/guts/setgroups.c @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_setgroups(size_t size, const gid_t *list) { + * int rc = -1; + */ + + /* let gcc know we're ignoring these */ + (void) size; + (void) list; + /* you always have all group privileges. we're like magic! */ + rc = 0; + +/* return rc; + * } + */ diff --git a/ports/linux/guts/setresgid.c b/ports/linux/guts/setresgid.c new file mode 100644 index 0000000..2a26405 --- /dev/null +++ b/ports/linux/guts/setresgid.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_setresgid(gid_t rgid, gid_t egid, gid_t sgid) { + * int rc = -1; + */ + rc = 0; + if (pseudo_euid != 0 && rgid != (gid_t) -1 && + rgid != pseudo_egid && rgid != pseudo_rgid && rgid != pseudo_sgid) { + rc = -1; + errno = EPERM; + } + if (pseudo_euid != 0 && egid != (gid_t) -1 && + egid != pseudo_egid && egid != pseudo_rgid && egid != pseudo_sgid) { + rc = -1; + errno = EPERM; + } + if (pseudo_euid != 0 && sgid != (gid_t) -1 && + sgid != pseudo_egid && sgid != pseudo_rgid && sgid != pseudo_sgid) { + rc = -1; + errno = EPERM; + } + if (rc != -1) { + if (rgid != (gid_t) -1) + pseudo_rgid = rgid; + if (egid != (gid_t) -1) + pseudo_egid = egid; + if (sgid != (gid_t) -1) + pseudo_sgid = sgid; + pseudo_fgid = pseudo_egid; + pseudo_client_touchuid(); + } +/* return rc; + * } + */ diff --git a/ports/linux/guts/setresuid.c b/ports/linux/guts/setresuid.c new file mode 100644 index 0000000..a0a367f --- /dev/null +++ b/ports/linux/guts/setresuid.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_setresuid(uid_t ruid, uid_t euid, uid_t suid) { + * int rc = -1; + */ + rc = 0; + if (pseudo_euid != 0 && ruid != (uid_t) -1 && + ruid != pseudo_euid && ruid != pseudo_ruid && ruid != pseudo_suid) { + rc = -1; + errno = EPERM; + } + if (pseudo_euid != 0 && euid != (uid_t) -1 && + euid != pseudo_euid && euid != pseudo_ruid && euid != pseudo_suid) { + rc = -1; + errno = EPERM; + } + if (pseudo_euid != 0 && suid != (uid_t) -1 && + suid != pseudo_euid && suid != pseudo_ruid && suid != pseudo_suid) { + rc = -1; + errno = EPERM; + } + if (rc != -1) { + if (ruid != (uid_t) -1) + pseudo_ruid = ruid; + if (euid != (uid_t) -1) + pseudo_euid = euid; + if (suid != (uid_t) -1) + pseudo_suid = suid; + pseudo_fuid = pseudo_euid; + pseudo_client_touchuid(); + } +/* return rc; + * } + */ diff --git a/ports/linux/guts/setxattr.c b/ports/linux/guts/setxattr.c new file mode 100644 index 0000000..de2de98 --- /dev/null +++ b/ports/linux/guts/setxattr.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * int setxattr(const char *pathname, const char *name, const void *value, size_t size, int flags) + * 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/ports/linux/guts/truncate64.c b/ports/linux/guts/truncate64.c new file mode 100644 index 0000000..a798984 --- /dev/null +++ b/ports/linux/guts/truncate64.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_truncate64(const char *path, off64_t length) { + * int rc = -1; + */ + + rc = real_truncate64(path, length); + +/* return rc; + * } + */ diff --git a/ports/linux/guts/ulckpwdf.c b/ports/linux/guts/ulckpwdf.c new file mode 100644 index 0000000..bdb6f42 --- /dev/null +++ b/ports/linux/guts/ulckpwdf.c @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_ulckpwdf(void) { + * int rc = -1; + */ + + /* lock is cleared automatically on close */ + pseudo_pwd_lck_close(); + rc = 0; + +/* return rc; + * } + */ diff --git a/ports/linux/newclone/guts/clone.c b/ports/linux/newclone/guts/clone.c new file mode 100644 index 0000000..b3400c7 --- /dev/null +++ b/ports/linux/newclone/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, pid, tls, ctid); +/* ... + * return rc; + * } + */ 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); |