Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

[Explained] Platform-dependent behavior observed in POSIX::strftime

by Narveson (Chaplain)
on Aug 25, 2010 at 15:59 UTC ( [id://857235]=perlquestion: print w/replies, xml ) Need Help??

Narveson has asked for the wisdom of the Perl Monks concerning the following question:

Update: Thanks, BrowserUK and ikegami, for the Perl wisdom.

My team is migrating from Windows Server 2003 to Windows Server 2008. We run the same ActiveState build of Perl 5.8.9 in both operating systems (verified using perl -V). Here is a transcript from the old server. Note the incorrect format string:

>perl -e "use POSIX; print qq(POSIX version $POSIX::VERSION\n); print + (strftime '%Y%m%d%', localtime)" POSIX version 1.1501 20100825 >

Here is the same little test run on the new server:

>perl -e "use POSIX; print qq(POSIX version $POSIX::VERSION\n); print +(strftime '%Y%m%d%', localtime)" POSIX version 1.1501 %Y%m%d% >

We had a program with this incorrect format string that nevertheless ran as intended on the old server, but of course it misbehaved badly on the new server.

Isn't POSIX supposed to give platform-independent results?

If it is argued that the test suites for POSIX only cover valid input, so with bad input all bets are off - then shouldn't POSIX::strftime blow up when it is given a malformed format string?

Replies are listed 'Best First'.
Re: Platform-dependent behavior observed in POSIX::strftime
by BrowserUk (Patriarch) on Aug 25, 2010 at 18:36 UTC

    POSIX functions are XS wrappers around C runtime library routines of the same name. The difference almost certainly arises because of differences in the different C-runtimes installed on the two platforms. Newer versions of MS CRTs are much stricter about parameter checking.

    As for why no error is raised, it appears to be a side-effect of Perl's attempts to be portable. There doesn't appear to be a code path in there for the situations where CRT strftime() returns 0 for reasons other than buffer overflow?

    buflen = 64; Newx(buf, buflen, char); len = strftime(buf, buflen, fmt, &mytm); /* ** The following is needed to handle to the situation where ** tmpbuf overflows. Basically we want to allocate a buffer ** and try repeatedly. The reason why it is so complicated ** is that getting a return value of 0 from strftime can indicate ** one of the following: ** 1. buffer overflowed, ** 2. illegal conversion specifier, or ** 3. the format string specifies nothing to be returned(not ** an error). This could be because format is an empty string ** or it specifies %p that yields an empty string in some locale. ** If there is a better way to make it portable, go ahead by ** all means. */ if ((len > 0 && len < buflen) || (len == 0 && *fmt == '\0')) return buf; else { /* Possibly buf overflowed - try again with a bigger buf */ const int fmtlen = strlen(fmt); int bufsize = fmtlen + buflen; Newx(buf, bufsize, char); while (buf) { buflen = strftime(buf, bufsize, fmt, &mytm); if (buflen > 0 && buflen < bufsize) break; /* heuristic to prevent out-of-memory errors */ if (bufsize > 100*fmtlen) { Safefree(buf); buf = NULL; break; } bufsize *= 2; Renew(buf, bufsize, char); } return buf; } #
Re: Platform-dependent behavior observed in POSIX::strftime
by ikegami (Patriarch) on Aug 25, 2010 at 18:55 UTC

    In general, the POSIX module provides access to system's implementation (whereas the builtin functions provide portability).

    Isn't POSIX supposed to give platform-independent results?

    If your platform doesn't conform to POSIX, that's an issue to take up with you platform's provider.

Re: Platform-dependent behavior observed in POSIX::strftime
by zentara (Archbishop) on Aug 25, 2010 at 16:11 UTC

      Thanks, but how to get a desired date string was not my question. I was wondering if anybody could help me understand the difference in behavior between two platforms.

        I believe japhy's solution suggested that taking the lowercase of the string, made some difference in some systems that either ignore case, or make a big deal of it. Like the difference between old windows and a unix system. I thought I would just point that out. There may be a subtle difference, which you may be overlooking.

        I'm not really a human, but I play one on earth.
        Old Perl Programmer Haiku ................... flash japh

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://857235]
Approved by moritz
Front-paged by toolic
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (3)
As of 2024-04-20 04:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found