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;
}