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]; };