如何检测在Linux中通过GUI登录的用户

我想在我的程序中捕获通过GUI登录的用户名。 我的程序作为root登录的守护进程运行。 如果非root用户通过GUI登录,则应通知我的程序。 我正在粘贴我当前的程序,该程序调用perl脚本,利用系统调用来检查当前用户是谁登录。我也粘贴了我的perl脚本以供参考。

#include  #include  #include  #include  #include  int main() { char *user; char buf[1024]; int fd, ret; fd = open("/tmp/log", O_TRUNC|O_RDWR|O_CREAT); if (!fd) { printf("Error opening file\n"); exit(1); } chmod("/tmp/log", S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH); daemon(0, 0); while (1) { system("perl /home/curr-usr.pl"); sleep(5); } return 0; } 

perl脚本,用于获取当前用户的登录信息。

 #!/usr/bin/perl my $result; $result = `whoami`; open FH, "+>>", "/tmp/log" or die $!; print FH "$result "; close (FH); 

在上面的c程序中,我每隔5秒在一个while循环中调用perl脚本。 perl脚本使用命令“whoami”来获取当前用户登录并将其转储到/ tmp / log文件中。

我想要实现的是如果user1登录perl脚本应该给我当前用户为user1。 相反,perl脚本将root作为当前用户,而不管我通过GUI登录的用户,因为我正在运行带有root用户的C程序和perl脚本。

有谁可以告诉我一个机制,通过该机制,C程序可以了解通过GUI登录的当前用户? 任何帮助是极大的赞赏。

您可以使用主显示器检测用户,如下所示:

 #!/bin/bash #Detect the name of the display in use display=":$(ls /tmp/.X11-unix/* | sed 's#/tmp/.X11-unix/X##' | head -n 1)" #Detect the user using such display user=$(who | grep '('$display')' | awk '{print $1}') #Detect the id of the user uid=$(id -u $user) 

正如您所提到的,您的程序作为守护程序运行。 因此,它产生的任何进程都将作为启动该守护进程的用户运行。 通过UI(或任何其他方法)登录的用户永远不会是您通过从守护程序调用whoami获得的用户。

相反,您应该做的是显式通知您的守护程序登录事件,或者,如果这不是一个选项,请保留当前在框中运行的所有登录会话的列表,并查看是否出现新会话 – 这将是一个会话新登录用户的身份。

我正在使用XFCE4和LXDM。 “who”和“users”仅报告登录终端的用户。 GUI登录未报告为Nominal Animal指出(谢谢!)。 我使用“pgrep xfce”来检查XFCE4是否正在运行。 下面打印出当前的xfce-user:

 #!/usr/bin/perl # Get all processes my @xfce_processes = `pgrep xfce`; # If processes exist, get user of first process in list. if(scalar @xfce_processes) { print `ps -o user h $xfce_processes[0]`; } else { # No xfce processes. ; } 

程序员和users从文件/var/run/utmp获取信息。

该文件包含N个大小为“struct utmp”的条目,在定义。您对USER_PROCESS类型条目感兴趣。 主机字段包含显示。

请注意,如果用户打开了一些终端仿真(xterm,konsole ……),则同一显示有多个条目。

您可以监视此文件或/var/log/wtmp以获取历史记录

 struct utmp ut_entry; FILE *fp = fopen(UTMP_FILE, "r"); if( !fp ) { printf("Could not open utmp file!"); return; } while(fread(&ut_entry, sizeof(struct utmp), 1, fp) == 1) { if(ut_entry.ut_type != USER_PROCESS) continue; // string entries are not 0 terminated if too long... // copy user name to make sure it is 0 terminated char tmpUser[UT_NAMESIZE+1] = {0}; strncpy(tmpUser, ut_entry.ut_user, UT_NAMESIZE); // do more stuff... read the display from ut_entry.host } 

有关更多信息,请参阅utmp手册页

您可能想要调查ConsoleKit或其更新的化身loginctl 。

这些工具专门用于管理席位和会话,同时保持本地文本控制台,GUI和远程会话之间的区别。 它们不能保证出现在每台X11机器上,但如果你的机器相对较新,则有可能使用其中一种或另一种机器。