001/* 002 * This file is part of the Jikes RVM project (http://jikesrvm.org). 003 * 004 * This file is licensed to You under the Eclipse Public License (EPL); 005 * You may not use this file except in compliance with the License. You 006 * may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/eclipse-1.0.php 009 * 010 * See the COPYRIGHT.txt file distributed with this work for information 011 * regarding copyright ownership. 012 */ 013package org.jikesrvm.runtime; 014 015import java.io.BufferedInputStream; 016import java.io.BufferedOutputStream; 017import java.io.FileDescriptor; 018import java.io.FileInputStream; 019import java.io.FileOutputStream; 020import java.io.PrintStream; 021import org.jikesrvm.VM; 022import org.jikesrvm.scheduler.RVMThread; 023import static org.jikesrvm.runtime.SysCall.sysCall; 024import org.vmmagic.pragma.NoInline; 025import org.vmmagic.pragma.NoOptCompile; 026import org.vmmagic.pragma.BaselineSaveLSRegisters; 027import org.vmmagic.pragma.Unpreemptible; 028 029/** 030 * Interface to filesystem of underlying operating system. Historically 031 * this has provided a blocking IO abstraction on top of non-blocking IO, 032 * which was necessary for green threads. The current code contains only 033 * abstractions for dealing with things like file status. 034 */ 035public class FileSystem { 036 037 /** 038 * Read single byte from file. 039 * 040 * @param fd file descriptor 041 * @return byte that was read (< -2: i/o error, -2: timeout, -1: eof, >= 0: data) 042 */ 043 @NoInline 044 @NoOptCompile 045 @BaselineSaveLSRegisters 046 @Unpreemptible 047 public static int readByte(int fd) { 048 RVMThread.saveThreadState(); 049 RVMThread.enterNative(); 050 int result = sysCall.sysReadByte(fd); 051 RVMThread.leaveNative(); 052 return result; 053 } 054 055 /** 056 * Write single byte to file 057 * 058 * @param fd file descriptor 059 * @param b byte to be written 060 * @return -2: i/o error, -1: timeout, 0: ok 061 */ 062 @NoInline 063 @NoOptCompile 064 @BaselineSaveLSRegisters 065 @Unpreemptible 066 public static int writeByte(int fd, int b) { 067 RVMThread.saveThreadState(); 068 RVMThread.enterNative(); 069 int result = sysCall.sysWriteByte(fd,b); 070 RVMThread.leaveNative(); 071 return result; 072 } 073 074 /** 075 * Reads multiple bytes. 076 * 077 * @param fd the file descriptor for the file that should be read from 078 * @param buf a pinned byte array to read into 079 * @param off the offset in the buffer to read into 080 * @param cnt the number of bytes to read 081 * @return -2: i/o error, -1: timeout, >=0: number of bytes read 082 */ 083 @NoInline 084 @NoOptCompile 085 @BaselineSaveLSRegisters 086 @Unpreemptible 087 public static int readBytes(int fd, byte[] buf, int off, int cnt) { 088 RVMThread.saveThreadState(); 089 RVMThread.enterNative(); 090 int result = sysCall.sysReadBytes(fd,Magic.objectAsAddress(buf).plus(off),cnt); 091 RVMThread.leaveNative(); 092 return result; 093 } 094 095 /** 096 * Writes multiple bytes. 097 * 098 * @param fd the file descriptor for the file that should be written to 099 * @param buf a pinned byte array to write from 100 * @param off the offset in the buffer to start writing from 101 * @param cnt the number of bytes to write 102 * @return -2: i/o error, -1: timeout, >=0: number of bytes written 103 */ 104 @NoInline 105 @NoOptCompile 106 @BaselineSaveLSRegisters 107 @Unpreemptible 108 public static int writeBytes(int fd, byte[] buf, int off, int cnt) { 109 RVMThread.saveThreadState(); 110 RVMThread.enterNative(); 111 int result = sysCall.sysWriteBytes(fd,Magic.objectAsAddress(buf).plus(off),cnt); 112 RVMThread.leaveNative(); 113 return result; 114 } 115 116 // not sure if this is the right place to have this. 117 /** 118 * Called from VM.boot to set up java.lang.System.in, java.lang.System.out, 119 * and java.lang.System.err 120 */ 121 public static void initializeStandardStreams() { 122 FileInputStream fdIn = new FileInputStream(FileDescriptor.in); 123 FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out); 124 FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err); 125 System.setIn(new BufferedInputStream(fdIn)); 126 System.setOut(new PrintStream(new BufferedOutputStream(fdOut, 128), true)); 127 System.setErr(new PrintStream(new BufferedOutputStream(fdErr, 128), true)); 128 Callbacks.addExitMonitor(new Callbacks.ExitMonitor() { 129 @Override 130 public void notifyExit(int value) { 131 try { 132 System.err.flush(); 133 System.out.flush(); 134 } catch (Throwable e) { 135 VM.sysWriteln("vm: error flushing stdout, stderr"); 136 e.printStackTrace(); 137 } 138 } 139 }); 140 } 141} 142 143