![]() |
| | #1 |
| Registered User Join Date: Feb 2009
Posts: 31
| The UNIX System Interface It seems to only be printing from the buffer once and then fails to reuse it after it's been flushed. At least I think that's whats happening. I wrote a small test program to test my header and it should print more than 1024 bytes which is the size of my buffer. I manually counted the output and it stops at 1021. I just can't figure it out. I'd appreciate any help you guys can give me. Header: Code: /* Exercise 8-3. Design and write _flushbuf, fflush, and fclose. */
#define NULL 0
#define EOF (-1)
#define BUFSIZ 1024
#define OPEN_MAX 20 /* max #files open at once */
typedef struct _iobuf
{
int cnt; /* characters left */
char *ptr; /* next character position */
char *base; /* location of buffer */
int flag; /* mode of file access */
int fd; /* file descriptor */
} FILE_;
FILE_ _iob[OPEN_MAX];
#define stdin (&_iob[0])
#define stdout (&_iob[1])
#define stderr (&_iob[2])
enum _flags
{
_READ = 01, /* file open for reading */
_WRITE = 02, /* file open for writing */
_UNBUF = 04, /* file is unbuffered */
_EOF = 010, /* EOF has occurred on this file */
_ERR = 020 /* error occurred on this file */
};
FILE_ *_fopen(char *, char *);
int _fillbuf(FILE_ *);
int _flushbuf(int, FILE_ *);
int _fflush(FILE_ *);
int _fclose(FILE_ *);
#define feof(p) ((p)->flag & _EOF) != 0)
#define ferror(p) ((p)->flag & _ERR) != 0)
#define fileno(p) ((p)->fd)
#define getc(p) (--(p)->cnt >= 0 \
? (unsigned char) *(p)->ptr++ : _fillbuf(p))
#define putc(x,p) (--(p)->cnt >= 0 \
? *(p)->ptr++ = (x) : _flushbuf((x),p))
#define getchar() getc(stdin)
#define putcher(x) putc((x), stdout)
#include <fcntl.h>
#define PERMS 0666 /* RW for owner, group, others */
FILE_ *_fopen(char *name, char *mode)
{
int fd;
FILE_ *fp;
if (*mode != 'r' && *mode != 'w' && *mode != 'a')
return NULL;
for (fp = _iob; fp < _iob + OPEN_MAX; fp++)
if ((fp->flag & (_READ | _WRITE)) == 0)
break; /* found free slot */
if (fp >= _iob + OPEN_MAX) /* no free slots */
return NULL;
if (*mode == 'w')
fd = creat(name, PERMS);
else if (*mode == 'a')
{
if ((fd = open(name, O_WRONLY, 0)) == -1)
fd = creat(name, PERMS);
lseek(fd, 0L, 2);
}
else
fd = open(name, O_RDONLY, 0);
if (fd == -1) /* couldn't access name */
return NULL;
fp->fd = fd;
fp->cnt = 0;
fp->base = NULL;
fp->flag = (*mode == 'r') ? _READ : _WRITE;
return fp;
}
#include <stdlib.h>
/* _fillbuf: allocate and fill input buffer */
int _fillbuf(FILE_ *fp)
{
int bufsize;
if ((fp->flag&(_READ|_EOF|_ERR)) != _READ)
return EOF;
bufsize = (fp->flag & _UNBUF) ? 1 : BUFSIZ;
if (fp->base == NULL) /* no buffer yet */
if ((fp->base = (char *) malloc(bufsize)) == NULL)
return EOF; /* can't get buffer */
fp->ptr = fp->base;
fp->cnt = read(fp->fd, fp->ptr, bufsize);
if (--fp->cnt < 0)
{
if (fp->cnt == -1)
fp->flag |= _EOF;
else
fp->flag |= _ERR;
fp->cnt = 0;
return EOF;
}
return (unsigned char) *fp->ptr++;
}
int _flushbuf(int c, FILE_ *fp)
{
int bufsize;
unsigned char uc = c;
if (fp->flag & (_WRITE | _EOF | _ERR) != _WRITE)
return EOF;
bufsize = (fp->flag & _UNBUF) ? 1 : BUFSIZ;
if (fp->base == NULL)
if ((fp->base = (char *) malloc(bufsize)) == NULL)
return EOF;
if (bufsize == BUFSIZ && fp->ptr != 0)
{
if (write(fp->fd, fp->base, BUFSIZ) != BUFSIZ)
return EOF;
}
else if (fp->ptr != 0)
if (write(fp->fd, fp->base, 1) != 1)
return EOF;
fp->ptr = fp->base;
*fp->ptr++ = uc;
fp->cnt = BUFSIZ-1;
return uc;
}
int _fflush(FILE_ *fp)
{
int strm;
if (fp->flag & (_WRITE | _EOF | _ERR) != _WRITE)
return EOF;
if (fp == NULL)
for (strm = 0; _iob[strm].flag != 0; ++strm)
if (write(fp->fd, fp->ptr, (fp->ptr-fp->base)) != fp->cnt)
return EOF;
else
if (write(fp->fd, fp->ptr, (fp->ptr-fp->base)) != fp->cnt)
return EOF;
return 0;
}
int _fclose(FILE_ *fp)
{
if (fp->flag & _ERR)
return EOF;
if (fp->flag & _WRITE)
fflush(fp);
free(fp->base);
close(fp->fd);
return 0;
}
FILE_ _iob[OPEN_MAX] = { /* stdin, stdout, stderr */
{ 0, (char *) 0, (char *) 0, _READ, 0 },
{ 0, (char *) 0, (char *) 0, _WRITE, 1 },
{ 0, (char *) 0, (char *) 0, _WRITE | _UNBUF, 2 },
{ 0, (char *) 0, (char *) 0, 0, 0 },
{ 0, (char *) 0, (char *) 0, 0, 0 },
{ 0, (char *) 0, (char *) 0, 0, 0 },
{ 0, (char *) 0, (char *) 0, 0, 0 },
{ 0, (char *) 0, (char *) 0, 0, 0 },
{ 0, (char *) 0, (char *) 0, 0, 0 },
{ 0, (char *) 0, (char *) 0, 0, 0 },
{ 0, (char *) 0, (char *) 0, 0, 0 },
{ 0, (char *) 0, (char *) 0, 0, 0 },
{ 0, (char *) 0, (char *) 0, 0, 0 },
{ 0, (char *) 0, (char *) 0, 0, 0 },
{ 0, (char *) 0, (char *) 0, 0, 0 },
{ 0, (char *) 0, (char *) 0, 0, 0 },
{ 0, (char *) 0, (char *) 0, 0, 0 },
{ 0, (char *) 0, (char *) 0, 0, 0 },
{ 0, (char *) 0, (char *) 0, 0, 0 },
{ 0, (char *) 0, (char *) 0, 0, 0 }
};
Code: /* Exercise 8-3. Design and write _flushbuf, fflush, and fclose. */
#include "exercise.8-3.h"
/* cat: concatenate files, version 1 */
main(int argc, char *argv[])
{
FILE_ *fp;
void filecopy(FILE_ *, FILE_ *);
if (argc == 1) /* no args; copy standard input */
filecopy(stdin, stdout);
else
while(--argc > 0)
if ((fp = _fopen(*++argv, "r")) == NULL)
{
putc('X', stderr);
return 1;
}
else
{
filecopy(fp, stdout);
_fclose(fp);
}
return 0;
}
/* filecopy: copy file ifp to file ofp */
void filecopy(FILE_ *ifp, FILE_ *ofp)
{
int c;
while ((c = getc(ifp)) != EOF)
putc(c, ofp);
}
|
| rrc55 is offline | |
| | #2 |
| Registered User Join Date: Feb 2009
Posts: 31
| Here's the macro and suspect function by themselves: Code: #define putc(x,p) (--(p)->cnt >= 0 \
? *(p)->ptr++ = (x) : _flushbuf((x),p))
int _flushbuf(int c, FILE_ *fp)
{
int bufsize;
unsigned char uc = c;
if (fp->flag & (_WRITE | _EOF | _ERR) != _WRITE)
return EOF;
bufsize = (fp->flag & _UNBUF) ? 1 : BUFSIZ;
if (fp->base == NULL)
if ((fp->base = (char *) malloc(bufsize)) == NULL)
return EOF;
if (bufsize == BUFSIZ && fp->ptr != 0)
{
if (write(fp->fd, fp->base, BUFSIZ) != BUFSIZ)
return EOF;
}
else if (fp->ptr != 0)
if (write(fp->fd, fp->base, 1) != 1)
return EOF;
fp->ptr = fp->base;
*fp->ptr++ = uc;
fp->cnt = BUFSIZ-1;
return uc;
}
|
| rrc55 is offline | |
![]() |
| Tags |
| code |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Calling IRichEditOle interface methods | Niara | C Programming | 2 | 01-16-2009 01:23 PM |
| How to get the user ID and group ID from UNIX system | dragonfly1801 | Linux Programming | 6 | 11-16-2006 04:45 AM |
| Linux Media Player | joshdick | A Brief History of Cprogramming.com | 43 | 09-07-2003 08:08 AM |
| problem with lseek system call on unix | kheinz | C Programming | 2 | 06-03-2003 12:50 PM |
| question about open file in unix system | wu7up | C Programming | 6 | 03-13-2003 06:20 AM |