f



function "strftime" produce "No such file or directory" error

Hello, everyone.
This is a test program that generates undesired results when cross 
compiling with eldk-4.0.
It is strange that localtime_r sets errno to ENOENT at the first time, 
but never again in the following calls, while strftime always sets errno 
to ENOENT.
But errno will never be set if run on Ubuntu 12.04.4, or Debian 7.
Can someone help me?

This is the output:
# ./test_timegen
1st errno = 0, Success
2nd errno = 2, No such file or directory
3rd errno = 2, No such file or directory
2000-01-05 04:12:11.661426
1st errno = 0, Success
2nd errno = 0, Success
3rd errno = 2, No such file or directory
2000-01-05 04:12:11.662134
1st errno = 0, Success
2nd errno = 0, Success
3rd errno = 2, No such file or directory
2000-01-05 04:12:11.662265
# uname -a
Linux ePM837x 2.6.25 #531 Tue Sep 13 09:35:34 PDT 2011 ppc unknown
# ldd --version | grep libc
ldd (GNU libc) 2.5
# cat /proc/cpuinfo | grep cpu
cpu             : e300c4
#

This is the cross compile command:
/opt/eldk-4.0/usr/bin/ppc_82xx-gcc test_timegen.c -lrt -o test_timegen

This is the source code test_timegen.c:
#include    <stdio.h>
#include    <stdlib.h>
#include    <string.h>
#include    <errno.h>
#include    <time.h>

static void print(const char *s) {
     fprintf(stderr, "%s errno = %d, %s\n", s, errno, strerror(errno));
     errno = 0;
}

void print_time() {
     const clockid_t clkid = CLOCK_REALTIME;
     struct tm tm_inst;
     char timebuf[64] = {0};
     struct timespec t;
     if (clock_gettime(clkid, &t) < 0) {
         perror("set_time");
         exit(1);
     }
     print("1st");
     if (localtime_r(&t.tv_sec, &tm_inst) == NULL) {
         perror("localtime_r");
         exit(1);
     }
     print("2nd");
     if (strftime(timebuf, sizeof(timebuf), "%F %T", &tm_inst) == 0) {
         perror("strftime");
         exit(1);
     }
     print("3rd");
     int len = strlen(timebuf);
     snprintf(timebuf+len, sizeof(timebuf)-len,
              ".%06ld", t.tv_nsec / 1000);
     fprintf(stderr, "%s\n", timebuf);
}

int main() {
     int j;
     for (j = 0; j < 3; j++)
         print_time();
     return 0;
}
0
wy
3/19/2014 7:34:51 AM
comp.unix.programmer 10848 articles. 0 followers. kokososo56 (350) is leader. Post Follow

5 Replies
805 Views

Similar Articles

[PageSpeed] 14

On Wednesday, March 19, 2014 12:34:51 AM UTC-7, wy wrote:
> This is a test program that generates undesired results when cross=20
> compiling with eldk-4.0.
> It is strange that localtime_r sets errno to ENOENT at the first time,=20
> but never again in the following calls, while strftime always sets errno=
=20
> to ENOENT.
> But errno will never be set if run on Ubuntu 12.04.4, or Debian 7.
> Can someone help me?

To quote the POSIX standard:
    Some functions provide the error number in a variable accessed through
    the symbol errno, defined by including the <errno.h> header. The value
    of errno should only be examined when it is indicated to be valid by a
    function's return value.
and
    Many functions provide an error number in errno, which has type int and
    is defined in <errno.h>. The value of errno shall be defined only after
    a call to a function for which it is explicitly stated to be set and
    until it is changed by the next function call or if the application
    assigns it a value. The value of errno should only be examined when it
    is indicated to be valid by a function's return value.

That is, the value of errno when a standard interface like clock_gettime() =
or localtime_r() *succeeds* is UNDEFINED.  It might tell you something abou=
t the internals of the involved function, but you can probably get that inf=
ormation more easily by reading the public source, or using the platforms's=
 system call or function tracing functionality, and it doesn't change the f=
act that the call has claimed to do what it should.

To put it another way: What problem are you trying to solve by looking at e=
rrno on *success*?


Philip Guenther

0
Philip
3/19/2014 8:02:45 AM
On 2014-03-19, wy <warmyouth@gmail.com> wrote:
> It is strange that localtime_r sets errno to ENOENT at the first time, 

Not really. Don't you have some system call tracing utility to see
what is going on?

The first time some rarely-used function is invoked, it might have
to initialize some persistent state.

This is a common optimization known by names such as "late binding"
or "lazy initialization".

It's possible that the initializations triggered by localtime_r need to
read some files some files related to time zones and whatnot (which
is a good idea to avoid doing if the program doesn't need it).  Maybe that code
searches the filesystem for some things, some of which are not installed, and
so it receives some ENOENT errors.
0
Kaz
3/19/2014 8:13:02 AM
On 03/19/2014 04:13 PM, Kaz Kylheku wrote:
> Not really. Don't you have some system call tracing utility to see
> what is going on?
This is the first time I hear system call tracing utility. Is it useful 
for application developers?

> This is a common optimization known by names such as "late binding"
> or "lazy initialization".
>
> It's possible that the initializations triggered by localtime_r need to
> read some files some files related to time zones and whatnot (which
> is a good idea to avoid doing if the program doesn't need it).  Maybe that code
> searches the filesystem for some things, some of which are not installed, and
> so it receives some ENOENT errors.
>
You are right.
After uploading the file /etc/localtime to the target PowerPC, the 
program does not set errno any more, and the result time has added the 
time zone.
After that, I remove the file /etc/localtime on Ubuntu. And now it also 
shows an ENOENT error after localtime_r, but does not set errno after 
strftime.
Whatever, it makes sense. And I learned what had happened.
Thanks!

0
wy
3/19/2014 12:35:12 PM
On 03/19/2014 04:02 PM, Philip Guenther wrote:
I see.
These functions have done what they should do.
And errno should be checked only when you are sure the system call failed.
It does provide the detail of failure, for this system call, or the 
internals.
Thank you!

0
wy
3/19/2014 12:37:32 PM
On Wed, 2014-03-19, wy wrote:
> On 03/19/2014 04:13 PM, Kaz Kylheku wrote:
>> Not really. Don't you have some system call tracing utility to see
>> what is going on?

> This is the first time I hear system call tracing utility. Is it useful 
> for application developers?

Yes, it is very useful, for many different things.

Since you appear to be on Linux, its name is strace.  Do 'strace ls'
to see an example of what it does.

/Jorgen

-- 
  // Jorgen Grahn <grahn@  Oo  o.   .     .
\X/     snipabacken.se>   O  o   .
0
Jorgen
3/19/2014 6:51:12 PM
Reply: