gpt4 book ai didi

objective-c - Cocoa 中 AuthorizationExecuteWithPriveleges 的非常奇怪的问题

转载 作者:行者123 更新时间:2023-11-29 09:41:28 24 4
gpt4 key购买 nike

我正在使用 AuthorizationExecuteWithPriveleges 以管理员权限从我的应用程序执行 bash 命令。我发现了非常奇怪的问题。这是我正在使用的

    FILE *pipe=nil;
OSStatus err;
AuthorizationRef authorizationRef;
char *command= "/bin/chmod";


char *args[] = {"644","folderPath", nil};

if(err!=0)
{
err = AuthorizationCreate(nil,
kAuthorizationEmptyEnvironment,
kAuthorizationFlagDefaults,
&authorizationRef);
}
NSLog(@"test");
err = AuthorizationExecuteWithPrivileges(authorizationRef,
command,
kAuthorizationFlagDefaults,
args,
&pipe);

调用此函数大约 40 次后,开始响应非常缓慢。之后它就会死掉,并卡住应用程序,我不知道这是怎么回事。在调用大约 40 次后,它没有显示日志“测试”,也没有做任何事情。使用什么 Bash 命令或什么参数并不重要。它仍然做同样的事情。这有什么问题?我之所以使用它,是因为我的应用程序也需要在 10.5 上运行。

如果有人有想法,我该怎么办。对此,我真的非常感激。我需要尽快。谢谢

最佳答案

仔细研究了这一点,并编写了以下示例,没有任何保证,但对我来说,它可以毫无问题地调用数千次 AuthorizationExecuteWithPrivileges:

void DoOtherStuff(AuthorizationRef auth, char* path);

void DoStuff(char* path)
{
AuthorizationItem foo;
foo.name = kAuthorizationRightExecute;
foo.value = NULL;
foo.valueLength = 0;
foo.flags = 0;

AuthorizationRights rights;
rights.count = 1;
rights.items = &foo;

AuthorizationRef authorizationRef;
OSStatus err = errAuthorizationSuccess;

if (errAuthorizationSuccess != (err = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authorizationRef)))
{
NSLog(@"Error on AuthorizationCreate: %lu", (long)err);
return;
}

for (NSUInteger i = 0; i < 5000; i++)
{
NSLog(@"Doing run: %lu", (long)i+1);
DoOtherStuff(authorizationRef, "/tmp/foo");
}

if (errAuthorizationSuccess != (err = AuthorizationFree(authorizationRef, kAuthorizationFlagDefaults)))
{
NSLog(@"Error on AuthorizationFree: %lu", (long)err);
return;
}
}

void DoOtherStuff(AuthorizationRef authorizationRef, char* path)
{
OSStatus err = errAuthorizationSuccess;
FILE *pipe = NULL;
@try
{
char *args[] = {"644", path, NULL};
if (errAuthorizationSuccess != (err = AuthorizationExecuteWithPrivileges(authorizationRef,
"/bin/chmod", kAuthorizationFlagDefaults, args, &pipe)))
{
NSLog(@"Error on AuthorizationExecuteWithPrivileges: %lu", (long)err);
return;
}

int stat;
wait(&stat);

NSLog(@"Success! Child Process Died!");
}
@finally
{
if (pipe)
fclose(pipe);
}
}

Chris Suter 所说的完全正确。当您调用 AuthorizationExecuteWithPrivileges 时发生的事情是它 fork()s 您的进程,然后 exec()s 从子进程请求的进程(在本例中为 chmod)。在有人调用 wait() 之前,子进程不会被收割,但这很难,因为我们无法从 AuthorizationExecuteWithPrivileges 中获取子进程的 PID(它会由 fork() 返回)。正如他所说,如果您确定没有其他线程同时产生进程(即您的线程是唯一创建子进程的线程),那么您可以调用 wait() 的非 PID 特定版本,例如我在这个例子中这样做。

如果您不调用 wait() ,那么您会累积这些等待收割的僵尸子进程。最终操作系统说“不再”。

我觉得发布这个有点不好,因为它只是对 Chris Suter 所说内容的翻版;我赞成他的回答。

为了完整起见,这里是该示例的修改版本,它通过忽略 SIGCHLD 而不是调用等待来实现目标。它也没有保修,但对我有用。

void DoOtherStuff(AuthorizationRef auth, char* path);

void DoStuff(char* path)
{
AuthorizationItem foo;
foo.name = kAuthorizationRightExecute;
foo.value = NULL;
foo.valueLength = 0;
foo.flags = 0;

AuthorizationRights rights;
rights.count = 1;
rights.items = &foo;

AuthorizationRef authorizationRef;
OSStatus err = errAuthorizationSuccess;

struct sigaction oldAction;
struct sigaction newAction;

newAction.__sigaction_u.__sa_handler = SIG_IGN;
newAction.sa_mask = 0;
newAction.sa_flags = 0;

if(0 != sigaction(SIGCHLD, &newAction, &oldAction))
{
NSLog(@"Couldn't ignore SIGCHLD");
return;
}

@try
{
if (errAuthorizationSuccess != (err = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authorizationRef)))
{
NSLog(@"Error on AuthorizationCreate: %lu", (long)err);
return;
}

for (NSUInteger i = 0; i < 1000; i++)
{
NSLog(@"Doing run: %lu", (long)i+1);
DoOtherStuff(authorizationRef, "/tmp/foo");
}

if (errAuthorizationSuccess != (err = AuthorizationFree(authorizationRef, kAuthorizationFlagDefaults)))
{
NSLog(@"Error on AuthorizationFree: %lu", (long)err);
return;
}
}
@finally
{
const struct sigaction cOldAction = oldAction;
if(0 != sigaction(SIGCHLD, &cOldAction, NULL))
{
NSLog(@"Couldn't restore the handler for SIGCHLD");
return;
}

}
}

void DoOtherStuff(AuthorizationRef authorizationRef, char* path)
{
OSStatus err = errAuthorizationSuccess;
FILE *pipe = NULL;
@try
{
char *args[] = {"644", path, NULL};
if (errAuthorizationSuccess != (err = AuthorizationExecuteWithPrivileges(authorizationRef,
"/bin/chmod", kAuthorizationFlagDefaults, args, &pipe)))
{
NSLog(@"Error on AuthorizationExecuteWithPrivileges: %lu", (long)err);
return;
}

NSLog(@"Success!");
}
@finally
{
if (pipe)
fclose(pipe);
}
}

关于objective-c - Cocoa 中 AuthorizationExecuteWithPriveleges 的非常奇怪的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8094683/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com