uclibc-0.9.30 - ppoll returns invalid argument
Ursus
ursus at pajkc.eu
Thu Jan 29 15:09:48 UTC 2009
Denys Vlasenko wrote:
> On Wednesday 28 January 2009 16:03, Ursus wrote:
>> In the uclibc sources I found that uclibc calls kernel ppoll with four
>> arguments:
>> _syscall4(int, __libc_ppoll, struct pollfd *, fds,
>> nfds_t, nfds, const struct timespec *, timeout,
>> const __sigset_t *, sigmask)
>>
>> But the kernel ppoll (sys_ppoll) declaration specifies five parameters:
>> long sys_ppoll(struct pollfd __user *ufds, unsigned int nfds,
>> struct timespec __user *tsp, const sigset_t __user *sigmask,
>> size_t sigsetsize)
>>
>>
>> I substituted the ordinary ppoll call with indirect call to see if above
>> is true.
>> syscall(SYS_ppoll, fds, count, &timeout, &sigmask, sizeof(sigset_t));
>> Strace returned:
>> ...
>> ppoll([{fd=0, events=POLLIN}], 1, {5, 0}, [], 128) = -1 EINVAL (Invalid
>> argument)
>> ...
>>
>> I made a little research and figured out that the kernel expects last
>> argument to be 16 (128 / 8).
>
> I believe you are wrong here. All arches except MIPS have 64 signals
> and therefore need 64-bit sigset_t. 64 bits == 8 bytes, not 16.
Yes I was wrong. In kernel space sizeof(sigetset_t) returns 8 as you said.
>
> The rest of your analysis is correct.
>
>> That confused me because I thought the
>> sizeof(sigset_t) returns the same in kernel and user space.
>
> Yes, it wasn't, we had glibc-like overblown 1024-bit sigset_t.
> (That's where 128 came from in your code. 1024/8 = 128)
>
> It will match kernel's sigset_t starting from 0.9.31.
>
> Please try attached patch.
> --
> vda
>
Your patch has fixed the problem and function ppoll works fine.
Thanks for patch and all the explanation.
Ursus
More information about the uClibc
mailing list