home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
gnu
/
pdksh-src.lha
/
src
/
amiga
/
pdksh
/
sh
/
io.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-12-01
|
4KB
|
244 lines
/*
* shell buffered IO and formatted output
*/
#ifndef lint
static char *RCSid = "$Id: io.c,v 1.2 1992/04/25 08:33:28 sjg Exp $";
#endif
#include "stdh.h"
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <setjmp.h>
#ifdef __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include "sh.h"
#if 0
/* fputc with ^ escaping */
static void
fzotc(c, f)
register int c;
register FILE *f;
{
if ((c&0x60) == 0) { /* C0|C1 */
putc((c&0x80) ? '$' : '^', f);
putc((c&0x7F|0x40), f);
} else if ((c&0x7F) == 0x7F) { /* DEL */
putc((c&0x80) ? '$' : '^', f);
putc('?', f);
} else
putc(c, f);
}
#endif
/*
* formatted output functions
*/
/* shellf(...); error() */
int
#ifdef __STDC__
errorf(const char *fmt, ...) {
#else
errorf(va_alist) va_dcl
{
char *fmt;
#endif
va_list va;
#ifdef __STDC__
va_start(va, fmt);
#else
va_start(va);
fmt = va_arg(va, char *);
#endif
vfprintf(shlout, fmt, va);
va_end(va);
/*fflush(shlout);*/
error();
}
/* printf to shlout (stderr) */
int
#ifdef __STDC__
shellf(const char *fmt, ...) {
#else
shellf(va_alist) va_dcl
{
char *fmt;
#endif
va_list va;
#ifdef __STDC__
va_start(va, fmt);
#else
va_start(va);
fmt = va_arg(va, char *);
#endif
vfprintf(shlout, fmt, va);
va_end(va);
return 0;
}
/*
* We have a stdio stream for any open shell file descriptors (0-9)
*/
FILE * shf [NUFILE]; /* map shell fd to FILE * */
/* open stream for shell fd */
void
fopenshf(fd)
int fd;
{
if (shf[fd] != NULL)
return;
#ifndef amigados
if (fd <= 2)
#ifdef _MINIX
/* ? */;
#else
_iob[fd]._flag = 0; /* re-use stdin, stdout, stderr */
#endif
#else
if (fd <= 2)
shf[fd] = (fd == 0) ? __sF[0] : (fd == 1 ? __sF[1] : __sF[2]);
else
#endif
/* "r+" is too lazy.. modern stdio implementation don't allow you
to open a O_RDONLY file this way, nor a O_WRONLY one... */
#ifdef amigados
{
int mode = fcntl (fd, F_GETFL, 0);
if (mode >= 0)
switch (mode & 3)
{
case 0:
shf[fd] = fdopen (fd, "r");
break;
case 1:
shf[fd] = fdopen (fd, "w");
break;
case 2:
shf[fd] = fdopen (fd, "r+");
break;
}
else
shf[fd] = 0;
}
#else
shf[fd] = fdopen(fd, "r+");
#endif
if (shf[fd] == NULL)
return;
setvbuf(shf[fd], (char*)NULL, _IOFBF, (size_t)BUFSIZ);
}
/* flush stream assoc with fd */
/* this must invalidate input and output buffers */
void
flushshf(fd)
int fd;
{
if (shf[fd] != NULL) {
#ifndef amigados
/* if you do this with BSD4.4 stdio, weird things start
to happen to your output.. don't know why, that's just
the way it is ;-(( */
fseek(shf[fd], 0L, 1); /* V7 derived */
#endif
fflush(shf[fd]); /* standard C */
}
}
/*
* move fd from user space (0<=fd<10) to shell space (fd>=10)
*/
int
savefd(fd)
int fd;
{
int nfd;
if (fd < FDBASE) {
flushshf(fd);
nfd = fcntl(fd, F_DUPFD, FDBASE);
if (nfd < 0)
if (errno == EBADF)
return -1;
else
errorf("too many files open in shell\n");
#ifdef F_SETFD
(void) fcntl(nfd, F_SETFD, 1);
#else
(void) fd_clexec(ttyfd);
#endif
close(fd);
} else
nfd = fd;
return nfd;
}
void
restfd(fd, ofd)
int fd, ofd;
{
if (ofd == 0) /* not saved (e.savefd) */
return;
flushshf(fd);
close(fd);
if (ofd < 0) /* original fd closed */
return;
(void) fcntl(ofd, F_DUPFD, fd);
close(ofd);
}
void
openpipe(pv)
register int *pv;
{
if (pipe(pv) < 0)
errorf("can't create pipe - try again\n");
pv[0] = savefd(pv[0]);
pv[1] = savefd(pv[1]);
}
void
closepipe(pv)
register int *pv;
{
close(pv[0]);
close(pv[1]);
}
/*
* temporary files
*/
struct temp *
maketemp(ap)
Area *ap;
{
register struct temp *tp;
static unsigned int inc = 0;
char path [PATH];
sprintf(path, "/tmp/sh%05u%02u", (unsigned)getpid(), inc++);
#if defined(_SYSV) || defined(_BSD)
close(creat(path, 0600)); /* to get appropriate permissions */
#endif
tp = (struct temp *) alloc(sizeof(struct temp), ap);
tp->next = NULL;
tp->name = strsave(path, ap);
return tp;
}