LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   ctime() on ut_tv.tv_sec of utmp structure? (https://www.linuxquestions.org/questions/programming-9/ctime-on-ut_tv-tv_sec-of-utmp-structure-823035/)

hppyhjh 07-30-2010 08:43 AM

ctime() on ut_tv.tv_sec of utmp structure?
 
I'm using ubuntu9.10 (x86_64) and have some code,

Code:

void show_utmp(struct utmp* ent)
{
        time_t tmp;
        if  (ent->ut_type != USER_PROCESS)
                return;
        printf("%10s ", ent->ut_user);
        printf("%10s ", ent->ut_line);
       
        tmp = ent->ut_tv.tv_sec;
        printf("%25s ", ctime(&tmp)); // display ok
        printf("\n");
        printf("%25s", ctime((time_t *)&(ent->ut_tv.tv_sec))); // display wrong
        printf("\n");
}

the output is like the following:
guest tty7 Sat Jul 31 04:37:29 2010

Thu Feb 16 20:35:21 28472119

why?

and in /usr/include/bits/utmp.h, i found sippet:
Code:

#if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32
  int32_t ut_session;                /* Session ID, used for windowing.  */
  struct
  {
    int32_t tv_sec;                /* Seconds.  */
    int32_t tv_usec;                /* Microseconds.  */
  } ut_tv;                        /* Time entry was made.  */
#else
  long int ut_session;                /* Session ID, used for windowing.  */
  struct timeval ut_tv;                /* Time entry was made.  */
#endif

I want to know, where __WORDSIZE would be defined?

hppyhjh 07-30-2010 08:25 PM

somebody help me...

bigearsbilly 08-01-2010 05:27 AM

can you make a compilable example?

hppyhjh 08-02-2010 10:02 AM

sorry for late reply.

the following is the example.


Code:

#include <stdio.h>
#include <utmp.h>
#include <fcntl.h>
#include <time.h>
#include <limits.h>

#define SHOWHOST

#define UTMP "/var/run/utmp"
#define CNT 12
#define UTMPSIZE (sizeof(struct utmp))


void show_utmp(struct utmp* ent);
int open_utmp();
struct utmp* read_utmp(int fd);
int reload_utmp(int fd);


char utmpbuf[CNT * UTMPSIZE];
int total, curent;

int main(int argc, char **argv) {
        int fd;
        struct utmp *entry;
        fd = open_utmp();
        while ( (entry = read_utmp(fd)) != NULL )
                show_utmp(entry);
}

int open_utmp()
{
        int fd;
        if ((fd = open(UTMP, O_RDONLY)) == -1)
        {
                perror("open error");
                return -1;
        }
        curent = 0;
        return fd;
}

struct utmp* read_utmp(int fd)
{
        struct utmp *ut;
        if (curent == total && reload_utmp(fd) <= 0)
                return (struct utmp*)NULL;
        ut = &(utmpbuf[curent * UTMPSIZE]); 
        curent++;
        return ut;
}

int reload_utmp(int fd)
{
        int nsize;
        nsize = read(fd , utmpbuf, CNT*UTMPSIZE);
        if (nsize < 0) {
                perror("reaload utmp error");
                return 0;
        }
        total = nsize / UTMPSIZE;
        curent = 0;
        return total;
}

void show_utmp(struct utmp* ent)
{
        time_t tmp;
        if  (ent->ut_type != USER_PROCESS)
                return;
        printf("%10s ", ent->ut_user);
        printf("%10s ", ent->ut_line);
        tmp = ent->ut_tv.tv_sec;
        printf("%25s ", ctime(&tmp));
        printf("\n");
        printf("%25s", ctime((time_t *)&(ent->ut_tv.tv_sec)));
#ifdef SHOWHOST
        printf("%10s", ent->ut_host);
#endif
        printf("\n");
}


dwhitney67 08-02-2010 10:09 AM

ctime() creates a printable date-time string which includes a newline character.
Code:

    The ctime() function adjusts the time value for the current time zone, in the same
    manner as localtime().  It returns a pointer to a 26-character string of the form:

          Thu Nov 24 18:22:48 1986\n\0

Oh wait, you are probably concerned about the formatting itself. My bad.

Wim Sturkenboom 08-02-2010 10:25 AM

When compiling with -Wall, your code gives warnings
Code:

fortyfourgalena@desktop1:~/progs/c/lq823035$ gcc -Wall lq823035.c -o lq823035
lq823035.c: In function ‘main’:
lq823035.c:29: warning: control reaches end of non-void function
lq823035.c: In function ‘read_utmp’:
lq823035.c:48: warning: assignment from incompatible pointer type
lq823035.c: In function ‘reload_utmp’:
lq823035.c:56: warning: implicit declaration of function ‘read’
fortyfourgalena@desktop1:~/progs/c/lq823035$

Not said that this is the problem, but the incompatible pointer type is worrying.

And this is the output
Code:

fortyfourgalena@desktop1:~/progs/c/lq823035$ ./lq823035
fortyfourgalena      tty9 Mon Aug  2 16:59:04 2010
 
Mon Aug  2 16:59:04 2010
        :0
fortyfourgalena      pts/0 Mon Aug  2 17:15:53 2010
 
Mon Aug  2 17:15:53 2010
      :0.0
fortyfourgalena      pts/1 Mon Aug  2 17:17:20 2010
 
Mon Aug  2 17:17:20 2010
      :0.0
fortyfourgalena@desktop1:~/progs/c/lq823035$


hppyhjh 08-02-2010 12:12 PM

the following is my output:
plz put you uname output...I think the problem only appears in 64-bit OS. for ctime() expects a pointer to 64bit, but i give it a pointer to 32bit, so the following 32bit is included in, so produce the wrong result.

guest@bequiet:~/workspaceCpp/PGMPractise$ uname -a
Code:

Linux bequiet 2.6.31-14-generic #48-Ubuntu SMP Fri Oct 16 14:05:01 UTC 2009 x86_64 GNU/Linux
guest@bequiet:~/workspaceCpp/PGMPractise$ make iwho
Code:

cc    iwho.c  -o iwho
iwho.c: In function ‘read_utmp’:
iwho.c:59: warning: assignment from incompatible pointer type

guest@bequiet:~/workspaceCpp/PGMPractise$ ./iwho
Code:

    guest      tty7 Mon Aug  2 22:52:51 2010
 
Fri Jul 16 16:22:27 11813086
        :0
    guest      pts/0 Mon Aug  2 22:55:20 2010
 
Wed Feb 18 04:40:56 81151660
      :0.0


Wim Sturkenboom 08-02-2010 12:38 PM

I indeed use a 32-bit version of Ubuntu 8.04

Code:

fortyfourgalena@desktop1:~$ uname -a
Linux desktop1 2.6.24-26-386 #1 Tue Dec 1 17:56:13 UTC 2009 i686 GNU/Linux
fortyfourgalena@desktop1:~$


hppyhjh 08-02-2010 12:50 PM

so, how to write portable program...?


All times are GMT -5. The time now is 04:05 AM.