Пример #1
0
// Closes a stdio stream after flushing the stream and freeing any buffer
// associated with the stream (unless the buffer was set with setbuf).  Returns
// zero on success; EOF on failure (e.g., if the flush fails, or it is not a
// valid fileo or the file is not open, etc.).
extern "C" int __cdecl fclose(FILE* const public_stream)
{
    __crt_stdio_stream const stream(public_stream);

    _VALIDATE_RETURN(stream.valid(), EINVAL, EOF);

    // If the stream is backed by a string, it requires no synchronization,
    // flushing, etc., so we can simply free it, which resets all of its
    // data to the defaults.
    if (stream.is_string_backed())
    {
        __acrt_stdio_free_stream(stream);
        return EOF;
    }

    int return_value = 0;

    _lock_file(stream.public_stream());
    __try
    {
        return_value = _fclose_nolock(stream.public_stream());
    }
    __finally
    {
        _unlock_file(stream.public_stream());
    }

    return return_value;
}
Пример #2
0
// Writes the binary int value to the stream, byte-by-byte.  On success, returns
// the value written; on failure, returns EOF.  Note, however, that the value may
// be EOF--that is, after all, a valid integer--so be sure to test ferror() and
// feof() to check for error conditions.
extern "C" int __cdecl _putw(int const value, FILE* const stream)
{
    _VALIDATE_RETURN(stream != nullptr, EINVAL, EOF);

    int return_value = EOF;

    _lock_file(stream);
    __try
    {
        char const* const first = reinterpret_cast<char const*>(&value);
        char const* const last  = first + sizeof(value);
        for (char const* it = first; it != last; ++it)
        {
            _fputc_nolock(*it, stream);
        }

        if (ferror(stream))
            __leave;

        return_value = value;
    }
    __finally
    {
        _unlock_file(stream);
    }

    return return_value;
}
Пример #3
0
int close(int fd) {
  FSFile *file = (FSFile*)fd;
  
  if (!_valid_file(fd))
    return -1;
  
  //do reference counting
  file->refs--;
  if (file->refs > 0) {
    return 0;
  }
  
  file->closed = 1;

  if (file->fs->close) {
    _lock_file(file);
    file->fs->close(file->fs, file->device, file->internalfd);
    _unlock_file(file);
  }
  
  file->magic = 0;
  
  Process *p = process_get_current(0);
  LinkNode *node;
  
  for (node=p->open_files.first; node; node=node->next) {
    if (node->data == file) {
      klist_remove(&p->open_files, node);
      kfree(node);
      break;
    }
  }

  return 0;
}
Пример #4
0
int read(int fd, void *buf, unsigned int bytes) {
  if (!_valid_file(fd)) {
    klogf("read: Invalid file %x\n", fd);
    return -1;
  }
  
  FSFile *file = (FSFile*) fd;
  _lock_file(file);
  
  int reverse = (!!(file->mode & O_PIPE_MODE)) ^ (!!(file->mode & _O_REVERSE));
  
  if (!(file->access & O_RDONLY) || !(file->fs->accessmode(file->fs, file->device) & O_RDONLY)) {
    klogf("Permission error: %d\n", file->access);
    
    _set_error(FILE_PERMISSIONS_ERROR, "Invalid permissions");
    _unlock_file(file);
    return -1;
  }
  
  if (!file->fs->pread) {
    klogf("Read not supported by filesystem: %x\n", file->fs->pread);
    
    _set_error(FILE_TYPE_ERROR, "Read not supported by the filesystem driver");
    _unlock_file(file);
    return -1;
  }
  
  int ret, *cursor = ((file->mode & O_PIPE_MODE) && reverse) ? &file->pipe_rcursor : &file->cursor;
  
  ret = file->fs->pread(file->fs, file->device, file->internalfd, buf, bytes, *cursor);
  
  if (ret < 0) {
    _unlock_file(file);
    
    file->fs->lasterror_message[sizeof(file->fs->lasterror_message)-1] = 0;
    strncpy(file->errmsg, file->fs->lasterror_message, sizeof(file->errmsg)-1);
    file->errno = file->fs->lasterror;
    
    klogf("Read error:%d: %s\n", file->fs->lasterror, file->fs->lasterror_message);
    return -1;
  }
  
  *cursor += ret;
  
  //klogf("cursorr: %d, ret: %d\n", *cursor, ret);
  
  if (file->mode & O_PIPE_MODE) {
    struct stat sdata;
    
    file->fs->stat(file->fs, file->device, (int)file, &sdata);
    
    unsigned int size = sdata.st_size;
    *cursor = *cursor % size;
  }
  
  _unlock_file(file);
  
  return ret;
}
Пример #5
0
wint_t fgetwc(FILE *stream)
{
	StdioObject_t*  Object;
    wint_t          Result;
    int             ch;

    _lock_file(stream);
    Object = get_ioinfo(stream->_fd);
    if (Object == NULL) {
        _unlock_file(stream);
        _set_errno(EBADFD);
        return (wint_t)-1;
    }

    if ((Object->exflag & (EF_UTF8 | EF_UTF16)) || !(Object->wxflag & WX_TEXT)) {
        
        char *p;
        for (p = (char *)&Result; (wint_t *)p < &Result + 1; p++) {
            ch = fgetc(stream);
            if (ch == EOF) {
                Result = WEOF;
                break;
            }
            *p = (char)ch;
        }
    }
    else
    {
        char mbs[MB_LEN_MAX];
        int len = 0;

        ch = fgetc(stream);
        if (ch != EOF) {
            mbs[0] = (char)ch;
            if (_issjis1((unsigned char)mbs[0])) {
                ch = fgetc(stream);
                if (ch != EOF)
                {
                    mbs[1] = (char)ch;
                    len = 2;
                }
            }
            else {
                len = 1;
            }
        }

        if (!len || mbtowc((wchar_t*)&Result, mbs, len) == -1)
            Result = WEOF;
    }
    _unlock_file(stream);
    return Result;
}
Пример #6
0
int
__cdecl
vfwprintf(FILE* file, const wchar_t *format, va_list argptr)
{
     int ret;

    _lock_file(file);
    ret = wstreamout(file, format, argptr);
    _unlock_file(file);

    return ret;
}
Пример #7
0
int pread(int fd, void *buf, unsigned int bytes, unsigned int off) {
  if (!_valid_file(fd)) {
    klogf("pread: Invalid file %x\n", fd);
    return -1;
  }
  
  FSFile *file = (FSFile*) fd;
  _lock_file(file);
  
  //int reverse = (!!(file->mode & O_PIPE_MODE)) ^ (!!(file->mode & _O_REVERSE));
  
  if (!(file->access & O_RDONLY) || !(file->fs->accessmode(file->fs, file->device) & O_RDONLY)) {
    klogf("Permission error: %d\n", file->access);
    
    _set_error(FILE_PERMISSIONS_ERROR, "Invalid permissions");
    _unlock_file(file);
    return -1;
  }
  
  if (!file->fs->pread) {
    klogf("Read not supported by filesystem: %x\n", file->fs->pread);
    
    _set_error(FILE_TYPE_ERROR, "Read not supported by the filesystem driver");
    _unlock_file(file);
    return -1;
  }
  
  int ret = file->fs->pread(file->fs, file->device, file->internalfd, buf, bytes, off);
  
  //wrap around in pipe mode
  if (ret > 0 && ret < (int)bytes && (file->mode & O_PIPE_MODE)) {
    ret = file->fs->pread(file->fs, file->device, file->internalfd, buf+ret, bytes-ret, 0);
  }
  
  if (ret < 0) {
    _unlock_file(file);
    
    file->fs->lasterror_message[sizeof(file->fs->lasterror_message)-1] = 0;
    strncpy(file->errmsg, file->fs->lasterror_message, sizeof(file->errmsg)-1);
    file->errno = file->fs->lasterror;
    
    klogf("Read error:%d: %s\n", file->fs->lasterror, file->fs->lasterror_message);
    return -1;
  }
  
  //klogf("cursorr: %d, ret: %d\n", *cursor, ret);
  
  _unlock_file(file);
  
  return ret;
}
Пример #8
0
int fstat(int fd, struct stat *out) {
  FSFile *file = (FSFile*)fd;
  
  if (!out)
    return -1;
  if (!_valid_file(fd))
    return -1;
  
  _lock_file(file);
  int ret = file->fs->fstat(file->fs, file->device, file->internalfd, out);
  _unlock_file(file);
  
  return ret;
}
Пример #9
0
int flush(int fd) {
  if (!_valid_file(fd))
    return -1;
  
  FSFile *file = (FSFile*) fd;

  _lock_file(file);
  if (file->fs->flush) {
    file->fs->flush(file->fs, file->device, file->internalfd);
  }
  _unlock_file(file);
  
  return 0;
}
Пример #10
0
int write(int fd, void *buf, unsigned int bytes) {
  if (!_valid_file(fd))
    return -1;
  
  FSFile *file = (FSFile*) fd;

  _lock_file(file);
  
  int reverse = (!!(file->mode & O_PIPE_MODE)) ^ (!!(file->mode & _O_REVERSE));
  
  if (!(file->access & O_RDONLY) || !(file->fs->accessmode(file->fs, file->device) & O_RDONLY)) {
    _set_error(FILE_PERMISSIONS_ERROR, "Invalid permissions");
    
    _unlock_file(file);
    return -1;
  }
  
  if (!file->fs->pread) {
    _set_error(FILE_TYPE_ERROR, "Read not supported by the filesystem driver");
    
    _unlock_file(file);
    return -1;
  }
  
  int ret, *cursor = !((file->mode & O_PIPE_MODE) && reverse) ? &file->pipe_rcursor : &file->cursor;
  
  ret = file->fs->pwrite(file->fs, file->device, file->internalfd, buf, bytes, *cursor);
  
  if (!(file->mode & O_NOSEEK)) {
    *cursor += ret;
  }
  
  //kprintf("cursorw: %d, ret: %d\n", *cursor, ret);
  
  if (file->mode & O_PIPE_MODE) {
    struct stat sdata;
    
    file->fs->stat(file->fs, file->device, (int)file, &sdata);
    unsigned int size = sdata.st_size;
    
    if (*cursor != (int)size) {
      *cursor = *cursor % size;
    }
  }
  
  _unlock_file(file);
    
  return ret;
}
Пример #11
0
int ftruncate(int fd, size_t size) {
  if (!_valid_file(fd))
    return -1;
  
  FSFile *file = (FSFile*) fd;
  int ret = 0;
  
  _lock_file(file);
  if (file->fs->ftruncate) {
    ret = file->fs->ftruncate(file->fs, file->device, file->internalfd, fd);
  }
  _unlock_file(file);
  
  return ret;
}
Пример #12
0
void *mmap(void *addr, size_t length, int prot, int flags, int fd, int offset) {
  if (!_valid_file(fd))
    return NULL;
  
  FSFile *file = (FSFile*) fd;
  void *ret = NULL;
  
  _lock_file(file);
  if (file->fs->mmap) {
    ret = file->fs->mmap(file->fs, file->device, addr, length, prot, flags, file->internalfd, offset);
  }
  _unlock_file(file);
  
  return ret;
}
Пример #13
0
char *gets(
    _In_ char *buf)
{
  int    cc;
  char * buf_start = buf;

  _lock_file(stdin);
  for(cc = fgetc(stdin); cc != EOF && cc != '\n';
      cc = fgetc(stdin))
  if(cc != '\r') *buf++ = (char)cc;

  *buf = '\0';
  
  _unlock_file(stdin);
  return buf_start;
}
Пример #14
0
int lseek(int fd, int off, int whence) {
  if (!_valid_file(fd)) {
    klogf("lseek: Invalid file %x\n", fd);
    return -1;
  }
 
  FSFile *file = (FSFile*) fd;
  int reverse = (!!(file->mode & O_PIPE_MODE)) ^ (!!(file->mode & _O_REVERSE));
  int ret = -1, *cursor = ((file->mode & O_PIPE_MODE) && reverse) ? &file->pipe_rcursor : &file->cursor;
  
  _lock_file(file);
  if (file->fs->lseek) {
    ret = file->fs->lseek(file->fs, file->device, file->internalfd, off, whence);
    
    if (ret < 0) {
      _unlock_file(file);
      return ret;
    }
    
    *cursor = ret;
  } else { //adjust internal pointer directly
    struct stat st = {0,};
    
    file->fs->fstat(file->fs, file->device, file->internalfd, &st);
    
    if (whence == SEEK_SET) {
      *cursor = off;
    } else if (whence == SEEK_CUR) {
      *cursor += off;
    } else if (whence == SEEK_END) {
      intptr_t newoff = st.st_size - off;
      
      if (newoff < 0)
        newoff = 0;
      
      *cursor = newoff;
    }
    
    if (*cursor > st.st_size) {
      *cursor = st.st_size;
    }
  }
  
  _unlock_file(file);
  
  return ret;
}
Пример #15
0
int _fs_clear_mode(int fd, int mode) {
  if (!_valid_file(fd))
    return -1;
  
  FSFile *file = (FSFile*) fd;
  
  _lock_file(file);
  
  file->mode &= ~mode;
  if (file->fs->clearmode) {
    file->fs->clearmode(file->fs, file->device, file->internalfd, mode);
  }
  
  _unlock_file(file);
  
  return 0;
}
Пример #16
0
//return 1 if eof, 0 otherwise, or <0, for error
int peof(int fd) {
  FSFile *file = (FSFile*)fd;
  
  if (!_valid_file(fd))
    return -1;
  
  _lock_file(file);
  
  //XXX: macroatize me!
  int reverse = (!!(file->mode & O_PIPE_MODE)) ^ (!!(file->mode & _O_REVERSE));
  int *cursor = ((file->mode & O_PIPE_MODE) && reverse) ? &file->pipe_rcursor : &file->cursor;
  
  int ret = file->fs->eof ? file->fs->eof(file->fs, file->device, file->internalfd, *cursor) : -1;
  
  _unlock_file(file);
  return ret;
}
Пример #17
0
///////////////////////////////////////////////////////////////////////////////////
//Lock A File
///////////////////////////////////////////////////////////////////////////////////
Void FileHandler::LockFile(FilePointer Stream)
{
	if(Stream.fp != NULL)
	{
		_lock_file(Stream.fp);
		return;
	}
	else
	{
		/////////////////////////////////////////
		//Error
		/////////////////////////////////////////
		printf("ERROR: Bad File Pointer");
		return;
	}
	
}
Пример #18
0
int
__cdecl
vfwprintf_s(FILE* file, const wchar_t *format, va_list argptr)
{
    int ret;

    if(!MSVCRT_CHECK_PMT( file != NULL)) {
        _set_errno(EINVAL);
        return -1;
    }

    _lock_file(file);
    ret = wstreamout(file, format, argptr);
    _unlock_file(file);

    return ret;
}
Пример #19
0
static Integer __cdecl common_ftell(__crt_stdio_stream const stream) throw()
{
    _VALIDATE_RETURN(stream.valid(), EINVAL, -1);

    Integer return_value = 0;

    _lock_file(stream.public_stream());
    __try
    {
        return_value = common_ftell_nolock<Integer>(stream);
    }
    __finally
    {
        _unlock_file(stream.public_stream());
    }

    return return_value;
}
Пример #20
0
extern "C" wint_t __cdecl fgetwc(FILE* const stream)
{
    _VALIDATE_RETURN(stream != nullptr, EINVAL, WEOF);

    wint_t return_value = 0;

    _lock_file(stream);
    __try
    {
        return_value = _fgetwc_nolock(stream);
    }
    __finally
    {
        _unlock_file(stream);
    }

    return return_value;
}
Пример #21
0
int fs_ioctl_handle(int fd, intptr_t req, intptr_t arg) {
  if (!_valid_file(fd)) {
    klogf("lseek: Invalid file %x\n", fd);
    return -1;
  }
 
  FSFile *file = (FSFile*) fd;
  //int reverse = (!!(file->mode & O_PIPE_MODE)) ^ (!!(file->mode & _O_REVERSE));
  int ret = -1; // *cursor = ((file->mode & O_PIPE_MODE) && reverse) ? &file->pipe_rcursor : &file->cursor;
  
  _lock_file(file);
  
  if (file->fs->ioctl) {
    ret = file->fs->ioctl(file->fs, file->device, file->internalfd, req, arg);
  }
  
  _unlock_file(file);
  
  return ret;
}
Пример #22
0
// Repositions the file pointer of a stream to the specified location, relative
// to 'whence', which can be SEEK_SET (the beginning of the file), SEEK_CUR (the
// current pointer position), or SEEK_END (the end of the file).  The offset may
// be negative.  Returns 0 on success; returns -1 and sets errno on failure.
static int __cdecl common_fseek(
    __crt_stdio_stream const stream,
    __int64            const offset,
    int                const whence
    ) throw()
{
    _VALIDATE_RETURN(stream.valid(), EINVAL, -1);
    _VALIDATE_RETURN(whence == SEEK_SET || whence == SEEK_CUR || whence == SEEK_END, EINVAL, -1);

    int return_value = -1;

    _lock_file(stream.public_stream());
    __try
    {
        return_value = common_fseek_nolock(stream, offset, whence);
    }
    __finally
    {
        _unlock_file(stream.public_stream());
    }

    return return_value;
}
Пример #23
0
static errno_t __cdecl common_freopen(
    FILE**             const result,
    Character const*   const file_name,
    Character const*   const mode,
    __crt_stdio_stream const stream,
    int                const share_flag
    ) throw()
{
    typedef __acrt_stdio_char_traits<Character> stdio_traits;

    _VALIDATE_RETURN_ERRCODE(result != nullptr, EINVAL);
    *result = nullptr;

    // C11 7.21.5.4/3:  "If filename is a null pointer, the freopen function
    // attempts to change the mode of the stream to that specified by mode, as
    // if the name of the file currently associated with the stream had been
    // used. It is implementation-defined which changes of mode are permitted
    // (if any), and under what circumstances."
    //
    // In our implementation, we do not currently support changing the mode
    // in this way.  In the future, we might consider use of ReOpenFile to
    // implement support for changing the mode.
    _VALIDATE_RETURN_ERRCODE_NOEXC(file_name != nullptr, EBADF);

    _VALIDATE_RETURN_ERRCODE(mode      != nullptr, EINVAL);
    _VALIDATE_RETURN_ERRCODE(stream.valid()      , EINVAL);

    // Just as in the common_fsopen function, we do not hard-validate empty
    // 'file_name' strings in this function:
    _VALIDATE_RETURN_ERRCODE_NOEXC(*file_name != 0, EINVAL);

    errno_t return_value = 0;

    _lock_file(stream.public_stream());
    __try
    {
        // If the stream is in use, try to close it, ignoring possible errors:
        if (stream.is_in_use())
            _fclose_nolock(stream.public_stream());

        stream->_ptr  = nullptr;
        stream->_base = nullptr;
        stream->_cnt  = 0;
        stream.unset_flags(-1);

        // We may have called fclose above, which will deallocate the stream.
        // We still hold the lock on the stream, though, so we can just reset
        // the allocated flag to retain ownership.
        stream.set_flags(_IOALLOCATED);

        *result = stdio_traits::open_file(file_name, mode, share_flag, stream.public_stream());
        if (*result == nullptr)
        {
            stream.unset_flags(_IOALLOCATED);
            return_value = errno;
        }
    }
    __finally
    {
        _unlock_file(stream.public_stream());
    }

    return return_value;
}
Пример #24
0
int VMPI_ftrylockfile (FILE *stream)
{
    _lock_file(stream); //yep that's cheap ...
    return 0;
}
Пример #25
0
// ---- C.stdio ---- 
void VMPI_flockfile (FILE *stream)
{
    _lock_file(stream);
}
Пример #26
0
static void flockfile(FILE* fp) { _lock_file(fp); }