On PowerPC systems the following short check fails:
errno = 0;
unsigned long dev = 0xfacefeed00000000ULL | makedev(1, 7);
syscall(__NR_mknod, "/", S_IFCHR | 0777, dev);
if (errno != EEXIST) {
perror("mknod");
exit(1);
}
(see github repository: [1])
On ppc mknod is successful, but it should fail with EEXISTS (as “/” exists). Other architectures are fine [2].
If 0xfacefeed00000000ULL magic is removed from dev, the check passes on pcc too. Although the choice of this dev value might seem irrational, this kind of or-ing is frequently used is strace tests, where mknod test started failing about a week ago [3].
[1] https://github.com/AkosUzonyi/travis-ppc-bugreport
[2] https://travis-ci.org/github/AkosUzonyi/travis-ppc-bugreport/builds/720778638
[3] https://travis-ci.com/github/strace/strace/builds
WFM with below code.
Setting errno = 0
and not checking the return code of syscall
looks like the problem.
#include <errno.h>
#include <stdio.h>
#include <sys/sysmacros.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
int main(void)
{
dev_t dev = 0xfacefeed00000000ULL | makedev(1, 7);
if (syscall(__NR_mknod, "/", S_IFCHR | 0777, dev)) {
perror("mknod");
return 0;
}
return 1;
}
Thanks, but the problem is fixed now, so both version work (although I didn’t check the return value in my code above, it was 0, so checking it wouldn’t have helped either).
The thing is, the original version didn’t work for me, even locally
That’s interesting. I suspect it didn’t work because on your system errno isn’t set to EEXISTS as expected, but for example EPERM. That can be also a correct behaviour. However in the past on ppc travis systems errno was ESUCCESS which is clearly not acceptable.
1 Like