1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
| #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/syscall.h> #include <errno.h> #include <string.h>
// 通用的syscall错误处理函数 void handle_syscall_error(const char* syscall_name) { fprintf(stderr, "系统调用 %s 失败: ", syscall_name); switch(errno) { case EPERM: fprintf(stderr, "操作不被允许\n"); break; case ENOENT: fprintf(stderr, "文件或目录不存在\n"); break; case EACCES: fprintf(stderr, "权限不足\n"); break; case EFAULT: fprintf(stderr, "地址错误\n"); break; case EINVAL: fprintf(stderr, "无效参数\n"); break; case ENOMEM: fprintf(stderr, "内存不足\n"); break; case EBUSY: fprintf(stderr, "资源忙\n"); break; default: fprintf(stderr, "%s\n", strerror(errno)); break; } }
// 获取系统调用名称的辅助函数 const char* get_syscall_name(long syscall_num) { switch(syscall_num) { case SYS_getpid: return "getpid"; case SYS_getppid: return "getppid"; case SYS_getuid: return "getuid"; case SYS_geteuid: return "geteuid"; case SYS_getgid: return "getgid"; case SYS_getegid: return "getegid"; default: return "unknown"; } }
// 安全的syscall包装函数 long safe_syscall(long number, const char* name) { errno = 0; // 清除之前的错误 long result = syscall(number); if(result == -1) { handle_syscall_error(name); } return result; }
int main() { printf("=== 自定义系统调用封装和错误处理 ===\n"); // 测试各种系统调用 struct { long number; const char* name; const char* description; } syscalls[] = { {SYS_getpid, "getpid", "获取进程ID"}, {SYS_getppid, "getppid", "获取父进程ID"}, {SYS_getuid, "getuid", "获取用户ID"}, {SYS_geteuid, "geteuid", "获取有效用户ID"}, {SYS_getgid, "getgid", "获取组ID"}, {SYS_getegid, "getegid", "获取有效组ID"} }; int num_syscalls = sizeof(syscalls) / sizeof(syscalls[0]); printf("\n系统信息获取测试:\n"); printf("----------------------------\n"); for(int i = 0; i < num_syscalls; i++) { printf("%-10s: ", syscalls[i].description); long result = safe_syscall(syscalls[i].number, syscalls[i].name); if(result != -1) { printf("%ld\n", result); } } // 测试错误处理 - 调用不存在的系统调用 printf("\n错误处理测试:\n"); printf("----------------------------\n"); printf("调用不存在的系统调用 (编号999999):\n"); errno = 0; long result = syscall(999999); if(result == -1) { handle_syscall_error("invalid_syscall"); } // 测试权限相关的系统调用 printf("\n权限相关测试:\n"); printf("----------------------------\n"); // 获取当前工作目录 (使用getcwd系统调用) printf("当前工作目录测试:\n"); char cwd[1024]; errno = 0; long cwd_result = syscall(SYS_getcwd, cwd, sizeof(cwd)); if(cwd_result != -1) { printf("当前目录: %s\n", cwd); } else { handle_syscall_error("getcwd"); } // 测试系统资源使用情况 printf("\n系统资源使用测试:\n"); printf("----------------------------\n"); struct { long ru_utime_sec; // 用户CPU时间(秒) long ru_utime_usec; // 用户CPU时间(微秒) long ru_stime_sec; // 系统CPU时间(秒) long ru_stime_usec; // 系统CPU时间(微秒) long ru_maxrss; // 最大常驻集大小 long ru_ixrss; // 共享内存大小 long ru_idrss; // 非共享数据大小 long ru_isrss; // 非共享栈大小 long ru_minflt; // 页错误(次要) long ru_majflt; // 页错误(主要) long ru_nswap; // 交换次数 long ru_inblock; // 输入操作数 long ru_oublock; // 输出操作数 long ru_msgsnd; // 消息发送数 long ru_msgrcv; // 消息接收数 long ru_nsignals; // 信号接收数 long ru_nvcsw; // 自愿上下文切换 long ru_nivcsw; // 非自愿上下文切换 } usage; errno = 0; result = syscall(SYS_getrusage, RUSAGE_SELF, &usage); if(result == 0) { printf("用户CPU时间: %ld.%06ld 秒\n", usage.ru_utime_sec, usage.ru_utime_usec); printf("系统CPU时间: %ld.%06ld 秒\n", usage.ru_stime_sec, usage.ru_stime_usec); printf("最大内存使用: %ld KB\n", usage.ru_maxrss); } else { handle_syscall_error("getrusage"); } // 演示syscall的优势 - 访问新系统调用 printf("\n新系统调用演示:\n"); printf("----------------------------\n"); printf("注意: 某些新系统调用可能在当前内核版本中不可用\n"); // 尝试调用eventfd系统调用(如果可用) errno = 0; result = syscall(SYS_eventfd, 0); if(result != -1) { printf("eventfd系统调用成功,文件描述符: %ld\n", result); close(result); // 关闭文件描述符 } else { printf("eventfd系统调用不可用或失败\n"); } printf("\n=== 测试完成 ===\n"); return 0; }
|