We will now see how to achieve similar tasks from within a C program.
int chdir(char *path) -- changes directory to specified path string.
 
Example: C emulation of UNIX's cd command:
#include<stdio.h>
#include<unistd.h>
 
main(int argc,char **argv) 
   { 
				if (argc < 2)
						{  printf(``Usage: %s
								  <pathname
  n'',argv[0]);
								 exit(1);
						 }
				if (chdir(argv[1]) != 0)
						{ printf(``Error in chdir
n'',argv[0]);
								 exit(1);
						 }
				if (chdir(argv[1]) != 0)
						{ printf(``Error in chdir n'');
								 exit(1);
						}
		}
n'');
								 exit(1);
						}
		}
char *getwd(char *path) -- get the full   pathname
of the current working directory. path is a pointer to a string where the
pathname will be returned. getwd returns a pointer to the string or NULL
if an error occurs.
 
Two useful functions (On BSD platforms and NOT in multi-threaded application) are available
scandir(char *dirname, struct direct **namelist, int
(*select)(),
int (*compar)()) -- reads the directory dirname and builds an array
of pointers  to directory entries or -1 for an error. namelist is a pointer
to an array  of  structure  pointers.
(*select))() is  a  pointer  to a function which is
called with a pointer to a directory entry (defined in <sys/types> and should
return a  non  zero value if the directory entry should be
included in the array.  If this pointer is NULL, then all the 
directory  entries  will  be  included.   
 
The  last argument is a
pointer to a routine which is passed to qsort (see man qsort) -- a
built in function which sorts the completed  array.  If this pointer
is NULL, the array is not sorted.
alphasort(struct direct **d1, **d2) --   alphasort() is a
built in routine which will sort the  array alphabetically.
 
Example - a simple C version of UNIX ls utility
#include <sys/types.h>
#include <sys/dir.h>
#include <sys/param.h>
#include <stdio.h>
 
#define FALSE 0
#define TRUE !FALSE
 
extern  int alphasort();
 
char pathname[MAXPATHLEN];
 
main()   { int count,i;
				struct direct **files;
				int file_select();
 
				if (getwd(pathname) == NULL )
						{ printf("Error getting path
 n");
								exit(0);
						}
				printf("Current Working Directory = %s
n");
								exit(0);
						}
				printf("Current Working Directory = %s n",pathname);
				count =
				  scandir(pathname, &files, file_select, alphasort);
 
				/* If no files found, make a non-selectable menu item */
				if 		(count <= 0)
						{		 printf(``No files in this directory
n",pathname);
				count =
				  scandir(pathname, &files, file_select, alphasort);
 
				/* If no files found, make a non-selectable menu item */
				if 		(count <= 0)
						{		 printf(``No files in this directory n'');
								exit(0);
						}
				printf(``Number of files = %d
n'');
								exit(0);
						}
				printf(``Number of files = %d n'',count);
				for (i=1;i<count+1;++i)
						 printf(``%s  '',files[i-1]->d_name);
				printf(``
n'',count);
				for (i=1;i<count+1;++i)
						 printf(``%s  '',files[i-1]->d_name);
				printf(`` n''); /* flush buffer */
		}
n''); /* flush buffer */
		}
int file_select(struct direct   *entry)
 
		{if ((strcmp(entry->d_name, ``.'') == 0) ||
						(strcmp(entry->d_name, ``..'') == 0))
						 return (FALSE);
				else
								return (TRUE);
		}
scandir returns the current directory (.) and the directory above this (..) as well as all files so we need to check for these and return FALSE so that they are not included in our list.
Note: scandir and alphasort have definitions in sys/types.h and
sys/dir.h. 
MAXPATHLEN and getwd definitions in 
sys/param.h
We can go further than this and search for specific files: Let's
write a  modified 
file_select() that only scans for files with a
.c, .o or .h suffix:
int file_select(struct direct   *entry)
 
		{char *ptr;
				 char *rindex(char *s, char c);
 
				if ((strcmp(entry->d_name, ``.'')== 0) ||
						(strcmp(entry->d_name, ``..'') == 0))
						 return (FALSE);
 
				 /* Check for filename extensions */
				 ptr = rindex(entry->d_name, '.')
				 if ((ptr != NULL) &&
						 ((strcmp(ptr, ``.c'') == 0)
						 
 (strcmp(ptr, ``.h'') == 0)
 (strcmp(ptr, ``.h'') == 0)
						  (strcmp(ptr, ``.o'') == 0) ))
								 return (TRUE);
				 else
						 return(FALSE);
		}
 (strcmp(ptr, ``.o'') == 0) ))
								 return (TRUE);
				 else
						 return(FALSE);
		}
NOTE: rindex() is a string handling function that returns a pointer to the last occurrence of character c in string s, or a NULL pointer if c does not occur in the string. (index() is similar function but assigns a pointer to 1st occurrence.)
The function struct direct *readdir(char *dir) also exists in <sys/dir.h>> to return a given directory dir listing.
There are many system calls that can applied directly to files stored in a directory.
path points to a path name naming a file. access() checks the named file for accessibility according to mode, defined in #include <unistd.h>:
access() returns: 0 on success, -1 on failure and sets errno to indicate the error. See man pages for list of errors.
errno is a special system variable that is set if a system
call cannot perform its set task. 
To use errno in a C program it must be declared via:
   extern int errno;
