C语言进程调度与IPC编程实战

24、编写一个设置用户 ID 为 root 的程序,它是实时调度方面类似于 nice(1) 的程序。该程序的命令行界面如下:# ./rtsched policy priority command arg… 在上述命令中,policy 用 r 表示 SCHED_RR,用 f 表示 SCHED_FIFO。此程序在执行命令前应放弃其特权 ID。

以下是实现该功能的 C 语言代码示例:

#include <stdio.h>
#include <stdlib.h>
#include <sched.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/resource.h>

int main(int argc, char *argv[]) {
    if (argc < 4) {
        fprintf(stderr, "Usage: %s policy priority command arg...\n", argv[0]);
        return 1;
    }

    int policy;
    if (argv[1][0] == 'r') {
        policy = SCHED_RR;
    } else if (argv[1][0] == 'f') {
        policy = SCHED_FIFO;
    } else {
        fprintf(stderr, "Invalid policy. Use 'r' for SCHED_RR or 'f' for SCHED_FIFO.\n");
        return 1;
    }

    int priority = atoi(argv[2]);
    if (priority < sched_get_priority_min(policy) || priority > sched_get_priority_max(policy)) {
        fprintf(stderr, "Invalid priority for the selected policy.\n");
        return 1;
    }

    struct sched_param param;
    param.sched_priority = priority;
    if (sched_setscheduler(0, policy, &param) == -1) {
        perror("sched_setscheduler");
        return 1;
    }

    // 放弃特权 ID
    if (seteuid(getuid()) == -1) {
        perror("seteuid");
        return 1;
    }

    // 执行命令
    execvp(argv[3], &argv[3]);
    perror("execvp");
    return 1;
}

代码说明:

  1. 参数检查 :首先检查命令行参数的数量是否足够,如果不足则输出使用说明并退出。
  2. 解析策略 :根据用户输入的 policy 参数( r f )设置相应的调度策略。
  3. 解析优先级 :将用户输入的 priority 参数转换为整数,并检查其是否在所选策略的有效范围内。
  4. 设置调度策略和优先级 :使用 sched_setscheduler 函数设置当前进程的调度策略和优先级。
  5. 放弃特权 ID :使用 seteuid 函数将有效用户 ID 设置为实际用户 ID,从而放弃特权。
  6. 执行命令 :使用 execvp 函数执行用户指定的命令。如果执行失败,则输出错误信息并退出。

25、编写一个C语言程序,在使用dlsym()获取函数指针后,添加一个dladdr()调用,以获取有关dlsym()返回地址的信息。打印返回的Dl_info结构的字段值,并验证这些值是否符合预期。

以下是添加 dladdr() 调用后的代码示例:

#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
    void *libHandle;            /* Handle for shared library */
    void (*funcp)(void);        /* Pointer to function with no arguments */
    const char *err;
    Dl_info info;

    if (argc != 3 || strcmp(argv[1], "--help") == 0) {
        fprintf(stderr, "Usage: %s lib-path func-name\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    /* Load the shared library and get a handle for later use */
    libHandle = dlopen(argv[1], RTLD_LAZY);
    if (libHandle == NULL) {
        fprintf(stderr, "dlopen: %s\n", dlerror());
        exit(EXIT_FAILURE);
    }

    /* Search library for symbol named in argv[2] */
    (void) dlerror();                           /* Clear dlerror() */
    *(void **) (&funcp) = dlsym(libHandle, argv[2]);
    err = dlerror();
    if (err != NULL
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值