Exploration in C
We’re going to run through a few exercises here.
/* CSCI 235 lab */ #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <string.h> #include <unistd.h> int main(int argc, char** argv) { return (EXIT_SUCCESS); }
Make sure you can compile it.
Testing your homework answers
First download a pretty simple C program.
C gives you many ways to “cheat” on tranforming float
to/from int
(should use uint32_t
) and
double
to/from long
(should use uint64_t
).
Modify your program to try out the following:
Java provides some safer operations for these transformations.
Float.floatToRawIntBits(float)
Double.doubleToRawIntBits(double)
Float.intBitsToFloat(int)
Double.longBitsToDouble(long)
Evidently, it is useful to access the bits when implementing some numerical routines.
Using command line arguments and creating file
Write a program that, when run with a variable number of
arguments, as shown below:
yourprogname filename1 filename2 ...
will, for each i, check if a file named
filenamei exists
(use access()
)
and, if it does not,
create filenamei
and write a single line containing
i to filenamei.
Use access
,
fopen
, fprintf
, and fclose
.
Listing a directory
Look at the GNU example of a simple program to list a directory. Cut-and-past the program and compile it on your computer.
Modify the program so displays only “files” that
that are regular files (not directories). Display both the
file name and inode number for these files.
Look at the documentation for
readdir
to see how your can obtain the inode number.
Sorting a directory
This part is a little more difficult.
Read the /var/tmp directory;
and store copies of the
struct dirent
returned for each file into an array.
Assume that there are no more than 1000 files in the array.
You should be able to copy the struct dirent
into the array with a single assignment statement.
Now try using
qsort
to
sort the files of /var/tmp by
inode number.
OK. That is a bit much, but look at the
Microsoft page on using qsort
to
see some outragious use of type puning.
Polishing off the old lab
Were going to finish up last week and then do a few more explorations of C.
Retrieving the old lab work
Download the
C
file you created last week.
It should have a working copy of the
name2num
program.
I suggest you use the command line this week. It will be easier for testing. Use nano (or a similar text editor) to modify your program and use make for compilation and gdb for debugging.
Small task two: Routing addresses
Many of you have already done this part. If so, go to the next section.
The output of netstat -nr contains the following lines:
Kernel IP routing table Destination Gateway Genmask Flags MSS Window irtt Iface 0.0.0.0 152.18.69.254 0.0.0.0 UG 0 0 0 eth0 152.18.69.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
The destination and mask together define a matching rule.
Suppose the IP number of a running computer is 152.18.69.70 in dotted
decimal and consequently 0x98124546
in raw bits.
Also, assume netstat has a routing entry for
destination 152.18.69.0 (0x98124500
) with the mask
255.255.255.0 (0xffffff00
).
If you go into gdb and perform
a bit-wise AND (&
) of
0x98124546
(152.19.69.70) and
0xffffff00
(255.255.255.0), you will get
0x98124500
(152.19.69.0), which matches
a route entry’s getway.
That’s how the operating
system knows that packets to 152.19.69.70 should be sent directly
through the Ethernet interface eth0
.
See the Wikipedia
article on routing tables for more information and try out the
following gdb command to verify my
calculation.
printf "%x",0x98124546 & 0xffffff00
The real task
Modify your program to write LOCAL after each IP number that is local to the computer science VLAN, 152.18.69.0 with gateway 255.255.255 — usually written as 152.18.69.0/24.
Small task three: Reading command line arguments
Modify your program so that, if it is started with two arguments, one
for the network destination and the other for the network mask, it will
use use the first argument for the gateway and the second for this task.
This means that your program could be started with either of the
following commands:
progname
progname 192.168.0.0 255.255.0.0
Small task four: Writing to a file
Modify your program so that it writes its output to
the file /var/tmp/output.txt.
This is really a very small change: It involves adding
one statement (calling fopen
)
and modifying two others.