Link to home
Start Free TrialLog in
Avatar of simhm
simhm

asked on

display uptime in C programming

Hi there,

              anyone know how to output unix command "uptime" IN C programming ? example i want the uptime below to be display in C form
*get the result from uptime then display like below
23:14:15 up 6 days, 9:45, 22 users, load average: 0.72, 0.94,1.64


I know it is rather simple but i can't get it! thanks

regards,
mshc
Avatar of cookre
cookre
Flag of United States of America image

In old timey C, the call was 'system()'
E.g.,
system("cp a b")
Avatar of corduroy9
corduroy9

cookre is getting there

microsoft created a new EXE for getting this info, it is downloadable from here:

http://www.microsoft.com/downloads/details.aspx?displaylang=en&familyid=bc18ffdb-d6fe-400b-b892-94783ae44c91

when you run it in a DOS window, it displays this message:

\\COMPUTER_NAME has been up for: 5 day(s), 22 hour(s), 57 minute(s), 30 second(s)

you can call it from C using that system call, as long as you have the uptime.exe in a system PATH drive, like this:

system( "uptime" );

but....that will only display it on the console window,
you may have to direct the output to a file and parse the file

here; is the redirect of output:

system( "uptime > uptime.txt" );

good luck!
It depends... what OS are you targetting. Each OS is a little different with respect
to the API that you would call to get the current uptime information.

In Windows, you will probably want to look at GetTickCount() or the Performance
Monitoring APIs for a more precise time.

In most Berkeley derived UNIXes, you can use the sysctl system call to get the
boot time. Under FreeBSD, the sysctl argument vector is CTL_KERN and
KERN_BOOTTIME and the result is a struct timeval that gives you the UTC time
at which the system was booted.

Under Solaris, I'd imagine that you can get the information by reading the proc
files (/proc) for PID 0 but I'm not really too familiar with Solaris systems programming.

I'm not sure about how to do this under Linux but I would imagine that it would
be similar to either the Solaris or BSD model.

Of course the option of spawning some utiilty and capturing it's output is always
acceptable as well.

