Last revised: 09Apr2002 GLGTable of Contents
- About the Tests
- Mac OS X and Setuid Executables
- Using app.posix.test.TestEnv
- Using app.posix.test.TestFactories
- Using app.posix.test.TestFile
- Using app.posix.test.TestFileRel
- Using app.posix.test.TestFileState
- Using app.posix.test.TestGID
- Using app.posix.test.TestLimits
- Using app.posix.test.TestLimitsCPU
- Using app.posix.test.TestMounts
- Using app.posix.test.TestNice
- Using app.posix.test.TestSignals
- Using app.posix.test.TestSignalsCaught
- Using app.posix.test.TestTime
- Using app.posix.test.TestTimeSet
- Using app.posix.test.TestUGID
- Using app.posix.test.TestUID
- Using app.posix.test.TestUIDSet
- Using app.posix.test.TestUMask
All the tests are in the "app.posix.test" package. All the tests use standard output (or standard error) for text messages and results.Some tests use command-line args, but many do not. The ones that do are pointed out.
Some tests create files and other things in the file-system, which endure after the test ends. You should delete these after you have examined them. Most file-system creations can be examined with the command 'ls -l', and removed with the command 'rm'.
Some tests are more interesting when run as superuser or as setuid executables. When this is relevant, the description tells how to do it. You must be logged in as an administrative user in order to do those test variations involving superuser or setuid.
The tests consist of individual classes, each with a main() method. Each test class also has a single test() method that does the actual test. The main() method of each class simply does some setup and then calls test(). Thus, you can invoke an individual test, or you can call the tests yourself after doing your own setup in your own main() method.
Setup consists of setting the Posix factory class. The platform's default is used when no other factory is designated. You designate a specific factory by assigning the following property:
app.posix.test.factory = your.factory.name.HereSetting the app.posix.test.factory property to a fully qualified class name overrides any default factory-class for the platform.The glguerin.posix.PosixImps class reads system properties for additional factories. The property names have the pattern "glguerin.posix.imp.*", where the "*" is any text. The text is taken as the platform-identifier, has underbars translated to spaces, and is then used to match against the "os.name" property's value. See the API Javadocs for the glguerin.posix.PosixImps class and the glguerin.util.ImpList class for more details.
You must be an admin user in order to do this. If you're not, too bad. If you have an admin user account, you need to be logged in under that account.First, you should already be fairly fluent with the concept of superuser, and the 'sudo' command. If you're not, you can all too easily mistype something and seriously damage the system configuration. Being the superuser, or acting like one, carries certain responsibilities. Ignorance is not one of them.
The simplest way to run any of the Easy Posix Toolkit tests under setuid-root privileges is to make a shell file (a shell script). This is fairly easy to do. First, the shell file needs to contain the command-lines you want to execute as root. Here's an example that runs the TestUID test:
#!/bin/sh java -cp All-Posix.jar app.posix.test.TestUIDGet those lines into a text-file any way you can. Use 'echo', 'vi', or even TextEdit.app.Let's say you have those command-lines in a text file named 'tsuid'. So then issue these commands:
chgrp wheel tsuid sudo chown root tsuid sudo chmod 4550 tsuidThe first command changes the group to 'wheel', which is a privileged group that only admin users belong to. The second command changes the owner to 'root'. The third command sets the setuid bit, and also makes the file 'r-x' for the owner (root) and for members of the 'wheel' group. For everyone else, the file cannot be read, written, or executed. If you want more details, read 'man sudo' and 'man chmod'. If you have no idea what I'm talking about, you shouldn't be doing this.Next, execute the new command:
./tsuidand you should see TestUID run. The real user ID will be your login user ID, but the effective and original user ID will be root.When you're done playing, IMMEDIATELY DELETE THE SHELL FILE using the 'rm' command. DO NOT just drag it to the Trash. Deleting the setuid-root file ensures that neither you nor anyone else can execute it in the future, nor attack it trying to get root permissions.
TestEnv tests the getEnvString() method of the Environs class. This test uses command-line args as environment-string names, and prints out the values of the environment strings it received. If no command-line args are received, then no environment strings are printed.You can pass any name as a command-line arg and see its environment string, if any. If there is no such environment string, then "null" appears. In general, environment names are case-sensitive, so "USER", "User", and "user" each refer to different variables.
On Mac OS X, it is revealing to compare command-line outputs with those from a double-clickable app. First, you will find that a number of environment variables are not set in the double-clicked environment, including PWD, TERM, and GROUP. Even CLASSPATH may not be present as an environment variable, despite its availability as a system property. Second, you will find that some environment variables have different values than in a command-line environment, such as PATH (the command-path). As a result, double-clicked Java applications almost never have the same set of environment variables or values that a command-line Java application does.
Examples:
java -cp All-Posix.jar app.posix.test.TestEnv USER TERM java -cp All-Posix.jar app.posix.test.TestEnv PATHThe first command prints the values for the USER and TERM environment strings. The second command prints the value of the PATH environment string. It's typically a longer string than USER or TERM.
This is the only test that can be run without a concrete Posix implementation for the host platform. All the other tests instantiate a concrete Posix imp and then call its various methods and classes.TestFactories exercises the PosixImps and ImpList classes. It lists all the available factories, both hard-wired and loaded from system properties. It also tells you which factory would be selected for the platform, given the set of system properties it receives.
You can run this test using just the default system properties, to learn which Posix factory will be selected for your platform.
A more interesting way to run this test is to define additional system properties in the proper name pattern for PosixImps, and give them dummy values for factory-classes. Or you can given them real factory-class values and observe how different platforms select the factory class.
Examples:
java -cp All-Posix.jar app.posix.test.TestFactories java -Dglguerin.posix.imp.Mac_OS=no.Mac -Dglguerin.posix.imp.Win=lose -cp All-Posix.jar app.posix.test.TestFactories java -Dglguerin.posix.imp.Mac_OS_X=glguerin.posix.imp.un.UnPosix -cp All-Posix.jar app.posix.test.TestFactories java -Dapp.posix.test.factory=glguerin.posix.imp.un.UnPosix -cp All-Posix.jar app.posix.test.TestFactories
TestFile tests FileRef and FileState, and creates several files in the current directory. The filenames are in the pattern "file-*", so they are easy to remove. This test uses the glguerin.xio.Pathname class for representing absolute pathnames.TestFile begins by displaying the user ID info and the PathnameFormat class it's using. It then points a FileRef at the current directory and displays a multi-line description of it. Then it adds a "." element and a leaf file-name element to the Pathname, and creates the file. The "." is intentionally redundant, and exercise the pathname resolving process. The leaf file-name element is "file-accent", but with accented chars or "puns" for the "accen" chars. Specifically, the chars are a-circumflex, cent-sign, c-cedilla, e-grave, n-tilde. The 't' is ordinary. These are represented as their composed-accent forms. The accented chars are to exercise both the Pathname and PathnameFormat capabilities, and to see how well the FileRef implementation and OS handle accented chars. All the accented or special chars are valid ISO-Latin-1 chars.
With the file created, the test keeps the original permissions, then goes through setting the permissions to different values and displaying the result in a one-line output similar to 'ls'. It then restores the original permissions. At that point, the file's ownership is set: first to the process's real user ID, then to the process's login user ID. A line describing the result is printed each time. For setuid processes, the real and login user IDs will be the same. For 'sudo', the real user ID will be superuser but the login ID will identify the user. For other processes, the real and login IDs will already be identical to the file's owner, so no error occurs.
The test proceeds by creating first a hard-link ("file-link") then a symlink ("file-symlink") to "file-accent". After creating the hard-link, the link-count will be 2. After the symlink, it will still be 2. Then the test checks whether File.getCanonicalPath() resolves symlinks or not. If it does, the result should show the canonical path of "file-symlink" to be "file-link".
A named pipe is then created: "file-pipe". We don't test whether it works or not, but we do show it using the ls-like display.
Finally, a number of Unix-specific devices are listed, in order to check how well FileState.getNodeType() works. These are block and char devices, and may or may not exist on your platform. They exist on Mac OS X.
Examples:
java -cp All-Posix.jar app.posix.test.TestFile ls -l file-* rm -f file-* sudo java -cp All-Posix.jar app.posix.test.TestFile ls -l file-* rm -f file-*The first command runs the test. The second command shows the files the test created. The third command removes the test's files. The fourth command runs the test as superuser. You should observe different ownership on the files as the test runs. The fifth and sixth commands list and then remove the test files.
TestFileRel tests the relative-pathname capabilities of FileRef. Since implementations are not required to support relative pathnames, this tells you what the imp does.TestFileRel pretty much mirrors what TestFile does, so I won't repeat it here. TestFileRel stops after creating a symlink and then resolving it with getCanonicalPath(). So it doesn't go on to make a relative-pathname named pipe, nor does it test the node-type capabilities with device pathnames.
TestFileRel does not use the Pathname class. Instead, it has a simple nested class called Name that is basically just a mutable holder for a String. You could extract and reuse it, but it's so simple you can probably figure it out yourself.
Examples:
java -cp All-Posix.jar app.posix.test.TestFileRel ls -l rel-* rm -f rel-*The three commands do the same as for TestFile, but for the relative-pathname files.
TestFileRel tests the FileRel and FileState imps by using them to do a very simple ls-like utility. Well, it's not really very ls-like because it does not list directories. It's really more like 'ls -ld'.This test is almost a demo, because it doesn't really exercise much that other tests don't already do. It does show how to use the Easy Posix Toolkit in a more real-world kind of application, though.
Examples:
java -cp All-Posix.jar app.posix.test.TestFileState . .. All-Posix.jarThe command will produce output summarizing the current directory (.), the parent directory (..), and the JAR file itself. The output is similar to that produce by 'ls -ld', though not exactly.
TestGID exercises the GroupID methods. It could do more, testing toReal(), toEffective(), and become().The test begins by listing the real, effective, and stored group ID. It then calls GroupID.getGroups() and lists all the groups to which you belong.
Examples:
java -cp All-Posix.jar app.posix.test.TestGID
TestLimits exercises the ResourceLimit and ResourceUsage implementations, and the Posix methods that use them. It's also useful for seeing what the current limits are. Finally, you can set the limits using a shell command and observe the effects by running TestLimits.The test begins by telling you the real and effective user ID of the process. It then tells you the current process ID and parent process ID, along with the umask and nice values. Then it tells you the current hard and soft limits for every limit. Finally, it tells you the ResourceUsage statistics up to that point.
On Mac OS X, most limits initially have an unlimited hard-limit. Stack-size is typically the only initially hard-limited resource. There are initially soft-limits of 100 processes and 256 open files (descriptors).
If you set a limit with the 'limit' shell command, then you will see different soft-limits. You may also see that a resource with no previous hard-limit then takes on a hard-limit. These are typically the system-imposed limits, or those imposed by the shell's implementation of the 'limit' command.
Examples:
java -cp All-Posix.jar app.posix.test.TestLimits limit descriptors 512 java -cp All-Posix.jar app.posix.test.TestLimitsThe above example runs TestLimits to see the initial limits, then runs the shell command 'limit' to set the descriptors soft-limit to 512. The next run of TestLimits will show the new soft-limit, and also a system-imposed hard-limit for descriptors ("Open-files" in the TestLimits output).
TestLimitsCPU tests the operation of the CPU-time resource-limit. If the feature isn't available on your platform, the program will exit with a message to that effect. If the feature is available, a 15-sec CPU-time limit is established and then exceeded. The program should then terminate, since it does not establish a signal-handler to catch the time-limiting signal.The test begins by showing the initial default CPU-time limit. This will typically be unlimited, unless your configuration sets CPU-time limits. The test then sets a soft-limit of 15 secs, and displays that as the requested limit. After setting the new 15-sec limit, the test then rereads the limit and displays that. The new limit should be the same as what was requested. With the new limit in place, a purely computational loop is entered, thereby consuming CPU-time. If CPU-time limits really work, then the process is eventually terminated with an appropriate signal. If CPU-time limits don't work, then you should be able to tell after about 15 secs or so. Then you can just terminate the program with a keyboard interrupt, or a kill, or whatever.
Processes that are terminated by signals typically emit a very brief message to the terminal. On Mac OS X, this is "Cputime limit exceeded" for the signal representing CPU-time limits.
Examples:
java -cp All-Posix.jar app.posix.test.TestLimitsCPUThe command runs the test. On Mac OS X, which supports CPU-time limits, you will see 3 lines describing the steps of the test, then about 15 secs will elapse, and finally "Cputime limit exceeded" will appear when the process is terminated. You can also interrupt the program before the CPU-time limit expires.
TestMounts exercises the Environs.getMounted() method. That method returns an array of MountInfo objects representing all the mounted volumes and partitions. The boot drive appears as the root "/". Thene there are some other incidental system-maintained mounts. Finally, the volumes mounted in "/Volumes/" are listed.You can use this test to see everything that's mounted as a volume, including CD's or other removable media. You can also see the free space on every disk.
As a variation, you can make a disk-image or two, mount them, then run this test to see them listed as mounted volumes.
Examples:
java -cp All-Posix.jar app.posix.test.TestMounts
TestNice exercises the ProcessAttributes methods for working with nice levels (process priority).The test begins by telling you the process ID and parent process ID and the initial nice level. It then goes throw its test sequence. This consists of increasing the nice level (i.e. decreasing the priority) by 10 units, then restoring it by steps of 3. Normal users will only be able to increase the nice level. The attempts to restore it will have no effect.
If you run the test again using the 'nice' command, you can see the initial nice level change (from 0 to 10), and the subsequent test sequence then goes to nice 20 and attempted restoration.
If you run the test as superuser using the 'sudo' command, you can see the nice level is movable in both directions, and can even go negative.
Examples:
java -cp All-Posix.jar app.posix.test.TestNice nice java -cp All-Posix.jar app.posix.test.TestNice sudo java -cp All-Posix.jar app.posix.test.TestNiceThe first command shows that normal users can increase nice level but not decrease it. The second command shows the change in default nice level when you 'nice' a command. The third command shows how the superuser can change nice levels in both directions.
TestSignals exercises the basic signal naming and identification capabilities. It does not send signals, nor does it change the disposition of any signals. It does not receive signals, either.The test begins by telling you the real and effective user ID of the process. It then tells you the current process ID and parent process ID, along with the umask and nice values. Finally, it tells you the signal-mask value followed by a list of signal numbers, signal names, and signal dispositions.
The list always consists of signal numbers 0 thru 32. Some platforms may not support all these signals. Indeed, no platform supports signal number 0, because that means "no signal". A specific range of numbers is used in order to test the Signals error-handling for unsupported signal numbers. Any unsupported signal number returns a name of "???" and a disposition of NORMAL.
A supported signal number returns its signal name and disposition. On Mac OS X, you'll see valid names for signal numbers 1 thru 31. The disposition will be NORMAL, IGNORED, or UNIDENTIFIED. On Mac OS X, you'll typically see NORMAL for all signals except SIGQUIT and SIGPIPE. SIGQUIT will be UNIDENTIFIED, and SIGPIPE will be IGNORED. On other platforms you may see other signals with UNIDENTIFIED disposition, depending on which signals the JVM install signal-handlers for.
The UNIDENTIFIED disposition of SIGQUIT on Mac OS X is because the JVM installs a handler that generates a thread-dump on the system console or stderr. You can tell the JVM to not install this handler using the "-Xrs" option. Then you should see the NORMAL disposition for SIGQUIT.
Examples:
java -cp All-Posix.jar app.posix.test.TestSignals java -Xrs -cp All-Posix.jar app.posix.test.TestSignalsThe first command shows the typical set of signal dispositions. The second command tells the JVM to not install any signal-handlers of its own. You should then see NORMAL for all the signals whose disposition was UNIDENTIFIED under the first command.
TestSignalsCaught tests signal-handling and other signal-disposition options (ignoring, exiting, defaulting). It is the most complicated of the tests because it uses two Terminal windows. In one window, you run TestSignalsCaught. In the other, you use the 'kill' command to send signals to the waiting TestSignalsCaught program. Depending on the signal you send, TestSignalsCaught will either do something immediately, or let the signal be delivered into a SignalQueue. Some signals cause TestSignalsCaught to terminate immediately, or to enter the stopped state.The test begins very much like TestSignals does, telling you the initial signal-handling state. It then sets up its own signal dispositions, and displays the new signal-handling state. This new state will show several signals as "received on Incoming", several others as "received on Hoarding". Signal 6: SIGBRT will show as EXITING and signal 20: SIGCHLD will show as IGNORED. Finally, a few lines are displayed telling you which signals to send that cause various actions, and the all-important pid (process ID) that the signals must be sent to.
The test arranges for signals to be delivered to two different SignalQueues, named "Incoming" and "Hoarding". It then waits for signals to arrive on the "Incoming" queue and takes different actions depending on what the signal number is. The "Hoarding" queue, however, is simply left to accumulate signals until a signal 31 arrives on "Incoming", then the "Hoarding" queue is emptied and each signal displayed in the order received. This illustrates both the wait-for-signal approach and the let-signals-arrive approach that programs can employ with SignalQueues. It also illustrates how individual signals are delivered only to a single SignalQueue.
When this test is run on platforms other than Mac OS X (using your own implementation), the signal-numbers may differ, though the signal names should be unambiguous. You may have to tailor the source so that platform-supported signal numbers are delivered to the "Hoarding" queue.
Examples:
Run this command in one Terminal window:java -cp All-Posix.jar app.posix.test.TestSignalsCaughtAt the end of its output, it will stall waiting to receive signals. Note the process ID in the line that says "Send to pid: NN" where NN is some number. Go to another Terminal window and type:kill -31 NNwhere NN is the process ID you noted earlier. You will see brief messages in the original Terminal window:## Received signal 31, SIGUSR2 ## Nothing hoardedYou can then send additional signals, which will be hoarded:kill -16 NN kill -23 NN kill -24 NN kill -25 NNYou can also go back to the original Terminal window and resize it, which causes a signal 28 to be sent. Then send a signal 31 again, and the hoarded (queued-up) signals will be dumped:kill -31 NNTo terminate the signal-receiving process, you can enter ctrl-C in the original window, or you can send a signal from the second window:kill NNThe program catches the signal, ends its signal-waiting loop, and terminates cleanly. You can send it other signals that terminate it or cause an immediate exit, or are ignored, or do other things.You can also run TestSignalsCaught as a Mac OS X double-clickable app with console output. You still send it signals using the 'kill' command. You may have to bring TestSignalsCaught to front to get it to update its console window. Play around, have fun. Signals are one of the really fun toys in Mac OS X.
TestTime tests the two SysTime methods getMicroseconds() and isMicrosecondsSinceEpoch(). It does not test the setSystemTime() nor adjustSystemTime() methods. See TestTimeSet for those tests.These tests show the minimum time it takes for getting microseconds, and do trial measurements of how long a few of the Posix calls take to execute. This will show you whether you have microsecond resolution on your platform (Mac OS X does), and give you some idea of how long it takes for some Posix calls.
The test begins by making two calls to SysTime.getMicroseconds() in rapid succession. This is roughly the minimum elapsed time you can measure. It will vary somewhat from run to run. It will also vary depending on which machine you run it on, and how fast the CPU is being clocked.
The test then measures the elapsed time for calling Posix.getMounted() once and UserID.getUserInfo() twice. The two calls to getUserInfo() should show the second faster than the first, because the data being parsed will be cached. Finally, the stop time is shown as a Date, and isMicrosecondsSinceEpoch() is shown.
You can try to observe the effects of the HotSpot JITC by passing different args that control HotSpot. Try -Xint along with -client and -server. Your version of Mac OS X or Java may not support the -server option. On Mac OS X, try -Xcomp, too.
Examples:
java -cp All-Posix.jar app.posix.test.TestTime java -Xint -cp All-Posix.jar app.posix.test.TestTimeThe first command runs with the default HotSpot behavior (mixed-mode). The second command runs in interpreted mode only.
TestTimeSet exercises the SysTime methods methods setSystemTime() and adjustSystemTime(). The effective user ID must be superuser. I recommend running the test via 'sudo', though you could also use a setuid-root executable.Because reckless changing of system time can have unpleasant consequences, this test is careful in what it does. It calls setSystemTime() to advance the clock 30 secs. This avoids the possibility of failing should the system not allow backwards time-setting. Besides, even if the system allowed backwards time-setting, it's a bad idea to set time back. A 30-sec interval is enough to see, but not enough to be a serious problem, even if left uncorrected.
However, the test also arranges to correct what it just set. After setting the time forward by 30 secs, it calls adjustSystemTime() with a correction of -30 secs. That is, the requested correction negates the effect of the forward jump. The correction will be applied gradually, though, not in a quantum jump.
Depending on the platform, the 30-sec forward jump may or may not appear to the test program. Regardless of platform the minus-30-sec correction will not appear to the test. Since the test may not see the results of its action, we have to enlist other commands. The POSIX 'date' command works perfectly for this. You run 'date' right before running TestTimeSet, then again right after. You should observe a 30-sec forward jump in the time that 'date' emits.
There is no easy way to directly observe the minus-30-sec correction. It's applied too gradually to be observed. One way you can indirectly observe the effects of the correction is by synchronizing to a network time server. Do this once before running TestTimeSet. If you do it again shortly after running TestTimeSet, you should observe about 30 secs of difference. This is expected because you've jumped the system time forward by 30 secs, but haven't given the correction enough time to be applied. So to observe the correction effects, do this. Synchronize to a network time server before running TestTimeSet. Run TestTimeSet. Then about an hour or two later, synchronize to the time server again. This should give enough elapsed time for the correction to be applied, or at least partially applied. When you resynchronize after an hour or two, you may still see a difference of more than a second or two. This means that the 30-sec correction has not been fully applied. Try the sequence again, but wait 3 or 4 hours before resynchronizing. Crystal oscillators, even ones that aren't temperature-stabilized, are not so inaccurate that they lose 30 secs over a period of 3 to 4 hours. So if at the end of your waiting period you see that the system time and the time server agree to within a few seconds, it means the correction was applied, and shows that adjustSystemTime() works.
Examples:
sudo ls date; sudo java -cp All-Posix.jar app.posix.test.TestTimeSet; dateThe first command simply ensures that 'sudo' is primed with your password and user identity. It executes the innocuous 'ls' command. If 'sudo' isn't primed, it will ask for your password on the 'ls' command, rather than on the 'java' command. The trio on the second line is a one-line sequence that executes the 'date' command before and after running TestTimeSet as superuser. You should see the test's output, bookended by two time-stamps from 'date'. On Mac OS X, you will probably not see any time-difference in the test's output. You should, however, see about 30-secs of difference between date's two time-stamps. You may see a few seconds more than 30, which is basically the time it takes to load and run the 'java' command.
TestUGID simply runs the TestUID test then the TestGID test in a single run.Examples:
java -cp All-Posix.jar app.posix.test.TestUGID
TestUID exercises the UserID class. It can be run from a setuid executable to show how a real and an effective user ID are managed and manipulated. See the directions for making Mac OS X setuid executables.The test begins by listing the login, real, effective, and stored user ID's. Each ID is listed as "number:name", where the number is the integer user ID and the name is that returned by UserID.getName(). The getName() method is actually declared in AccessID, but is inherited by UserID and GroupID.
Next, the test lists the UserInfo data it retrieves for its own real user ID. If you are running with 'sudo', and you have enabled the root account, this will show the encrypted root password. Even though it's encrypted, all password data should be considered sensitive data, and the root password even more sensitive. If the root account is not enabled, or you are not running with 'sudo', then the root password is returned as "*", which means "unavailable".
Following the UserInfo for the real user ID, the test lists all the available account data for all available accounts, as returned by UserID.getAllUserInfo(). As before, encrypted passwords are shown, but this is still sensitive data. You should expect to see a handful of accounts that you did not create. For example, user names "unknown", "www", "daemon", and "nobody" will appear on Mac OS X (and probably other Posix-like OSes). There are user IDs that the system keeps for its own use. You will notice that that all have "*" for the password, and "/dev/null" for the login shell. That means that these accounts cannot be logged in. You should think of them as user-IDs only, rather than as full-fledged user accounts.
After listing the user account data, the test finally executes a series of toReal(), toEffective(), and become() methods, showing the real, effective, and stored user IDs after each method call. Whether you run as a normal user or superuser with sudo, these should all show the same user ID. The only way you'll see differences in the user IDs is if you're running a setuid executable. You can do this by making a shell script, or by making a double-clickable app setuid. See the directions for making Mac OS X setuid executables. Examples:
java -cp All-Posix.jar app.posix.test.TestUID sudo java -cp All-Posix.jar app.posix.test.TestUIDThe first command runs the test under your normal user identity. The second command runs the test as root. Notice how 'sudo' changes the real and effective user ID to root when running the test. Also notice that despite 'sudo' changing the real user ID, it has no effect on the login ID.
TestUIDSet tests the UserID.as() method more extensively than TestUID does. It also illustrates that there are constraints on the user-ID transitions, even for superusers. This test uses the command-line args. The test creates files, which remain after the test ends.The test begins by showing the login, real, effective, and original user IDs. If the process lacks superpowers, then a message is printed and the test ends. Continuing, the test then takes on the effective user ID of the superuser. It then walks the command-line args as a series of numerical user IDs, which it acts as in order, creating a unique file under each ID. Failures elicit a message, and the next arg is tried. The file created under each ID is named "created-as-N", where "N" is the numeric user ID. The user ID must have write permission in the current directory, or the file will not be created.
After running the test, use 'ls -l' and observe that the owner of each created file is the effective user ID at the time of creation.
Examples:
java -cp All-Posix.jar app.posix.test.TestUIDSet 601 0 602 sudo java -cp All-Posix.jar app.posix.test.TestUIDSet 601 0 602 sudo java -cp All-Posix.jar app.posix.test.TestUIDSet 1 0 -2 rm -f created-as-*The first command does nothing but print a message, unless it's running setuid-root or you are logged in as root. The test detects that you don't have superpowers and stops.The second command runs as superuser, thanks to 'sudo', so it's able to act as all the user IDs. However, it can create files only for those users that have write permission in the current directory. You can temporarily change the write permissions and observe that all files are created, and see their ownership. The user IDs are arbitrary, and you may not have any actual user account under 601 or 602 IDs. You can use user IDs that you do have, if you want.
The third command also runs as superuser, and acts as the user IDs 1, superuser, and -2. User ID 1 is the 'daemon' user, and -2 is 'nobody', both of which are system-maintained IDs.
The fourth command removes all the test-created files. You may need to use it after each test run.
TestUMask exercises the ProcessAttributes methods for working with the umask. The umask determines which permissions-bits are forced to 0 when new files and directories are created with default permissions. The typical default value of the umask is 022 octal.The test begins by showing the umask as an octal number. It then proceeds through a sequence of creating a directory and changing the umask. Each new directory's default permissions will be affected by the value of umask in effect at the time of creation. The directories are given names that indicate what value of umask was in effect at the time of creation.
This test creates directories in the default directory. The names all have the pattern "umask*.dir". Existing directories that conflict with a desired name are unaffected. Use the command 'ls -l' after running the test to observe the effects on the new directories. Use 'rmdir umask*.dir' to remove the created test directories.
Examples:
java -cp All-Posix.jar app.posix.test.TestUMask ls -l rmdir umask*.dirThe first command runs the test. The second command shows the results of the test. The third command removes the directories created by the test.
To Greg's Home Page
To Greg's Software Page