CS16, Fall 2009

lab07a: ("lab seven a")

Various topics
(chmod, ls -l, executable files, Ch for entire programs)

 



This lab does not require you to turn anything in
but the material in this lab WILL be on the midterm exam

So, it is strongly recommended that you complete it!

You can do so with your pair partner,
or individually—your choice

By the time you have completed this lab, you should:

Prior Skills/Knowledge Needed

Before completing this lab, you should:

 

Step by Step Instructions

 

Step 1: Log on to CSIL, create ~/cs16/lab07a and copy this lab's files:

If you've forgotten how to create the directory, consult steps 1 and 2 from lab01.

The files for this weeks lab can be found here:

And here:

~pconrad/public_html/cs16/09F/labs/lab07a/files/*

You can use the same techniques described in lab04 to copy those into your ~/cs16/lab06 directory. Consult the instructions for lab04 if you don't remember how to do this.

Step 2: Reviewing what we already know about the word "executable"

So far this quarter, when we've worked with a C program such as the cmdlinedemo.c program in this week's files, we've used the make command to create an "executable file", like this. (Try each of these commands for yourself as you follow along.)

-bash-3.2$ ls
cmdlinedemo.c demoTypes.c
-bash-3.2$ make cmdlinedemo
cc cmdlinedemo.c -o cmdlinedemo
-bash-3.2$

After doing this, as we know, we can use the command ./cmdlinedemo to run the program, with or without command line arguments:

-bash-3.2$ ./cmdlinedemo 
argc=1
argv[0]=./cmdlinedemo
-bash-3.2$ ./cmdlinedemo foo bar
argc=3
argv[0]=./cmdlinedemo
argv[1]=foo
argv[2]=bar
-bash-3.2$

This tells the operating system: "look in the current directory (the ./ stands for current directory) for a file called cmdlinedemo and start executing the instructions you find inside.

Now we want to look a little more closely at what is happening here.

Step 3: What makes a file "executable"

What you may already realize, but we want to highlight this week, is that the reason this works is because there is an executable file called cmdlinedemo in your current directory, as we can show with the ls command:

-bash-3.2$ ls
cmdlinedemo cmdlinedemo.c root.c
-bash-3.2$

If we use the ls -l command instead (-l stands for the "long" form of the directory listing), we see more information about the files:

-bash-3.2$ ls -l
total 16
-rwxr-xr-x 1 pconrad faculty 4955 2009-11-12 07:49 cmdlinedemo
-rwxr-xr-x 1 pconrad faculty 459 2009-11-12 07:49 cmdlinedemo.c
-rwxr--r-- 1 pconrad faculty 430 2009-11-12 07:49 root.c
-bash-3.2$

What we want to focus on here is the leftmost x that appears in the row for the file cmdlinedemo, namely the one underlined and bold in this listing below:

-bash-3.2$ ls -l
total 16
-rwxr-xr-x 1 pconrad faculty 4955 2009-11-12 07:49 cmdlinedemo
-rwxr-xr-x 1 pconrad faculty 459 2009-11-12 07:49 cmdlinedemo.c
-rwxr--r-- 1 pconrad faculty 430 2009-11-12 07:49 root.c
-bash-3.2$

That particular x indicates that the owner of the file "has permission to execute the file", i.e. to ask the Unix operating system to start carrying out the instructions in the file.

In this case, those instructions happen to "machine language instructions in binary". We can see that if we use the special command file cmdlinedemo, which tells what kind of file cmdlinedemo is:

-bash-3.2$ file cmdlinedemo
cmdlinedemo: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked
(uses shared libs), for GNU/Linux 2.6.9, not stripped
-bash-3.2$

The output is long and detailed, but focus on this part that's underlined and bold in the listing below:

-bash-3.2$ file cmdlinedemo
cmdlinedemo: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked
(uses shared libs), for GNU/Linux 2.6.9, not stripped
-bash-3.2$

That part of the output indicates that the file is in machine language that is targeted for the Intel 80386 family of processors. Contrast that with the output of the command file cmdlinedemo.c:

-bash-3.2$ file cmdlinedemo.c
cmdlinedemo.c: ASCII C++ program text
-bash-3.2$

Here we see that the file is ASCII text of a C program (which we already knew—but this shows that the "file" command is able to distinguish between the two.)

Step 4: When is an executable file not executable?
(When we don't have execute permission...)

Now comes the fun part.

We are going to show that even though the file cmdlinedemo contains executable instructions, we can take away our permission to "execute" the file—i.e. make it non-executable—by changing the permission modes with the chmod command.

Then, we can bring back that permission again.

To proceed, change the permissions on the file cmdlinedemo to rw-r--r--, which corresponds to 644, like this:

-bash-3.2$ ls -l cmdlinedemo
-rwxr-xr-x 1 pconrad faculty 4955 2009-11-12 07:49 cmdlinedemo
-bash-3.2$ chmod 644 cmdlinedemo
-bash-3.2$ ls -l cmdlinedemo
-rw-r--r-- 1 pconrad faculty 4955 2009-11-12 07:49 cmdlinedemo
-bash-3.2$

Then, try to execute the file. Notice that you get an error:

-bash-3.2$ ./cmdlinedemo
-bash: ./cmdlinedemo: Permission denied
-bash-3.2$

Then, try to change it back to rwxr-xr-x (i.e. 755) as shown here:

-bash-3.2$ chmod 755 cmdlinedemo
-bash-3.2$

Try running it again. Success!

-bash-3.2$ ./cmdlinedemo
argc=1
argv[0]=./cmdlinedemo
-bash-3.2$

Now, you see that even though a file might be in the executable format—that's not enough for us to be able to run the file:

Step 5: When is something executable not an executable file?
(Introducing shell scripts...)

As it turns out, we can set the execute permission on certain files other than those that contain binary machine language instructions. One example is something called a shell script.

As an example of when we might use a shell script: suppose we have a file that uses the sqrt function—this weeks file contain a little example program called root.c that prints the square root of its command line argument.

As you may recall, if we try to compile a program that uses math functions such as sqrt, sin, cos, etc. with our usual trick of just typing "make progname", we run into a problem, demonstrated here with trying that on root.c:

-bash-3.2$ make root
cc root.c -o root
/tmp/ccwG7MLC.o: In function `main':
root.c:(.text+0x6e): undefined reference to `sqrt'
collect2: ld returned 1 exit status
make: *** [root] Error 1
-bash-3.2$

The problem is that the math library has to be specifically requested, so there is a long version of the compile step:

-bash-3.2$ gcc -lm root.c -o root
-bash-3.2$ ./root
Usage: ./root floating-pt-number
-bash-3.2$ ./root 4.0
2.000000
-bash-3.2$

Suppose we want to avoid typing this every time. We can create a special file called a shell script.

Type the following command to start a new file in emacs called makeroot

-bash-3.2$ emacs makeroot

Inside the file makeroot, put the following:

#!/bin/sh -v
cc -lm root.c -o root
The first line, #!/bin/sh -v is a special line that indicates "this file is a shell script". The -v part indicates that you want each line in the script to be echoed as it is executed.

The remaining lines in the file are unix commands—just like the ones you type in at the command line. In this case, we have just one more line—the command we want to run.

So, now, all that remains is to try to run our shell script. We don't have to compile it—shell scripts are a kind of file that can be executed by Unix without having to be turned into machine languages instructions first. We run them just like programs—by typing, for example

./makeroot

There is just one catch, as we find out when we try this:

-bash-3.2$ ./makeroot
-bash: ./makeroot: Permission denied
-bash-3.2$

The problem is that makeroot must have the execute permission set! If we do an ls -l, we can see that it doesn't have that set yet:

-bash-3.2$ ls -l makeroot 
-rw-r--r-- 1 pconrad faculty 35 2009-11-12 08:00 makeroot
-bash-3.2$

So, all that is needed is to use the chmod command to set that—a permission mode of 700 should do the trick:

-bash-3.2$ chmod 700 makeroot
-bash-3.2$ ls -l
total 28
-rwxr-xr-x 1 pconrad faculty 4955 2009-11-12 07:49 cmdlinedemo
-rwxr-xr-x 1 pconrad faculty 459 2009-11-12 07:49 cmdlinedemo.c
-rwx------ 1 pconrad faculty 35 2009-11-12 08:00 makeroot
-rwxr-xr-x 1 pconrad faculty 5232 2009-11-12 07:58 root
-rwxr--r-- 1 pconrad faculty 430 2009-11-12 07:49 root.c
-bash-3.2$ ./makeroot
#!/bin/sh -v
cc -lm root.c -o root
-bash-3.2$

So, we now see that a file that isn't an "executable file"—in the sense that it doesn't contain machine language instructions—can still be executable—in the sense that it can have the execute permission set.

Of course, it isn't as simple as just setting the execute permission. Some files, like C program files, can't be directly executed by the Unix operating system. For example, if we try to run a C program directly, we'll get an error:

-bash-3.2$ ./root.c
-bash: ./root.c: Permission denied
-bash-3.2$

We can try to get around this by setting the execute permission, but that doesn't seem to help. Try it:

-bash-3.2$ chmod 755 root.c
-bash-3.2$ ./root.c
./root.c: line 1: //: is a directory
./root.c: line 2: //: is a directory
./root.c: line 8: syntax error near unexpected token `('
./root.c: line 8: `int main(int argc, char *argv[])'
-bash-3.2$

What is wrong here is that Unix is trying to interpret the C program language file as if it were a shell script—i.e. a sequence of Unix commands. That obviously is not going to get us very far.

If only there were a way to run a .c file directly, without having to compile.

Ah, but there is! Ch to the rescue...

Step 6: Using Ch to run entire C programs

It turns out that we can use the Ch program to execute C programs directly—as long as the execute permission is set on that file.

Try this:

-bash-3.2$ ch
Ch
Professional edition, version 6.1.0.13751
(C) Copyright 2001-2009 SoftIntegration, Inc.
http://www.softintegration.com
/cs/faculty/pconrad/cs16/lab07a> _prompt="Ch> "
Ch>
Ch> ls -l root.c
-rw-r--r-- 1 pconrad faculty 430 2009-11-12 07:49 root.c
Ch> chmod 755 root.c
Ch> ls -l root.c
-rwxr-xr-x 1 pconrad faculty 430 2009-11-12 07:49 root.c
Ch> ./root.c
Usage: /cs/faculty/pconrad/cs16/lab07a/root.c floating-pt-number
Ch> ./root.c 4.0
2.000000
Ch> ./root.c 0.25
0.500000
Ch> ./root.c -9.0
nan
Ch> ./root.c 9.0
3.000000
Ch> exit
-bash-3.2$

As you can see, we can use Unix commands such as ls -l and chmod from inside Ch. And, if we set the execute permission on our C source files (e.g. cmdlinedemo.c and root.c) we can execute them directly inside of Ch, as if they were executable files.

This is because the Ch program is a special kind of "Unix Shell"—one that understands the C programming language directly. Hence,

Why would I want to do this?

There are several reasons you might want to run C programs directly inside of Ch instead of compiling them:

What are the downsides of doing this?

The main drawback of using Ch for running complete programs—rather than the traditional compiler—is the possibility of getting confused about what is legal in C, and what is not.

Another drawback is that it is cumbersome to share pieces of code among different C programs when using Ch. So, this way of using Ch is mainly useful for small standalone programs, like the ones we've written up until now in the course.

Do I need to know how to use Ch?

We think you may find it helpful to know that Ch can be used for running complete programs—not just for little bits of code. But, whether or not you use it for that purpose is entirely up to you.

One thing you should know for the next midterm exam:

This lab has highlighted the point that when we speak of an executable file, there are two things we might mean:

As we've seen these two are independent of each other:

Before the next midterm go back over these steps and be prepared to give an example of each of these situations, drawing on your experiences from this lab.


There is no evaluation or grading for this lab
Completing it is on the "honor system".
But there may be midterm exam questions about its contents.

So the due date is: before midterm 2!

 


Copyright 2009, Phillip T. Conrad, CS Dept, UC Santa Barbara. Permission to copy for non-commercial, non-profit, educational purposes granted, provided appropriate credit is given; all other rights reserved.