HTH.
Under linux you can #include <sys/sysinfo.h>, that will allow you to call the sysinfo() function.
(man 2 sysinfo)
-------------
  struct sysinfo s_info;
  int days;
 
  if(! sysinfo(&s_info) ) {
  days = s_info.uptime / (24*3600);
-------------

Under windows you're out of luck, GetTickCount() wraps after 49.7 days (with a spectacular crash under Win9x) is the main API call to use, under NT (Win2k/XP) you are hacking the registry.  Look for the "System Up Time" counter under HKEY_PERFORMANCE_DATA

Cheers
-Bill



Avatar of simhm

ASKER

Hi guys,

       sorry for not lack of details. I am using linux to do this problem. bill seem to be getting the close answer but i still have problem to get number of users ! as sysinfo does not contain details about the use login

23:14:15                up 6 days,           9:45,                          22 users,                    load average: 0.72, 0.94,1.64
current time           uptime days        uptime minute            num users                   load average
(ok)                        (ok)                     (ok)                      (can't get value here)        (okay but incorrect?)

Is there any other way to do it? cos the whole thing is going to get messy if i have to obtain each value seperately..

thanks.

ASKER CERTIFIED SOLUTION
Avatar of wnross
wnross

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of simhm

ASKER

hi bill,

       
 could how tell me how to parse out the information by using system call? as for C we can just use system("uptime") but i want it to save as a "char" so that i can use it to display next time? sorry, I am not a very good C user I suppose. :-

regards,
marc
Actually this stuff is a little advanced, but basically each process has stdin,stdout, and stderr streams attached.
What we want to do is replace stdin/stdout with a pipe, the tricky part is that system() is too high level.
Instead, use exec().  Note that exec replaces the running program with the new one, so we fork() first.

Finally dup(), dup2(): dup makes a backup of a file handle, dup2 changes what a given handle points to.
------------------------------------
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>

#define BUF_SIZ 256
int fdpipe[2];

int main() {
  char buffer[BUF_SIZ] = {0};
  pid_t pid;
 
  FILE *response;
  int stdout_backup;

  if ( pipe(fdpipe) ) { exit(10); }
  /* Reconnect stdout to our pipe, since exec shares
   * file descriptors we should be able to capture
   * output from our forked process
   */
  stdout_backup = dup(fileno(stdout));
  dup2(fdpipe[1],fileno(stdout));
 
 
  pid = fork();  /* now two programs are running from this line onward */
  switch(pid) {
  case 0: /* New Process */
    if(execl("/usr/bin/uptime","uptime",0) ) { exit(10); }
  default: /* Main thread */
    wait(pid);

    /* Reconnect stdout for reporting */
    dup2(stdout_backup,fileno(stdout));

    printf("\n\nParent Waiting...");
    response = fdopen( fdpipe[0], "r" );
    fgets(buffer,BUF_SIZ,response);
    /* Note: since I created the higher level "stream"
     * I should close it using fclose, but the output
     * pipe was never high level so I merely call close()
     */
    fclose(stdin);  
    close(fdpipe[1]);

    printf("Message from Uptime: \"%s\"\n", buffer);
  } /* end of fork() code */
}
----------------------------
Piece of cake :)

- Bill
Avatar of simhm

ASKER

hi bill,

          first thing, thank you so much for helping me!......I've modified your code into a function like below
 
char *
getuptime(char * path, char* command)
{
 static char buffer[BUF_SIZ];
 pid_t pid;

 FILE *response;
 int stdout_backup;

 if ( pipe(fdpipe) ) { exit(10); }
 /* Reconnect stdout to our pipe, since exec shares
   * file descriptors we should be able to capture
   * output from our forked process
  */
 stdout_backup = dup(fileno(stdout));
 dup2(fdpipe[1],fileno(stdout));


 pid = fork();  /* now two programs are running from this line onward */
 switch(pid) {
 case 0: /* New Process */
   if(execl(path,command,0) ) { exit(10); }
 default: /* Main thread */
   wait(pid);

   /* Reconnect stdout for reporting */
   dup2(stdout_backup,fileno(stdout));

 //  printf("\n\nParent Waiting...");
   response = fdopen( fdpipe[0], "r" );
   fgets(buffer,BUF_SIZ,response);
   /* Note: since I created the higher level "stream"
     * I should close it using fclose, but the output
     * pipe was never high level so I merely call close()
    */
   fclose(stdin);
   close(fdpipe[1]);

        return buffer;
  // printf("Message from Uptime: \"%s\"\n", buffer);
 } /* end of fork() code */
}


          this is because i need to make this because i am calling 'update", "date", and "who" at the same time..However, the path might be different (update and date eg. /bin/date = date         /usr/bin/uptime = uptime). Problem now is because the buffer will clear the memory once the function is exit...so i try this in main

int
main()
{
        char *current_up;
        char *date;
        current_up = getuptime("/usr/bin/uptime", "uptime");
        date     = getuptime("/bin/date", "date");
         printf("\n Message from Uptime: \"%s\"", current_up);
        printf("\n Message from Date  : \"%s\"", date);
}

my result is here...

 Message from Uptime: "Thu Sep  4 17:34:41 WST 2003 -----> incorrect
"
 Message from Date  : "Thu Sep  4 17:34:41 WST 2003 -----> correct

i know what is the problem but i cant solve it..pls help me


Avatar of simhm

ASKER

hey bill,

           I guess i figure that one out myself...way to easy and way to blur to see it myself!!
int
main()
{
       char *current_up;
       char *date;

       current_up = getuptime("/usr/bin/uptime", "uptime");
        printf("\n Message from Uptime: \"%s\"", current_up);

       date     = getuptime("/bin/date", "date");
       printf("\n Message from Date  : \"%s\"", date);
}
.......just something i lost my seem of programming...sorry about that...