diff options
40 files changed, 455 insertions, 157 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt index 9e26e5f..cc7083b 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,3 +1,9 @@ +2010-03-24: + * (seebs) regenerate wrappers when makewrappers is changed. + * (seebs) begin prep for chroot + * (seebs) standardize path expansion + * (seebs) extend makewrappers to handle function pointer args + 2010-03-17: * (seebs) fixup help options * (seebs) use strerror() in a couple more places diff --git a/Makefile.in b/Makefile.in index 8852802..9f9e67e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -94,7 +94,7 @@ pseudo_server.o: pseudo_server.h pseudo_wrappers.o: $(GUTS) -wrappers: wrapfuncs.in $(USE_64) +wrappers: wrapfuncs.in $(USE_64) makewrappers ./makewrappers wrapfuncs.in $(USE_64) .SECONDARY: wrappers diff --git a/guts/__fxstat64.c b/guts/__fxstat64.c index 59f8a59..2e7919c 100644 --- a/guts/__fxstat64.c +++ b/guts/__fxstat64.c @@ -16,7 +16,7 @@ errno = save_errno; return rc; } - msg = pseudo_client_op(OP_FSTAT, 0, fd, -1, 0, buf); + msg = pseudo_client_op(OP_FSTAT, fd, -1, 0, buf); if (msg) { if (msg->result == RESULT_SUCCEED) pseudo_stat_msg(buf, msg); diff --git a/guts/__fxstatat64.c b/guts/__fxstatat64.c index 3edd8c7..b8054f2 100644 --- a/guts/__fxstatat64.c +++ b/guts/__fxstatat64.c @@ -56,7 +56,7 @@ * 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, flags, -1, dirfd, path, buf); + msg = pseudo_client_op(OP_STAT, -1, dirfd, path, buf); if (msg) { pseudo_stat_msg(buf, msg); if (save_mode) { diff --git a/guts/__xmknodat.c b/guts/__xmknodat.c index a86d6aa..6bd0761 100644 --- a/guts/__xmknodat.c +++ b/guts/__xmknodat.c @@ -30,8 +30,9 @@ rc = real_openat(dirfd, path, O_CREAT | O_WRONLY | O_EXCL, PSEUDO_FS_MODE(mode)); #endif - if (rc == -1) + 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 @@ -43,7 +44,7 @@ buf.st_mode = (PSEUDO_DB_MODE(buf.st_mode, mode) & 07777) | (mode & ~07777); buf.st_rdev = *dev; - msg = pseudo_client_op(OP_MKNOD, AT_SYMLINK_NOFOLLOW, -1, dirfd, path, &buf); + msg = pseudo_client_op(OP_MKNOD, -1, dirfd, path, &buf); if (!msg) { errno = ENOSYS; rc = -1; diff --git a/guts/chdir.c b/guts/chdir.c index b910060..ca48738 100644 --- a/guts/chdir.c +++ b/guts/chdir.c @@ -3,11 +3,17 @@ * wrap_chdir(const char *path) { * int rc = -1; */ - pseudo_debug(3, "chdir: %s\n", path ? path : "<nil>"); + pseudo_debug(2, "chdir: '%s'\n", + path ? path : "<nil>"); + + if (!path) { + errno = EFAULT; + return -1; + } rc = real_chdir(path); if (rc != -1) { - pseudo_client_op(OP_CHDIR, 0, -1, -1, path, 0); + pseudo_client_op(OP_CHDIR, -1, -1, path, 0); } /* return rc; diff --git a/guts/close.c b/guts/close.c index 8edbee9..34b279e 100644 --- a/guts/close.c +++ b/guts/close.c @@ -6,7 +6,7 @@ /* this cleans up an internal table, and shouldn't even * make it to the server. */ - pseudo_client_op(OP_CLOSE, 0, fd, -1, 0, 0); + pseudo_client_op(OP_CLOSE, fd, -1, 0, 0); rc = real_close(fd); /* return rc; @@ -8,7 +8,7 @@ rc = real_dup(fd); save_errno = errno; pseudo_debug(2, "dup: %d->%d\n", fd, rc); - pseudo_client_op(OP_DUP, 0, fd, rc, 0, 0); + pseudo_client_op(OP_DUP, fd, rc, 0, 0); errno = save_errno; /* return rc; diff --git a/guts/dup2.c b/guts/dup2.c index 360c3ad..59d5293 100644 --- a/guts/dup2.c +++ b/guts/dup2.c @@ -8,10 +8,10 @@ /* close existing one first - this also causes the socket to the * server to get moved around if someone tries to overwrite it. */ pseudo_debug(2, "dup2: %d->%d\n", oldfd, newfd); - pseudo_client_op(OP_CLOSE, 0, newfd, -1, 0, 0); + pseudo_client_op(OP_CLOSE, newfd, -1, 0, 0); rc = real_dup2(oldfd, newfd); save_errno = errno; - pseudo_client_op(OP_DUP, 0, oldfd, newfd, 0, 0); + pseudo_client_op(OP_DUP, oldfd, newfd, 0, 0); errno = save_errno; /* return rc; diff --git a/guts/fchdir.c b/guts/fchdir.c index 5289f4c..b255511 100644 --- a/guts/fchdir.c +++ b/guts/fchdir.c @@ -7,7 +7,7 @@ rc = real_fchdir(dirfd); if (rc != -1) { - pseudo_client_op(OP_CHDIR, 0, -1, dirfd, 0, 0); + pseudo_client_op(OP_CHDIR, -1, dirfd, 0, 0); } /* return rc; diff --git a/guts/fchmod.c b/guts/fchmod.c index df2f9e9..663a026 100644 --- a/guts/fchmod.c +++ b/guts/fchmod.c @@ -12,7 +12,7 @@ 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(OP_FCHMOD, fd, -1, 0, &buf); real_fchmod(fd, PSEUDO_FS_MODE(mode)); if (!msg) { errno = ENOSYS; diff --git a/guts/fchmodat.c b/guts/fchmodat.c index 36bd4d1..9804711 100644 --- a/guts/fchmodat.c +++ b/guts/fchmodat.c @@ -33,7 +33,7 @@ /* purely for debugging purposes: check whether file * is already in database. */ - msg = pseudo_client_op(OP_STAT, flags, -1, -1, path, &buf); + msg = pseudo_client_op(OP_STAT, -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); @@ -54,7 +54,7 @@ */ buf.st_mode = (buf.st_mode & ~07777) | (mode & 07777); - msg = pseudo_client_op(OP_CHMOD, flags, -1, dirfd, path, &buf); + msg = pseudo_client_op(OP_CHMOD, -1, dirfd, path, &buf); if (!msg) { errno = ENOSYS; rc = -1; diff --git a/guts/fchown.c b/guts/fchown.c index 4d420c8..53a34de 100644 --- a/guts/fchown.c +++ b/guts/fchown.c @@ -15,7 +15,7 @@ return -1; } if (owner == -1 || group == -1) { - msg = pseudo_client_op(OP_STAT, 0, fd, -1, NULL, &buf); + msg = pseudo_client_op(OP_STAT, fd, -1, NULL, &buf); /* copy in any existing values... */ if (msg) { if (msg->result == RESULT_SUCCEED) { @@ -38,7 +38,7 @@ } 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); + msg = pseudo_client_op(OP_FCHOWN, fd, -1, 0, &buf); if (!msg) { errno = ENOSYS; rc = -1; diff --git a/guts/fchownat.c b/guts/fchownat.c index 8d24d3e..181fa6d 100644 --- a/guts/fchownat.c +++ b/guts/fchownat.c @@ -30,7 +30,7 @@ } save_errno = errno; - msg = pseudo_client_op(OP_STAT, flags, -1, -1, path, &buf); + msg = pseudo_client_op(OP_STAT, -1, -1, path, &buf); /* copy in any existing values... */ if (msg) { if (msg->result == RESULT_SUCCEED) { @@ -48,7 +48,7 @@ if (group != -1) { buf.st_gid = group; } - msg = pseudo_client_op(OP_CHOWN, flags, -1, dirfd, path, &buf); + msg = pseudo_client_op(OP_CHOWN, -1, dirfd, path, &buf); if (!msg) { errno = ENOSYS; rc = -1; diff --git a/guts/fclose.c b/guts/fclose.c index e0c5681..bcf4ace 100644 --- a/guts/fclose.c +++ b/guts/fclose.c @@ -9,7 +9,7 @@ return -1; } int fd = fileno(fp); - pseudo_client_op(OP_CLOSE, 0, fd, -1, 0, 0); + pseudo_client_op(OP_CLOSE, fd, -1, 0, 0); rc = real_fclose(fp); /* return rc; diff --git a/guts/fcntl.c b/guts/fcntl.c index d03d40c..ec7277d 100644 --- a/guts/fcntl.c +++ b/guts/fcntl.c @@ -22,7 +22,7 @@ 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); + pseudo_client_op(OP_DUP, fd, rc, 0, 0); } errno = save_errno; break; diff --git a/guts/fopen.c b/guts/fopen.c index 2aae54c..6495d69 100644 --- a/guts/fopen.c +++ b/guts/fopen.c @@ -16,13 +16,13 @@ pseudo_debug(2, "fopen '%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_CREAT, -1, -1, path, &buf); } - pseudo_client_op(OP_OPEN, 0, fd, -1, path, &buf); + pseudo_client_op(OP_OPEN, 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, 0, fd, -1, path, 0); + pseudo_client_op(OP_OPEN, fd, -1, path, 0); } errno = save_errno; } diff --git a/guts/fopen64.c b/guts/fopen64.c index 0b0ab58..c6de09c 100644 --- a/guts/fopen64.c +++ b/guts/fopen64.c @@ -5,6 +5,7 @@ */ struct stat64 buf; int save_errno; + int existed = (real___xstat64(_STAT_VER, path, &buf) != -1); rc = real_fopen64(path, mode); @@ -16,13 +17,13 @@ pseudo_debug(2, "fopen64 '%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_CREAT, -1, -1, path, &buf); } - pseudo_client_op(OP_OPEN, 0, fd, -1, path, &buf); + pseudo_client_op(OP_OPEN, 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, 0, fd, -1, path, 0); + pseudo_client_op(OP_OPEN, fd, -1, path, 0); } errno = save_errno; } diff --git a/guts/freopen.c b/guts/freopen.c index 312bc0a..92c9d87 100644 --- a/guts/freopen.c +++ b/guts/freopen.c @@ -16,13 +16,13 @@ pseudo_debug(2, "freopen '%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_CREAT, -1, -1, path, &buf); } - pseudo_client_op(OP_OPEN, 0, fd, -1, path, &buf); + pseudo_client_op(OP_OPEN, 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, 0, fd, -1, path, 0); + pseudo_client_op(OP_OPEN, fd, -1, path, 0); } errno = save_errno; } diff --git a/guts/get_current_dir_name.c b/guts/get_current_dir_name.c new file mode 100644 index 0000000..671c5dc --- /dev/null +++ b/guts/get_current_dir_name.c @@ -0,0 +1,15 @@ +/* + * 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/guts/getcwd.c b/guts/getcwd.c new file mode 100644 index 0000000..d8f4d36 --- /dev/null +++ b/guts/getcwd.c @@ -0,0 +1,40 @@ +/* + * static char * + * wrap_getcwd(char *buf, size_t size) { + * char * rc = NULL; + */ + pseudo_debug(2, "wrap_getcwd: %p, %lu\n", + (void *) buf, (unsigned long) size); + if (!pseudo_cwd) { + pseudo_diag("Asked for CWD, but don't have it!\n"); + errno = EACCES; + return NULL; + } + /* emulate Linux semantics in case of non-Linux systems. */ + if (!buf) { + /* if we don't have one, something's very wrong... */ + if (!size) { + size = pseudo_cwd_len; + } + if (size) { + buf = malloc(size); + } else { + pseudo_diag("can't figure out CWD: length %ld\n", + (unsigned long) pseudo_cwd_len); + } + if (!buf) { + pseudo_diag("couldn't allocate requested CWD buffer - need %ld byes\n", + (unsigned long) size); + errno = ENOMEM; + return NULL; + } + } + rc = buf; + memcpy(buf, pseudo_cwd, pseudo_cwd_len + 1); + if (!*buf) { + strcpy(buf, "/"); + } + +/* return rc; + * } + */ diff --git a/guts/getwd.c b/guts/getwd.c new file mode 100644 index 0000000..2bac467 --- /dev/null +++ b/guts/getwd.c @@ -0,0 +1,18 @@ +/* + * static char * + * wrap_getwd(char *buf) { + * char * rc = NULL; + */ + + pseudo_debug(3, "getwd (getcwd)\n"); + rc = wrap_getcwd(buf, pseudo_path_max()); + /* because it would violate everything we have ever known about + * UNIX for these functions to have the same errno semantics, + * that's why. + */ + if (rc == NULL && errno == ERANGE ) + errno = ENAMETOOLONG; + +/* return rc; + * } + */ diff --git a/guts/lchown.c b/guts/lchown.c index 6f7e53a..2d0aff2 100644 --- a/guts/lchown.c +++ b/guts/lchown.c @@ -4,14 +4,17 @@ */ pseudo_msg_t *msg; struct stat64 buf; - + if (!path) { + errno = EFAULT; + return -1; + } pseudo_debug(2, "lchown(%s, %d, %d)\n", - path ? path : "<null>", owner, group); + path ? path : "<nil>", owner, group); if (real___lxstat64(_STAT_VER, path, &buf) == -1) { return -1; } if (owner == -1 || group == -1) { - msg = pseudo_client_op(OP_STAT, AT_SYMLINK_NOFOLLOW, -1, -1, path, &buf); + msg = pseudo_client_op(OP_STAT, -1, -1, path, &buf); /* copy in any existing values... */ if (msg) { if (msg->result == RESULT_SUCCEED) { @@ -32,7 +35,7 @@ if (group != -1) { buf.st_gid = group; } - msg = pseudo_client_op(OP_CHOWN, AT_SYMLINK_NOFOLLOW, -1, -1, path, &buf); + msg = pseudo_client_op(OP_CHOWN, -1, -1, path, &buf); if (!msg) { errno = ENOSYS; rc = -1; diff --git a/guts/link.c b/guts/link.c index 278edd7..a68a1c1 100644 --- a/guts/link.c +++ b/guts/link.c @@ -17,11 +17,11 @@ * 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(OP_STAT, -1, -1, oldpath, &buf); if (msg) { pseudo_stat_msg(&buf, msg); } - pseudo_client_op(OP_LINK, 0, -1, -1, newpath, &buf); + pseudo_client_op(OP_LINK, -1, -1, newpath, &buf); } /* return rc; diff --git a/guts/mkdirat.c b/guts/mkdirat.c index a5ae5d8..188e66b 100644 --- a/guts/mkdirat.c +++ b/guts/mkdirat.c @@ -22,7 +22,7 @@ stat_rc = real___fxstatat64(_STAT_VER, dirfd, path, &buf, AT_SYMLINK_NOFOLLOW); #endif if (stat_rc != -1) { - pseudo_client_op(OP_MKDIR, AT_SYMLINK_NOFOLLOW, -1, dirfd, path, &buf); + pseudo_client_op(OP_MKDIR, -1, dirfd, path, &buf); } else { pseudo_debug(1, "mkdir of %s succeeded, but stat failed: %s\n", path, strerror(errno)); diff --git a/guts/mkstemp.c b/guts/mkstemp.c index b339b5c..a8f5915 100644 --- a/guts/mkstemp.c +++ b/guts/mkstemp.c @@ -5,21 +5,40 @@ */ struct stat64 buf; int save_errno; + size_t len; + char *tmp_template; - rc = real_mkstemp(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_mkstemp(tmp_template); if (rc != -1) { save_errno = errno; + if (real___fxstat64(_STAT_VER, rc, &buf) != -1) { - pseudo_client_op(OP_CREAT, 0, -1, -1, template, &buf); - pseudo_client_op(OP_OPEN, 0, rc, -1, template, &buf); + pseudo_client_op(OP_CREAT, -1, -1, tmp_template, &buf); + pseudo_client_op(OP_OPEN, 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, 0, rc, -1, template, 0); + pseudo_client_op(OP_OPEN, 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/guts/openat.c b/guts/openat.c index 9475aeb..801f1e3 100644 --- a/guts/openat.c +++ b/guts/openat.c @@ -48,13 +48,13 @@ 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_CREAT, -1, dirfd, path, &buf); } - pseudo_client_op(OP_OPEN, 0, rc, dirfd, path, &buf); + pseudo_client_op(OP_OPEN, 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, 0, rc, dirfd, path, 0); + pseudo_client_op(OP_OPEN, rc, dirfd, path, 0); } errno = save_errno; } diff --git a/guts/rename.c b/guts/rename.c index 9dd6d99..117eb78 100644 --- a/guts/rename.c +++ b/guts/rename.c @@ -8,7 +8,7 @@ int oldrc, newrc; int save_errno; - pseudo_debug(1, "rename: %s->%s\n", + pseudo_debug(2, "rename: %s->%s\n", oldpath ? oldpath : "<nil>", newpath ? newpath : "<nil>"); @@ -53,10 +53,10 @@ */ /* newpath must be removed. */ - pseudo_client_op(OP_UNLINK, AT_SYMLINK_NOFOLLOW, -1, -1, newpath, &newbuf); + pseudo_client_op(OP_UNLINK, -1, -1, newpath, &newbuf); /* fill in "correct" details from server */ - msg = pseudo_client_op(OP_STAT, AT_SYMLINK_NOFOLLOW, -1, -1, oldpath, &oldbuf); + msg = pseudo_client_op(OP_STAT, -1, -1, oldpath, &oldbuf); if (msg && msg->result == RESULT_SUCCEED) { pseudo_stat_msg(&oldbuf, msg); pseudo_debug(1, "renaming %s, got old mode of 0%o\n", oldpath, (int) msg->mode); @@ -67,9 +67,9 @@ */ pseudo_debug(1, "renaming new '%s' [%llu]\n", oldpath, (unsigned long long) oldbuf.st_ino); - pseudo_client_op(OP_LINK, AT_SYMLINK_NOFOLLOW, -1, -1, oldpath, &oldbuf); + pseudo_client_op(OP_LINK, -1, -1, oldpath, &oldbuf); } - pseudo_client_op(OP_RENAME, AT_SYMLINK_NOFOLLOW, -1, -1, newpath, &oldbuf, oldpath); + pseudo_client_op(OP_RENAME, -1, -1, newpath, &oldbuf, oldpath); errno = save_errno; /* return rc; diff --git a/guts/rmdir.c b/guts/rmdir.c index 029e5a2..94de46a 100644 --- a/guts/rmdir.c +++ b/guts/rmdir.c @@ -13,7 +13,7 @@ rc = real_rmdir(path); save_errno = errno; if (rc != -1) { - pseudo_client_op(OP_UNLINK, AT_SYMLINK_NOFOLLOW, -1, -1, path, &buf); + pseudo_client_op(OP_UNLINK, -1, -1, path, &buf); } errno = save_errno; diff --git a/guts/symlink.c b/guts/symlink.c index bc1c4be..324fef7 100644 --- a/guts/symlink.c +++ b/guts/symlink.c @@ -1,10 +1,10 @@ /* * static int - * wrap_symlink(const char *oldpath, const char *newpath) { + * wrap_symlink(const char *oldname, const char *newpath) { * int rc = -1; */ - rc = wrap_symlinkat(oldpath, AT_FDCWD, newpath); + rc = wrap_symlinkat(oldname, AT_FDCWD, newpath); /* return rc; * } diff --git a/guts/symlinkat.c b/guts/symlinkat.c index 5f1cc59..df1df06 100644 --- a/guts/symlinkat.c +++ b/guts/symlinkat.c @@ -1,21 +1,23 @@ /* * static int - * wrap_symlinkat(const char *oldpath, int dirfd, const char *newpath) { + * wrap_symlinkat(const char *oldname, int dirfd, const char *newpath) { * int rc = -1; */ struct stat64 buf; + char *roldname = 0; #ifdef PSEUDO_NO_REAL_AT_FUNCTIONS if (dirfd != AT_FDCWD) { errno = ENOSYS; return -1; } - rc = real_symlink(oldpath, newpath); + rc = real_symlink(roldname ? roldname : oldname, newpath); #else - rc = real_symlinkat(oldpath, dirfd, newpath); + rc = real_symlinkat(roldname ? roldname : oldname, dirfd, newpath); #endif if (rc == -1) { + free(roldname); return rc; } #ifdef PSEUDO_NO_REAL_AT_FUNCTIONS @@ -28,10 +30,13 @@ pseudo_diag("symlinkat: couldn't stat '%s' even though symlink creation succeeded (%s).\n", newpath, strerror(errno)); errno = save_errno; + free(roldname); return rc; } /* just record the entry */ - pseudo_client_op(OP_SYMLINK, AT_SYMLINK_NOFOLLOW, -1, dirfd, newpath, &buf); + pseudo_client_op(OP_SYMLINK, -1, dirfd, newpath, &buf); + + free(roldname); /* return rc; * } diff --git a/guts/unlinkat.c b/guts/unlinkat.c index cfa71e7..1c2868a 100644 --- a/guts/unlinkat.c +++ b/guts/unlinkat.c @@ -1,6 +1,6 @@ /* * static int - * wrap_unlinkat(int dirfd, const char *path, int flags) { + * wrap_unlinkat(int dirfd, const char *path, int rflags) { * int rc = -1; */ #ifdef PSEUDO_NO_REAL_AT_FUNCTIONS @@ -8,18 +8,17 @@ errno = ENOSYS; return -1; } - if (flags) { + if (rflags) { /* the only supported flag is AT_REMOVEDIR. We'd never call * with that flag unless the real AT functions exist, so * something must have gone horribly wrong.... */ pseudo_diag("wrap_unlinkat called with flags (0x%x), path '%s'\n", - flags, path ? path : "<nil>"); + rflags, path ? path : "<nil>"); errno = ENOSYS; return -1; } #endif - struct stat64 buf; #ifdef PSEUDO_NO_REAL_AT_FUNCTIONS @@ -33,10 +32,10 @@ #ifdef PSEUDO_NO_REAL_AT_FUNCTIONS rc = real_unlink(path); #else - rc = real_unlinkat(dirfd, path, flags); + rc = real_unlinkat(dirfd, path, rflags); #endif if (rc != -1) { - pseudo_client_op(OP_UNLINK, AT_SYMLINK_NOFOLLOW, -1, dirfd, path, &buf); + pseudo_client_op(OP_UNLINK, -1, dirfd, path, &buf); } /* return rc; diff --git a/makewrappers b/makewrappers index 11ef407..bc01e0d 100755 --- a/makewrappers +++ b/makewrappers @@ -51,6 +51,11 @@ cat >&5 <<EOF #include <string.h> #include <errno.h> #include <pthread.h> +#include <dirent.h> +#include <fts.h> +#include <ftw.h> +#include <glob.h> +#include <utime.h> #include <sys/types.h> #include <unistd.h> @@ -140,26 +145,64 @@ do \#*) continue;; esac # obtain return type, name, and arguments - args=`expr "$signature" : '.*(\(.*\));'` - return_and_name=`expr "$signature" : '\(.*\)('` + args=`expr "$signature" : '[^(]*(\(.*\));'` + modifiers=`expr "$signature" : '.*; /\* \(.*\) \*/'` + return_and_name=`expr "$signature" : '\([^(]*\)('` name=`expr "$return_and_name" : '.*[^a-zA-Z0-9_]\([a-zA-Z0-9_]*\)$'` type=`expr "$return_and_name" : '\(.*[^ ]\) *'"$name"'$'` printf >&2 ' %s' "$name" + wrapargnames='' argnames='' + # for handling path canonicalization + pathnames='' + flags='0' + dirfd='AT_FDCWD' + save_IFS=$IFS IFS=, set -- $args - IFS=$save_ifs + IFS=$save_IFS args='' optional_arg=false + prepend='' + depth=0 for arg do - # strip whitespace - arg=${arg# } - arg=${arg% } # handle optional arguments, like the third arg # to open() + if [ $depth -gt 0 ]; then + case $arg in + *\)*) + lcount=`echo $arg | tr -cd '(' | wc -c` + rcount=`echo $arg | tr -cd ')' | wc -c` + depth=`expr $depth + $lcount - $rcount` + prepend="${prepend:+$prepend,}$arg" + arg="" + ;; + *) prepend="${prepend:+$prepend,}$arg" + arg="" + ;; + esac + else + case $arg in + *\(*) lcount=`echo $arg | tr -cd '(' | wc -c` + rcount=`echo $arg | tr -cd ')' | wc -c` + depth=`expr $depth + $lcount - $rcount` + prepend="${prepend:+$prepend,}$arg" + arg="" + ;; + esac + fi + # we're inside nested ()s + if [ $depth -gt 0 ]; then + continue + fi + arg="$prepend$arg" + # strip whitespace + arg=${arg# } + arg=${arg% } + prepend='' case $arg in ...*) optional_arg=true @@ -167,6 +210,7 @@ do arg=`expr "$arg" : '\.\.\.{\(.*\)}'` argname=`expr "$arg" : '.*[^a-zA-Z0-9_]\([a-zA-Z0-9_]*\)$'` argnames="$argnames${argnames:+, }$argname" + wrapargnames="$wrapargnames${wrapargnames:+, }$argname" # we need this to extract and pass the argument optional_decl=$arg @@ -174,24 +218,61 @@ do optional_name=$argname optional_type=`expr "$arg" : '\(.*[^ ]\) *'"$argname"'$'` ;; + *\(*) # function pointer + argname=`expr "$arg" : '[^(]*(\*\([a-zA-Z0-9_]*\).*'` + args="$args${args:+, }$arg" + wrapargnames="$wrapargnames${wrapargnames:+, }$argname" + argnames="$argnames${argnames:+, }$argname" + prev_argname=$argname + ;; *) - argname=`expr "$arg" : '.*[^a-zA-Z0-9_]\([a-zA-Z0-9_]*\)$'` + argname=`expr "$arg" : '.*[^a-zA-Z0-9_](*\([a-zA-Z0-9_]*\))*(*)*$'` args="$args${args:+, }$arg" + # special handling for canonicalization + # set this before changing path -> rpath, for guts files + wrapargnames="$wrapargnames${wrapargnames:+, }$argname" + case $argname in + *path) pathnames="${pathnames+${pathnames} }$argname" + argname="r$argname" + ;; + dirfd) dirfd='dirfd';; + flags) flags='flags';; + esac argnames="$argnames${argnames:+, }$argname" prev_argname=$argname ;; esac done + # see whether flags was overridden + flags_tmp=`expr "$modifiers" : 'flags=\([^ ]*\)'` + if [ -n "$flags_tmp" ]; then + flags=$flags_tmp + fi + decl_paths='' + alloc_paths='' + free_paths='' + # any argument ending in "path" is presumed to need to be + # converted to a chroot path. To avoid this, name the + # argument something else (e.g. "template" for mkstemp) + for p in $pathnames; do + decl_paths="${decl_paths} + char *r$p = (char *) $p;" + alloc_paths="${alloc_paths} + r$p = pseudo_root_path(__func__, __LINE__, $dirfd, $p, $flags);" + free_paths="${free_paths} + free(r$p);" + done # determine default return value. case $type in - int) + int|ssize_t|long) default_value=-1;; uid_t|gid_t) default_value=0;; - 'FILE *') + 'FILE *' | 'char *' | 'DIR *' | 'FTS *') default_value=NULL;; - *) echo >&2 "Unknown type '$type'." ; exit 1 ;; + *) echo >&2 " +Unknown type '$type'." ; exit 1 ;; esac # create the wrappers # first the dummy, and the function pointer: @@ -226,10 +307,12 @@ EOF fi # and now the body of the wrapper: cat >&5 <<EOF + pseudo_debug(4, "called: $name\n"); if (pseudo_getlock()) { errno = EBUSY; return $default_value; } + $decl_paths if (pseudo_populate_wrappers()) { $type rc = $default_value; int save_errno; @@ -240,14 +323,18 @@ EOF rc = dummy_$name($argnames); } } else { +$alloc_paths rc = wrap_$name($argnames); +$free_paths } save_errno = errno; pseudo_droplock(); errno = save_errno; + pseudo_debug(4, "completed: $name\n"); return rc; } else { pseudo_droplock(); + pseudo_debug(4, "completed: $name\n"); return dummy_$name($argnames); } } @@ -302,7 +389,7 @@ EOF * $type rc = $default_value; */ - rc = real_$name($argnames); + rc = real_$name($wrapargnames); /* return rc; * } @@ -316,7 +403,7 @@ EOF * $type rc = $default_value; */ - rc = real_$name($argnames); + rc = real_$name($wrapargnames); /* return rc; * } @@ -64,9 +64,11 @@ main(int argc, char *argv[]) { int lockfd, newfd; char *ld_env = getenv("LD_PRELOAD"); int rc; - char opts[PATH_MAX] = "", *optptr = opts; + char opts[pseudo_path_max()], *optptr = opts; char *lockname; + opts[0] = '\0'; + s = getenv("PSEUDO_DEBUG"); if (s) { int level = atoi(s); @@ -108,7 +110,7 @@ main(int argc, char *argv[]) { usage(0); break; case 'l': - optptr += snprintf(optptr, PATH_MAX - (optptr - opts), + optptr += snprintf(optptr, pseudo_path_max() - (optptr - opts), "%s-l", optptr > opts ? " " : ""); opt_l = 1; break; @@ -124,7 +126,7 @@ main(int argc, char *argv[]) { pseudo_diag("Timeout must be an integer value.\n"); usage(EXIT_FAILURE); } - optptr += snprintf(optptr, PATH_MAX - (optptr - opts), + optptr += snprintf(optptr, pseudo_path_max() - (optptr - opts), "%s-t %d", optptr > opts ? " " : "", pseudo_server_timeout); break; @@ -118,6 +118,8 @@ extern void pseudo_dropenv(void); extern void pseudo_setupenv(char *); extern char *pseudo_prefix_path(char *); extern char *pseudo_get_prefix(char *); +extern ssize_t pseudo_sys_path_max(void); +extern ssize_t pseudo_path_max(void); extern char *pseudo_version; diff --git a/pseudo_client.c b/pseudo_client.c index d957116..5ada209 100644 --- a/pseudo_client.c +++ b/pseudo_client.c @@ -37,14 +37,16 @@ #include "pseudo_ipc.h" #include "pseudo_client.h" +static char *base_path(int dirfd, const char *path, int leave_last); + static int connect_fd = -1; static int server_pid = 0; int pseudo_dir_fd = -1; +char *pseudo_cwd = 0; +size_t pseudo_cwd_len; static char **fd_paths = 0; static int nfds = 0; -static char cwdbuf[PATH_MAX * 2], *cwd; -static int cwdlen = 0; static int messages = 0; static struct timeval message_time = { 0 }; static int pseudo_inited = 0; @@ -75,13 +77,52 @@ pseudo_client_touchgid(void) { setenv("PSEUDO_GIDS", gidbuf, 1); } +char * +pseudo_root_path(const char *func, int line, int dirfd, const char *path, int leave_last) { + char *rc; + pseudo_antimagic(); + rc = base_path(dirfd, path, leave_last); + pseudo_magic(); + if (!rc) { + pseudo_diag("couldn't allocate absolute path for '%s'.\n", + path); + } + pseudo_debug(3, "root_path [%s, %d]: '%s' from '%s'\n", + func, line, + rc ? rc : "<nil>", + path ? path : "<nil>"); + return rc; +} + +int +pseudo_client_getcwd(void) { + char *cwd; + cwd = malloc(pseudo_path_max()); + if (!cwd) { + pseudo_diag("Can't allocate CWD buffer!\n"); + return -1; + } + pseudo_debug(2, "getcwd: trying to find cwd.\n"); + if (getcwd(cwd, pseudo_path_max())) { + /* cwd now holds a canonical path to current directory */ + pseudo_cwd_len = strlen(cwd); + pseudo_debug(3, "getcwd okay: [%s] %d bytes\n", cwd, (int) pseudo_cwd_len); + free(pseudo_cwd); + pseudo_cwd = cwd; + return 0; + } else { + pseudo_diag("Can't get CWD: %s\n", strerror(errno)); + return -1; + } +} + static char * fd_path(int fd) { if (fd >= 0 && fd < nfds) { return fd_paths[fd]; } if (fd == AT_FDCWD) { - return cwd; + return pseudo_cwd; } return 0; } @@ -130,8 +171,7 @@ pseudo_client_reset() { close(connect_fd); connect_fd = -1; } - cwd = getcwd(cwdbuf, PATH_MAX); - cwdlen = strlen(cwd); + pseudo_client_getcwd(); if (!pseudo_inited) { char *env; @@ -551,39 +591,42 @@ pseudo_client_shutdown(void) { static char * base_path(int dirfd, const char *path, int leave_last) { char *basepath = 0; - size_t pathlen = -1; - size_t baselen; + size_t baselen = 0; char *newpath; - if (dirfd != -1 && dirfd != AT_FDCWD) { - if (dirfd >= 0) { - basepath = fd_path(dirfd); - baselen = strlen(basepath); + if (path[0] != '/') { + if (dirfd != -1 && dirfd != AT_FDCWD) { + if (dirfd >= 0) { + basepath = fd_path(dirfd); + baselen = strlen(basepath); + } else { + pseudo_diag("got *at() syscall for unknown directory, fd %d\n", dirfd); + } } else { - pseudo_diag("got *at() syscall for unknown directory, fd %d\n", dirfd); + basepath = pseudo_cwd; + baselen = pseudo_cwd_len; + } + if (!basepath) { + pseudo_diag("unknown base path for fd %d, path %s\n", dirfd, path); + return 0; } - } else { - basepath = cwd; - baselen = cwdlen; - } - if (!basepath) { - pseudo_diag("unknown base path for fd %d, path %s\n", dirfd, path); - return 0; } - pathlen = baselen + strlen(path) + 2; newpath = pseudo_fix_path(basepath, path, baselen, NULL, leave_last); + pseudo_debug(4, "base_path: %s</>%s\n", + basepath ? basepath : "<nil>", + path ? path : "<nil>"); return newpath; } pseudo_msg_t * -pseudo_client_op(op_id_t op, int flags, int fd, int dirfd, const char *path, const struct stat64 *buf, ...) { +pseudo_client_op(op_id_t op, int fd, int dirfd, const char *path, const struct stat64 *buf, ...) { pseudo_msg_t *result = 0; pseudo_msg_t msg = { .type = PSEUDO_MSG_OP }; - char *newpath = 0; size_t pathlen = -1; int do_request = 0; char *oldpath = 0; + char *newpath = 0; /* disable wrappers */ pseudo_antimagic(); @@ -606,43 +649,27 @@ pseudo_client_op(op_id_t op, int flags, int fd, int dirfd, const char *path, con pseudo_magic(); return 0; } - if (oldpath[0] != '/') { - oldpath = base_path(dirfd, oldpath, 1); - } else { - oldpath = pseudo_fix_path(NULL, oldpath, 0, NULL, 1); - } } if (path) { - /* fixup relative path */ - if (*path != '/') { - newpath = base_path(dirfd, path, flags); - } else { - newpath = pseudo_fix_path(NULL, path, 0, NULL, flags); - } - if (newpath) { - pathlen = strlen(newpath) + 1; - } else { - pseudo_diag("couldn't allocate space for a path (%s). Sorry.\n", path); - free(oldpath); - pseudo_magic(); - return 0; - } + /* path fixup has to happen in the specific functions, + * because they may have to make calls which have to be + * fixed up for chroot stuff already. + */ + pathlen = strlen(path) + 1; if (oldpath) { size_t full_len = strlen(oldpath) + 1 + pathlen; char *both_paths = malloc(full_len); if (!both_paths) { pseudo_diag("can't allocate space for paths for a rename operation. Sorry.\n"); - free(newpath); - free(oldpath); pseudo_magic(); return 0; } snprintf(both_paths, full_len, "%s%c%s", - newpath, 0, oldpath); + path, 0, oldpath); pseudo_debug(2, "rename: %s -> %s [%d]\n", both_paths + pathlen, both_paths, (int) full_len); - free(newpath); + path = both_paths; newpath = both_paths; pathlen = full_len; } @@ -660,10 +687,9 @@ pseudo_client_op(op_id_t op, int flags, int fd, int dirfd, const char *path, con (dirfd != -1 && dirfd != AT_FDCWD && op != OP_DUP) ? "at" : ""); if (oldpath) { pseudo_debug(2, " %s ->", (char *) oldpath); - free(oldpath); } - if (newpath || path) { - pseudo_debug(2, " %s", newpath ? newpath : path); + if (path) { + pseudo_debug(2, " %s", path); } if (fd != -1) { pseudo_debug(2, " [fd %d]", fd); @@ -688,12 +714,11 @@ pseudo_client_op(op_id_t op, int flags, int fd, int dirfd, const char *path, con pseudo_debug(4, "processing request [ino %llu]\n", (unsigned long long) msg.ino); switch (msg.op) { case OP_CHDIR: - cwd = getcwd(cwdbuf, PATH_MAX); - cwdlen = strlen(cwd); + pseudo_client_getcwd(); do_request = 0; break; case OP_OPEN: - pseudo_client_path(fd, newpath ? newpath : path); + pseudo_client_path(fd, path); do_request = 1; break; case OP_CLOSE: @@ -752,7 +777,7 @@ pseudo_client_op(op_id_t op, int flags, int fd, int dirfd, const char *path, con 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, newpath ? newpath : path); + result = pseudo_client_request(&msg, pathlen, path); gettimeofday(&tv2, NULL); ++messages; message_time.tv_sec += (tv2.tv_sec - tv1.tv_sec); @@ -787,6 +812,7 @@ pseudo_client_op(op_id_t op, int flags, int fd, int dirfd, const char *path, con } pseudo_debug(2, "\n"); + /* if not NULL, newpath is the buffer holding both paths */ free(newpath); if (do_request && (messages % 1000 == 0)) { diff --git a/pseudo_client.h b/pseudo_client.h index b5a6075..a1e8d45 100644 --- a/pseudo_client.h +++ b/pseudo_client.h @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -extern pseudo_msg_t *pseudo_client_op(op_id_t op, int flags, int fd, int dirfd, const char *path, const struct stat64 *buf, ...); +extern pseudo_msg_t *pseudo_client_op(op_id_t op, int fd, int dirfd, const char *path, const struct stat64 *buf, ...); extern void pseudo_antimagic(void); extern void pseudo_magic(void); extern void pseudo_client_reset(void); @@ -41,6 +41,13 @@ extern int pseudo_rgid; extern int pseudo_fgid; extern int pseudo_dir_fd; +/* support related to chroot/getcwd/etc. */ +extern int pseudo_client_getcwd(void); +extern char *pseudo_root_path(const char *, int, int, const char *, int); +#define PSEUDO_ROOT_PATH(x, y, z) pseudo_root_path(__func__, __LINE__, (x), (y), (z)); +extern char *pseudo_cwd; +extern size_t pseudo_cwd_len; + /* Root can read, write, and execute files which have no read, write, * or execute permissions. * diff --git a/pseudo_util.c b/pseudo_util.c index 0a2c683..4bc2d5a 100644 --- a/pseudo_util.c +++ b/pseudo_util.c @@ -30,7 +30,9 @@ #include "pseudo_ipc.h" #include "pseudo_db.h" -/* 3 = detailed protocol analysis +/* 5 = ridiculous levels of duplication + * 4 = exhaustive detail + * 3 = detailed protocol analysis * 2 = higher-level protocol analysis * 1 = stuff that might go wrong * 0 = fire and arterial bleeding @@ -43,6 +45,8 @@ static size_t pid_len; static int pseudo_append_element(char **newpath, size_t *allocated, char **current, const char *element, size_t elen, int leave_last); static int pseudo_append_elements(char **newpath, size_t *allocated, char **current, const char *elements, size_t elen, int leave_last); extern char **environ; +static ssize_t pseudo_max_pathlen = -1; +static ssize_t pseudo_sys_max_pathlen = -1; char *pseudo_version = PSEUDO_VERSION; @@ -198,11 +202,11 @@ pseudo_append_element(char **pnewpath, size_t *pallocated, char **pcurrent, cons is_link = 0; } if (is_link) { - char linkbuf[PATH_MAX + 1]; + char linkbuf[pseudo_path_max() + 1]; ssize_t linklen; int retval; - linklen = readlink(newpath, linkbuf, PATH_MAX); + linklen = readlink(newpath, linkbuf, pseudo_path_max()); if (linklen == -1) { pseudo_diag("uh-oh! '%s' seems to be a symlink, but I can't read it. Ignoring.", newpath); return 0; @@ -459,29 +463,29 @@ pseudo_get_prefix(char *pathname) { char *s; s = getenv("PSEUDO_PREFIX"); if (!s) { - char mypath[PATH_MAX]; + char mypath[pseudo_path_max()]; char *dir; char *tmp_path; if (pathname[0] == '/') { - snprintf(mypath, PATH_MAX, "%s", pathname); + snprintf(mypath, pseudo_path_max(), "%s", pathname); s = mypath + strlen(mypath); } else { - if (!getcwd(mypath, PATH_MAX)) { + if (!getcwd(mypath, pseudo_path_max())) { mypath[0] = '\0'; } s = mypath + strlen(mypath); - s += snprintf(s, PATH_MAX - (s - mypath), "/%s", + s += snprintf(s, pseudo_path_max() - (s - mypath), "/%s", pathname); } - tmp_path = pseudo_fix_path(NULL, mypath, 0, 0, 0); + tmp_path = pseudo_fix_path(NULL, mypath, 0, 0, AT_SYMLINK_NOFOLLOW); /* point s to the end of the fixed path */ - if (strlen(tmp_path) >= PATH_MAX) { - pseudo_diag("Can't expand path '%s' -- expansion exceeds PATH_MAX.\n", - mypath); + if (strlen(tmp_path) >= pseudo_path_max()) { + pseudo_diag("Can't expand path '%s' -- expansion exceeds %d.\n", + mypath, (int) pseudo_path_max()); free(tmp_path); } else { - s = mypath + snprintf(mypath, PATH_MAX, "%s", tmp_path); + s = mypath + snprintf(mypath, pseudo_path_max(), "%s", tmp_path); free(tmp_path); } @@ -508,3 +512,57 @@ pseudo_get_prefix(char *pathname) { } return s; } + +/* these functions define the sizes pseudo will try to use + * when trying to allocate space, or guess how much space + * other people will have allocated; see the GNU man page + * for realpath(3) for an explanation of why the sys_path_max + * functions exists, approximately -- it's there to be a size + * that I'm pretty sure the user will have allocated if they + * provided a buffer to that defective function. + */ +/* I'm pretty sure this will be larger than real PATH_MAX */ +#define REALLY_BIG_PATH 16384 +/* A likely common value for PATH_MAX */ +#define SORTA_BIG_PATH 4096 +ssize_t +pseudo_path_max(void) { + if (pseudo_max_pathlen == -1) { + long l = pathconf("/", _PC_PATH_MAX); + if (l < 0) { + if (_POSIX_PATH_MAX > 0) { + pseudo_max_pathlen = _POSIX_PATH_MAX; + } else { + pseudo_max_pathlen = REALLY_BIG_PATH; + } + } else { + if (l <= REALLY_BIG_PATH) { + pseudo_max_pathlen = l; + } else { + pseudo_max_pathlen = REALLY_BIG_PATH; + } + } + } + return pseudo_max_pathlen; +} + +ssize_t +pseudo_sys_path_max(void) { + if (pseudo_sys_max_pathlen == -1) { + long l = pathconf("/", _PC_PATH_MAX); + if (l < 0) { + if (_POSIX_PATH_MAX > 0) { + pseudo_sys_max_pathlen = _POSIX_PATH_MAX; + } else { + pseudo_sys_max_pathlen = SORTA_BIG_PATH; + } + } else { + if (l <= SORTA_BIG_PATH) { + pseudo_sys_max_pathlen = l; + } else { + pseudo_sys_max_pathlen = SORTA_BIG_PATH; + } + } + } + return pseudo_sys_max_pathlen; +} diff --git a/wrapfuncs.in b/wrapfuncs.in index e92de5e..5b262e7 100644 --- a/wrapfuncs.in +++ b/wrapfuncs.in @@ -1,44 +1,47 @@ int open(const char *path, int flags, ...{mode_t mode}); +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); -int rename(const char *oldpath, const char *newpath); -int renameat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath); -int unlink(const char *path); -int unlinkat(int dirfd, const char *path, int flags); +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); +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); +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); -int __xmknodat(int ver, int dirfd, const char *path, mode_t mode, dev_t *dev); +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); +int mkdir(const char *path, mode_t mode); /* flags=AT_SYMLINK_NOFOLLOW */ int mkdirat(int dirfd, const char *path, mode_t mode); -int rmdir(const char *path); +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}); int fork(void); int vfork(void); # just so we know the inums of symlinks -int symlink(const char *oldpath, const char *newpath); -int symlinkat(const char *oldpath, int dirfd, const char *newpath); +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); +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); diff --git a/wrapfuncs64.in b/wrapfuncs64.in index 94c4744..8470c04 100644 --- a/wrapfuncs64.in +++ b/wrapfuncs64.in @@ -3,7 +3,7 @@ int openat64(int dirfd, const char *path, int flags, ...{mode_t mode}); int __openat64_2(int dirfd, const char *path, int flags); 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); +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); |