all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Paul Eggert <eggert@CS.UCLA.EDU>
Cc: bug-gnu-emacs@gnu.org
Subject: Re: Emacs current-time-string core dump on 64-bit hosts
Date: Mon, 27 Mar 2006 14:00:15 -0800	[thread overview]
Message-ID: <878xqv1rbk.fsf@penguin.cs.ucla.edu> (raw)
In-Reply-To: <u1wwwzy2p.fsf@gnu.org> (Eli Zaretskii's message of "Mon, 20 Mar 2006 21:59:58 +0200")

Eli Zaretskii <eliz@gnu.org> writes:

>> From: Paul Eggert <eggert@CS.UCLA.EDU>
>> Date: Sun, 19 Mar 2006 15:44:25 -0800
>> 
>> 	* lib-src/ntlib.c (sys_ctime): Remove, since Emacs never calls
>> 	ctime any more.
>> 	* lib-src/ntlib.h (ctime): Likewise.
>> 	* src/w32.c (sys_ctime): Likewise.
>> 	* src/s/ms-w32.h (ctime): Likewise.
>
> Please don't remove these from the w32 files (I explained earlier why).

I've left them alone but I'd like to follow up on this, since a
comment or two would be helpful even if we don't change the code.

Here's your earlier explanation:

   I wouldn't remove these: the functions are almost trivial wrappers
   around the library version, and someone could try using ctime in the
   future (in a different context), in which case they will hit the
   Windows library bug again.

But this explanation is problematic, at least in the context of an
Emacs that is intended to be portable to 64-bit hosts.  Here's why.
The ntlib.c and w32 wrappers do this:

  char *str = (char *) ctime (t);
  return (str ? str : "Sun Jan 01 00:00:00 1970");

That is, the wrappers cause 'ctime' to always return a non-NULL pointer.
But any future Emacs code that uses ctime on an arbitrary time stamp
cannot expect ctime to always return a non-null pointer.  Even glibc
ctime (a "nice" ctime, which always has well-defined behavior) returns
NULL in some cases, e.g., if given a time stamp equal to 2**56.

Any future Emacs code that attempts to use ctime on an arbitrary time
stamp and an arbitrary POSIX platform will have to do something like
this, to be safe:

  struct tm *tm = localtime (&timestamp);
  if (! (tm && -999 - 1900 <= tm->tm_year && tm->tm_year <= 9999 - 1900))
    fatal ("current time is out of range");
  p = asctime (tm);

Even if Emacs can assume a "nice" ctime (a big assumption), it'd still
have to do something like this:

  p = ctime (&timestamp);
  if (! p)
    fatal ("current time is out of range");

But notice that neither code snippet needs the w32-style wrapper; so
the wrapper can be safely removed.

I suppose Emacs code might in theory want to invoke ctime in a context
where the time stamp is known to be in range, presumably because the
equivalent of the abovementioned tests have already been done.  But
this is pretty unlikely, because if the tests have already been done,
then the code already has the translated time.

If these arguments convince you, then let's please install the
above-mentioned change to the w32 files, which removes the ctime
wrappers.  If not, then I suggest the following change instead.  It
inserts a comment that attempts to explain the current situation, as I
understand it.  It also corrects a minor problem with the wrappers:
they return "Sun Jan 01 00:00:00 1970" for out-of-range time stamps,
which is wrong for two reasons.  First, 1970-01-01 was a Thursday, not
a Sunday.  Second, the day of the month should be space-padded, not
zero-padded.

There is a similar issue for src/mac.c and mac/inc/s-mac.h but I'd
like to get the W32 issues out of the way first.

2006-03-27  Paul Eggert  <eggert@cs.ucla.edu>

	* lib-src/ntlib.c (sys_ctime): Add a comment explaining why this
	wrapper is still here, even though Emacs doesn't use it.
	Correct the substitute string from "Sun Jan 01 00:00:00 1970"
	to "Thu Jan  1 00:00:00 1970".
	* src/w32.c (sys_ctime): Likewise.

*** lib-src/ntlib.c	6 Feb 2006 11:28:28 -0000	1.13
--- lib-src/ntlib.c	27 Mar 2006 21:47:52 -0000
*************** fchown (int fd, int uid, int gid)
*** 190,201 ****
  
  /* Place a wrapper around the MSVC version of ctime.  It returns NULL
     on network directories, so we handle that case here.
!    (Ulrich Leodolter, 1/11/95).  */
  char *
  sys_ctime (const time_t *t)
  {
    char *str = (char *) ctime (t);
!   return (str ? str : "Sun Jan 01 00:00:00 1970");
  }
  
  FILE *
--- 190,208 ----
  
  /* Place a wrapper around the MSVC version of ctime.  It returns NULL
     on network directories, so we handle that case here.
!    (Ulrich Leodolter, 1/11/95).
! 
!    ctime has undefined behavior with out-of-range time stamps so Emacs
!    no longer uses it.  However, a future version of Emacs might find a
!    use for ctime, in a context where time stamps are known to be in a
!    safe range for POSIX (i.e., from 1970 through 9999), but not for NT
!    (1970 through 3000), so this wrapper has not been removed from the
!    Emacs source code.  */
  char *
  sys_ctime (const time_t *t)
  {
    char *str = (char *) ctime (t);
!   return (str ? str : "Thu Jan  1 00:00:00 1970");
  }
  
  FILE *
*** src/w32.c	27 Feb 2006 02:07:37 -0000	1.100
--- src/w32.c	27 Mar 2006 21:47:52 -0000
*************** gettimeofday (struct timeval *tv, struct
*** 1327,1338 ****
  
  /* Place a wrapper around the MSVC version of ctime.  It returns NULL
     on network directories, so we handle that case here.
!    (Ulrich Leodolter, 1/11/95).  */
  char *
  sys_ctime (const time_t *t)
  {
    char *str = (char *) ctime (t);
!   return (str ? str : "Sun Jan 01 00:00:00 1970");
  }
  
  /* Emulate sleep...we could have done this with a define, but that
--- 1327,1345 ----
  
  /* Place a wrapper around the MSVC version of ctime.  It returns NULL
     on network directories, so we handle that case here.
!    (Ulrich Leodolter, 1/11/95).
! 
!    ctime has undefined behavior with out-of-range time stamps so Emacs
!    no longer uses it.  However, a future version of Emacs might find a
!    use for ctime, in a context where time stamps are known to be in a
!    safe range for POSIX (i.e., from 1970 through 9999), but not for W32
!    (1970 through 3000), so this wrapper has not been removed from the
!    Emacs source code.  */
  char *
  sys_ctime (const time_t *t)
  {
    char *str = (char *) ctime (t);
!   return (str ? str : "Thu Jan  1 00:00:00 1970");
  }
  
  /* Emulate sleep...we could have done this with a define, but that

  reply	other threads:[~2006-03-27 22:00 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-03-17  5:58 Emacs current-time-string core dump on 64-bit hosts Paul Eggert
2006-03-17 12:16 ` Eli Zaretskii
2006-03-17 12:46   ` Andreas Schwab
2006-03-17 16:04   ` Kevin Rodgers
2006-03-18  0:44   ` Paul Eggert
2006-03-18 11:50     ` Eli Zaretskii
2006-03-19  2:30       ` Paul Eggert
2006-03-21 19:25         ` Richard Stallman
2006-03-18  8:43   ` Richard Stallman
2006-03-19  1:53     ` Paul Eggert
2006-03-19 21:50       ` Richard Stallman
2006-03-19 23:44         ` Paul Eggert
2006-03-20 19:59           ` Eli Zaretskii
2006-03-27 22:00             ` Paul Eggert [this message]
2006-03-28 10:16               ` Eli Zaretskii
2006-03-30  7:52                 ` Paul Eggert
2006-03-30 20:36                   ` Eli Zaretskii
2006-04-04  4:57                   ` Paul Eggert
2006-04-04 18:20                     ` Eli Zaretskii
2006-03-21  1:00           ` Richard Stallman
2006-03-24 20:45             ` Paul Eggert
2006-03-25  9:10               ` Eli Zaretskii
2006-03-26  5:25                 ` Paul Eggert
2006-03-26 20:06                   ` Eli Zaretskii
2006-03-27 22:29                     ` Richard Stallman
2006-03-28 10:20                       ` Eli Zaretskii
2006-03-29  8:14                         ` Richard Stallman
2006-03-25 15:26               ` Richard Stallman
2006-03-24 21:00             ` Paul Eggert
2006-03-24 21:09             ` Paul Eggert
2006-03-25 15:26               ` Richard Stallman
2006-03-26  7:31                 ` Paul Eggert
     [not found]                   ` <E1FNnCd-0000pN-J4@fencepost.gnu.org>
2006-03-27 20:49                     ` Paul Eggert
2006-03-28 19:33                       ` Richard Stallman
2006-03-30  7:57                         ` Paul Eggert
2006-03-31 17:28                           ` Richard Stallman
2006-03-31 20:51                             ` Paul Eggert
2006-04-01 20:28                               ` Richard Stallman
2006-04-03  4:44                                 ` Paul Eggert
2006-03-17 16:25 ` Andreas Schwab
  -- strict thread matches above, loose matches on Subject: below --
2006-03-17  8:02 Paul Eggert

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=878xqv1rbk.fsf@penguin.cs.ucla.edu \
    --to=eggert@cs.ucla.edu \
    --cc=bug-gnu-emacs@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.