|
@@ -49,7 +49,7 @@ extern void _free_stdio_buffer(unsigned char *buf);
|
|
|
extern void _free_stdio_stream(FILE *fp);
|
|
|
#endif
|
|
|
|
|
|
-#ifdef L__stdio_buffer
|
|
|
+#ifdef L__alloc_stdio_buffer
|
|
|
unsigned char *_alloc_stdio_buffer(size_t size)
|
|
|
{
|
|
|
if (size == BUFSIZ) {
|
|
@@ -63,7 +63,9 @@ unsigned char *_alloc_stdio_buffer(size_t size)
|
|
|
}
|
|
|
return malloc(size);
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
+#ifdef L__free_stdio_buffer
|
|
|
void _free_stdio_buffer(unsigned char *buf)
|
|
|
{
|
|
|
int i;
|
|
@@ -117,8 +119,10 @@ FILE *_stderr = _stdio_streams + 2;
|
|
|
*/
|
|
|
FILE *__IO_list = _stdio_streams;
|
|
|
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
+ * __stdio_close_all is automatically when exiting if stdio is used.
|
|
|
+ * See misc/internals/__uClibc_main.c and and stdlib/atexit.c.
|
|
|
+ */
|
|
|
void __stdio_close_all(void)
|
|
|
{
|
|
|
FILE *fp;
|
|
@@ -129,6 +133,9 @@ void __stdio_close_all(void)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ * __init_stdio is automatically by __uClibc_main if stdio is used.
|
|
|
+ */
|
|
|
void __init_stdio(void)
|
|
|
{
|
|
|
#if (FIXED_BUFFERS > 2) || (FIXED_STREAMS > 3)
|
|
@@ -148,12 +155,13 @@ void __init_stdio(void)
|
|
|
_fixed_buffers[0].used = 1;
|
|
|
_fixed_buffers[1].used = 1;
|
|
|
|
|
|
- if (isatty(1)) {
|
|
|
- stdout->mode |= _IOLBF;
|
|
|
- }
|
|
|
+#if _IOFBF != 0 || _IOLBF != 1
|
|
|
+#error Assumption violated -- values of _IOFBF and/or _IOLBF
|
|
|
+
|
|
|
+#endif
|
|
|
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
+ _stdio_streams[1].mode |= isatty(1);
|
|
|
}
|
|
|
#endif
|
|
|
|
|
@@ -206,9 +214,18 @@ FILE *fp;
|
|
|
if (fp->mode & __MODE_WRITING)
|
|
|
fflush(fp);
|
|
|
|
|
|
+#if 1
|
|
|
+#warning Need to check out tie between stdin and stdout.
|
|
|
+
|
|
|
+ * This bit of code needs checking. The way I read the C89 standard,
|
|
|
+ * there is no guarantee that stdout is flushed before reading stdin.
|
|
|
+ * Plus, this is broken if either stdin or stdout has been closed and
|
|
|
+ * reopend.
|
|
|
+ */
|
|
|
if ( (fp == stdin) && (stdout->fd != -1)
|
|
|
&& (stdout->mode & __MODE_WRITING) )
|
|
|
fflush(stdout);
|
|
|
+#endif
|
|
|
|
|
|
|
|
|
if ((fp->mode & (__MODE_READ | __MODE_EOF | __MODE_ERR)) !=
|
|
@@ -572,32 +589,32 @@ const char *mode;
|
|
|
int fopen_mode;
|
|
|
int i;
|
|
|
|
|
|
- fopen_mode = 0;
|
|
|
+ nfp = fp;
|
|
|
|
|
|
-
|
|
|
- if (fp) {
|
|
|
- fopen_mode |=
|
|
|
- (fp->mode & (__MODE_BUF | __MODE_FREEFIL | __MODE_FREEBUF));
|
|
|
- fp->mode &= ~(__MODE_FREEFIL | __MODE_FREEBUF);
|
|
|
- fclose(fp);
|
|
|
+
|
|
|
+ if (nfp) {
|
|
|
+ fflush(nfp);
|
|
|
+ close(nfp->fd);
|
|
|
+ nfp->mode &= (__MODE_FREEFIL | __MODE_FREEBUF);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
+
|
|
|
switch (*mode++) {
|
|
|
case 'r':
|
|
|
- fopen_mode |= __MODE_READ;
|
|
|
+ fopen_mode = __MODE_READ;
|
|
|
open_mode = O_RDONLY;
|
|
|
break;
|
|
|
case 'w':
|
|
|
- fopen_mode |= __MODE_WRITE;
|
|
|
+ fopen_mode = __MODE_WRITE;
|
|
|
open_mode = (O_WRONLY | O_CREAT | O_TRUNC);
|
|
|
break;
|
|
|
case 'a':
|
|
|
- fopen_mode |= __MODE_WRITE;
|
|
|
+ fopen_mode = __MODE_WRITE;
|
|
|
open_mode = (O_WRONLY | O_CREAT | O_APPEND);
|
|
|
break;
|
|
|
default:
|
|
|
- return 0;
|
|
|
+ errno = EINVAL;
|
|
|
+ goto _fopen_ERROR;
|
|
|
}
|
|
|
|
|
|
if ((*mode == 'b')) {
|
|
@@ -618,7 +635,6 @@ const char *mode;
|
|
|
++mode;
|
|
|
}
|
|
|
|
|
|
- nfp = 0;
|
|
|
if (fp == 0) {
|
|
|
for (i = 0; i < FIXED_STREAMS; i++) {
|
|
|
if (_stdio_streams[i].fd == -1) {
|
|
@@ -629,46 +645,46 @@ const char *mode;
|
|
|
if ((i == FIXED_STREAMS) && (!(nfp = malloc(sizeof(FILE))))) {
|
|
|
return 0;
|
|
|
}
|
|
|
+ nfp->mode = __MODE_FREEFIL;
|
|
|
+
|
|
|
+ nfp->bufstart = nfp->unbuf;
|
|
|
+ nfp->bufend = nfp->unbuf + sizeof(nfp->unbuf);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
if (fname) {
|
|
|
fd = open(fname, open_mode, 0666);
|
|
|
}
|
|
|
- if (fd < 0) {
|
|
|
+#warning fdopen should check that modes are compatible with existing fd.
|
|
|
+
|
|
|
+ if (fd < 0) {
|
|
|
+ _fopen_ERROR:
|
|
|
if (nfp) {
|
|
|
+ if (nfp->mode & __MODE_FREEBUF) {
|
|
|
+ _free_stdio_buffer(nfp->bufstart);
|
|
|
+ }
|
|
|
_free_stdio_stream(nfp);
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+ nfp->fd = fd;
|
|
|
+
|
|
|
if (fp == 0) {
|
|
|
- fp = nfp;
|
|
|
- fp->next = __IO_list;
|
|
|
- __IO_list = fp;
|
|
|
-
|
|
|
- fp->mode = __MODE_FREEFIL;
|
|
|
- if (!(fp->bufstart = _alloc_stdio_buffer(BUFSIZ))) {
|
|
|
-
|
|
|
- fp->bufstart = fp->unbuf;
|
|
|
- fp->bufend = fp->unbuf + sizeof(fp->unbuf);
|
|
|
- } else {
|
|
|
- fp->bufend = fp->bufstart + BUFSIZ;
|
|
|
- fp->mode |= __MODE_FREEBUF;
|
|
|
- }
|
|
|
- }
|
|
|
+ nfp->next = __IO_list;
|
|
|
+ __IO_list = nfp;
|
|
|
|
|
|
- if (isatty(fd)) {
|
|
|
- fp->mode |= _IOLBF;
|
|
|
- } else {
|
|
|
- fp->mode |= _IOFBF;
|
|
|
+ if ((nfp->bufstart = _alloc_stdio_buffer(BUFSIZ)) != 0) {
|
|
|
+ nfp->bufend = nfp->bufstart + BUFSIZ;
|
|
|
+ nfp->mode |= __MODE_FREEBUF;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|
|
|
- fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart;
|
|
|
- fp->mode |= fopen_mode;
|
|
|
- fp->fd = fd;
|
|
|
- return fp;
|
|
|
+ nfp->bufpos = nfp->bufread = nfp->bufwrite = nfp->bufstart;
|
|
|
+ nfp->mode |= fopen_mode;
|
|
|
+ nfp->mode |= isatty(fd);
|
|
|
+
|
|
|
+ return nfp;
|
|
|
}
|
|
|
#endif
|
|
|
|
|
@@ -688,33 +704,38 @@ FILE *fp;
|
|
|
rv = EOF;
|
|
|
}
|
|
|
|
|
|
- if (fp->mode & __MODE_FREEBUF) {
|
|
|
+ if (fp->mode & __MODE_FREEBUF) {
|
|
|
_free_stdio_buffer(fp->bufstart);
|
|
|
}
|
|
|
|
|
|
- if (fp->mode & __MODE_FREEFIL) {
|
|
|
- prev = 0;
|
|
|
- for (ptr = __IO_list; ptr ; ptr = ptr->next) {
|
|
|
- if (ptr == fp) {
|
|
|
- if (prev == 0) {
|
|
|
- __IO_list = fp->next;
|
|
|
- } else {
|
|
|
- prev->next = fp->next;
|
|
|
- }
|
|
|
- _free_stdio_stream(fp);
|
|
|
- break;
|
|
|
+ prev = 0;
|
|
|
+ for (ptr = __IO_list; ptr ; ptr = ptr->next) {
|
|
|
+ if (ptr == fp) {
|
|
|
+ if (prev == 0) {
|
|
|
+ __IO_list = fp->next;
|
|
|
+ } else {
|
|
|
+ prev->next = fp->next;
|
|
|
}
|
|
|
- prev = ptr;
|
|
|
+ break;
|
|
|
}
|
|
|
+ prev = ptr;
|
|
|
}
|
|
|
|
|
|
+ _free_stdio_stream(fp);
|
|
|
+
|
|
|
return rv;
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
-
|
|
|
+#ifdef L__free_stdio_stream
|
|
|
+
|
|
|
void _free_stdio_stream(FILE *fp)
|
|
|
{
|
|
|
int i;
|
|
|
+
|
|
|
+ if (!(fp->mode & __MODE_FREEFIL)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
for (i = 0; i < FIXED_STREAMS; i++) {
|
|
|
if (fp == _stdio_streams + i) {
|