It can be manually reset within a C program other wise it simply retains its
last value.
 
int chmod(char *path, int mode) change the mode of access of a file.
specified by path to the given mode.     
chmod() returns 0 on success, -1 on failure and sets errno to
indicate the error. Errors are defined in #include <sys/stat.h>
The access mode of a file can be set using predefined macros in sys/stat.h
-- see man pages -- or by setting the mode in a a 3 digit octal number.
 
The rightmost digit specifies owner privileges, middle group privileges and the
leftmost other users privileges. 
For each octal digit think of it a 3 bit binary number. Leftmost bit = read
access (on/off) middle is write, right is executable.
So  4 (octal 100) = read only, 2 (010) = write, 6 (110) = read and write, 1
(001)
= execute.
so for access mode 600 gives user read and write access others no access. 666
gives everybody read/write access.
NOTE: a UNIX command chmod also exists
Two useful functions exist to inquire about the files current status. You can find out how large the file is (st_size) when it was created (st_ctime) etc. (see stat structure definition below. The two functions are prototyped in <sys/stat.h>
int stat(char *path, struct stat *buf), int fstat(int fd, struct stat *buf)
stat() obtains information about the  file  named  by  path. Read,  write 
or execute permission of the named file is not required, but all directories
listed in the path name  leading to the file must be searchable.
fstat() obtains the same  information  about  an  open  file referenced 
by  the  argument  descriptor,  such as would be obtained by an open call
(Low level I/O).
 
stat(), and fstat() return 0 on success, -1 on failure and sets errno to indicate the error. Errors are again defined in #include <sys/stat.h>
buf is a pointer to a stat structure into which information is placed concerning the file. A stat structure is define in #include <sys/types.h>, as follows
struct stat {
          mode_t   st_mode;     /* File mode (type, perms) */
          ino_t    st_ino;      /* Inode number */
          dev_t    st_dev;      /* ID of device containing */
                                /* a directory entry for this file */
          dev_t    st_rdev;     /* ID of device */
                                /* This entry is defined only for */
                                /* char special or block special files */
          nlink_t  st_nlink;    /* Number of links */
          uid_t    st_uid;      /* User ID of the file's owner */
          gid_t    st_gid;      /* Group ID of the file's group */
          off_t    st_size;     /* File size in bytes */
          time_t   st_atime;    /* Time of last access */
          time_t   st_mtime;    /* Time of last data modification */
          time_t   st_ctime;    /* Time of last file status change */
                                /* Times measured in seconds since */
                                /* 00:00:00 UTC, Jan. 1, 1970 */
          long     st_blksize;  /* Preferred I/O block size */
          blkcnt_t st_blocks;   /* Number of 512 byte blocks allocated*/
}
There are few functions that exist to delete and rename files. Probably the most common way is to use the stdio.h functions:
int remove(const char *path); int rename(const char *old, const char *new);
Two system calls (defined in unistd.h) which are actually used by remove() and rename() also exist but are probably harder to remember unless you are familiar with UNIX.
   int unlink(cons
char *path) -- removes the directory entry named by  path
unlink() returns 0 on success, -1 on failure and sets errno to indicate the error. Errors listed in #include <sys/stat.h>
A similar function link(const char *path1, const char *path2)
creates a linking from an existing directory entry path1 to a new
entry path2
Programs often need to create files just for the life of the program. Two convenient functions (plus some variants) exist to assist in this task. Management (deletion of files etc) is taken care of by the Operating System.
The function FILE *tmpfile(void) creates a temporary file and opens a corresponding stream. The file will automatically be deleted when all references to the file are closed.
The function char *tmpnam(char *s) generate file names that can safely be used for a temporary file. Variant functions char *tmpnam_r(char *s) and char *tempnam(const char *dir, const char *pfx) also exist
NOTE: There are a few more file manipulation routines not listed here see man pages.
Exercise 12675
Write a C program to emulate the ls -l UNIX command that prints all files in a current directory and lists access privileges etc. DO NOT simply exec ls -l from the program.
Exercise 12676
Write a program to print the lines of a file which contain a word given as the program argument (a simple version of grep UNIX utility).
Exercise 12677
Write a program to list the files given as arguments, stopping every 20 lines until a key is hit.(a simple version of more UNIX utility)
Exercise 12678
Write a program that will list all files in a current directory and all files in subsequent sub directories.
Exercise 12679
Write a program that will only list subdirectories in alphabetical order.
Exercise 12680
Write a program that shows the user all his/her C source programs and then prompts interactively as to whether others should be granted read permission; if affirmative such permission should be granted.
Exercise 12681
Write a program that gives the user the opportunity to remove any or all of the files in a current working directory. The name of the file should appear followed by a prompt as to whether it should be removed.