blob: 0b438a60f7abc190306163efa0b9f2b86d7692ff [file] [log] [blame] [raw]
/*
* This file has no copyright assigned and is placed in the Public Domain.
* No warranty is given.
*
* Written by Rivoreo
*
*/
#include <stdio.h>
#include <errno.h>
#include <io.h>
/* XXX: This implementation is currently broken; programs that using fdopen
* and linking to this library will fail due to the following unresolvable
* symbols. However this error is still better than allowing link to a wrong
* version of fdopen in msvcrt.dll.
*/
extern FILE *_getstream(void);
extern int _alloc_osfhnd(void);
extern int _set_osfhnd(int, intptr_t);
FILE *fdopen(int fd, const char *mode) {
#if 0
extern int __p__commode(void);
int stream_flag = *__p__commode();
#else
int stream_flag = 0;
#endif
if(fd == -1) {
errno = EBADF;
return NULL;
}
while(*mode == ' ') mode++;
switch(*mode) {
case 'r':
stream_flag |= _IOREAD;
break;
case 'w':
stream_flag |= _IOWRT;
break;
case 'a':
stream_flag |= _IOWRT;
lseek(fd, 0, SEEK_END);
break;
default:
errno = EINVAL;
return NULL;
}
while(*++mode) switch(*mode) {
case ' ':
break;
case '+':
//if(stream_flag & _IORW) goto mode_done;
stream_flag &= _IOREAD | _IOWRT;
stream_flag |= _IORW;
break;
case 'b':
// TODO
break;
default:
errno = EINVAL;
return NULL;
}
//mode_done:
FILE *r = _getstream();
if(!r) {
errno = EMFILE;
return NULL;
}
r->_file = _alloc_osfhnd();
if(r->_file == -1) {
errno = EMFILE;
return NULL;
}
_set_osfhnd(r->_file, (intptr_t)fd);
// TODO: set flags for r->_file, see "msvcrt/open.c"
r->_flag = stream_flag;
return r;
}