system 函数被废除的替代方法(system volume information是什么文件)

网友投稿 394 2022-10-09


system 函数被废除的替代方法(system volume information是什么文件)

做越狱应用和插件开发,经常会调用 system 去执行系统命令,早在 Xcode 7,使用 system 函数提示警告:

'system' is deprecated: first deprecated in iOS 8.0 - Use posix_spawn APIs installd

只是警告,还是可以正常编译和使用,但是升级到 Xcode 9,system 函数就从 SDK 中移除了,不能再使用了,提示:

'system' is unavailable: not available on iOS

替代的方法一般有三种,第一种是使用 posix_spawn,代码如下:

pid_t pid; char *argv[] = {   "/bin/ls",  //path   "-al",     //parameter1   "/",       //parameter2   NULL };   posix_spawn(&pid, argv[0], NULL, NULL, argv, NULL);   printf("pid=%d,child pid = %d\n",getpid(),pid);   int stat; waitpid(pid,&stat,0); printf("stat is %d\n",stat);

第二种是使用 NSTask,代码如下:

NSTask *task = [[NSTask alloc] init]; task.launchPath = @"/bin/ls"; task.arguments = [NSArray arrayWithObjects:                   @"-al",                   @"/",                   nil]; [task launch]; [task waitUntilExit];

NSTask.h 头文件信息如下:

#import    @class NSString, NSArray, NSDictionary;   @interface NSTask : NSObject   // Create an NSTask which can be run at a later time // An NSTask can only be run once. Subsequent attempts to // run an NSTask will raise. // Upon task death a notification will be sent //   { Name = NSTaskDidTerminateNotification; object = task; } //   - (instancetype)init;   // set parameters // these methods can only be done before a launch // if not set, use current // if not set, use current   // set standard I/O channels; may be either an NSFileHandle or an NSPipe - (void)setStandardInput:(id)input; - (void)setStandardOutput:(id)output; - (void)setStandardError:(id)error;   // get parameters @property (NS_NONATOMIC_IOSONLY, copy) NSString *launchPath; @property (NS_NONATOMIC_IOSONLY, copy) NSArray *arguments; @property (NS_NONATOMIC_IOSONLY, copy) NSDictionary *environment; @property (NS_NONATOMIC_IOSONLY, copy) NSString *currentDirectoryPath;   // get standard I/O channels; could be either an NSFileHandle or an NSPipe - (id)standardInput; - (id)standardOutput; - (id)standardError;   // actions - (void)launch;   - (void)interrupt; // Not always possible. Sends SIGINT. - (void)terminate; // Not always possible. Sends SIGTERM.   @property (NS_NONATOMIC_IOSONLY, readonly) BOOL suspend; @property (NS_NONATOMIC_IOSONLY, readonly) BOOL resume;   // status @property (NS_NONATOMIC_IOSONLY, readonly) int processIdentifier;  @property (NS_NONATOMIC_IOSONLY, getter=isRunning, readonly) BOOL running;   @property (NS_NONATOMIC_IOSONLY, readonly) int terminationStatus;   @end   @interface NSTask (NSTaskConveniences)   + (NSTask *)launchedTaskWithLaunchPath:(NSString *)path arguments:(NSArray *)arguments; // convenience; create and launch   - (void)waitUntilExit; // poll the runLoop in defaultMode until task completes   @end   FOUNDATION_EXPORT NSString * const NSTaskDidTerminateNotification;

如果非要调用 system 函数不可,那就使用第三种方法,找到 system 函数地址直接调用,方法参见: 动态调用函数,具体代码如下:

typedef int (*my_system) (const char *str); int call_system(const char *str){          //动态库路径     char *dylib_path = "/usr/lib/libSystem.dylib";     //打开动态库     void *handle = dlopen(dylib_path, RTLD_GLOBAL | RTLD_NOW);     if (handle == NULL) {         //打开动态库出错         fprintf(stderr, "%s\n", dlerror());     } else {         //获取 system 地址         my_system system = dlsym(handle, "system");                  //地址获取成功则调用         if (system) {                          int ret = system(str);             return ret;         }         dlclose(handle); //关闭句柄     }          return -1; }

这样 call_system 函数就相当于 system 的功能了,替换即可。

原文地址:https://exchen.net/ios-hacker-system-%E5%87%BD%E6%95%B0%E8%A2%AB%E5%BA%9F%E9%99%A4%E7%9A%84%E6%9B%BF%E4%BB%A3%E6%96%B9%E6%B3%95.html


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:如何使用Bean Validation 解决业务中参数校验
下一篇:dlopen 和 dlsym 动态调用函数(dlopen函数)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~