Skip to content

Commit c7e8a39

Browse files
committed
Mac: replace executeCommand with posix apis
1 parent 4c01220 commit c7e8a39

1 file changed

Lines changed: 32 additions & 14 deletions

File tree

src/backends/darwin.mm

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,29 +23,47 @@ void hideDockIcon(bool shouldHide) {
2323
return filePath;
2424
}
2525

26-
NSString *executeCommand(NSString *command, NSArray *arguments) {
27-
NSTask *task = [[NSTask alloc] init];
28-
task.launchPath = command;
29-
task.arguments = arguments;
26+
std::string executeCommand(const std::string &command, const std::vector<std::string> &arguments) {
27+
int pipefd[2];
28+
pipe(pipefd);
29+
30+
pid_t pid = fork();
31+
if (pid == 0) {
32+
dup2(pipefd[1], STDOUT_FILENO);
33+
close(pipefd[0]);
34+
close(pipefd[1]);
35+
36+
std::vector<char *> argv;
37+
argv.push_back(const_cast<char *>(command.c_str()));
38+
for (const auto &arg : arguments) argv.push_back(const_cast<char *>(arg.c_str()));
39+
argv.push_back(nullptr);
40+
41+
execv(command.c_str(), argv.data());
42+
_exit(1);
43+
}
44+
45+
close(pipefd[1]);
3046

31-
NSPipe *pipe = [NSPipe pipe];
32-
task.standardOutput = pipe;
33-
task.standardError = [NSPipe pipe];
34-
[task launch];
47+
std::string output;
48+
char buffer[4096];
49+
ssize_t count;
50+
while ((count = read(pipefd[0], buffer, sizeof(buffer))) > 0) {
51+
output.append(buffer, count);
52+
}
3553

36-
NSData *data = [[pipe fileHandleForReading] readDataToEndOfFile];
37-
NSString *output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
38-
[task waitUntilExit];
54+
close(pipefd[0]);
55+
waitpid(pid, nullptr, 0);
3956

4057
return output;
4158
}
4259

4360
std::shared_ptr<MediaInfo> backend::getMediaInformation() {
44-
// apple decided to prevent apps not signed by them to use media remote, so we use an apple script instead. But that script only works on Sonoma or newer and the other one is arguably better, so keep the old method as well
61+
// apple decided to prevent apps not signed by them to use media remote, so we use an apple script instead. But that
62+
// script only works on Sonoma or newer and the other one is arguably better, so keep the old method as well
4563
if (@available(macOS 15.0, *)) {
4664
static NSString *script = getFilePathFromBundle(@"MediaRemote", @"js");
47-
NSString *output = executeCommand(@"/usr/bin/osascript", @[ @"-l", @"JavaScript", script ]);
48-
nlohmann::json j = nlohmann::json::parse([output UTF8String]);
65+
std::string output = executeCommand("/usr/bin/osascript", {"-l", "JavaScript", script.UTF8String});
66+
nlohmann::json j = nlohmann::json::parse(output);
4967

5068
std::string appName = j["player"].get<std::string>();
5169
if (appName == "none")

0 commit comments

Comments
 (0)