使用 C 语言中的 execlp 函数
本文将演示关于如何使用 C 语言中的 execlp
函数的多种方法。
使用 execlp
在 C 语言中使用文件名执行新程序
exec
系列函数是作为低级 execve
系统调用的替代 API 提供的,用于管理将新程序加载到进程内存中。这个系列有 6 个独立的函数,它们主要是参数不同而不是结果不同。execlp
函数是给用户指定文件名的选项,程序会在当前 PATH
环境变量列出的目录中搜索。
如果文件名仍然包含斜线,则被视为相对或绝对路径名。在下面的例子中,我们实现了一个行为类似于 shell 的程序。也就是说,它从用户那里获取程序名,并作为一个子进程来执行。父进程等待,一旦子进程返回,控制权就会进入用户输入的下一个迭代。程序应该由用户用Ctrl+D这样的按键终止(取决于操作系统)。注意,有些 shell 命令不能执行,最重要的是,命令行参数没有传递,而程序却打印出 couldn't execute
。
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "unistd.h"
#include <sys/wait.h>
enum {MAXLINE = 256, MAXARGS = 48};
int main(int argc, char *argv[]) {
char buf[MAXLINE];
pid_t pid;
int status;
char *str1, *token;
printf("%% ");
while (fgets(buf, MAXLINE, stdin) != NULL) {
if (buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = 0;
if ((pid = fork()) < 0) {
perror("fork");
} else if (pid == 0) {
execlp(buf, buf, (char *) NULL);
printf("couldn't execute: %s", buf);
exit(127);
}
if (waitpid(pid, &status, 0) < 0)
perror("waitpid");
printf("%% ");
}
exit(EXIT_SUCCESS);
}
execlp
是可变函数,因此,它可以接受不同数量的参数。不过第一个和最后一个参数是固定的,代表文件名的指针,而 NULL
则相应地投向 char*
。需要注意的是,强制转换 null 指针是函数工作的必备条件,同时也表示变量参数数的结束。总之,第二个位置的参数应该指定程序的命令行参数,其中第一个参数应该是文件名本身。
另外,我们也可以实现前面的例子,能够执行带有参数的命令。在这种情况下,我们利用了 execvp
函数,它将参数列表作为一个数组。同时,我们使用 strtok
来解析用户输入,将每个空格分隔的字符串作为参数传递。结果,我们得到了更接近 shell 程序的仿真。
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "unistd.h"
#include <sys/wait.h>
enum {MAXLINE = 256, MAXARGS = 48};
int main(int argc, char *argv[]) {
char buf[MAXLINE];
char *args[MAXARGS];
pid_t pid;
int status, args_num = 0;
char *str1, *token;
printf("%% ");
while (fgets(buf, MAXLINE, stdin) != NULL) {
if (buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = 0;
str1 = strdup(buf);
for (int j = 0; ; j++, str1 = NULL) {
token = strtok(str1, " ");
if (token == NULL)
break;
args[j] = token;
args_num += 1;
printf("%d: %s\n", j + 1, args[j]);
}
free(str1);
args[args_num] = (char *) NULL;
if ((pid = fork()) < 0) {
perror("fork");
} else if (pid == 0) {
execvp(args[0], &args[0]);
printf("couldn't execute: %s", buf);
exit(127);
}
if (waitpid(pid, &status, 0) < 0)
perror("waitpid");
printf("%% ");
}
exit(EXIT_SUCCESS);
}
相关文章
在 Chrome 上使用 Visual Studio IDE 调试 JavaScript 代码
发布时间:2024/03/17 浏览次数:90 分类:JavaScript
-
在本教程中,我们将了解如何使用 Microsoft Visual Studio IDE 和 chrome 浏览器调试 JavaScript 代码。
在 C# 中将 List<string>转换为字符串
发布时间:2024/03/16 浏览次数:198 分类:编程语言
-
在 C# 中,有两种主要方法可用于将 List
转换为字符串变量,Linq 方法和 String.Join()函数。
在 C# 中将 List<string>转换为字符串
发布时间:2024/03/16 浏览次数:171 分类:编程语言
-
在 C# 中,有两种主要方法可用于将 List
转换为字符串变量,Linq 方法和 String.Join()函数。
在 C# 中将 List<string>转换为字符串
发布时间:2024/03/16 浏览次数:187 分类:编程语言
-
在 C# 中,有两种主要方法可用于将 List
转换为字符串变量,Linq 方法和 String.Join()函数。
在 C# 中发出 HTTP POST Web 请求
发布时间:2024/02/04 浏览次数:131 分类:编程语言
-
在 C# 中,可以使用 3 种主要方法来发出 HTTP POST Web 请求:WebClient 类,HttpWebRequest 类和 HttpClient 类。本教程将讨论在 C# 中发出 HTTP POST Web 请求的方法。使用 C# 中的 WebClient 类发出 HTTP POST Web 请求
在 C# 中运行命令提示符命令
发布时间:2024/02/04 浏览次数:130 分类:编程语言
-
Process 类可用于在 C# 中运行命令提示符命令。在 C# 中使用 Process.Start() 函数运行命令提示符命令
在 C# 中调整图像大小
发布时间:2024/02/04 浏览次数:203 分类:编程语言
-
有两种主要方法可用于在 C# 中调整图像的大小,Bitmap 类构造函数和 graphics.DrawImage()函数。在本教程中,我们将讨论在C#中调整图像大小的方法。我们将带您完成整个过程,从加载原始图像到保
在 C# 中下载图片
发布时间:2024/02/04 浏览次数:138 分类:编程语言
-
有 3 种主要方法可用于下载 C# 中的图片,WebClient.DownloadFile()函数,Bitmap 类和 Image.FromStream()函数。在 C# 中使用 WebClient 类下载图片 WebClient 类提供了用于向 C# 中的 URL 发送数据和从 URL 接收数据
在 C# 中使用秒表
发布时间:2024/02/04 浏览次数:139 分类:编程语言
-
我们可以使用 Stopwatch 类来计算 C# 中的经过时间。使用 C# 中的秒表类计算经过时间 Stopwatch 类在 C# 中准确测量经过的时间。