CO527 Anonymous Questions and Answers |
This page lists the various questions and answers. To submit a question, use the anonymous questions page. You may find the keyword index and/or top-level index useful for locating past questions and answers.
We have taken the liberty of making some minor typographical corrections to some of the questions as originally put. Although most of the questions here will have been submitted anonymously, this page also serves to answer some questions of general interest to those on the course.
I was wondering how you take inputs from teh screen (MOSS) because I have got this if the file exists then send to the screen this message:
MPosixIf.writestring (MPosixIf.STDOUT, "File Exists- Do you want to OVERWRITE? [Y / N] : \n");
and if the arguement now is "Y" i.e by typing:
if (argv[0].equals ("Y")) { // it should overrite the file else do nothing ...
but it dosent seem to read anything on screen!!!
This is because you're not actually reading anything, per se. The String you're testing is "argv[0]". This is one of the command-line arguments, in this case, the full path to the executable (e.g. "/bin/copy"). To actually read something from the user, you need to read, as in "MPosixIf.read()". Bear in mind that you're not reading from the screen -- screens are output only devices (unless you're lucky enough to have a touchscreen, which usually appears as a different device for input anyway). The input comes from the keyboard, presumably, which is available to processes through the descriptor "MPosixIf.STDIN" (contrast with "MPosixIf.STDOUT" which is where screen output goes).
The answer to Question 72 (2004) may also help.
Keywords: moss2004 , moss2004-1
Referrers: Question 122 (2004) , Question 123 (2004)
Following on from Question 121 (2004): but "MPosixIf.read()" has this header:
/** * this performs a read from the given descriptor. * * @param fd file-descriptor to read from * @param buffer buffer where data will be stored * @param count maximum number of bytes to read * * @return number of bytes read on success, 0 on end-of-file, or -ve on error */ public static int read (int fd, byte buffer[], int count)
it returns a file descriptor so I cannot check if what is put on screen is a "Y" or "N". Should I use "System.in" ?
Nowhere in that method header does it suggest anything about returning a file-descriptor..! The return value is specified as "number of bytes read on success, 0 on end-of-file, or -ve on error". When this call is made, it will read a line of input from the user and place it in the buffer specified by "buffer", up to a maximum of "count" bytes. It then returns the number of bytes that were actually placed in the buffer.
Keywords: moss2004 , moss2004-1
Hi you said in Question 72 (2004) and Question 121 (2004) that we should use "MPosixIf.read", but if you use it like:
MPosixIf.read (MPosixIf.STDIN, buf, buflen);
it returns an int value, and also you have to create a buf and buflen for its arguements. I'm not understanding how we are supposed to do this.
You do exactly as you've suggested! Create a buffer then pass it as a parameter to "MPosixIf.read()". E.g.:
byte keybuf[] = new byte[16]; int r; r = MPosixIf.read (MPosixIf.STDIN, keybuf, keybuf.length);
Which will leave whatever the user typed in the "keybuf" array. Assuming "r" > 0, then something was definitely typed (as opposed to end-of-file or error).
Keywords: moss2004 , moss2004-1
When it comes to "-i" and a file that doesn't exist, should we throw an error that the file doesn't exist or should we just create the file ?
It should just create the file anyway -- i.e. the "-i" option does nothing if the file doesn't exist.
Keywords: moss2004 , moss2004-1
What are we supposed to do if the destination is a directory and the source file already exists in the directory and also the -a option is given ? So for example it is like:
/bin/copy -a /abc.txt /
and the file "abc.txt" already exists in the "/" (root) directory. What shoud it do in this case?
With the "-a" option here, you (well, the end-user) are attempting to append a file to itself. Without the "-a" option here, you'd still be trying to copy a file to itself. Neither makes particular sense -- best to report and error and stop. Some real-world mechanisms will report an error in this case, others will happily trash your input file.. Handling this is nice (i.e. bonus marks), but not strictly necessary. And it all gets complicated when you have multiple directory entries hard-linked to the same physical file -- checking the full paths for equivalence is no longer enough.. (thankfully MOSS doesn't support hard-linking, yet!).
Keywords: moss2004 , moss2004-1
If both the "-a" and "-i" options are given, then how should copy deal with this ? Is it suppose to append to the destination file in case the user response is "NO" to overwrite ? And if the user response is "YES" to overwrite, I assume it should just overwrite the destination file ignoring the append option.
Ideally, in the case where both flags are specified, it should prompt the user as to whether or not they want the file appended. If no, exit as usual. If yes, append to the file, but don't overwrite it. Of course, if the destination file didn't already exist, it should just create and write to it as usual (appending something to nothing still gives you something).
Keywords: moss2004 , moss2004-1
Just wanted to check with you this little problem. My copy function works but did you want us to do something like this:
/bin/copy /readme.txt /temp
where "/temp" is a directory, the file "readme.txt" will be copied into it. Becase mine doesn't do that. Instead I have to put down the entire path for it to work e.g.:
/bin/copy /readme.txt /temp/readme.txt
... please tell me that's cool!
It's not so cool I'm afraid :(. The copy utility should check to see if "/temp" is a directory, and if it is, add the "readme.txt" bit to the destination path itself (rather than the user having to do it). Question Question 112 (2004) gives some ideas about how to check whether something is a directory or not.
Keywords: moss2004 , moss2004-1
Hi, I am testing my file copy and this is what I get:
MOSS# /bin/copy /README.TXT /target.txt fd of source -2fd of target 3MOSS#
I am not sure what -2 means, but please tell me why is it not copying from the source to the target? Both files exit in my moss directory. should they be elsewhere or this location is fine?
The error -2 is "-MSystem.ENOENT". I.e. no such file or directory. But the root-directory on MOSS is not your "moss/" directory on raptor. Listing the contents of "/" should tell you that! If you want to read the "README.TXT" from your own directory on raptor you'll need to give the source as something like "/host/home/cur/login/co501/moss/README.TXT". Alternatively, just use a source file that already exists on MOSS, e.g. "/proc/cpuinfo". If you want a big source file, use something like "/host/etc/passwd" (106k or thereabouts).
Keywords: moss2004 , moss2004-1
Im doing the file-copy utility and last night my code was compiling and working fine. This morning, I add about 5 lines of code and call make to compile, and make just hangs:
javac moss/modules/UCopy.java ^Cmake: *** [moss/modules/UCopy.class] Error 130
and ideas what's happening here ? I tried taking out the new code i'd written but still hangs.
Welcome to software efficiency 101.. Raptor's load is currently at 55, which means it's trying to do 55 times as much stuff as it actually can. Very overloaded. The Java compiler is not a particularly efficient bit of software. It will run eventually, you may just have to wait a while.. The dependency mechanisms of javac may also mean that compiling "UCopy.java" causes a load of other things to be compiled too, but that shouldn't be the case here -- since the modules are only built at the end.
Keywords: moss2004 , moss2004-1
In the "UWfln.java" file, the following code is used:
/* open file for writing (create if it doesn't exist already) */ fd = MPosixIf.open (argv[i], MFileOps.OPEN_WRITE | FileOps.OPEN_CREAT); if (fd < 0) { MPosixIf.writestring (MPosixIf.STDERR, argv[0]+ ": failed to open " + argv[i] + " for writing: " + M StdLib.strerror (fd) + "\n"); MPosixIf.exit (1); }
I don't quite understand this. If the file is supposed to be created if it doesn't exist, why would it not be able to open it ? Will this code actually create a new file ?
Yes, this code will normally create a new file, but could fail for various reasons. For example:
Keywords: moss2004
The compiler will not let me use the following:
MInode ino = new MInode (); int res = MPosixIf.stat (argv[1], ino); if ((res & MInode.S_IFREG) == MInode.S_IFREG) { MPosixIf.writestring (MPosixIf.STDOUT, "It's a regular file!\n"); }
It's pretty much taken from one of your answers, but it gives 4 errors, 1 on each of the references to MInode. Is there any reason why this might happen ?
The first thing here is that you're testing the return-value ("res") for a flag. The return value isn't a set of flags though; you should be testing "ino.mode". But I suspect the reason it's not compiling is because you've not imported "MInode". Stick this up by the other imports:
import moss.fs.MInode;
Keywords: moss2004 , moss2004-1
I am having a bit of trouble opening files. I have:
int source = MPosixIf.open (argv[1], MFileOps.OPEN_READ); if (source < 0) { MPosixIf.writestring (MPosixIf.STDERR, argv[0] + ": failed to open " + argv[1] + " for writing: " + MStdLib.strerror (source) + "\n"); MPosixIf.exit (1); }
I have passed "/proc/cpuinfo" as the first argument but it throws an error each time saying that it can't open the file. I know that the file is present as I have used "cat /proc/cpuinfo" to view what is in the file, so I dont know why this is happening!
This fragment of code looks fine -- although the error says "writing". Things to check are: that it is actually this bit of code reporting the error (not from somewhere else), and that you haven't accidently trashed "argv[1]" somewhere (which should show up when it displays the error message). Also check that you are calling it correctly, e.g. "/bin/copy /proc/cpuinfo ...".
Keywords: moss2004 , moss2004-1
Where can the "foo" file be found within the MOSS setup ? And can you give an example instruction for copy. i.e. copy a file named "test1" to "test2" which is stored within the "foo" directory ?
There is no file "foo" in MOSS, unless you create one yourself. As an example of copying into a directory called "foo", you'd have to create the directory first (alternatively just use an existing directory such as "/etc"):
MOSS# /bin/mkdir /foo MOSS# /bin/copy /proc/cpuinfo /foo MOSS# /bin/cat /foo/cpuinfo CPU0(busy): VCPU:JVM/1.4.2_06-b03/SunOS/5.9 CPU1(idle): VCPU:JVM/1.4.2_06-b03/SunOS/5.9 MOSS#
Keywords: moss2004 , moss2004-1
I noticed something strange when calling "MPosixIf.stat()" on the root directory "/", it fails with "no such file or directory" ?
Yes, this is a small bug I'm afraid (but only 2 so far for this operating-system isn't bad going considering). Using a different directory to test for directory output will get around the problem, e.g.:
MOSS# /bin/copy /host/etc/passwd /etc/ MOSS#
Keywords: moss2004 , moss2004-1
Currently, my prompting system reads 2 bytes from MPosixIf.STDIN at a time - if more than one character is typed, then my code loops around several times, printing my prompt message & calling char several times.
Things work like clockwork when the user types in a single character, and they still do work if they type in several - it's just that the prompt will be printed several times in a row.
It seems to me that what I need to be able to make it all a little neater is the ability to find out how many bytes are waiting to be read from MPosixIf.STDIN. Is this possible ?
I have a check in place that ensures that the source & destination paths are not equal - sort of. The moment you try things like "/bin/copy /etc/../etc/init /etc" it'll get confused - and then, of course, there are symblinks. I tried comparing file descriptors rather than paths, but for some reason, the source and destination FDs are always the same, irrespective of what files they reference, which seems weird, though the utility seems to work otherwise. Any way of making this check more thorough ?
Unfortunately, no, it seems this is not possible. I did try at one point -- mainly to get the console to support some form of command-line history, but failed. There may be another way to get the Java console into unbuffered mode, but I haven't found it yet. The way it ought to work is that an application calls "MPosixIf.fcntl()" with MPosixIf.STDIN and sets the O_NONBLOCK flag, then calls "MPosixIf.read()" with a count of 1. But it doesn't work -- the MOSS "MJavaConsole" driver only gets the keyboard input when the user hits return, or flushes it some other way. This would, in theory (since they're not implemented yet), work for consoles connected via a network socket or graphical interface.
The source and destination file-descriptors must be different, if they are from separate calls to "MPosixIf.open()". If they're being reported to be the same, that must be a printing error somewhere.. But as for dealing with complex paths (e.g. "/etc/../etc/init"), MOSS doesn't, and things may behave strangely. You could do the path reduction yourself, but it's not expected -- that code should really be inside "MFileSystem" or "MPosixIf".
MOSS doesn't do symblinks quite properly either -- i.e. the object file-system doesn't support them and the host file-system just sees them as normal files (it seems that the Java API and/or JVM don't support symbolic links).
Keywords: moss2004 , moss2004-1
I've got a few questions about expected functionality of the copy command:
Should it output anything on success, or remain silent ?
What is the best way to display error and exit ? At the moment, I'm writing to MPosixIf.STDERR then calling MPosixIf.exit(1), is this the best way ?
When writing over an existing file, if the data being written is less than the data originally in the file, the remaining old data is still there after copying. Is this the correct functionality ? If not, should we clear the file somehow prior to copying, or is there a way to readjust the EOF pointer?
I'm using a verbose flag for testing with my copy command (-v), is it OK to leave this in there when submitting it ? or should I remove it. It only outputs fairly useful info when used, and nothing otherwise.
Ideally it should be silent.
Yes, that is pretty much the best (and probably only) way to display an error and exit.
Nope, if overwriting a file with one smaller, the output file shouldn't have left-overs in it. The way to do this is to truncate it -- specified using the "MFileOps.OPEN_TRUNC" flag to "MPosixIf.open()".
Yes, that's fine. Often verbose operation is useful, and there's possibly some extra marks for things like that.
Keywords: moss2004 , moss2004-1
When reading data from the user, using MPosixIf.STDIN, how can we read what is returned as a String ? I've tried doing toString(), but it comes out as garbage. So the way I'm doing it is by comparing the first element of the input buffer array with the ASCII no. of the character. It works, but is this acceptable?
This is not nice -- magic numbers. If you want to turn the byte-array into a String, just construct a String with the array as its argument. But it's easier to deal with these things as byte-arrays. But instead of testing against ASCII values, test against character constants -- this should work just fine. E.g. "(data[0] == 'y')".
Keywords: moss2004 , moss2004-1
Out of interest, how long did it take you to code moss ?
If I'd sat down and not done much else (besides eat and sleep), probably about 2 weeks. But it was developed more slowly over a few months.
Keywords: moss2004
This might be a silly question, but midnight monday, means sunday 23.59 + 60 seconds does it not ? Do we have untill monday evening or sunday evening ?
Monday evening, i.e. just before Tuesday. I generally think of midnight being at the end of a day, rather than the start. The assessments page says Monday.
Keywords: moss2004
This question is referring to Question 117 (2004), I have written this code for the seek:
if (app = true) { int lsf2e; lsf2e = MPosixIf.lseek (f2, 0, MFileOps.LSEEK_END); }
I thought it looks ok but when compiling it points to the dot in "MPosixIf.lseek". So I had a look in the "MPosixIf" class in the latest version of MOSS on your webpage, and "lseek" ain't there. Any ideas?
See the answer to Question 77 (2004). It was missing.. I posted to the course newsgroup about this as well.
Keywords: moss2004 , moss2004-1
Maintained by Fred Barnes, last modified Thu May 8 12:58:04 2014 |