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 |
![]() |
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 |
![]() |
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 |
![]() |
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 |
![]() |
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 |
![]() |
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 |
![]() |