@@ -120,6 +120,12 @@ static void llama_log_callback_logTee(ggml_log_level level, const char * text, v
120
120
}
121
121
122
122
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
+
123
129
gpt_params params;
124
130
g_params = ¶ms;
125
131
@@ -128,6 +134,16 @@ int main(int argc, char ** argv) {
128
134
}
129
135
llama_sampling_params & sparams = params.sparams ;
130
136
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
+
131
147
#ifndef LOG_DISABLE_LOGS
132
148
log_set_target (log_filename_generator (" main" , " log" ));
133
149
LOG_TEE (" Log start\n " );
@@ -530,17 +546,6 @@ int main(int argc, char ** argv) {
530
546
exit (1 );
531
547
}
532
548
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
-
544
549
while ((n_remain != 0 && !is_antiprompt) || params.interactive ) {
545
550
// predict
546
551
if (!embd.empty ()) {
@@ -758,20 +763,18 @@ int main(int argc, char ** argv) {
758
763
// Console/Stream Output
759
764
if (!llama_token_is_control_token (llama_get_model (ctx), id)) {
760
765
// Stream Output Token To Standard Output
761
- fflush (stdout);
762
766
fprintf (stdout, " %s" , token_str.c_str ());
763
767
} else if (!params.ctrl_token_no_out ) {
764
768
#ifndef _MSC_VER
765
- if (control_token_descriptor_is_attached ) {
769
+ if (control_token_file_descriptor_is_attached ) {
766
770
// 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 ()) ;
769
773
} else
770
774
#endif
771
775
if (control_token_allowed_on_standard_stream)
772
776
{
773
777
// Stream Control Token To Standard Output Stream
774
- fflush (stdout);
775
778
fprintf (stdout, " %s" , token_str.c_str ());
776
779
}
777
780
}
0 commit comments