develooper Front page | perl.perl5.porters | Postings from April 2018

Re: [perl #132560] perl-5.24.3, wrong Configure test for IPC_STAT

Thread Previous | Thread Next
From:
Leon Timmermans
Date:
April 13, 2018 23:16
Subject:
Re: [perl #132560] perl-5.24.3, wrong Configure test for IPC_STAT
Message ID:
CAHhgV8j2Wg0Jdt9UYG2j9mm0x=fKTKZE7Uy7hdzYu_-n8DT=zA@mail.gmail.com
On Thu, Mar 29, 2018 at 4:23 PM, H.Merijn Brand <h.m.brand@xs4all.nl> wrote:
> Added James and Leon to To: as my mails do not seem to arrive in p5p
>
> On Sun, 10 Dec 2017 09:19:47 -0800, (via RT) <perlbug-followup@perl.org> wrote:
>
>> # Please include the string:  [perl #132560]
>> # <URL: https://rt.perl.org/Ticket/Display.html?id=132560 >
>> -----------------------------------------------------------------
>> in perl Configure script there is this test for IPC_STAT:
>
> That is unit U/modified/d_union_semun.U, which you can find here:
> https://github.com/perl5-metaconfig/metaconfig/blob/master/U/modified/d_union_semun.U#L176
>
>> #include <sys/types.h>
>> #include <sys/ipc.h>
>> #include <sys/sem.h>
>> #include <sys/stat.h>
>> #include "tryh.h"
>> #include <stdio.h>
>> #include <errno.h>
>> #ifndef errno
>> extern int errno;
>> #endif
>> int main() {
>>     struct semid_ds arg;
>>     int sem, st;
>>
>> #if defined(IPC_PRIVATE) && defined(S_IRWXU) && defined(S_IRWXG) &&  defined(S_IRWXO) && defined(IPC_CREAT)
>>     printf("size:%d\n", sizeof(semopts));
>>     sem = semget(IPC_PRIVATE, 1, S_IRWXU|S_IRWXG|S_IRWXO|IPC_CREAT);
>>     if (sem > -1) {
>> #       ifdef IPC_STAT
>>             st = semctl(sem, 0, IPC_STAT, &arg);
>>         if (st == 0)
>>             printf("semid_ds\n");
>>         else
>> #       endif /* IPC_STAT */
>>             printf("semctl IPC_STAT failed: errno = %d\n", errno);
>> #       ifdef IPC_RMID
>>         if (semctl(sem, 0, IPC_RMID, &arg) != 0)
>> #       endif /* IPC_RMID */
>>             printf("semctl IPC_RMID failed: errno = %d\n", errno);
>>     } else
>> #endif /* IPC_PRIVATE && ... */
>>         printf("semget failed: errno = %d\n", errno);
>>
>>     return 0;
>> }
>>
>> This fails on ppc32 with:
>>   semctl IPC_STAT failed: errno = 14
>> because the test is flawed. The semctl() test must be like so:
>>
>>     union semun {
>>       void *buf;
>>     } semopts;
>>     semopts.buf = &arg;
>> ..
>>     st = semctl(sem, 0, IPC_STAT, semopts);
>> ..
>>     if (semctl(sem, 0, IPC_RMID, semopts) != 0) /* semopts not really needed */
>>
>> Now the test works.
>
> If I read the rest of the unit, combined with your rem,arks, that makes
> me think this ought to fix it:
>
> --8<---
> diff --git a/U/modified/d_union_semun.U b/U/modified/d_union_semun.U
> index 55f224f..6ddad1a 100644
> --- a/U/modified/d_union_semun.U
> +++ b/U/modified/d_union_semun.U
> @@ -184,21 +184,31 @@ END
>  extern int errno;
>  #endif
>  int main() {
> -    struct semid_ds arg;
> +    union semun
> +#ifndef HAS_UNION_SEMUN
> +    {
> +       int val;
> +       struct semid_ds *buf;
> +       unsigned short *array;
> +    }
> +#endif
> +    arg;
> +    struct semid_ds argbuf;
>      int sem, st;
>
>  #if defined(IPC_PRIVATE) && defined(S_IRWXU) && defined(S_IRWXG) &&  defined(S_IRWXO) && defined(IPC_CREAT)
>      sem = semget(IPC_PRIVATE, 1, S_IRWXU|S_IRWXG|S_IRWXO|IPC_CREAT);
>      if (sem > -1) {
> +       arg.buf = &argbuf;
>  #      ifdef IPC_STAT
> -       st = semctl(sem, 0, IPC_STAT, &arg);
> +       st = semctl(sem, 0, IPC_STAT, arg);
>         if (st == 0)
>             printf("semid_ds\n");
>         else
>  #      endif /* IPC_STAT */
>             printf("semctl IPC_STAT failed: errno = %d\n", errno);
>  #      ifdef IPC_RMID
> -       if (semctl(sem, 0, IPC_RMID, &arg) != 0)
> +       if (semctl(sem, 0, IPC_RMID, arg) != 0)
>  #      endif /* IPC_RMID */
>             printf("semctl IPC_RMID failed: errno = %d\n", errno);
>      } else
> -->8---
>
>
> Do people with more knowledge on semctl agree?

Yeah, this looks sensible, as far as anything dealing with semctl can
ever look sensible. The old code takes a shortcut by assuming a
pointer type and a union containing that pointer type (and nothing
bigger) are equivalent when passed as an argument to a varargs
function. I'm not sure why they're apparently not on ppc32, but the C
standard defines rather little about unions anyway.

Leon

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About