Hi, The attached test program is extracted from one of p11-kit tests (the only failing test) in trust/test_token.c: test_not_writable (): token = p11_token_new (333, "/non-existant", "Label"); main(): p11_test (test_not_writable, "/token/not-writable");
This test fails with fakeroot-hurd on Hurd due to that /non-existant is writable for faked nodes according to: error_t netfs_report_access (struct iouser *cred, struct node *np, int *types) { struct netnode *nn = netfs_node_netnode (np); if (!(nn->faked & FAKE_MODE)) return file_check_access (nn->file, types); else *types = O_RDWR|O_EXEC; return 0; } which is reasonable if fakeroot is to mimic real root accesses. Return values are *is_writable=1 and errno="No such file or directory". However, running this program with fakeroot-tcp on Hurd or fakeroot-sysv on Linux returns *is_writable=0 and errno="Permission denied" while running it as real root of course returns *is_writable=1 and errno="No such file or directory" on both Linux and Hurd. Maybe even the tests should not be run under fakeroot at all as is done now with fakeroot debian/rules binary? The attached patch makes the behaviour the same as on Linux and fakeroot-tcp. The question is which behaviour is the expected one. Index: hurd-0.6.git20150704/trans/fakeroot.c =================================================================== --- hurd-0.6.git20150704.orig/trans/fakeroot.c +++ hurd-0.6.git20150704/trans/fakeroot.c @@ -785,11 +785,7 @@ error_t netfs_report_access (struct iouser *cred, struct node *np, int *types) { struct netnode *nn = netfs_node_netnode (np); - if (!(nn->faked & FAKE_MODE)) - return file_check_access (nn->file, types); - else - *types = O_RDWR|O_EXEC; - return 0; + return = file_check_access (nn->file, types); } error_t
#include <stdio.h> #include <string.h> #include <errno.h> #include <error.h> #include <unistd.h> #include <sys/stat.h> #include <sys/types.h> #include <libgen.h> #define bool int #define true 1 #define false 0 static bool check_directory (const char *path, bool *make_directory, bool *is_writable) { struct stat sb; char *parent, *path1; bool dummy = 0; bool ret; fprintf(stderr,"\ntrust/token.c (check_directory): ENTERING stat() path=%s, *make_directory=%d, *is_writable=%d\n", path, *make_directory, *is_writable); fflush(stderr); if (stat (path, &sb) == 0) { fprintf(stderr,"\ntrust/token.c (check_directory): stat(path, &sb) == 0 BEFORE *is_writable\n"); fflush(stderr); *make_directory = false; int err = access (path, W_OK); *is_writable = S_ISDIR (sb.st_mode) && (err == 0); fprintf(stderr,"\ntrust/token.c (check_directory): stat(path, &sb) == 0 AFTER *is_writable, access(2) sets errno\n"); fprintf(stderr,"\ntrust/token.c (check_directory): access(path, W_OK)=%d, errno=%s, *is_writable=%d\n", err, strerror(errno), *is_writable); fflush(stderr); return true; } switch (errno) { case EACCES: fprintf(stderr,"\ntrust/token.c (check_directory): case EACCES\n"); fflush(stderr); *is_writable = false; *make_directory = false; return true; case ENOENT: fprintf(stderr,"\ntrust/token.c (check_directory): case ENOENT\n"); fflush(stderr); *make_directory = true; //parent = p11_path_parent (path); path1 = strdup(path); parent = dirname (path1); if (parent == NULL) ret = false; else ret = check_directory (parent, &dummy, is_writable); return ret; default: fprintf(stderr,"\ntrust/token.c (check_directory): case default\n"); fflush(stderr); error (1, errno, "couldn't access: %s", path); return false; } } int main(void) { const char *path ="/non-existant"; bool ret = false, make_directory = false; int is_writable = 0; ret = check_directory (path, &make_directory, &is_writable); return ret; }