CSCI 235 — Directory search — C and Python

Getting started

Makefile

It’s a little complicated to use nftw, so copy our Makefile.

C

Stick this at the beggining of your C code.

#define _XOPEN_SOURCE 500
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <ftw.h>

int main(int argc, char *argv[]) {
  

Check the command arguments! Be sure that argc > 1. Then make sure that argv[1] is a directory! You can do this with a call to stat by passing the pathname and a struct stat and then use S_ISDIR to check the mode (st_mode) field returned in the stat structure.

For consistency with the rest of this tutorial, save the name of your directory in the variable dir_name.

Python

Stick this at the beggining of your python code.

#! /usr/bin/env python3
""" CSCI 235 program to list files """
import sys
import os
  

Check out the documentation for sys.argv to see how Python programs process command line arguments. (Hint: It’s pretty much an array of strings.) Now take look up os.path.isdir to see how to check if a pathname refers to a directory. Finally, look at sys.exit to see how to make an early exit from your program. For consistency with the rest of this tutorial, save the name of your directory in the variable DIR_NAME.

Be sure to make your Python script executable by using the chmod program. This is possible due to the Unix sha-bang.

I/O has changed a bit in Python 3. The following statement shows you have to print a semi-nicely formatted error message.

    print("{0} is not a directory".format(DIR_NAME)) ;
  

Wait! There’s one more thing. As a Python hacker, you must run pylint3 to make sure your code is a 10.

Getting ready

C

Well, this will be a tad difficult. Add a dummy routine called file_check that can be passed as the second argument of nftw. For now, your routine should do nothing more than return 0. Place your file_check before main. Start by going to the man page for nftw and coping the second parameter of nftw into your program to create a header for file_check. You will need to replace the (*fn) with file_check.

Python

It’s hard to think of something comparable to add to the Python program, but go ahead and take a look at os.walk. Also, add the following do-nothing for loop to the end of your Python code and wonder what it does.

for dir_path, dir_names, file_names in os.walk(DIR_ARG, followlinks=False):
    print("waz up") ;
  

Try out your program.

Getting close

C

Add to main a call to nftw, the magic tree walker. It has four arguments:

  1. A directory name. This is the command-line argument, that is argv[1] or dir_name.
  2. The file inspector. You called it file_check.
  3. Number of open files. I used 235.
  4. The flags argument. I used FTW_MOUNT | FTW_PHYS; to avoid getting into loops.

Now go into file_check and change it to print the argument fpath.

Python

Printing waz up was silly. How about using a for to iterate through all the files in file_names and doing something like: print("{0:s}".format(f)).

Getting there

C

The problem with the C program is that prints both files and directories.

There’s an easy fix for this. All you have to do is check the typeflag passed to nftw. There is a special flag for a regular file!

Python

The problem with the Python is that it doesn’t print the entire file name. It leaves out the directory part. This sounds like a job for os.path.join.