platforms as possible -- we will, anyway, and it's nice to save
oneself from public embarrassment.
+If using gcc, starting from Perl 5.9.4 Perl core C files will be
+compiled with the C<-std=c89> option which will hopefully catch
+most of these unportabilities.
+
Also study L<perlport> carefully to avoid any bad assumptions
about the operating system, filesystem, and so forth.
=item *
-Do not use strcpy() or strcat()
+Do not use strcpy() or strcat() or strncpy() or strncat()
-While some uses of these still linger in the Perl source code,
-we have inspected them for safety and are very, very ashamed of them,
-and plan to get rid of them. Use my_strlcpy() and my_strlcat() instead:
-they either use the native implementation, or Perl's own implementation
-(borrowed from the public domain implementation of INN).
+Use my_strlcpy() and my_strlcat() instead: they either use the native
+implementation, or Perl's own implementation (borrowed from the public
+domain implementation of INN).
=item *
It would be good to teach C<embed.pl> to understand the conditional
compilation, and hence remove the duplication, and the mistakes it has caused.
-
-
-
-
-
=head1 Tasks that need a little sysadmin-type knowledge
Or if you prefer, tasks that you would learn from, and broaden your skills
assumed then to be copied to TARGET machine and used as a replacement of full
C<perl> executable.
-This should be done litle differently. Namely C<miniperl> should be built for
+This could be done little differently. Namely C<miniperl> should be built for
HOST and then full C<perl> with extensions should be compiled for TARGET.
-
-
+This, however, might require extra trickery for %Config: we have one config
+first for HOST and then another for TARGET.
=head1 Tasks that need a little C knowledge
running a shell. readpipe() (the function behind qx//) could be similarly
extended.
+=head2 strcat(), strcpy(), strncat(), strncpy(), sprintf(), vsprintf()
+Maybe create a utility that checks after each libperl.a creation that
+none of the above (nor sprintf(), vsprintf(), or *SHUDDER* gets())
+ever creep back to libperl.a.
+ nm libperl.a | ./miniperl -alne '$o = $F[0] if /:$/; print "$o $F[1]" if $F[0] eq "U" && $F[1] =~ /^(?:strn?c(?:at|py)|v?sprintf|gets)$/'
+Note, of course, that this will only tell whether B<your> platform
+is using those naughty interfaces.
=head1 Tasks that need a knowledge of the interpreter
*s++ = '\\';
*s++ = *filename++;
}
- strcpy(s, " 2>&1");
+ if (s - cmdline < size)
+ my_strlcpy(s, " 2>&1", size - (s - cmdline));
myfp = PerlProc_popen(cmdline, "r");
Safefree(cmdline);
/* some Xenix systems wipe out errno here */
#ifdef apollo
if (SvNVX(sv) == 0.0)
- (void)strcpy(s,"0");
+ my_strlcpy(s, "0", SvLEN(sv));
else
#endif /*apollo*/
{
errno = olderrno;
#ifdef FIXNEGATIVEZERO
if (*s == '-' && s[1] == '0' && !s[2])
- strcpy(s,"0");
+ my_strlcpy(s, "0", SvLEN(s));
#endif
while (*s) s++;
#ifdef hcx
{
const STRLEN len =
my_snprintf(buf,
- PERL_MEM_LOG_SPRINTF_BUF_SIZE,
+ sizeof(buf),
# ifdef PERL_MEM_LOG_TIMESTAMP
"%10d.%06d: "
# endif
{
const STRLEN len =
my_snprintf(buf,
- PERL_MEM_LOG_SPRINTF_BUF_SIZE,
+ sizeof(buf),
# ifdef PERL_MEM_LOG_TIMESTAMP
"%10d.%06d: "
# endif
{
const STRLEN len =
my_snprintf(buf,
- PERL_MEM_LOG_SPRINTF_BUF_SIZE,
+ sizeof(buf),
# ifdef PERL_MEM_LOG_TIMESTAMP
"%10d.%06d: "
# endif
(void)clearenv();
# elif defined(HAS_UNSETENV)
int bsiz = 80; /* Most envvar names will be shorter than this. */
- char *buf = (char*)safesysmalloc(bsiz * sizeof(char));
+ int bufsiz = bsiz * sizeof(char); /* sizeof(char) paranoid? */
+ char *buf = (char*)safesysmalloc(bufsiz);
while (*environ != NULL) {
char *e = strchr(*environ, '=');
int l = e ? e - *environ : strlen(*environ);
if (bsiz < l + 1) {
(void)safesysfree(buf);
bsiz = l + 1;
- buf = (char*)safesysmalloc(bsiz * sizeof(char));
+ buf = (char*)safesysmalloc(bufsiz);
}
- strncpy(buf, *environ, l);
+ my_strlcpy(buf, bufsiz, *environ, l);
*(buf + l) = '\0';
(void)unsetenv(buf);
}