#include <stdio.h> /* FILE, sprintf, fgets, puts */
#include <stdlib.h> /* atoi, exit, EXIT_SUCCESS */
#include <string.h> /* strtok, strcmp */
#include <sys/types.h> /* pid_t */
#include <sys/wait.h> /* WIFEXITED, WEXITSTATUS */
char *procname(pid_t pid)
{
static char line[133], command[80], *linep, *token, *cmd;
FILE *fp;
int status;
if (0 == pid) return (char *)0;
sprintf(command, "ps -p %d 2>/dev/null", pid);
fp = popen(command, "r");
if ((FILE *)0 == fp) return (char *)0;
/* 读取标题行 */
if ((char *)0 == fgets(line, sizeof line, fp))
{
pclose(fp);
return (char *)0;
}
/* 从标题栏分析出命令名所在列。
* (BSD风格的系统将指示命令的"COMMAND"字符串放在第5列,SysV好象将
* 指示命令的“CMD”或“COMMAND”字符串放在第4列)
*/
for (linep = line; ; linep = (char *)0)
{
if ((char *)0 == (token = strtok(linep, " \t\n")))
{
pclose(fp);
return (char *)0;
}
if (0 == strcmp("COMMAND", token) || 0 == strcmp("CMD", token))
{ /* 我们找到COMMAND所在列 */
cmd = token;
break;
}
}
/* 读取 ps(1) 输出行 */
if ((char *)0 == fgets(line, sizeof line, fp))
{
pclose(fp);
return (char *)0;
}
/* 抓COMMAND标题下面的词 ... */
if ((char *)0 == (token = strtok(cmd, " \t\n")))
{
pclose(fp);
return (char *)0;
}
status = pclose(fp);
if (!WIFEXITED(status) || 0 != WEXITSTATUS(status))
return (char *)0;
return token;
}
int main(int argc, char *argv[])
{
puts(procname(atoi(argv[1])));
exit(EXIT_SUCCESS);
}