-
Notifications
You must be signed in to change notification settings - Fork 1
/
SysLib.java
284 lines (243 loc) · 11 KB
/
SysLib.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
import java.util.*;
public class SysLib {
/* Added by Brendan Sweeney */
/**
* Reads up to buffer.length bytes from the file associated with file
* descriptor fd, starting at the current position of the seek pointer. If
* bytes remaining between the current seek pointer and the end of file
* are less than buffer.length, as many bytes as possible are read,
* putting them into the beginning of buffer. The seek pointer is
* incremented by the number of bytes that have been read. The return
* value is the number of bytes that have been read, or a negative value
* upon an error.
* @param fd File descriptor of the file to read.
* @param buffer A buffer into which bytes read from the file are placed.
* @pre The file described by fd is open.
* @post buffer contains all bytes from the file's original seek pointer
* up to either buffer.length or the end of the file; seek pointer
* is set to one past the last byte read.
* @return The number of bytes read if successful; -1 otherwise.
*/
public static int read(int fd, byte[] buffer) {
return Kernel.interrupt(Kernel.INTERRUPT_SOFTWARE,
Kernel.READ, fd, buffer);
} // end delete(String)
/**
* Writes the contents of buffer to the file associated with the file
* descriptor fd, starting at the current position of the seek pointer.
* The operation may overwrite existing data in the file and/or append to
* the end of the file. The seek pointer is incremented by the number of
* bytes to have been written. The return value is the number of bytes
* that have been written, or a negative value upon an error.
* @param fd File descriptor of the file to write into.
* @param buffer A buffer containing the bytes to be written to the file.
* @pre The file described by fd is open; there are enough free blocks
* on the disk to hold the written bytes.
* @post All bytes in buffer have been written to the file starting from
* its original seek pointer; seek pointer is set to one past the
* last byte written.
* @return The number of bytes written if successful; -1 otherwise.
*/
public static int write(int fd, byte[] buffer) {
return Kernel.interrupt(Kernel.INTERRUPT_SOFTWARE,
Kernel.WRITE, fd, buffer);
} // end delete(String)
/**
* Opens the file specified by the fileName string in the given mode and
* allocates a new int file descriptor to reference this file. For modes
* "w", "w+" or "a", the file is created if it does not exist; for mode
* "r", an error results if the file does not exist. The seek pointer is
* positioned at the beginning of the file in modes "r", "w", and "w+"; it
* is positioned at the end of the file in mode "a". File descriptors 3
* thru 31 are available for user files. If the calling thread's user file
* descriptor table is full, an error is returned; otherwise the new file
* descriptor is returned.
* @param fileName The name of the file to open.
* @param mode Access mode of the file. May be "r" for read-only, "w" for
* write-only, "w+" for read-and-write, or "a" for append.
* @pre mode specifies a valid access mode; if mode is "r" then fileName
* specifies an existing file; the caller's file descriptor table
* is not full.
* @post The specified file is added to the file table and is accessible
* in the specified mode through the returned file descriptor.
* @return A file descriptor if the file could be opened; -1 otherwise.
*/
public static int open(String fileName, String mode) {
String[] args = new String[2];
args[0] = fileName;
args[1] = mode;
return Kernel.interrupt(Kernel.INTERRUPT_SOFTWARE,
Kernel.OPEN, 0, args);
} // end open(String, String)
/**
* Closes the file corresponding to fd, commits all file transactions on
* this file, and unregisters fd from the user file descriptor table of
* the calling thread's TCB.
* @param fd File descriptor of the file to close.
* @pre The file described by fd is open.
* @post All transactions on this file are committed; fd is unregistered
* from the caller's file descriptor table.
* @return 0 if the file was found and closed; -1 otherwise.
*/
public static int close(int fd) {
return Kernel.interrupt(Kernel.INTERRUPT_SOFTWARE,
Kernel.CLOSE, fd, null);
} // end close(int)
/**
* Returns the size in bytes of the file indicated by fd.
* @param fd File descriptor of the file whose size is requested.
* @pre The file described by fd is open.
* @post None.
* @return The size, in bytes, of the file if found; -1 otherwise.
*/
public static int fsize(int fd) {
return Kernel.interrupt(Kernel.INTERRUPT_SOFTWARE,
Kernel.SIZE, fd, null);
} // end fsize(int)
/**
* Updates the seek pointer corresponding to fd depending on the value of
* whence and offset.
* @param fd File descriptor of the file to seek into.
* @param offset Distance to set the seek pointer from whence. May be
* negative to specify a distance before whence.
* @param whence Location in the file from which offset should start. 0
* is the start of the file, 1 is the current seek pointer
* position, and 2 is the end of the file.
* @pre If whence is 0, then offset is positive; if whence is 2, then
* offset is negative; whence plus offset is within the bounds of
* the file.
* @post The file's seek pointer is set to the specified location.
* @return The new seek pointer position if set; -1 otherwise.
*/
public static int seek(int fd, int offset, int whence) {
int[] args = new int[2];
args[0] = offset;
args[1] = whence;
return Kernel.interrupt(Kernel.INTERRUPT_SOFTWARE,
Kernel.SEEK, fd, args);
} // end seek(int, int, int)
/**
* Formats the disk, (i.e., Disk's data contents). The parameter files
* specifies the maximum number of files to be created, (i.e., the number
* of inodes to be allocated) in your file system. The return value is 0
* on success, otherwise -1.
* @param files The maximum number of files to support.
* @pre The disk file has been created.
* @post The disk file contains a file system that supports up to the
* specified number of files.
* @return 0 if the format succeeded; -1 otherwise.
*/
public static int format(int files) {
return Kernel.interrupt(Kernel.INTERRUPT_SOFTWARE,
Kernel.FORMAT, files, null);
} // end format(int)
/**
* Deletes the file specified by fileName. If the file is currently open,
* it is not deleted until the last open on it is closed, but new attempts
* to open it will fail.
* @param fileName The name of the file to delete.
* @pre fileName specifies a file that exists.
* @post The file is removed from the file system directory, its inode is
* made available, and its blocks are returned to the free list.
* @return 0 if the file existed and was deleted; -1 otherwise.
*/
public static int delete(String fileName) {
return Kernel.interrupt(Kernel.INTERRUPT_SOFTWARE,
Kernel.DELETE, 0, fileName);
} // end delete(String)
/* End additions */
public static int exec( String args[] ) {
return Kernel.interrupt( Kernel.INTERRUPT_SOFTWARE,
Kernel.EXEC, 0, args );
}
public static int join( ) {
return Kernel.interrupt( Kernel.INTERRUPT_SOFTWARE,
Kernel.WAIT, 0, null );
}
public static int boot( ) {
return Kernel.interrupt( Kernel.INTERRUPT_SOFTWARE,
Kernel.BOOT, 0, null );
}
public static int exit( ) {
return Kernel.interrupt( Kernel.INTERRUPT_SOFTWARE,
Kernel.EXIT, 0, null );
}
public static int sleep( int milliseconds ) {
return Kernel.interrupt( Kernel.INTERRUPT_SOFTWARE,
Kernel.SLEEP, milliseconds, null );
}
public static int disk( ) {
return Kernel.interrupt( Kernel.INTERRUPT_DISK,
0, 0, null );
}
public static int cin( StringBuffer s ) {
return Kernel.interrupt( Kernel.INTERRUPT_SOFTWARE,
Kernel.READ, 0, s );
}
public static int cout( String s ) {
return Kernel.interrupt( Kernel.INTERRUPT_SOFTWARE,
Kernel.WRITE, 1, s );
}
public static int cerr( String s ) {
return Kernel.interrupt( Kernel.INTERRUPT_SOFTWARE,
Kernel.WRITE, 2, s );
}
public static int rawread( int blkNumber, byte[] b ) {
return Kernel.interrupt( Kernel.INTERRUPT_SOFTWARE,
Kernel.RAWREAD, blkNumber, b );
}
public static int rawwrite( int blkNumber, byte[] b ) {
return Kernel.interrupt( Kernel.INTERRUPT_SOFTWARE,
Kernel.RAWWRITE, blkNumber, b );
}
public static int sync( ) {
return Kernel.interrupt( Kernel.INTERRUPT_SOFTWARE,
Kernel.SYNC, 0, null );
}
public static int cread( int blkNumber, byte[] b ) {
return Kernel.interrupt( Kernel.INTERRUPT_SOFTWARE,
Kernel.CREAD, blkNumber, b );
}
public static int cwrite( int blkNumber, byte[] b ) {
return Kernel.interrupt( Kernel.INTERRUPT_SOFTWARE,
Kernel.CWRITE, blkNumber, b );
}
public static int flush( ) {
return Kernel.interrupt( Kernel.INTERRUPT_SOFTWARE,
Kernel.CFLUSH, 0, null );
}
public static int csync( ) {
return Kernel.interrupt( Kernel.INTERRUPT_SOFTWARE,
Kernel.CSYNC, 0, null );
}
public static String[] stringToArgs( String s ) {
StringTokenizer token = new StringTokenizer( s," " );
String[] progArgs = new String[ token.countTokens( ) ];
for ( int i = 0; token.hasMoreTokens( ); i++ ) {
progArgs[i] = token.nextToken( );
}
return progArgs;
}
public static void short2bytes( short s, byte[] b, int offset ) {
b[offset] = (byte)( s >> 8 );
b[offset + 1] = (byte)s;
}
public static short bytes2short( byte[] b, int offset ) {
short s = 0;
s += b[offset] & 0xff;
s <<= 8;
s += b[offset + 1] & 0xff;
return s;
}
public static void int2bytes( int i, byte[] b, int offset ) {
b[offset] = (byte)( i >> 24 );
b[offset + 1] = (byte)( i >> 16 );
b[offset + 2] = (byte)( i >> 8 );
b[offset + 3] = (byte)i;
}
public static int bytes2int( byte[] b, int offset ) {
int n = ((b[offset] & 0xff) << 24) + ((b[offset+1] & 0xff) << 16) +
((b[offset+2] & 0xff) << 8) + (b[offset+3] & 0xff);
return n;
}
}