1 /* A server must occasionally print some message. It uses a simple version of
2 * printf() found in the system lib that calls kputc() to output characters.
3 * Printing is done with a call to the kernel, and not by going through FS.
5 * This routine can only be used by servers and device drivers. The kernel
6 * must define its own kputc(). Note that the log driver also defines its own
7 * kputc() to directly call the TTY instead of going through this library.
12 #include <minix/com.h>
14 #define OVERFLOW_STR "[...]\n"
16 #define PRINTPROCS (sizeof(procs)/sizeof(procs[0]))
18 static char print_buf
[80]; /* output is buffered here */
20 int kputc_use_private_grants
= 0;
22 static int buf_count
= 0; /* # characters in the buffer */
23 static int buf_offset
= 0; /* Start of current line in buffer */
24 static int procs
[] = OUTPUT_PROCS_ARRAY
;
25 static cp_grant_id_t printgrants
[PRINTPROCS
];
26 static int procbusy
[PRINTPROCS
];
27 static int do_flush
= FALSE
;
28 static int overflow
= FALSE
;
30 /*===========================================================================*
32 *===========================================================================*/
36 /* Accumulate another character. If 0 or buffer full, print it. */
40 static int firstprint
= 1;
44 if (buf_count
> buf_offset
)
47 else if (buf_count
>= sizeof(print_buf
))
50 if (buf_count
> buf_offset
)
54 print_buf
[buf_count
++] = c
;
56 if (!do_flush
|| buf_offset
!= 0)
59 buf_offset
= buf_count
;
60 if (kputc_use_private_grants
)
62 for (p
= 0; p
<PRINTPROCS
; p
++)
63 printgrants
[p
]= GRANT_INVALID
;
67 for(p
= 0; procs
[p
] != NONE
; p
++) {
68 printgrants
[p
] = GRANT_INVALID
;
73 /* First time? Initialize grant table;
74 * Grant printing processes read copy access to our
75 * print buffer forever. (So buffer can't be on stack!)
77 for(p
= 0; procs
[p
] != NONE
; p
++) {
78 printgrants
[p
] = cpf_grant_direct(procs
[p
],
79 (vir_bytes
) print_buf
,
80 sizeof(print_buf
), CPF_READ
);
85 for(p
= 0; procs
[p
] != NONE
; p
++) {
86 /* Send the buffer to this output driver. */
87 m
.DIAG_BUF_COUNT
= buf_count
;
88 if(GRANT_VALID(printgrants
[p
])) {
89 m
.m_type
= DIAGNOSTICS_S
;
90 m
.DIAG_PRINT_BUF_G
= (char *) printgrants
[p
];
92 m
.m_type
= DIAGNOSTICS
;
93 m
.DIAG_PRINT_BUF_G
= print_buf
;
95 if (procs
[p
] == LOG_PROC_NR
)
98 (void) asynsend(procs
[p
], &m
);
102 sendrec(procs
[p
], &m
);
107 PUBLIC
void diag_repl()
112 driver_e
= m_in
.m_source
;
114 /* Find busy flag to clear */
115 for(p
= 0; procs
[p
] != NONE
; p
++)
117 if (procs
[p
] == driver_e
)
120 if (procs
[p
] == NONE
)
122 /* Message from wrong source */
127 /* Wait for more replies? */
128 for(p
= 0; procs
[p
] != NONE
; p
++)
133 if (buf_count
> buf_offset
)
135 memmove(&print_buf
[0], &print_buf
[buf_offset
],
136 buf_count
-buf_offset
);
138 buf_count
-= buf_offset
;
142 if (buf_count
+ sizeof(OVERFLOW_STR
) > sizeof(print_buf
))
143 buf_count
= sizeof(print_buf
)-sizeof(OVERFLOW_STR
);
146 printf("%s", OVERFLOW_STR
);