Skip to content

Commit c1e8a6d

Browse files
committed
main: must check pipe status on very top of program
1 parent 50048f5 commit c1e8a6d

File tree

1 file changed

+19
-16
lines changed

1 file changed

+19
-16
lines changed

examples/main/main.cpp

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,12 @@ static void llama_log_callback_logTee(ggml_log_level level, const char * text, v
120120
}
121121

122122
int main(int argc, char ** argv) {
123+
#ifndef _MSC_VER
124+
// Check if we have an external attachment to a file descriptor for out of band control tokens (e.g. bash `3>/dev/null` )
125+
// Placed here to avoid file descriptor being polluted by gpt_params_parse() opening files
126+
const bool control_token_file_descriptor_is_attached = fcntl(CONTROL_TOKEN_FILENO, F_GETFL) != -1;
127+
#endif
128+
123129
gpt_params params;
124130
g_params = &params;
125131

@@ -128,6 +134,16 @@ int main(int argc, char ** argv) {
128134
}
129135
llama_sampling_params & sparams = params.sparams;
130136

137+
const bool control_token_allowed_on_standard_stream = !params.conversation && sparams.grammar.empty();
138+
139+
#ifndef _MSC_VER
140+
// Merge normal token stream and control token streams together only if not in conversation or grammar mode
141+
if (control_token_allowed_on_standard_stream && !control_token_file_descriptor_is_attached) {
142+
// Duplicate stdout file descriptor to control token file descriptor to merge the two streams
143+
dup2(STDOUT_FILENO, CONTROL_TOKEN_FILENO);
144+
}
145+
#endif
146+
131147
#ifndef LOG_DISABLE_LOGS
132148
log_set_target(log_filename_generator("main", "log"));
133149
LOG_TEE("Log start\n");
@@ -530,17 +546,6 @@ int main(int argc, char ** argv) {
530546
exit(1);
531547
}
532548

533-
const bool control_token_allowed_on_standard_stream = !params.conversation && sparams.grammar.empty();
534-
535-
#ifndef _MSC_VER
536-
const bool control_token_descriptor_is_attached = fcntl(CONTROL_TOKEN_FILENO, F_GETFL) != -1;
537-
if (control_token_allowed_on_standard_stream && !control_token_descriptor_is_attached) {
538-
// Control Token File Descriptor has nothing attached to it so make control token file descriptor be an alias of stdout
539-
// This is not done however if we are in conversation mode or grammar mode as that is typically discarded
540-
dup2(STDOUT_FILENO, CONTROL_TOKEN_FILENO);
541-
}
542-
#endif
543-
544549
while ((n_remain != 0 && !is_antiprompt) || params.interactive) {
545550
// predict
546551
if (!embd.empty()) {
@@ -758,20 +763,18 @@ int main(int argc, char ** argv) {
758763
// Console/Stream Output
759764
if (!llama_token_is_control_token(llama_get_model(ctx), id)) {
760765
// Stream Output Token To Standard Output
761-
fflush(stdout);
762766
fprintf(stdout, "%s", token_str.c_str());
763767
} else if (!params.ctrl_token_no_out) {
764768
#ifndef _MSC_VER
765-
if (control_token_descriptor_is_attached) {
769+
if (control_token_file_descriptor_is_attached) {
766770
// Stream Control Token To Special Token Output. Useful for debugging control token behaviour
767-
ssize_t result = write(CONTROL_TOKEN_FILENO, token_str.c_str(), token_str.length());
768-
(void) result;
771+
fflush(stdout); // Ensure control token is always appended to stdout stream
772+
(void)! write(CONTROL_TOKEN_FILENO, token_str.c_str(), token_str.length());
769773
} else
770774
#endif
771775
if (control_token_allowed_on_standard_stream)
772776
{
773777
// Stream Control Token To Standard Output Stream
774-
fflush(stdout);
775778
fprintf(stdout, "%s", token_str.c_str());
776779
}
777780
}

0 commit comments

Comments
 (0)