При компиляции работающего кода :) Выводятся на экран следующие ошибки (см. по ссылке Ошибки).
hashTable.h
#ifndef HASH_TABLE_H
#define HASH_TABLE_H
struct node;
struct hashMap;
void initializeHashMap(struct hashMap* mp);
void insert(struct hashMap* mp, char* key, char* value);
void delete (struct hashMap* mp, char* key);
char* search(struct hashMap* mp, char* key);
#endif
error_functions.h
#ifndef ERROR_FUNCTIONS_H
#define ERROR_FUNCTIONS_H
void errMsg(const char* format, ...);
#ifdef __GNUC__
/* This macro blocks compiler warnings when using command 'gcc -Wall'
complaining that 'control reaches end of non-void function',that is
control reached end of function, which must return a value, if we use
the following functions to stop execution of main(), or some other
function, which must return a value of some defined type (not void) */
#define NORETURN __attribute__ ((__noreturn__))
#else
#define NORETURN
#endif
void errExit(const char* format, ...) NORETURN;
void err_exit(const char* format, ...) NORETURN;
void errExitEN(int errnum, const char* format, ...) NORETURN;
void fatal(const char* format, ...) NORETURN;
void usageErr(const char* format, ...) NORETURN;
void cmdLineErr(const char* format, ...) NORETURN;
#endif
dup.c
#include <string.h>
#include <fcntl.h> //O_CREAT
#include <stdlib.h>
#include <stdio.h> // snprintf
#include "error_functions.h"
#include "hashTable.h"
typedef struct FileDescriptor {
int stateFlg;
int desc;
} FileDescriptor;
static struct FileDescriptor *descriptors;
void initDescriptorsTable() {
if (NULL == descriptors)
#define SIZE_OF_DESCRIPTORS_ARRAY 1024
descriptors = malloc(SIZE_OF_DESCRIPTORS_ARRAY*sizeof(FileDescriptor));
}
void insertFileDescriptor(struct FileDescriptor * pFileDsc) {
if (pFileDsc == NULL)
fatal("pFileDsc is NULL");
int i = 0;
while (descriptors[i++].desc != -1) {}
descriptors[--i].desc = pFileDsc->desc;
}
typedef struct OpFileDesc {
int key;
int offset;
int stateFlags;
int accessMode;
int ioSigFlags;
int indexRef;
} OpFileDesc;
static struct OpFileDesc *openedFiles;
void initOpenedFilesTable() {
if (NULL == openedFiles)
#define OPENED_FILES_DESC 4096
openedFiles = malloc(OPENED_FILES_DESC*sizeof(OpFileDesc));
}
void insertOpenFileDescription(struct OpFileDesc * pOpFileDesc) {
if (pOpFileDesc == NULL)
fatal("pOpFileDesc is NULL");
int i = 0;
while (openedFiles[i++].key != -1) {}
openedFiles[--i].key = pOpFileDesc->key;
}
int
main(int argc, char *argv[])
{
if (argc != 2 || strcmp(argv[1], "--help") == 0)
usageErr("%s FD");
initDescriptorsTable();
initOpenedFilesTable();
int oldfd = atoll(argv[1]);
int i = 0;
while (descriptors[i++].desc != -1) {}
int newfd = i; /* It is expected to point to the same opened file description as oldfd */
FileDescriptor newFileDesc = {0, newfd};
insertFileDescriptor(&newFileDesc);
OpFileDesc opFileDesc = {
0,
O_CREAT|O_APPEND,
S_IWUSR|S_IRUSR,
0,
0
};
insertOpenFileDescription(&opFileDesc);
struct hashMap* mp
= (struct hashMap*)malloc(sizeof(struct hashMap));
initializeHashMap(mp);
#define BUF_SIZE 4096
char newFileDscBuf[BUF_SIZE];
snprintf(newFileDscBuf, BUF_SIZE, "%ld", newFileDesc.desc);
char newOpFileDscBuf[BUF_SIZE];
snprintf(newOpFileDscBuf, BUF_SIZE, "%ld", opFileDesc.key);
insert(mp, newFileDscBuf, newOpFileDscBuf);
free(descriptors);
free(opFiles);
exit(newfd);
}
hashTable.c
// Linked List node
struct node {
// key is string
char* key;
// value is also string
char* value;
struct node* next;
};
// like constructor
void setNode(struct node* node, char* key, char* value)
{
node->key = key;
node->value = value;
node->next = NULL;
return;
};
struct hashMap {
// Current number of elements in hashMap
// and capacity of hashMap
int numOfElements, capacity;
// hold base address array of linked list
struct node** arr;
};
// like constructor
void initializeHashMap(struct hashMap* mp)
{
// Default capacity in this case
mp->capacity = 100;
mp->numOfElements = 0;
// array of size = 1
mp->arr = (struct node**)malloc(sizeof(struct node*)
* mp->capacity);
return;
}
int hashFunction(struct hashMap* mp, char* key)
{
int bucketIndex;
int sum = 0, factor = 31;
for (int i = 0; i < strlen(key); i++) {
// sum = sum + (ascii value of
// char * (primeNumber ^ x))...
// where x = 1, 2, 3....n
sum = ((sum % mp->capacity)
+ (((int)key[i]) * factor) % mp->capacity)
% mp->capacity;
// factor = factor * prime
// number....(prime
// number) ^ x
factor = ((factor % __INT16_MAX__)
* (31 % __INT16_MAX__))
% __INT16_MAX__;
}
bucketIndex = sum;
return bucketIndex;
}
void insert(struct hashMap* mp, char* key, char* value)
{
// Getting bucket index for the given
// key - value pair
int bucketIndex = hashFunction(mp, key);
struct node* newNode = (struct node*)malloc(
// Creating a new node
sizeof(struct node));
// Setting value of node
setNode(newNode, key, value);
// Bucket index is empty....no collision
if (mp->arr[bucketIndex] == NULL) {
mp->arr[bucketIndex] = newNode;
}
// Collision
else {
// Adding newNode at the head of
// linked list which is present
// at bucket index....insertion at
// head in linked list
newNode->next = mp->arr[bucketIndex];
mp->arr[bucketIndex] = newNode;
}
return;
}
void delete (struct hashMap* mp, char* key)
{
// Getting bucket index for the
// given key
int bucketIndex = hashFunction(mp, key);
struct node* prevNode = NULL;
// Points to the head of
// linked list present at
// bucket index
struct node* currNode = mp->arr[bucketIndex];
while (currNode != NULL) {
// Key is matched at delete this
// node from linked list
if (strcmp(key, currNode->key) == 0) {
// Head node
// deletion
if (currNode == mp->arr[bucketIndex]) {
mp->arr[bucketIndex] = currNode->next;
}
// Last node or middle node
else {
prevNode->next = currNode->next;
}
free(currNode);
break;
}
prevNode = currNode;
currNode = currNode->next;
}
return;
}
char* search(struct hashMap* mp, char* key)
{
// Getting the bucket index
// for the given key
int bucketIndex = hashFunction(mp, key);
// Head of the linked list
// present at bucket index
struct node* bucketHead = mp->arr[bucketIndex];
while (bucketHead != NULL) {
// Key is found in the hashMap
if (bucketHead->key == key) {
return bucketHead->value;
}
bucketHead = bucketHead->next;
}
// If no key found in the hashMap
// equal to the given key
char* errorMssg = (char*)malloc(sizeof(char) * 25);
errorMssg = "Oops! No data found.\n";
return errorMssg;
}
error_functions.c
#include <stdarg.h>
#include <stdlib.h>
#include "error_functions.h"
#include "tlpi_hdr.h"
#include "ename.c" /* Defines ename and MAX_ENAME */
#ifdef __GNUC__
__attribute__ ((__noreturn__))
#endif
static void
terminate(Boolean useExit3)
{
char *s;
/* Saves core dump, if environment variable EF_DUMPCORE is defined
and contains an unempty string; otherwise it calls exit(3)
or _exit(2), depending on value of 'useExit3'. */
s = getenv("EF_DUMPCORE");
if (s != NULL && *s != '\0')
abort();
else if (useExit3)
exit(EXIT_FAILURE);
else
_exit(EXIT_FAILURE);
}
static void
outputError(Boolean useErr, int err, Boolean flushStdout,
const char *format, va_list ap)
{
#define BUF_SIZE 500
char buf[BUF_SIZE], userMsg[BUF_SIZE], errText[BUF_SIZE];
vsnprintf(userMsg, BUF_SIZE, format, ap);
if (useErr)
snprintf(errText, BUF_SIZE, " [%s %s]",
(err > 0 && err <= MAX_ENAME) ?
ename[err] : "?UNKNOWN?", strerror(err));
else
snprintf(errText, BUF_SIZE, ":");
snprintf(buf, BUF_SIZE, "ERROR%s %s\n", errText, userMsg);
if (flushStdout)
fflush(stdout); /* Reset all pending output */
fputs(buf, stderr);
fflush(stderr);
}
void
errMsg(const char *format, ...)
{
va_list argList;
int savedErrno;
savedErrno = errno;
va_start(argList, format);
outputError(TRUE, errno, TRUE, format, argList);
va_end(argList);
errno = savedErrno;
}
void
errExit(const char *format, ...)
{
va_list argList;
va_start(argList, format);
outputError(TRUE, errno, TRUE, format, argList);
va_end(argList);
terminate(TRUE);
}
void
err_exit(const char *format, ...)
{
va_list argList;
va_start(argList, format);
outputError(TRUE, errno, FALSE, format, argList);
va_end(argList);
terminate(FALSE);
}
void
errExitEN(int errnum, const char *format, ...)
{
va_list argList;
va_start(argList, format);
outputError(TRUE, errnum, TRUE, format, argList);
va_end(argList);
terminate(TRUE);
}
void
fatal(const char *format, ...)
{
va_list argList;
va_start(argList, format);
outputError(TRUE, 0, TRUE, format, argList);
va_end(argList);
terminate(TRUE);
}
void
usageErr(const char *format, ...)
{
va_list argList;
fflush(stdout);
fprintf(stderr, "Usage: ");
va_start(argList, format);
vfprintf(stderr, format, argList);
va_end(argList);
fflush(stderr);
exit(EXIT_FAILURE);
}
void
cmdLineErr(const char *format, ...)
{
va_list argList;
fflush(stdout);
fprintf(stderr, "Command-line usage error: ");
va_start(argList, format);
vfprintf(stderr, format, argList);
va_end(argList);
fflush(stderr);
exit(EXIT_FAILURE);
}
ename.c
/* ename.c.inc
Built on GNU/Linux x86_64 with glibc 2.42
*/
static char *ename[] = {
/* 0 */ "",
/* 1 */ "EPERM", "ENOENT", "ESRCH", "EINTR", "EIO", "ENXIO",
/* 7 */ "E2BIG", "ENOEXEC", "EBADF", "ECHILD",
/* 11 */ "EAGAIN/EWOULDBLOCK", "ENOMEM", "EACCES", "EFAULT",
/* 15 */ "ENOTBLK", "EBUSY", "EEXIST", "EXDEV", "ENODEV",
/* 20 */ "ENOTDIR", "EISDIR", "EINVAL", "ENFILE", "EMFILE",
/* 25 */ "ENOTTY", "ETXTBSY", "EFBIG", "ENOSPC", "ESPIPE",
/* 30 */ "EROFS", "EMLINK", "EPIPE", "EDOM", "ERANGE",
/* 35 */ "EDEADLK/EDEADLOCK", "ENAMETOOLONG", "ENOLCK", "ENOSYS",
/* 39 */ "ENOTEMPTY", "ELOOP", "", "ENOMSG", "EIDRM", "ECHRNG",
/* 45 */ "EL2NSYNC", "EL3HLT", "EL3RST", "ELNRNG", "EUNATCH",
/* 50 */ "ENOCSI", "EL2HLT", "EBADE", "EBADR", "EXFULL", "ENOANO",
/* 56 */ "EBADRQC", "EBADSLT", "", "EBFONT", "ENOSTR", "ENODATA",
/* 62 */ "ETIME", "ENOSR", "ENONET", "ENOPKG", "EREMOTE",
/* 67 */ "ENOLINK", "EADV", "ESRMNT", "ECOMM", "EPROTO",
/* 72 */ "EMULTIHOP", "EDOTDOT", "EBADMSG/EFSBADCRC", "EOVERFLOW",
/* 76 */ "ENOTUNIQ", "EBADFD", "EREMCHG", "ELIBACC", "ELIBBAD",
/* 81 */ "ELIBSCN", "ELIBMAX", "ELIBEXEC", "EILSEQ", "ERESTART",
/* 86 */ "ESTRPIPE", "EUSERS", "ENOTSOCK", "EDESTADDRREQ",
/* 90 */ "EMSGSIZE", "EPROTOTYPE", "ENOPROTOOPT",
/* 93 */ "EPROTONOSUPPORT", "ESOCKTNOSUPPORT",
/* 95 */ "EOPNOTSUPP/ENOTSUP", "EPFNOSUPPORT", "EAFNOSUPPORT",
/* 98 */ "EADDRINUSE", "EADDRNOTAVAIL", "ENETDOWN", "ENETUNREACH",
/* 102 */ "ENETRESET", "ECONNABORTED", "ECONNRESET", "ENOBUFS",
/* 106 */ "EISCONN", "ENOTCONN", "ESHUTDOWN", "ETOOMANYREFS",
/* 110 */ "ETIMEDOUT", "ECONNREFUSED", "EHOSTDOWN", "EHOSTUNREACH",
/* 114 */ "EALREADY", "EINPROGRESS", "ESTALE",
/* 117 */ "EUCLEAN/EFSCORRUPTED", "ENOTNAM", "ENAVAIL", "EISNAM",
/* 121 */ "EREMOTEIO", "EDQUOT", "ENOMEDIUM", "EMEDIUMTYPE",
/* 125 */ "ECANCELED", "ENOKEY", "EKEYEXPIRED", "EKEYREVOKED",
/* 129 */ "EKEYREJECTED", "EOWNERDEAD", "ENOTRECOVERABLE",
/* 132 */ "ERFKILL", "EHWPOISON"
};
#define MAX_ENAME 133

