static char* test_insert2() { linked_list* list = llist_new(); llist_insert(list, 1, 1); llist_insert(list, 2, 2); mu_assert("** test_insert2: head == tail.", list->head != list->tail); mu_assert("** test_insert2: head->next != tail.", list->head->next == list->tail); mu_assert("** test_insert2: tail->prev != head.", list->tail->prev == list->head); mu_assert("** test_insert2: size != 2.", list->size == 2); return 0; }
static char* test_remove2() { linked_list* list = llist_new(); node* n = llist_insert(list, 1, 1); node* n2 = llist_insert(list, 2, 2); free(llist_remove(list, n)); free(llist_remove(list, n2)); mu_assert("** test_remove2: size != 0.", list->size == 0); mu_assert("** test_remove2: head != tail.", list->head == list->tail); mu_assert("** test_remove2: head != NULL.", list->head == NULL); return 0; }
static char* test_remove3() { linked_list* list = llist_new(); llist_insert(list, 1, 1); node* n = llist_insert(list, 2, 2); llist_remove(list, n); mu_assert("** test_remove3: head != tail.", list->head == list->tail); mu_assert("** test_remove3: head->next != NULL.", list->head->next == NULL); mu_assert("** test_remove3: head->prev != NULL.", list->head->prev == NULL); mu_assert("** test_remove3: removed node != n.", n->key == 2); free(n); return 0; }
//变长结构体版本 //类的概念:数据和方法都放入头节点 int main(int argc, const char *argv[]) { int i, ret; LLIST *handler; SCORE_ST tmp, *tmp_p; handler = llist_creat(sizeof(SCORE_ST)); for (i = 0; i < 7; i++) { tmp.id = i; snprintf(tmp.name, NAMESIZE, "middle school student%d", i); tmp.math = rand() %100; tmp.chinese = rand() %100; //myprint(&tmp); llist_insert(handler, &tmp, LLIST_FORWARD); } llist_travel(handler, myprint); printf("-----------------------------------\n"); char *name = "stu3"; tmp_p = llist_find(handler, name, cmp_name); if (tmp_p) { myprint(tmp_p); }else{ printf("not find\n"); } printf("-----------------------------------\n"); int id = 2; ret = llist_fetch(handler, &id, cmp_id, &tmp); if (ret) { printf("fetch "); myprint(&tmp); } printf("-----------------------------------\n"); name ="stu0"; ret = llist_delete(handler, name, cmp_name); if (ret) { printf("delete %s\n", name); } printf("-----------------------------------\n"); llist_travel(handler, myprint); printf("-----------------------------------\n"); name = malloc(NAMESIZE); for (i = 1; i < 7; i++) { snprintf(name, NAMESIZE, "stu%d", i); ret = llist_delete(handler, name, cmp_name); if (ret) { printf("delete %s\n", name); } } llist_travel(handler, myprint); llist_destroy(handler); return 0; }
int pre_reservation_request_new(llist *pre_reservation_list, reservation *request) { /* reservation *request is the original reservation */ llist_insert(pre_reservation_list, request); write_reservations("pre_reservations.txt", pre_reservation_list); return 0; }
int insert(const struct score *data) { int ind; ind = hash(data->name) % LIST_NR; llist_insert(list[ind], data, DIR_BACK); return 0; }
int main(void) { struct score tmp, *datap; int i, id; LLIST *list; int ret; list = llist_creat(sizeof(struct score)); for (i = 0; i < 7; i++) { tmp.id = i; tmp.math = 100 - i; snprintf(tmp.name, NAMESIZE, "stu%d", i); llist_insert(list, &tmp, LLIST_BACKWARD); } llist_travel(list, print_s); id = 4; ret = llist_fetch(list, &tmp, &id, id_cmp); printf("\n"); if (ret == -1) { printf("Can not find.\n"); } else { print_s(&tmp); } printf("\n"); llist_travel(list, print_s); #if 0 id = 8; llist_delet(list, &id, id_cmp); printf("\n"); llist_travel(list, print_s); id = 2; datap = llist_find(list, &id, id_cmp); if (datap == NULL) { printf("Can not find.\n"); } else { print_s(datap); } #endif llist_save(list, "stu.data"); llist_destroy(list); LLIST *list2 = llist_load("stu.data"); llist_travel(list2, print_s); llist_destroy(list2); return 0; }
static char* test_remove4() { linked_list* list = llist_new(); llist_insert(list, 1, 1); node* n = llist_insert(list, 2, 2); llist_insert(list, 3, 3); llist_remove(list, n); mu_assert("** test_remove4: head == tail.", list->head != list->tail); mu_assert("** test_remove4: head->next != tail.", list->head->next == list->tail); mu_assert("** test_remove4: tail->prev != head.", list->tail->prev == list->head); mu_assert("** test_remove4: head->prev != NULL.", list->head->prev == NULL); mu_assert("** test_remove4: tail->next != NULL.", list->tail->next == NULL); mu_assert("** test_remove4: head != 1.", list->head->key == 3); mu_assert("** test_remove4: tail != 3.", list->tail->key == 1); free(n); return 0; }
int create_testcols_table( Arb_connection *conn) { int rc; int col; COLUMN_DEF *colp; ARBOR_LLIST *columns; rc = llist_create( &columns, LLIST_COMPARISON_FUNC, column_cmp, LLIST_DELETE_ITEM_FUNC, free, LLIST_DUPLICATE_STRATEGY, LLIST_DUPLICATES_NOT_ALLOWED, LLIST_SORT_STRATEGY, LLIST_UNORDERED_LIST, LLIST_NO_MORE_ARGS); if( rc != SUCCESS) abort(); for( col = 0; col < WIDGET_TABLE_NUM_COLS; ++col) { colp = (COLUMN_DEF *) calloc (1, sizeof (COLUMN_DEF)); assert( colp != NULL); colp->row_position = col; switch(col) { case 0: initcol_id(colp); break; case 1: initcol_quantity(colp); break; case 2: initcol_category(colp); break; case 3: initcol_langcode(colp); break; case 4: initcol_shortdesc(colp); break; case 5: initcol_wdesc(colp); break; case 6: initcol_opcode(colp); break; case 7: initcol_inceptdate(colp); break; case 8: initcol_termdate(colp); break; case 9: initcol_weight(colp); break; case 10: initcol_volume(colp); break; case 11: initcol_bitflags(colp); break; case 12: initcol_license(colp); break; default: abort(); } rc = llist_insert( columns, colp); if( rc != SUCCESS) abort(); } /* loop */ rc = arb_create_table( conn, TABLENAME, columns); if( rc != SUCCESS) abort(); llist_delete( columns); return 0; }
static char* test_insert1() { linked_list* list = llist_new(); node* n = llist_insert(list, 1, 1); mu_assert("** test_insert1: n->key != 1", n->key == 1); mu_assert("** test_insert1: n->data != 1", n->data == 1); mu_assert("** test_insert1: unable to insert node.", list->head != NULL); mu_assert("** test_insert1: head and tail not equal.", list->head == list->tail); mu_assert("** test_insert1: size != 1", list->size == 1); mu_assert("** test_insert1: head->next != null.", list->head->next == NULL); mu_assert("** test_insert1: head->prev != null.", list->head->prev == NULL); return 0; }
int main() { struct score tmp,*datap; int i,id,ret; char name[] = "sstu1"; LLIST *handle; handle = llist_create(sizeof(struct score)); if(handle == NULL) return -1; for(i = 0; i < 6 ;i++) { tmp.id = i; tmp.math = 100-i; snprintf(tmp.name,NAMESIZE,"stu%d",i); llist_insert(handle,&tmp,LLIST_BACKWARD); } llist_travel(handle,print_s); printf("\n\n"); id = 3; ret = llist_fetch(handle,&id,id_cmp,&tmp); if(ret != -1) print_s(&tmp); printf("\n\n"); llist_travel(handle,print_s); llist_destroy(handle); // llist_delete(handle,&id,id_cmp); // llist_travel(handle,print_s); #if 0 // datap = llist_find(handle,&id,id_cmp); datap = llist_find(handle,name,name_cmp); if(datap == NULL) printf("can not find!\n"); else print_s(datap); #endif return 0; }
int main(void) { LLIST *llist; struct score tmp, *datap; int i; int id; struct sum_st sum = {0,0}; llist = llist_creat(sizeof(struct score)); /* if error */ for (i = 0; i < 7; i++) { tmp.id = i; snprintf(tmp.name, NAMESIZE, "stu%d", i); tmp.ch = 100 - i; tmp.math = 100 - 2 * i; llist_insert(llist, &tmp); /* if error */ } llist_travel(llist, print_score, NULL); printf("\n"); #if 1 id = 3; llist_delet(llist, &id, id_cmp); llist_travel(llist, print_score, NULL); #else datap = llist_find(llist, &id, id_cmp); if (datap == NULL) { printf("Can not find.\n"); } else { print_score(datap, NULL); } llist_travel(llist, get_sum, &sum); printf("sum: ch = %d, math = %d\n", sum.ch, sum.math); #endif llist_destroy(llist); return 0; }
int main() { LLIST *handle; int i ,ret, id = 3; char *name = "person2"; struct person_st tmp, *datap; handle = llist_create(sizeof(struct person_st)); if(handle== NULL) return -1; for(i = 0; i < 6; i++) { tmp.id = i; tmp.age = 20 + i; snprintf(tmp.name,NAMESIZE,"person%d",i); llist_insert(handle,&tmp,LLIST_FORWARD); } llist_travel(handle,print_s); printf("\n\n"); ret = llist_fetch(handle,name,name_cmp,&tmp); if(ret == 0) print_s(&tmp); printf("\n\n"); // llist_delete(handle,&id,id_cmp); // llist_travel(handle,print_s); #if 0 //datap = llist_find(handle,&id,id_cmp); datap = llist_find(handle,name,name_cmp); if(datap == NULL) printf("ca not find!\n"); else print_s(datap); #endif llist_destroy(handle); return 0; }
static inline struct llist_item *llist_insert_sorted_unique(struct llist *list, const unsigned char *sha1, struct llist_item *hint) { struct llist_item *prev = NULL, *l; l = (hint == NULL) ? list->front : hint; while (l) { int cmp = hashcmp(l->sha1, sha1); if (cmp > 0) { /* we insert before this entry */ return llist_insert(list, prev, sha1); } if (!cmp) { /* already exists */ return l; } prev = l; l = l->next; } /* insert at the end */ return llist_insert_back(list, sha1); }
static inline struct llist_item *llist_insert_sorted_unique(struct llist *list, const struct object_id *oid, struct llist_item *hint) { struct llist_item *prev = NULL, *l; l = (hint == NULL) ? list->front : hint; while (l) { int cmp = oidcmp(l->oid, oid); if (cmp > 0) { /* we insert before this entry */ return llist_insert(list, prev, oid); } if (!cmp) { /* already exists */ return l; } prev = l; l = l->next; } /* insert at the end */ return llist_insert_back(list, oid); }
void read_client(char *file, llist *client_list) { FILE *fp; char client_name[MAX_NAME_SIZE]; int client_id; client *client; if ((fp = fopen(file, "r")) == NULL) { return; } while (fscanf(fp, "%[^,], %d\n", client_name, &client_id) == 2) { client = client_new(client_name); client->id = client_id; llist_insert(client_list, client); } fclose(fp); }
int main(int argc, char *argv[]) { LLIST *handle = NULL, *find = NULL; int n; if (argc > 1) handle = llist_load("./db"); else { handle = llist_create(sizeof(int)); while (1) { printf("please input num : "); scanf("%d", &n); if (n == -1) break; /*llist_append(&n, handle);*/ /*llist_prepend(&n, handle);*/ /*llist_insert(&n, PREPEND, handle);*/ llist_sort_insert(&n, cmp, handle); } llist_travel(ls, NULL, handle); printf("\n"); n = 9999; llist_insert(&n, 3, handle); if (!llist_store("./db", handle)) printf("存储成功!\n"); } llist_travel(ls, NULL, handle); printf("\n"); llist_sort(cmp, handle); printf("sort : "); llist_travel(ls, NULL, handle); printf("\n"); while (1) { printf("please input key : "); scanf("%d", &n); if (n == -1) break; find = llist_findall(&n, cmp, handle); if (find != NULL) { llist_travel_find(ls, NULL, find); printf("\n"); } /* * printf("delete = %d\n", llist_delete(&n, cmp, handle)); * * llist_travel(ls, NULL, handle); * printf("\n"); */ } llist_destroy(&handle); return 0; }
static inline struct llist_item *llist_insert_back(struct llist *list, const struct object_id *oid) { return llist_insert(list, list->back, oid); }
int main(void) { int n, ret; void *ret1; LLIST *handle = NULL; LLIST *find = NULL; handle = llist_create(sizeof(int), NULL, NULL, NULL); while (1) { printf("please input num : "); scanf("%d", &n); if (n == -1) break; llist_insert(&n, APPEND, handle); } llist_travel(printf_s, NULL, handle); printf("\n"); printf("insert num : "); scanf("%d", &n); llist_insert(&n, 3, handle); llist_travel(printf_s, NULL, handle); printf("\n"); printf("delete num : "); scanf("%d", &n); llist_delete(&n, cmp, handle); llist_travel(printf_s, NULL, handle); printf("\n"); printf("find num : "); scanf("%d", &n); ret1 = llist_find(&n, cmp, handle); if(ret1 != NULL) printf("find = %d\n", *(int*)ret1); printf("\n"); printf("findall num : "); scanf("%d", &n); find = llist_findall(&n, cmp, handle); llist_travel(printf_s, find, handle); printf("\n"); llist_sort(cmp, handle); printf("sort:"); llist_travel(printf_s, NULL, handle); printf("\n"); ret = llist_store("./db", handle); if(ret == 0) printf("存储成功!\n"); llist_destroy(&handle); return 0; }
int stack_push(STACK *ptr, const void *data) { return llist_insert(ptr, data, DIR_FRONT); }
static inline struct llist_item *llist_insert_back(struct llist *list, const unsigned char *sha1) { return llist_insert(list, list->back, sha1); }
int stack_push(STACK *ptr, void *data){ return llist_insert(ptr, data, LLIST_FORWARD); }
/** * Move QE process into CGroup for resource enforcement purpose. */ int MoveToCGroup(uint32 pid, const char *cgroup_name) { int res = FUNC_RETURN_OK; CGroupInfo *cgi = NULL; uint32 *pid_add = NULL; GSimpStringPtr pkey = stringToGSimpString(cgroup_name); if (pkey == NULL) { write_log("%s Prepare CGroup name %s failed with out of memory", ENFORCER_MESSAGE_HEAD, cgroup_name); return RESENFORCER_ERROR_INSUFFICIENT_MEMORY; } Pair cgroup = getGHashNode(g_ghash_cgroup, (void *)pkey); if (cgroup == NULL) { if (rm_enforce_cpu_enable) { res = createCGroup(cgroup_name, "cpu"); if (res != FUNC_RETURN_OK) { write_log("%s Create CGroup %s failed", ENFORCER_MESSAGE_HEAD, cgroup_name); return res; } } cgi = (CGroupInfo *)malloc(sizeof(CGroupInfo)); if (cgi == NULL) { write_log("%s Create CGroup %s failed with out of memory", ENFORCER_MESSAGE_HEAD, cgroup_name); return RESENFORCER_ERROR_INSUFFICIENT_MEMORY; } Assert(strlen(cgroup_name) < sizeof(cgi->name)); strncpy(cgi->name, cgroup_name, strlen(cgroup_name)+1); cgi->creation_time = gettime_microsec(); cgi->pids = llist_create(); if (cgi->pids == NULL) { write_log("%s Add PID %d to CGroup %s failed", ENFORCER_MESSAGE_HEAD, pid, cgroup_name); res = RESENFORCER_ERROR_INSUFFICIENT_MEMORY; goto exit; } cgi->vcore_current = 0; cgi->vdisk_current = 0; cgi->to_be_deleted = 0; void *oldvalue = NULL; #ifdef DEBUG_GHASH write_log("%s ########## Before add CGroup %s in hash in MoveToCGroup ##########", ENFORCER_MESSAGE_HEAD, cgroup_name); dumpGHash(g_ghash_cgroup); #endif if (setGHashNode(g_ghash_cgroup, (void *)pkey, (void *)cgi, false, &oldvalue) != FUNC_RETURN_OK) { write_log("%s Add CGroup to list failed with out of memory", ENFORCER_MESSAGE_HEAD); res = RESENFORCER_ERROR_INSUFFICIENT_MEMORY; goto exit; } #ifdef DEBUG_GHASH write_log("%s ########## After add CGroup %s in hash in MoveToCGroup ##########", ENFORCER_MESSAGE_HEAD, cgroup_name); dumpGHash(g_ghash_cgroup); #endif } else { cgi = (CGroupInfo *)(cgroup->Value); /* revert the delete operation */ if (cgi == NULL) { write_log("%s CGroup %s found in hash but its content is inaccessible", ENFORCER_MESSAGE_HEAD, cgroup_name); goto exit; } else if (cgi->to_be_deleted > 0) { cgi->to_be_deleted = 0; } } #ifdef DEBUG_GHASH write_log("%s ########## Before add PID %d in CGroup %s in hash in MoveToCGroup ##########", ENFORCER_MESSAGE_HEAD, pid, cgroup_name); dumpGHash(g_ghash_cgroup); #endif pid_add = (uint32 *)malloc(sizeof(uint32)); if (pid_add == NULL) { write_log("%s Create PID %d failed with out of memory", ENFORCER_MESSAGE_HEAD, pid); res = RESENFORCER_ERROR_INSUFFICIENT_MEMORY; goto exit; } *pid_add = pid; llist_insert(cgi->pids, pid_add); #ifdef DEBUG_GHASH write_log("%s ########## After add PID %d in CGroup %s in hash in MoveToCGroup ##########", ENFORCER_MESSAGE_HEAD, pid, cgroup_name); dumpGHash(g_ghash_cgroup); #endif /* Process CGroup for cpu sub-system */ if (rm_enforce_cpu_enable) { res = setCGroupProcess(cgroup_name, "cpu", pid); if (res != FUNC_RETURN_OK) { write_log("%s Add PID %d to CPU CGroup %s failed", ENFORCER_MESSAGE_HEAD, pid, cgroup_name); goto exit; } } return FUNC_RETURN_OK; exit: if (pkey) { free(pkey); } if (pid_add) { free(pid_add); } if (cgi) { freeCGroupInfo(cgi); } return res; }
int main(int argc, char argv[]) { int ret = 0; struct sockaddr_in client_address; int client_fd = 0; printf("\n"); printf("Welcome to Chat Server....\n"); memset(&serverStats, 0, sizeof(struct ServerStats_t)); serverStats.max_threads = MAX_THREADS; // start the main and make the server listen on port 12345 if (server_socket_init() == -1) { printf("An error occured. Closing program \n"); return 1 ; } //server_wait_client(server_fd); while(1) { //int rfd; int *arg; char ipstr[INET6_ADDRSTRLEN]; int port; int new_sd; int ret =0; struct sockaddr_storage remote_info ; pthread_t threads[MAX_THREADS]; socklen_t addr_size; addr_size = sizeof(addr_size); new_sd = accept(server_fd, (struct sockaddr *) &remote_info, &addr_size); getpeername(new_sd, (struct sockaddr*)&remote_info, &addr_size); // deal with both IPv4 and IPv6: if (remote_info.ss_family == AF_INET) { struct sockaddr_in *s = (struct sockaddr_in *)&remote_info; port = ntohs(s->sin_port); inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr); } else { // AF_INET6 struct sockaddr_in6 *s = (struct sockaddr_in6 *)&remote_info; port = ntohs(s->sin6_port); inet_ntop(AF_INET6, &s->sin6_addr, ipstr, sizeof ipstr); } printf("\n"); if(new_sd >= 0) { printf("Server accepted new connection on socket id :%d\n", new_sd); /* A connection between a client and the server has been established. * Now create a new thread and handover the client_sockfd */ pthread_mutex_lock(&curr_thread_count_mutex); if (curr_thread_count < MAX_THREADS) { /* Prepare client infos in handy structure */ client_info *ci = (client_info *)malloc(sizeof(client_info)); ci->sockfd = new_sd; ci->address = remote_info; sprintf(ci->nickname, "Client_%d\n", new_sd); /* Add client info to linked list */ llist_insert(&list_start, ci); llist_show(&list_start); /* System Monitoring Statistics Counter : Increments the number of active_connections counter. Shows the number of active clients*/ serverStats.num_of_active_connections++; /* Pass client info and invoke new thread */ ret = pthread_create(&threads[curr_thread_count], NULL, (void *)&server_read_client, (void *)&new_sd); /* only pass socket id ? */ if (ret == 0) { serverStats.num_of_clients_serviced++; pthread_detach(threads[curr_thread_count]); curr_thread_count++; /* Notify server and clients */ printf("User %s joined the chat.\n", ci->nickname); printf("Connections used: %d of %d\n", curr_thread_count, MAX_THREADS); } else { serverStats.num_of_conn_dropped++; llist_remove_by_sockfd(&list_start, new_sd); serverStats.num_of_active_connections--; free(ci); close(new_sd); } } else { serverStats.num_of_conn_dropped++; printf("Max. connections reached. Connection limit is %d. Connection dropped.\n", MAX_THREADS); close(new_sd); } pthread_mutex_unlock(&curr_thread_count_mutex); } else { /* Connection could not be established. Post error and exit. */ //perror(strerror(errno)); printf("Error creating socket\n"); exit(-1); } } return 0; }
int create_testcols_table( Arb_connection *conn) { int rc; int col; COLUMN_DEF *colp; ARBOR_LLIST *columns; rc = llist_create( &columns, LLIST_COMPARISON_FUNC, column_cmp, LLIST_DELETE_ITEM_FUNC, free, LLIST_DUPLICATE_STRATEGY, LLIST_DUPLICATES_NOT_ALLOWED, LLIST_SORT_STRATEGY, LLIST_UNORDERED_LIST, LLIST_NO_MORE_ARGS); if( rc != SUCCESS) abort(); for( col = 0; col < 5; ++col) { colp = (COLUMN_DEF *) calloc (1, sizeof (COLUMN_DEF)); assert( colp != NULL); colp->row_position = col; switch( col) { case 0: strcpy( colp->name, "string_col_len11"); colp->type = ARB_TYPE_STRING; colp->null_allowed = 1; colp->length = 11; break; case 1: strcpy( colp->name, "int32_col"); colp->type = ARB_TYPE_INT32; colp->null_allowed = 1; break; case 2: strcpy( colp->name, "datelong_col"); colp->type = ARB_TYPE_DATELONG; colp->null_allowed = 1; break; case 3: strcpy( colp->name, "numeric_col"); colp->type = ARB_TYPE_NUMERIC; colp->null_allowed = 1; colp->precision = 3; break; case 4: strcpy( colp->name, "string_col_len37"); colp->type = ARB_TYPE_STRING; colp->null_allowed = 1; colp->length = 37; break; } /* switch */ rc = llist_insert( columns, colp); if( rc != SUCCESS) abort(); } /* loop */ rc = arb_create_table( conn, TABLENAME, columns); if( rc != SUCCESS) abort(); return 0; }
/* * Main program */ int main(int argc, char *argv[]) { int i = 0; int ret = 0; struct sockaddr_in client_address; int client_sockfd = 0; pthread_t threads[MAX_THREADS]; /* Parse commandline args */ params = malloc(sizeof(cmd_params)); ret = parse_cmd_args(&argc, argv); if (params->help) { display_help_page(); exit(0); } if (params->version) { display_version_info(); exit(0); } if (ret < 0) { if (ret == -2) logline(LOG_ERROR, "Error: Invalid port range specified (-p)"); if (ret == -6) logline(LOG_ERROR, "Error: Invalid log level option specified (-l)."); logline(LOG_ERROR, "Use the -h option if you need help."); exit(ret); } /* Set log level */ switch (params->loglevel) { case 1: set_loglevel(LOG_ERROR); break; case 2: set_loglevel(LOG_INFO); break; case 3: set_loglevel(LOG_DEBUG); break; default: set_loglevel(LOG_ERROR); } /* Setup signal handler */ signal(SIGINT, shutdown_server); signal(SIGTERM, shutdown_server); /* Show banner and stuff */ show_gnu_banner(); /* Startup the server listener */ if (startup_server() < 0) { logline(LOG_ERROR, "Error during server startup. Please consult debug log for details."); exit(-1); } /* Post ready message */ logline(LOG_INFO, "Server listening on %s, port %d", params->ip, params->port); switch (params->loglevel) { case LOG_ERROR: logline(LOG_INFO, "Log level set to ERROR"); break; case LOG_INFO: logline(LOG_INFO, "Log level set to INFO"); break; case LOG_DEBUG: logline(LOG_INFO, "Log level set to DEBUG"); break; default: logline(LOG_INFO, "Unknown log level specified"); break; } /* Handle connections */ while (1) { logline(LOG_INFO, "Waiting for incoming connection..."); /* Accept a client connection */ client_len = sizeof(client_address); client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_address, (socklen_t *)&client_len); if (client_sockfd > 0) { logline(LOG_INFO, "Server accepted new connection on socket id %d", client_sockfd); /* A connection between a client and the server has been established. * Now create a new thread and handover the client_sockfd */ pthread_mutex_lock(&curr_thread_count_mutex); if (curr_thread_count < MAX_THREADS) { /* Prepare client infos in handy structure */ client_info *ci = (client_info *)malloc(sizeof(client_info)); ci->sockfd = client_sockfd; ci->address = client_address; sprintf(ci->nickname, "anonymous_%d", client_sockfd); /* Add client info to linked list */ llist_insert(&list_start, ci); llist_show(&list_start); /* Pass client info and invoke new thread */ ret = pthread_create(&threads[curr_thread_count], NULL, (void *)&proc_client, (void *)&client_sockfd); /* only pass socket id ? */ if (ret == 0) { pthread_detach(threads[curr_thread_count]); curr_thread_count++; /* Notify server and clients */ logline(LOG_INFO, "User %s joined the chat.", ci->nickname); logline(LOG_DEBUG, "main(): Connections used: %d of %d", curr_thread_count, MAX_THREADS); } else { free(ci); close(client_sockfd); } } else { logline(LOG_ERROR, "Max. connections reached. Connection limit is %d. Connection dropped.", MAX_THREADS); close(client_sockfd); } pthread_mutex_unlock(&curr_thread_count_mutex); } else { /* Connection could not be established. Post error and exit. */ perror(strerror(errno)); exit(-3); } } free(params); return 0; }