diff --git a/src/music/extmidi.cpp b/src/music/extmidi.cpp --- a/src/music/extmidi.cpp +++ b/src/music/extmidi.cpp @@ -49,37 +49,25 @@ const char *MusicDriver_ExtMidi::Start(c if (StrEmpty(command)) command = EXTERNAL_PLAYER " " MIDI_ARG; #endif - /* Count number of arguments, but include 3 extra slots: 1st for command, 2nd for song title, and 3rd for terminating nullptr. */ - uint num_args = 3; - for (const char *t = command; *t != '\0'; t++) if (*t == ' ') num_args++; - - this->params = CallocT(num_args); - this->params[0] = stredup(command); + this->command_tokens.clear(); - /* Replace space with \0 and add next arg to params */ - uint p = 1; - while (true) { - this->params[p] = strchr(this->params[p - 1], ' '); - if (this->params[p] == nullptr) break; + std::string_view view = command; + for (;;) { + auto pos = view.find(' '); + this->command_tokens.emplace_back(view.substr(0, pos)); - this->params[p][0] = '\0'; - this->params[p]++; - p++; + if (pos == std::string_view::npos) break; + view.remove_prefix(pos + 1); } - /* Last parameter is the song file. */ - this->params[p] = this->song; - - this->song[0] = '\0'; + this->song.clear(); this->pid = -1; return nullptr; } void MusicDriver_ExtMidi::Stop() { - free(params[0]); - free(params); - this->song[0] = '\0'; + this->song.clear(); this->DoStop(); } @@ -87,14 +75,14 @@ void MusicDriver_ExtMidi::PlaySong(const { std::string filename = MidiFile::GetSMFFile(song); if (!filename.empty()) { - strecpy(this->song, filename.c_str(), lastof(this->song)); + this->song = std::move(filename); this->DoStop(); } } void MusicDriver_ExtMidi::StopSong() { - this->song[0] = '\0'; + this->song.clear(); this->DoStop(); } @@ -103,7 +91,7 @@ bool MusicDriver_ExtMidi::IsSongPlaying( if (this->pid != -1 && waitpid(this->pid, nullptr, WNOHANG) == this->pid) { this->pid = -1; } - if (this->pid == -1 && this->song[0] != '\0') this->DoPlay(); + if (this->pid == -1 && !this->song.empty()) this->DoPlay(); return this->pid != -1; } @@ -120,7 +108,14 @@ void MusicDriver_ExtMidi::DoPlay() close(0); int d = open("/dev/null", O_RDONLY); if (d != -1 && dup2(d, 1) != -1 && dup2(d, 2) != -1) { - execvp(this->params[0], this->params); + /* execvp is nasty as it *allows* the passed parameters to be written + * for backward compatibility, however we are a fork so do not care. */ + std::vector parameters; + for (auto &token : this->command_tokens) parameters.emplace_back(token.data()); + parameters.emplace_back(this->song.data()); + parameters.emplace_back(nullptr); + + execvp(parameters[0], parameters.data()); } _exit(1); } diff --git a/src/music/extmidi.h b/src/music/extmidi.h --- a/src/music/extmidi.h +++ b/src/music/extmidi.h @@ -14,8 +14,8 @@ class MusicDriver_ExtMidi : public MusicDriver { private: - char **params; - char song[MAX_PATH]; + std::vector command_tokens; + std::string song; pid_t pid; void DoPlay();