Differentiate between file pointers and file descriptors.
This commit is contained in:
Родитель
dd5c0f51c7
Коммит
0dbab8bac7
|
@ -52,32 +52,33 @@ LibraryManager.library = {
|
|||
___setErrNo(ERRNO_CODES.ENOTDIR);
|
||||
return 0;
|
||||
}
|
||||
var err = _open(dirname, {{{ cDefine('O_RDONLY') }}}, allocate([0, 0, 0, 0], 'i32', ALLOC_STACK));
|
||||
// open returns 0 on failure, not -1
|
||||
return err === -1 ? 0 : err;
|
||||
var fd = _open(dirname, {{{ cDefine('O_RDONLY') }}}, allocate([0, 0, 0, 0], 'i32', ALLOC_STACK));
|
||||
return fd === -1 ? 0 : FS.getPtrForStream(FS.getStream(fd));
|
||||
},
|
||||
closedir__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', 'close'],
|
||||
closedir__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', 'close', 'fileno'],
|
||||
closedir: function(dirp) {
|
||||
// int closedir(DIR *dirp);
|
||||
// http://pubs.opengroup.org/onlinepubs/007908799/xsh/closedir.html
|
||||
return _close(dirp);
|
||||
var fd = _fileno(dirp);
|
||||
return _close(fd);
|
||||
},
|
||||
telldir__deps: ['$FS', '__setErrNo', '$ERRNO_CODES'],
|
||||
telldir: function(dirp) {
|
||||
// long int telldir(DIR *dirp);
|
||||
// http://pubs.opengroup.org/onlinepubs/007908799/xsh/telldir.html
|
||||
var stream = FS.getStream(dirp);
|
||||
var stream = FS.getStreamFromPtr(dirp);
|
||||
if (!stream || !FS.isDir(stream.node.mode)) {
|
||||
___setErrNo(ERRNO_CODES.EBADF);
|
||||
return -1;
|
||||
}
|
||||
return stream.position;
|
||||
},
|
||||
seekdir__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', 'lseek'],
|
||||
seekdir__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', 'lseek', 'fileno'],
|
||||
seekdir: function(dirp, loc) {
|
||||
// void seekdir(DIR *dirp, long int loc);
|
||||
// http://pubs.opengroup.org/onlinepubs/007908799/xsh/seekdir.html
|
||||
_lseek(dirp, loc, {{{ cDefine('SEEK_SET') }}});
|
||||
var fd = _fileno(dirp);
|
||||
_lseek(fd, loc, {{{ cDefine('SEEK_SET') }}});
|
||||
},
|
||||
rewinddir__deps: ['seekdir'],
|
||||
rewinddir: function(dirp) {
|
||||
|
@ -89,7 +90,7 @@ LibraryManager.library = {
|
|||
readdir_r: function(dirp, entry, result) {
|
||||
// int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
|
||||
// http://pubs.opengroup.org/onlinepubs/007908799/xsh/readdir_r.html
|
||||
var stream = FS.getStream(dirp);
|
||||
var stream = FS.getStreamFromPtr(dirp);
|
||||
if (!stream) {
|
||||
return ___setErrNo(ERRNO_CODES.EBADF);
|
||||
}
|
||||
|
@ -134,7 +135,7 @@ LibraryManager.library = {
|
|||
readdir: function(dirp) {
|
||||
// struct dirent *readdir(DIR *dirp);
|
||||
// http://pubs.opengroup.org/onlinepubs/007908799/xsh/readdir_r.html
|
||||
var stream = FS.getStream(dirp);
|
||||
var stream = FS.getStreamFromPtr(dirp);
|
||||
if (!stream) {
|
||||
___setErrNo(ERRNO_CODES.EBADF);
|
||||
return 0;
|
||||
|
@ -2290,19 +2291,20 @@ LibraryManager.library = {
|
|||
clearerr: function(stream) {
|
||||
// void clearerr(FILE *stream);
|
||||
// http://pubs.opengroup.org/onlinepubs/000095399/functions/clearerr.html
|
||||
stream = FS.getStream(stream);
|
||||
stream = FS.getStreamFromPtr(stream);
|
||||
if (!stream) {
|
||||
return;
|
||||
}
|
||||
stream.eof = false;
|
||||
stream.error = false;
|
||||
},
|
||||
fclose__deps: ['close', 'fsync'],
|
||||
fclose__deps: ['close', 'fsync', 'fileno'],
|
||||
fclose: function(stream) {
|
||||
// int fclose(FILE *stream);
|
||||
// http://pubs.opengroup.org/onlinepubs/000095399/functions/fclose.html
|
||||
_fsync(stream);
|
||||
return _close(stream);
|
||||
var fd = _fileno(stream);
|
||||
_fsync(fd);
|
||||
return _close(fd);
|
||||
},
|
||||
fdopen__deps: ['$FS', '__setErrNo', '$ERRNO_CODES'],
|
||||
fdopen: function(fildes, mode) {
|
||||
|
@ -2323,21 +2325,21 @@ LibraryManager.library = {
|
|||
} else {
|
||||
stream.error = false;
|
||||
stream.eof = false;
|
||||
return fildes;
|
||||
return FS.getPtrForStream(stream);
|
||||
}
|
||||
},
|
||||
feof__deps: ['$FS'],
|
||||
feof: function(stream) {
|
||||
// int feof(FILE *stream);
|
||||
// http://pubs.opengroup.org/onlinepubs/000095399/functions/feof.html
|
||||
stream = FS.getStream(stream);
|
||||
stream = FS.getStreamFromPtr(stream);
|
||||
return Number(stream && stream.eof);
|
||||
},
|
||||
ferror__deps: ['$FS'],
|
||||
ferror: function(stream) {
|
||||
// int ferror(FILE *stream);
|
||||
// http://pubs.opengroup.org/onlinepubs/000095399/functions/ferror.html
|
||||
stream = FS.getStream(stream);
|
||||
stream = FS.getStreamFromPtr(stream);
|
||||
return Number(stream && stream.error);
|
||||
},
|
||||
fflush__deps: ['$FS', '__setErrNo', '$ERRNO_CODES'],
|
||||
|
@ -2351,7 +2353,7 @@ LibraryManager.library = {
|
|||
fgetc: function(stream) {
|
||||
// int fgetc(FILE *stream);
|
||||
// http://pubs.opengroup.org/onlinepubs/000095399/functions/fgetc.html
|
||||
var streamObj = FS.getStream(stream);
|
||||
var streamObj = FS.getStreamFromPtr(stream);
|
||||
if (!streamObj) return -1;
|
||||
if (streamObj.eof || streamObj.error) return -1;
|
||||
var ret = _fread(_fgetc.ret, 1, 1, stream);
|
||||
|
@ -2376,7 +2378,7 @@ LibraryManager.library = {
|
|||
fgetpos: function(stream, pos) {
|
||||
// int fgetpos(FILE *restrict stream, fpos_t *restrict pos);
|
||||
// http://pubs.opengroup.org/onlinepubs/000095399/functions/fgetpos.html
|
||||
stream = FS.getStream(stream);
|
||||
stream = FS.getStreamFromPtr(stream);
|
||||
if (!stream) {
|
||||
___setErrNo(ERRNO_CODES.EBADF);
|
||||
return -1;
|
||||
|
@ -2394,7 +2396,7 @@ LibraryManager.library = {
|
|||
fgets: function(s, n, stream) {
|
||||
// char *fgets(char *restrict s, int n, FILE *restrict stream);
|
||||
// http://pubs.opengroup.org/onlinepubs/000095399/functions/fgets.html
|
||||
var streamObj = FS.getStream(stream);
|
||||
var streamObj = FS.getStreamFromPtr(stream);
|
||||
if (!streamObj) return 0;
|
||||
if (streamObj.error || streamObj.eof) return 0;
|
||||
var byte_;
|
||||
|
@ -2418,8 +2420,7 @@ LibraryManager.library = {
|
|||
fileno: function(stream) {
|
||||
// int fileno(FILE *stream);
|
||||
// http://pubs.opengroup.org/onlinepubs/000095399/functions/fileno.html
|
||||
// We use file descriptor numbers and FILE* streams interchangeably.
|
||||
return stream;
|
||||
return FS.getStreamFromPtr(stream).fd;
|
||||
},
|
||||
ftrylockfile: function() {
|
||||
// int ftrylockfile(FILE *file);
|
||||
|
@ -2461,19 +2462,20 @@ LibraryManager.library = {
|
|||
___setErrNo(ERRNO_CODES.EINVAL);
|
||||
return 0;
|
||||
}
|
||||
var ret = _open(filename, flags, allocate([0x1FF, 0, 0, 0], 'i32', ALLOC_STACK)); // All creation permissions.
|
||||
return (ret == -1) ? 0 : ret;
|
||||
var fd = _open(filename, flags, allocate([0x1FF, 0, 0, 0], 'i32', ALLOC_STACK)); // All creation permissions.
|
||||
return fd === -1 ? 0 : FS.getPtrForStream(FS.getStream(fd));
|
||||
},
|
||||
fputc__deps: ['$FS', 'write'],
|
||||
fputc__deps: ['$FS', 'write', 'fileno'],
|
||||
fputc__postset: '_fputc.ret = allocate([0], "i8", ALLOC_STATIC);',
|
||||
fputc: function(c, stream) {
|
||||
// int fputc(int c, FILE *stream);
|
||||
// http://pubs.opengroup.org/onlinepubs/000095399/functions/fputc.html
|
||||
var chr = unSign(c & 0xFF);
|
||||
{{{ makeSetValue('_fputc.ret', '0', 'chr', 'i8') }}};
|
||||
var ret = _write(stream, _fputc.ret, 1);
|
||||
var fd = _fileno(stream);
|
||||
var ret = _write(fd, _fputc.ret, 1);
|
||||
if (ret == -1) {
|
||||
var streamObj = FS.getStream(stream);
|
||||
var streamObj = FS.getStreamFromPtr(stream);
|
||||
if (streamObj) streamObj.error = true;
|
||||
return -1;
|
||||
} else {
|
||||
|
@ -2489,11 +2491,12 @@ LibraryManager.library = {
|
|||
return _fputc(c, {{{ makeGetValue(makeGlobalUse('_stdout'), '0', 'void*') }}});
|
||||
},
|
||||
putchar_unlocked: 'putchar',
|
||||
fputs__deps: ['write', 'strlen'],
|
||||
fputs__deps: ['write', 'strlen', 'fileno'],
|
||||
fputs: function(s, stream) {
|
||||
// int fputs(const char *restrict s, FILE *restrict stream);
|
||||
// http://pubs.opengroup.org/onlinepubs/000095399/functions/fputs.html
|
||||
return _write(stream, s, _strlen(s));
|
||||
var fd = _fileno(stream);
|
||||
return _write(fd, s, _strlen(s));
|
||||
},
|
||||
puts__deps: ['fputs', 'fputc', 'stdout'],
|
||||
puts: function(s) {
|
||||
|
@ -2518,7 +2521,7 @@ LibraryManager.library = {
|
|||
return 0;
|
||||
}
|
||||
var bytesRead = 0;
|
||||
var streamObj = FS.getStream(stream);
|
||||
var streamObj = FS.getStreamFromPtr(stream);
|
||||
if (!streamObj) {
|
||||
___setErrNo(ERRNO_CODES.EBADF);
|
||||
return 0;
|
||||
|
@ -2528,7 +2531,7 @@ LibraryManager.library = {
|
|||
bytesToRead--;
|
||||
bytesRead++;
|
||||
}
|
||||
var err = _read(stream, ptr, bytesToRead);
|
||||
var err = _read(streamObj.fd, ptr, bytesToRead);
|
||||
if (err == -1) {
|
||||
if (streamObj) streamObj.error = true;
|
||||
return 0;
|
||||
|
@ -2542,7 +2545,7 @@ LibraryManager.library = {
|
|||
// FILE *freopen(const char *restrict filename, const char *restrict mode, FILE *restrict stream);
|
||||
// http://pubs.opengroup.org/onlinepubs/000095399/functions/freopen.html
|
||||
if (!filename) {
|
||||
var streamObj = FS.getStream(stream);
|
||||
var streamObj = FS.getStreamFromPtr(stream);
|
||||
if (!streamObj) {
|
||||
___setErrNo(ERRNO_CODES.EBADF);
|
||||
return 0;
|
||||
|
@ -2554,15 +2557,16 @@ LibraryManager.library = {
|
|||
_fclose(stream);
|
||||
return _fopen(filename, mode);
|
||||
},
|
||||
fseek__deps: ['$FS', 'lseek'],
|
||||
fseek__deps: ['$FS', 'lseek', 'fileno'],
|
||||
fseek: function(stream, offset, whence) {
|
||||
// int fseek(FILE *stream, long offset, int whence);
|
||||
// http://pubs.opengroup.org/onlinepubs/000095399/functions/fseek.html
|
||||
var ret = _lseek(stream, offset, whence);
|
||||
var fd = _fileno(stream);
|
||||
var ret = _lseek(fd, offset, whence);
|
||||
if (ret == -1) {
|
||||
return -1;
|
||||
}
|
||||
stream = FS.getStream(stream);
|
||||
stream = FS.getStreamFromPtr(stream);
|
||||
stream.eof = false;
|
||||
return 0;
|
||||
},
|
||||
|
@ -2571,7 +2575,7 @@ LibraryManager.library = {
|
|||
fsetpos: function(stream, pos) {
|
||||
// int fsetpos(FILE *stream, const fpos_t *pos);
|
||||
// http://pubs.opengroup.org/onlinepubs/000095399/functions/fsetpos.html
|
||||
stream = FS.getStream(stream);
|
||||
stream = FS.getStreamFromPtr(stream);
|
||||
if (!stream) {
|
||||
___setErrNo(ERRNO_CODES.EBADF);
|
||||
return -1;
|
||||
|
@ -2590,7 +2594,7 @@ LibraryManager.library = {
|
|||
ftell: function(stream) {
|
||||
// long ftell(FILE *stream);
|
||||
// http://pubs.opengroup.org/onlinepubs/000095399/functions/ftell.html
|
||||
stream = FS.getStream(stream);
|
||||
stream = FS.getStreamFromPtr(stream);
|
||||
if (!stream) {
|
||||
___setErrNo(ERRNO_CODES.EBADF);
|
||||
return -1;
|
||||
|
@ -2603,15 +2607,16 @@ LibraryManager.library = {
|
|||
}
|
||||
},
|
||||
ftello: 'ftell',
|
||||
fwrite__deps: ['$FS', 'write'],
|
||||
fwrite__deps: ['$FS', 'write', 'fileno'],
|
||||
fwrite: function(ptr, size, nitems, stream) {
|
||||
// size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream);
|
||||
// http://pubs.opengroup.org/onlinepubs/000095399/functions/fwrite.html
|
||||
var bytesToWrite = nitems * size;
|
||||
if (bytesToWrite == 0) return 0;
|
||||
var bytesWritten = _write(stream, ptr, bytesToWrite);
|
||||
var fd = _fileno(stream);
|
||||
var bytesWritten = _write(fd, ptr, bytesToWrite);
|
||||
if (bytesWritten == -1) {
|
||||
var streamObj = FS.getStream(stream);
|
||||
var streamObj = FS.getStreamFromPtr(stream);
|
||||
if (streamObj) streamObj.error = true;
|
||||
return 0;
|
||||
} else {
|
||||
|
@ -2674,7 +2679,7 @@ LibraryManager.library = {
|
|||
// void rewind(FILE *stream);
|
||||
// http://pubs.opengroup.org/onlinepubs/000095399/functions/rewind.html
|
||||
_fseek(stream, 0, 0); // SEEK_SET.
|
||||
var streamObj = FS.getStream(stream);
|
||||
var streamObj = FS.getStreamFromPtr(stream);
|
||||
if (streamObj) streamObj.error = false;
|
||||
},
|
||||
setvbuf: function(stream, buf, type, size) {
|
||||
|
@ -2731,7 +2736,7 @@ LibraryManager.library = {
|
|||
ungetc: function(c, stream) {
|
||||
// int ungetc(int c, FILE *stream);
|
||||
// http://pubs.opengroup.org/onlinepubs/000095399/functions/ungetc.html
|
||||
stream = FS.getStream(stream);
|
||||
stream = FS.getStreamFromPtr(stream);
|
||||
if (!stream) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -2756,7 +2761,7 @@ LibraryManager.library = {
|
|||
fscanf: function(stream, format, varargs) {
|
||||
// int fscanf(FILE *restrict stream, const char *restrict format, ... );
|
||||
// http://pubs.opengroup.org/onlinepubs/000095399/functions/scanf.html
|
||||
var streamObj = FS.getStream(stream);
|
||||
var streamObj = FS.getStreamFromPtr(stream);
|
||||
if (!streamObj) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -2899,7 +2904,7 @@ LibraryManager.library = {
|
|||
// ==========================================================================
|
||||
|
||||
mmap__deps: ['$FS'],
|
||||
mmap: function(start, num, prot, flags, stream, offset) {
|
||||
mmap: function(start, num, prot, flags, fd, offset) {
|
||||
/* FIXME: Since mmap is normally implemented at the kernel level,
|
||||
* this implementation simply uses malloc underneath the call to
|
||||
* mmap.
|
||||
|
@ -2910,13 +2915,13 @@ LibraryManager.library = {
|
|||
|
||||
if (!_mmap.mappings) _mmap.mappings = {};
|
||||
|
||||
if (stream == -1) {
|
||||
if (fd == -1) {
|
||||
ptr = _malloc(num);
|
||||
if (!ptr) return -1;
|
||||
_memset(ptr, 0, num);
|
||||
allocated = true;
|
||||
} else {
|
||||
var info = FS.getStream(stream);
|
||||
var info = FS.getStream(fd);
|
||||
if (!info) return -1;
|
||||
try {
|
||||
var res = FS.mmap(info, HEAPU8, start, num, offset, prot, flags);
|
||||
|
|
|
@ -413,6 +413,22 @@ mergeInto(LibraryManager.library, {
|
|||
FS.streams[fd] = null;
|
||||
},
|
||||
|
||||
//
|
||||
// file pointers
|
||||
//
|
||||
// instead of maintaining a separate mapping from FILE* to file descriptors,
|
||||
// we employ a simple trick: the pointer to a stream is its fd plus 1. This
|
||||
// means that all valid streams have a valid non-zero pointer while allowing
|
||||
// the fs for stdin to be the standard value of zero.
|
||||
//
|
||||
//
|
||||
getStreamFromPtr: function(ptr) {
|
||||
return FS.streams[ptr - 1];
|
||||
},
|
||||
getPtrForStream: function(stream) {
|
||||
return stream ? stream.fd + 1 : 0;
|
||||
},
|
||||
|
||||
//
|
||||
// devices
|
||||
//
|
||||
|
@ -1166,15 +1182,15 @@ mergeInto(LibraryManager.library, {
|
|||
|
||||
// open default streams for the stdin, stdout and stderr devices
|
||||
var stdin = FS.open('/dev/stdin', 'r');
|
||||
{{{ makeSetValue(makeGlobalUse('_stdin'), 0, 'stdin.fd', 'void*') }}};
|
||||
{{{ makeSetValue(makeGlobalUse('_stdin'), 0, 'FS.getPtrForStream(stdin)', 'void*') }}};
|
||||
assert(stdin.fd === 0, 'invalid handle for stdin (' + stdin.fd + ')');
|
||||
|
||||
var stdout = FS.open('/dev/stdout', 'w');
|
||||
{{{ makeSetValue(makeGlobalUse('_stdout'), 0, 'stdout.fd', 'void*') }}};
|
||||
{{{ makeSetValue(makeGlobalUse('_stdout'), 0, 'FS.getPtrForStream(stdout)', 'void*') }}};
|
||||
assert(stdout.fd === 1, 'invalid handle for stdout (' + stdout.fd + ')');
|
||||
|
||||
var stderr = FS.open('/dev/stderr', 'w');
|
||||
{{{ makeSetValue(makeGlobalUse('_stderr'), 0, 'stderr.fd', 'void*') }}};
|
||||
{{{ makeSetValue(makeGlobalUse('_stderr'), 0, 'FS.getPtrForStream(stderr)', 'void*') }}};
|
||||
assert(stderr.fd === 2, 'invalid handle for stderr (' + stderr.fd + ')');
|
||||
},
|
||||
ensureErrnoError: function() {
|
||||
|
|
Загрузка…
Ссылка в новой задаче