develooper Front page | perl.perl5.porters | Postings from September 2012

[perl #114516] Win32 Perl declares non-exported externs to XS Modules

Thread Next
From:
Steve Hay via RT
Date:
September 21, 2012 00:51
Subject:
[perl #114516] Win32 Perl declares non-exported externs to XS Modules
Message ID:
rt-3.6.HEAD-11172-1348213899-1746.114516-15-0@perl.org
On Mon Aug 20 13:57:27 2012, bulk88 wrote:
> Perl is declaring not exported from the Perl interp functions that
>    implement POSIX C lib functions that are not implemented in
>    Windows's native C lib (MS CRT), but these POSIX Perl C Lib
>    replacements are not exported from the Perl library DLL to XS
>    modules, so if a XS module tries to accidentally use one of these,
>    they will get only a link error, instead of a link error and a
>    undefined symbol error from c compiler making them think they
>    forgot got to include a .lib/.a, rather than the function simply
>    doesn't exist.
> _________________________________________________________________
> #line 216 "c:\\perl517\\lib\\core\\win32.h"
> extern� uid_t��� getuid(void);
> extern� gid_t��� getgid(void);
> extern� uid_t��� geteuid(void);
> extern� gid_t��� getegid(void);
> extern� int��� setuid(uid_t uid);
> extern� int��� setgid(gid_t gid);
> extern� int��� kill(int pid, int sig);
> extern� int��� killpg(int pid, int sig);
> 
> extern� void��� *sbrk(ptrdiff_t need);
> 
> #line 280 "c:\\perl517\\lib\\core\\win32.h"
> extern��� char *��� getlogin(void);
> extern��� int��� chown(const char *p, uid_t o, gid_t g);
> extern� int��� mkstemp(const char *path);
> _________________________________________________________________


Note that setuid and setgid are both exported. I haven't looked into
why, but it might not be necessary and could possibly be changed for 5.18?

Of the other 10, 7 of them get indirected through my_perl->IProc in a
default build with PERL_IMPLICIT_SYS, so any XS code like this:

    (void)getuid();
    (void)getgid();
    (void)geteuid();
    (void)getegid();
    (void)kill(0, 0);
    (void)killpg(0, 0);
    (void)getlogin();

gets turned into this by the pre-processor anyway:

    (void)(*(my_perl->IProc)->pGetuid)((my_perl->IProc));
    (void)(*(my_perl->IProc)->pGetgid)((my_perl->IProc));
    (void)(*(my_perl->IProc)->pGeteuid)((my_perl->IProc));
    (void)(*(my_perl->IProc)->pGetegid)((my_perl->IProc));
    (void)(*(my_perl->IProc)->pKill)((my_perl->IProc), (0), (0));
    (void)(*(my_perl->IProc)->pKillpg)((my_perl->IProc), (0), (0));
    (void)(*(my_perl->IProc)->pGetlogin)((my_perl->IProc));

so you still won't see any warnings from the compiler even with the
extern declarations removed (or the linker, for that matter: nothing is
undefined or unresolved there).

It is probably worth doing anyway, though (and won't break the above)
for the sake of perls built without PERL_IMPLICIT_SYS: in that case, the
above XS gets pre-processed into:

    (void)getuid();
    (void)getgid();
    (void)geteuid();
    (void)getegid();
    (void)win32_kill(0, 0);
    (void)killpg(0, 0);
    (void)getlogin();

so 6 of them are indeed getting 'undefined' warnings from the compiler
hidden by our extern declarations. (There's also no harm in hiding the
kill() declaration, although it won't achieve anything in that case
because it is changed to win32_kill, which is declared, defined and
exported.) It's not quite as simple as just removing them from
win32/win32.h, though, because 5 of them (getuid, getgid, geteuid,
getegid and getlogin) are also declared in perl.h, which XS modules also
(obviously) include, so they'll need to be hidden in there on Win32 too.

The remaining 3 (sbrk, chown and mkstemp) should definitely have their
declarations hidden. (It was one of those (mkstemp) which your original
problem stems from.)

So in short, I think we should indeed hide all 10 declarations (i.e. all
those other than setuid and setgid), although in some cases there is no
problem being solved since the function calls are pre-processed into
something else which isn't a problem anyway, but I see no harm in always
hiding them anyway.

I thought that we could hide them by moving them to new .h files (like
other UNIX compatibility functions declared in win32/include files) but
that won't easily fix the problem because installperl currently seems to
install *all* .h files. (Try just adding in a random new .h file: run
"nmake install" and it gets installed into lib/CORE.) But the
declarations could be hidden from CPAN XS modules by wrapping them in

#ifdef PERL_CORE
...
#endif

on the basis that no XS modules built outside of the core should define
PERL_CORE (although some naughtily do, of course, but that's their problem).

I'm therefore going to give the attached patch some testing and apply it
if all looks well and you're happy with this fix.

---
via perlbug:  queue: perl5 status: new
https://rt.perl.org:443/rt3/Ticket/Display.html?id=114516

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