Most Unix-like operating systems keep track of logged in users by maintaining a user accounting database. This user accounting database stores for each terminal, who has logged on, at what time, the process ID of the user's login shell, etc., etc., but also stores information about the run level of the system, the time of the last system reboot, and possibly more.
The user accounting database typically lives in /etc/utmp, /var/adm/utmp or /var/run/utmp. However, these files should never be accessed directly. For reading information from and writing information to the user accounting database, the functions described in this section should be used.
These functions and the corresponding data structures are declared in the header file utmp.h. function>struct exit_status/function> The exit_status data structure is used to hold information about the exit status of processes marked as DEAD_PROCESS in the user accounting database.
The exit status of the process.
The exit status of the process.
function>struct utmp/function> The utmp data structure is used to hold information about entries in the user accounting database. On the GNU system it has the following members:
Specifies the type of login; one of EMPTY, RUN_LVL, BOOT_TIME, OLD_TIME, NEW_TIME, INIT_PROCESS, LOGIN_PROCESS, USER_PROCESS, DEAD_PROCESS or ACCOUNTING.
The process ID number of the login process.
The device name of the tty (without /dev/).
The inittab ID of the process.
The user's login name.
The name of the host from which the user logged in.
The exit status of a process marked as DEAD_PROCESS.
The Session ID, used for windowing.
Time the entry was made. For entries of type OLD_TIME this is the time when the system clock changed, and for entries of type NEW_TIME this is the time the system clock was set to.
The Internet address of a remote host.
The ut_type, ut_pid, ut_id, ut_tv, and ut_host fields are not available on all systems. Portable applications therefore should be prepared for these situations. To help doing this the utmp.h header provides macros _HAVE_UT_TYPE, _HAVE_UT_PID, _HAVE_UT_ID, _HAVE_UT_TV, and _HAVE_UT_HOST if the respective field is available. The programmer can handle the situations by using #ifdef in the program code.
The following macros are defined for use as values for the ut_type member of the utmp structure. The values are integer constants.
This macro is used to indicate that the entry contains no valid user accounting information.
This macro is used to identify the systems runlevel.
This macro is used to identify the time of system boot.
This macro is used to identify the time when the system clock changed.
This macro is used to identify the time after the system changed.
This macro is used to identify a process spawned by the init process.
This macro is used to identify the session leader of a logged in user.
This macro is used to identify a user process.
This macro is used to identify a terminated process.
???
The size of the ut_line, ut_id, ut_user and ut_host arrays can be found using the sizeof operator.
Many older systems have, instead of an ut_tv member, an ut_time member, usually of type time_t, for representing the time associated with the entry. Therefore, for backwards compatibility only, utmp.h defines ut_time as an alias for ut_tv.tv_sec.
void function>setutent/function> (void) This function opens the user accounting database to begin scanning it. You can then call getutent, getutid or getutline to read entries and pututline to write entries.
If the database is already open, it resets the input to the beginning of the database.
struct utmp * function>getutent/function> (void) The getutent function reads the next entry from the user accounting database. It returns a pointer to the entry, which is statically allocated and may be overwritten by subsequent calls to getutent. You must copy the contents of the structure if you wish to save the information or you can use the getutent_r function which stores the data in a user-provided buffer.
A null pointer is returned in case no further entry is available.
void function>endutent/function> (void) This function closes the user accounting database.
struct utmp * function>getutid/function> (const struct utmp *id) This function searches forward from the current point in the database for an entry that matches id. If the ut_type member of the id structure is one of RUN_LVL, BOOT_TIME, OLD_TIME or NEW_TIME the entries match if the ut_type members are identical. If the ut_type member of the id structure is INIT_PROCESS, LOGIN_PROCESS, USER_PROCESS or DEAD_PROCESS, the entries match if the ut_type member of the entry read from the database is one of these four, and the ut_id members match. However if the ut_id member of either the id structure or the entry read from the database is empty it checks if the ut_line members match instead. If a matching entry is found, getutid returns a pointer to the entry, which is statically allocated, and may be overwritten by a subsequent call to getutent, getutid or getutline. You must copy the contents of the structure if you wish to save the information.
A null pointer is returned in case the end of the database is reached without a match.
The getutid function may cache the last read entry. Therefore, if you are using getutid to search for multiple occurrences, it is necessary to zero out the static data after each call. Otherwise getutid could just return a pointer to the same entry over and over again.
struct utmp * function>getutline/function> (const struct utmp *line) This function searches forward from the current point in the database until it finds an entry whose ut_type value is LOGIN_PROCESS or USER_PROCESS, and whose ut_line member matches the ut_line member of the line structure. If it finds such an entry, it returns a pointer to the entry which is statically allocated, and may be overwritten by a subsequent call to getutent, getutid or getutline. You must copy the contents of the structure if you wish to save the information.
A null pointer is returned in case the end of the database is reached without a match.
The getutline function may cache the last read entry. Therefore if you are using getutline to search for multiple occurrences, it is necessary to zero out the static data after each call. Otherwise getutline could just return a pointer to the same entry over and over again.
struct utmp * function>pututline/function> (const struct utmp *utmp) The pututline function inserts the entry *utmp at the appropriate place in the user accounting database. If it finds that it is not already at the correct place in the database, it uses getutid to search for the position to insert the entry, however this will not modify the static structure returned by getutent, getutid and getutline. If this search fails, the entry is appended to the database.
The pututline function returns a pointer to a copy of the entry inserted in the user accounting database, or a null pointer if the entry could not be added. The following errno error conditions are defined for this function:
The process does not have the appropriate privileges; you cannot modify the user accounting database.
All the get* functions mentioned before store the information they return in a static buffer. This can be a problem in multi-threaded programs since the data returned for the request is overwritten by the return value data in another thread. Therefore the GNU C Library provides as extensions three more functions which return the data in a user-provided buffer.
int function>getutent_r/function> (struct utmp *buffer, struct utmp **result) The getutent_r is equivalent to the getutent function. It returns the next entry from the database. But instead of storing the information in a static buffer it stores it in the buffer pointed to by the parameter buffer.
If the call was successful, the function returns 0 and the pointer variable pointed to by the parameter result contains a pointer to the buffer which contains the result (this is most probably the same value as buffer). If something went wrong during the execution of getutent_r the function returns -1.
This function is a GNU extension.
int function>getutid_r/function> (const struct utmp *id, struct utmp *buffer, struct utmp **result) This function retrieves just like getutid the next entry matching the information stored in id. But the result is stored in the buffer pointed to by the parameter buffer.
If successful the function returns 0 and the pointer variable pointed to by the parameter result contains a pointer to the buffer with the result (probably the same as result. If not successful the function return -1.
This function is a GNU extension.
int function>getutline_r/function> (const struct utmp *line, struct utmp *buffer, struct utmp **result) This function retrieves just like getutline the next entry matching the information stored in line. But the result is stored in the buffer pointed to by the parameter buffer.
If successful the function returns 0 and the pointer variable pointed to by the parameter result contains a pointer to the buffer with the result (probably the same as result. If not successful the function return -1.
This function is a GNU extension.
In addition to the user accounting database, most systems keep a number of similar databases. For example most systems keep a log file with all previous logins (usually in /etc/wtmp or /var/log/wtmp).
For specifying which database to examine, the following function should be used.
int function>utmpname/function> (const char *file) The utmpname function changes the name of the database to be examined to file, and closes any previously opened database. By default getutent, getutid, getutline and pututline read from and write to the user accounting database.
The following macros are defined for use as the file argument:
char * function>_PATH_UTMP/function> This macro is used to specify the user accounting database.
char * function>_PATH_WTMP/function> This macro is used to specify the user accounting log file.
The utmpname function returns a value of 0 if the new name was successfully stored, and a value of -1 to indicate an error. Note that utmpname does not try to open the database, and that therefore the return value does not say anything about whether the database can be successfully opened.
Specially for maintaining log-like databases the GNU C Library provides the following function:
void function>updwtmp/function> (const char *wtmp_file, const struct utmp *utmp) The updwtmp function appends the entry *utmp to the database specified by wtmp_file. For possible values for the wtmp_file argument see the utmpname function.
Portability Note: Although many operating systems provide a subset of these functions, they are not standardized. There are often subtle differences in the return types, and there are considerable differences between the various definitions of struct utmp. When programming for the GNU system, it is probably best to stick with the functions described in this section. If however, you want your program to be portable, consider using the XPG functions described in the section called “XPG User Accounting Database Functions”, or take a look at the BSD compatible functions in the section called “Logging In and Out”.
These functions, described in the X/Open Portability Guide, are declared in the header file utmpx.h. function>struct utmpx/function> The utmpx data structure contains at least the following members:
Specifies the type of login; one of EMPTY, RUN_LVL, BOOT_TIME, OLD_TIME, NEW_TIME, INIT_PROCESS, LOGIN_PROCESS, USER_PROCESS or DEAD_PROCESS.
The process ID number of the login process.
The device name of the tty (without /dev/).
The inittab ID of the process.
The user's login name.
Time the entry was made. For entries of type OLD_TIME this is the time when the system clock changed, and for entries of type NEW_TIME this is the time the system clock was set to.
On the GNU system, struct utmpx is identical to struct utmp except for the fact that including utmpx.h does not make visible the declaration of struct exit_status.
The following macros are defined for use as values for the ut_type member of the utmpx structure. The values are integer constants and are, on the GNU system, identical to the definitions in utmp.h.
This macro is used to indicate that the entry contains no valid user accounting information.
This macro is used to identify the systems runlevel.
This macro is used to identify the time of system boot.
This macro is used to identify the time when the system clock changed.
This macro is used to identify the time after the system changed.
This macro is used to identify a process spawned by the init process.
This macro is used to identify the session leader of a logged in user.
This macro is used to identify a user process.
This macro is used to identify a terminated process.
The size of the ut_line, ut_id and ut_user arrays can be found using the sizeof operator.
void function>setutxent/function> (void) This function is similar to setutent. On the GNU system it is simply an alias for setutent.
struct utmpx * function>getutxent/function> (void) The getutxent function is similar to getutent, but returns a pointer to a struct utmpx instead of struct utmp. On the GNU system it simply is an alias for getutent.
void function>endutxent/function> (void) This function is similar to endutent. On the GNU system it is simply an alias for endutent.
struct utmpx * function>getutxid/function> (const struct utmpx *id) This function is similar to getutid, but uses struct utmpx instead of struct utmp. On the GNU system it is simply an alias for getutid.
struct utmpx * function>getutxline/function> (const struct utmpx *line) This function is similar to getutid, but uses struct utmpx instead of struct utmp. On the GNU system it is simply an alias for getutline.
struct utmpx * function>pututxline/function> (const struct utmpx *utmp) The pututxline function is functionally identical to pututline, but uses struct utmpx instead of struct utmp. On the GNU system, pututxline is simply an alias for pututline.
int function>utmpxname/function> (const char *file) The utmpxname function is functionally identical to utmpname. On the GNU system, utmpxname is simply an alias for utmpname.
You can translate between a traditional struct utmp and an XPG struct utmpx with the following functions. On the GNU system, these functions are merely copies, since the two structures are identical.
int function>getutmp/function> (const struct utmpx *utmpx, struct utmp *utmp) getutmp copies the information, insofar as the structures are compatible, from utmpx to utmp.
int function>getutmpx/function> (const struct utmp *utmp, struct utmpx *utmpx) getutmpx copies the information, insofar as the structures are compatible, from utmp to utmpx.
These functions, derived from BSD, are available in the separate libutil library, and declared in utmp.h. Note that the ut_user member of struct utmp is called ut_name in BSD. Therefore, ut_name is defined as an alias for ut_user in utmp.h.
int function>login_tty/function> (int filedes) This function makes filedes the controlling terminal of the current process, redirects standard input, standard output and standard error output to this terminal, and closes filedes.
This function returns 0 on successful completion, and -1 on error.
void function>login/function> (const struct utmp *entry) The login functions inserts an entry into the user accounting database. The ut_line member is set to the name of the terminal on standard input. If standard input is not a terminal login uses standard output or standard error output to determine the name of the terminal. If struct utmp has a ut_type member, login sets it to USER_PROCESS, and if there is an ut_pid member, it will be set to the process ID of the current process. The remaining entries are copied from entry.
A copy of the entry is written to the user accounting log file.
int function>logout/function> (const char *ut_line) This function modifies the user accounting database to indicate that the user on ut_line has logged out.
The logout function returns 1 if the entry was successfully written to the database, or 0 on error.
void function>logwtmp/function> (const char *ut_line, const char *ut_name, const char *ut_host) The logwtmp function appends an entry to the user accounting log file, for the current time and the information provided in the ut_line, ut_name and ut_host arguments.
Portability Note: The BSD struct utmp only has the ut_line, ut_name, ut_host and ut_time members. Older systems do not even have the ut_host member.