CSC 357 Lecture Notes Week 5
More on Files and Directories Function Pointers in C Standard I/O Library
System Data Files and Information
DIR* opendir(const char *filename); struct dirent *readdir(DIR* dirp); int closedir(DIR* dirp);
typedef struct dirent {
ino_t d_ino; /* inode numberof entry */
off_t d_off; /* offset of disk directory entry*/
short d_reclen; /* len of this record */
char d_name[]; /* name of file */
} dirent_t;
int chdir(const char *pathname); int fchdir(int fildes); char* getcwd(char* buf, size_t size);
int ftw(const char *path,
int (*fn) (const char*, const struct stat*, int),
int depth);
int nftw(const char *path,
int (*fn) (const char*, const struct stat*, int, struct FTW*),
int depth,
int flags);
#include <stdio.h>
#include <ftw.h>
/****
*
* Example use of nftw.
*
*/
/**
* The visit function is called by nftw for each element of a traversed
* directory hierarchy. It prints out the path of the element being visited,
* and its mode as an octal value. The first three octits of the mode are the
* file type, with 040 indicating a directory, and 100 a plain file. The last
* three octits are the file permissions, e.g., 644 = "rw-r--r--".
*/
int visit(const char* path, const struct stat* stat, int flags, struct FTW* ftw) {
printf("path=%s, mode=%o\n", path, stat->st_mode);
return 0;
}
/**
* The main function just calls nftw, catching any error it might return.
*/
main() {
if (nftw(".", visit, 10, 0) != 0) {
perror("nftw");
}
}
#include <stdio.h>
#include <unistd.h>
#include "std-macros.h"
/**
*
* This program exercises the system qsort function. The focus is on the
* comparator functions that qsort calls, as an illustration of using function
* pointers in C.
*
*/
/**
* Compare two void* values as ints, by casting them and using normal numeric
* comparison.
*/
int intcmp(const void* a1, const void* a2) {
int v1 = *((int*) a1);
int v2 = *((int*) a2);
if (v1 < v2) return -1;
if (v1 > v2) return 1;
return 0;
}
/**
* Like intcmp, but reverses the sense of the comparison. This allows the
* sorting order to defined as descending, without changing the implementation
* of the sort function.
*/
int intcmp_reverse(const void* a1, const void* a2) {
int v1 = *((int*) a1);
int v2 = *((int*) a2);
if (v1 > v2) return -1;
if (v1 < v2) return 1;
return 0;
}
/**
* Compare two void* values as numeric strings, by casting them to char*, then
* converting them using atoi, then using normal numeric comparison.
*
* Note here the intermediate use of char** as a cast, then the deference down
* to char*. I.e,. the following code is used to cast the incoming void*
* argument a1 into the char* variable s1:
*
* char* s1 = *((char**) a1);
*
* The deal is that qsort works with pointers to the array values it's sorting,
* not the values themselves. In this case, the array being sorted contains
* char* values. This means that qsort is working with element pointers of
* type char**, since it's pointing to each char* element of the arrays.
* Hence, this function receives values of type char**, carried in the generic
* pointers of type void*.
*/
int str_intcmp(const void* a1, const void* a2) {
char* s1 = *((char**) a1);
char* s2 = *((char**) a2);
int v1 = atoi(s1);
int v2 = atoi(s2);
if (v1 < v2) return -1;
if (v1 > v2) return 1;
return 0;
}
/**
* The main function defines unsorted int and string arrays. It then calls the
* system qsort function to sort the int array in ascending and descending
* orders, using the preceding two int comparison functions. It also calls
* qsort to sort the string array in ascending order, using str_intcmp.
*/
main() {
int i;
int int_data[6] = {1, 8, 3, 4, 2, 1};
char* str_data[6] = {"1", "8", "3", "4", "2", "1"};
size_t int_nelems = sizeof(int_data) / sizeof(int);
size_t str_nelems = sizeof(str_data) / sizeof(int);
/*
* Print the int array before sorting.
*/
for (i = 0; i < int_nelems; i++) printf("%d ", int_data[i]);
printf("\n");
/*
* Sort the int array using intcmp comparator and print results.
*/
qsort((void*) int_data, int_nelems, sizeof(int), intcmp);
for (i = 0; i < int_nelems; i++) printf("%d ", int_data[i]);
printf("\n");
/*
* Sort the int array using intcmp_reverse comparator and print results.
*/
qsort((void*) int_data, int_nelems, sizeof(int), intcmp_reverse);
for (i = 0; i < int_nelems; i++) printf("%d ", int_data[i]);
printf("\n");
/*
* Print the string array before sorting.
*/
for (i = 0; i < str_nelems; i++) printf("%s ", str_data[i]);
printf("\n");
/*
* Sort the string array using str_intcmp comparator and print results.
*/
qsort((void*) str_data, str_nelems, sizeof(char*), str_intcmp);
for (i = 0; i < str_nelems; i++) printf("%s ", str_data[i]);
printf("\n");
}
void qsort(void* base, size_t nel, size_t width,
int (*compar)(const void*, const void*));
which declares that compar is a function returning a pointer to an int, which is a different thing.int *compar(const void*, const void*));
int (*fn) (const char*, const struct stat*, int, struct FTW*)
int visit(const char* path, const struct stat* stat, int flags, struct FTW* ftw)
typedef int (* CompareFunc)(const void*, const void*); void qsort(void* base, size_t nel, size_t width, CompareFunc compar);
typedef int CompareFunc(const void*, const void*); void qsort(void* base, size_t nel, size_t width, CompareFunc* compar);
void qsort(void* base, size_t nel, size_t width, CompareFunc compar);
struct passwd {
char *pw_name;
char *pw_passwd;
uid_t pw_uid;
gid_t pw_gid;
char *pw_age;
char *pw_comment;
char *pw_gecos;
char *pw_dir;
char *pw_shell;
};
struct passwd *getpwnam(
const char *name);
struct passwd *getpwuid(
uid_t uid);
int uname(struct utsname *name);
struct utsname {
char sysname[_SYS_NMLN];
char nodename[_SYS_NMLN];
char release[_SYS_NMLN];
char version[_SYS_NMLN];
char machine[_SYS_NMLN];
};