2 * shell buffered IO and formatted output
9 static int initio_done
;
12 * formatted output functions
16 /* A shell error occured (eg, syntax error, etc.) */
18 errorf(const char *fmt
, ...)
22 shl_stdout_ok
= 0; /* debugging: note that stdout not valid */
27 shf_vfprintf(shl_out
, fmt
, va
);
29 shf_putchar('\n', shl_out
);
35 /* like errorf(), but no unwind is done */
37 warningf(int fileline
, const char *fmt
, ...)
41 error_prefix(fileline
);
43 shf_vfprintf(shl_out
, fmt
, va
);
45 shf_putchar('\n', shl_out
);
49 /* Used by built-in utilities to prefix shell and utility name to message
50 * (also unwinds environments for special builtins).
53 bi_errorf(const char *fmt
, ...)
57 shl_stdout_ok
= 0; /* debugging: note that stdout not valid */
61 /* not set when main() calls parse_args() */
63 shf_fprintf(shl_out
, "%s: ", builtin_argv0
);
65 shf_vfprintf(shl_out
, fmt
, va
);
67 shf_putchar('\n', shl_out
);
70 /* POSIX special builtins and ksh special builtins cause
71 * non-interactive shells to exit.
72 * XXX odd use of KEEPASN; also may not want LERROR here
74 if ((builtin_flag
& SPEC_BI
) || (builtin_flag
& KEEPASN
))
76 builtin_argv0
= (char *) 0;
81 /* Called when something that shouldn't happen does */
83 internal_errorf(int jump
, const char *fmt
, ...)
88 shf_fprintf(shl_out
, "internal error: ");
90 shf_vfprintf(shl_out
, fmt
, va
);
92 shf_putchar('\n', shl_out
);
98 void error_prefix(int fileline
)
100 if (!fileline
|| !source
|| !source
->file
101 || strcmp(source
->file
, poshname
) != 0)
102 shf_fprintf(shl_out
, "%s: ", poshname
+ (*poshname
== '-'));
103 if (fileline
&& source
&& source
->file
!= NULL
) {
104 shf_fprintf(shl_out
, "%s:%d: ", source
->file
,
105 source
->errline
> 0 ? source
->errline
: source
->line
);
110 /* printf to shl_out (stderr) with flush */
112 shellf(const char *fmt
, ...)
116 if (!initio_done
) /* shl_out may not be set up yet... */
118 SH_VA_START(va
, fmt
);
119 shf_vfprintf(shl_out
, fmt
, va
);
124 /* printf to shl_stdout (stdout) */
126 shprintf(const char *fmt
, ...)
131 internal_errorf(1, "shl_stdout not valid");
132 SH_VA_START(va
, fmt
);
133 shf_vfprintf(shl_stdout
, fmt
, va
);
138 static struct shf
*kshdebug_shf
;
144 shf_close(kshdebug_shf
);
145 kshdebug_shf
= shf_open("/tmp/ksh-debug.log",
146 O_WRONLY
|O_APPEND
|O_CREAT
, 0600,
149 shf_fprintf(kshdebug_shf
, "\nNew shell[pid %d]\n", getpid());
150 shf_flush(kshdebug_shf
);
154 /* print to debugging log */
156 kshdebug_printf_(const char *fmt
, ...)
162 SH_VA_START(va
, fmt
);
163 shf_fprintf(kshdebug_shf
, "[%d] ", getpid());
164 shf_vfprintf(kshdebug_shf
, fmt
, va
);
166 shf_flush(kshdebug_shf
);
170 kshdebug_dump_(str
, mem
, nbytes
)
180 shf_fprintf(kshdebug_shf
, "[%d] %s:\n", getpid(), str
);
181 for (i
= 0; i
< nbytes
; i
+= nprow
) {
183 for (j
= 0; j
< nprow
&& i
+ j
< nbytes
; j
++) {
184 shf_fprintf(kshdebug_shf
, "%c%02x",
185 c
, ((const unsigned char *) mem
)[i
+ j
]);
188 shf_fprintf(kshdebug_shf
, "\n");
190 shf_flush(kshdebug_shf
);
192 #endif /* KSH_DEBUG */
194 /* test if we can seek backwards fd (returns 0 or SHF_UNBUF) */
201 return fstat(fd
, &statb
) == 0 && !S_ISREG(statb
.st_mode
) ?
205 struct shf shf_iob
[3];
210 shf_fdopen(1, SHF_WR
, shl_stdout
); /* force buffer allocation */
211 shf_fdopen(2, SHF_WR
, shl_out
);
212 shf_fdopen(2, SHF_WR
, shl_spare
); /* force buffer allocation */
216 /* A dup2() with error checking */
218 ksh_dup2(int ofd
, int nfd
, int errok
)
220 int ret
= dup2(ofd
, nfd
);
222 if (ret
< 0 && errno
!= EBADF
&& !errok
)
223 errorf("too many files open in shell");
226 /* Ultrix systems like to preserve the close-on-exec flag */
228 (void) fcntl(nfd
, F_SETFD
, 0);
229 #endif /* DUP2_BROKEN */
235 * move fd from user space (0<=fd<10) to shell space (fd>=10),
236 * set close-on-exec flag.
246 nfd
= ksh_dupbase(fd
, FDBASE
);
251 errorf("too many files open in shell");
266 shf_flush(&shf_iob
[fd
]);
267 if (ofd
< 0) /* original fd closed */
270 ksh_dup2(ofd
, fd
, TRUE
); /* XXX: what to do if this fails? */
280 errorf("can't create pipe - try again");
281 pv
[0] = savefd(pv
[0], 0);
282 pv
[1] = savefd(pv
[1], 0);
293 /* Called by iosetup() (deals with 2>&4, etc.), c_read, c_print to turn
294 * a string (the X in 2>&X, read -uX, print -uX) into a file descriptor.
297 check_fd(name
, mode
, emsgp
)
304 if (isdigit(name
[0]) && !name
[1]) {
306 if ((fl
= fcntl(fd
= name
[0] - '0', F_GETFL
, 0)) < 0) {
308 *emsgp
= "bad file descriptor";
314 if (setmode(fd
, O_TEXT
) == -1) {
316 *emsgp
= "couldn't set write mode";
319 } else if (mode
== R_OK
)
320 if (setmode(fd
, O_BINARY
) == -1) {
322 *emsgp
= "couldn't set read mode";
326 /* X_OK is a kludge to disable this check for dups (x<&1):
327 * historical shells never did this check (XXX don't know what
330 if (!(mode
& X_OK
) && fl
!= O_RDWR
331 && (((mode
& R_OK
) && fl
!= O_RDONLY
)
332 || ((mode
& W_OK
) && fl
!= O_WRONLY
)))
335 *emsgp
= (fl
== O_WRONLY
) ?
336 "fd not open for reading"
337 : "fd not open for writing";
344 else if (name
[0] == 'p' && !name
[1])
345 return coproc_getfd(mode
, emsgp
);
348 *emsgp
= "illegal file descriptor name";
353 /* Called once from main */
357 coproc
.read
= coproc
.readw
= coproc
.write
= -1;
362 /* Called by c_read() when eof is read - close fd if it is the co-process fd */
364 coproc_read_close(fd
)
367 if (coproc
.read
>= 0 && fd
== coproc
.read
) {
368 coproc_readw_close(fd
);
374 /* Called by c_read() and by iosetup() to close the other side of the
375 * read pipe, so reads will actually terminate.
378 coproc_readw_close(fd
)
381 if (coproc
.readw
>= 0 && coproc
.read
>= 0 && fd
== coproc
.read
) {
387 /* Called by c_print when a write to a fd fails with EPIPE and by iosetup
388 * when co-process input is dup'd
391 coproc_write_close(fd
)
394 if (coproc
.write
>= 0 && fd
== coproc
.write
) {
400 /* Called to check for existance of/value of the co-process file descriptor.
401 * (Used by check_fd() and by c_read/c_print to deal with -p option).
404 coproc_getfd(mode
, emsgp
)
408 int fd
= (mode
& R_OK
) ? coproc
.read
: coproc
.write
;
413 *emsgp
= "no coprocess";
417 /* called to close file descriptors related to the coprocess (if any)
418 * Should be called with SIGCHLD blocked.
421 coproc_cleanup(reuse
)
424 /* This to allow co-processes to share output pipe */
425 if (!reuse
|| coproc
.readw
< 0 || coproc
.read
< 0) {
426 if (coproc
.read
>= 0) {
430 if (coproc
.readw
>= 0) {
435 if (coproc
.write
>= 0) {
448 maketemp(ap
, type
, tlist
)
453 /* static unsigned int inc; */
460 dir
= tmpdir
? tmpdir
: "/tmp";
461 /* The 20 + 20 is a paranoid worst case for pid/inc */
462 len
= strlen(dir
) + 3 + 20 + 20 + 1;
463 tp
= (struct temp
*) alloc(sizeof(struct temp
) + len
, ap
);
464 tp
->name
= path
= (char *) &tp
[1];
465 tp
->shf
= (struct shf
*) 0;
467 snprintf(path
, len
, "%s/poshXXXXXX", dir
);
470 tp
->shf
= shf_fdopen(fd
, SHF_WR
, (struct shf
*) 0);