struct blk * copy(struct blk *hptr,int size) { register struct blk *hdr; register unsigned sz; register char *ptr; all++; nbytes += size; sz = length(hptr); ptr = nalloc(hptr->beg, (unsigned)size); if(ptr == 0){ garbage("copy"); if((ptr = nalloc(hptr->beg, (unsigned)size)) == NULL){ printf("copy size %d\n",size); ospace("copy"); } } if((hdr = hfree) == 0)hdr = morehd(); hfree = (struct blk *)hdr->rd; hdr->rd = hdr->beg = ptr; hdr->last = ptr+size; hdr->wt = ptr+sz; ptr = hdr->wt; while(ptr<hdr->last)*ptr++ = '\0'; return(hdr); }
static List *expandtilde(List *s) { List *top, *r, *var; char *home; size_t i, j, hsize, psize; bool tilde; for (r = s, tilde = FALSE; r != NULL; r = r->n) if (r->m != NULL && r->m[0] && r->w[0] == '~') tilde = TRUE; if (!tilde) return s; for (top = NULL; s != NULL; s = s->n) { if (top == NULL) top = r = nnew(List); else r = r->n = nnew(List); r->w = s->w; r->m = s->m; if (s->m == NULL || !s->m[0] || s->w[0] != '~') continue; for (i = 1; s->w[i] != '/' && s->w[i] != '\0'; i++); home = NULL; if (i == 1) { if ((var = varlookup("HOME")) != NULL) home = var->w; } else { char c = s->w[i]; struct passwd *pw; s->w[i] = '\0'; if ((pw = getpwnam(s->w + 1)) != NULL) home = pw->pw_dir; s->w[i] = c; } if (home == NULL || (hsize = strlen(home)) == 0) continue; psize = strlen(s->w + i) + 1; r->w = nalloc(psize + hsize); memcpy(r->w, home, hsize); memcpy(r->w + hsize, s->w + i, psize); for (j = i; s->w[j] != '\0'; j++) if (s->m[j]) break; if (s->w[j] != '\0') { r->m = nalloc(psize + hsize); memset(r->m, 0, hsize); memcpy(r->m + hsize, s->m + i, psize); } else r->m = NULL; } r->n = NULL; return top; }
// GDB needs malloc/free to prepare arguments for calls void *malloc(size_t size) { memnode_t *node = nalloc(size); void *ptr = (char *)node + sizeof(memnode_t); debug("GDB malloc(%ld) -> %p\n", size, ptr); return ptr; }
void counter_add(uint64_t ref_id, uint64_t mask) { if (all_counters +1 > (counter_t *)counters_node->ends) { // overflow, need a bigger node int cur_size = counters_node->index *PAGE_SIZE; memnode_t *new_node = nalloc(cur_size *2 -sizeof(memnode_t)); memcpy((void *)new_node->starts, all_counters, nr_counters *sizeof(counter_t)); nfree(counters_node); counters_node = new_node; all_counters = (counter_t *)new_node->starts; } counter_t *alpha = all_counters; counter_t *beta = all_counters +nr_counters; while (beta > alpha) { counter_t *mid = alpha + (beta-alpha)/2; if (mid->ref_id > ref_id) beta = mid; else alpha = mid +1; } // insert the new counter before *alpha memmove(alpha +1, alpha, (void *)(all_counters +nr_counters) -(void *)alpha); nr_counters++; counter_t *cntr = alpha; cntr->ref_id = ref_id; cntr->value = 0; cntr->mask = mask; }
extern Node *mk(int /*nodetype*/ t,...) { va_list ap; Node *n; va_start(ap, t); switch (t) { default: panic("unexpected node in mk"); /* NOTREACHED */ case nDup: n = nalloc(offsetof(Node, u[3])); n->u[0].i = va_arg(ap, int); n->u[1].i = va_arg(ap, int); n->u[2].i = va_arg(ap, int); break; case nWord: n = nalloc(offsetof(Node, u[3])); n->u[0].s = va_arg(ap, char *); n->u[1].s = va_arg(ap, char *); n->u[2].i = va_arg(ap, int); break; case nBang: case nNowait: case nCount: case nFlat: case nRmfn: case nSubshell: case nVar: case nCase: n = nalloc(offsetof(Node, u[1])); n->u[0].p = va_arg(ap, Node *); break; case nAndalso: case nAssign: case nBackq: case nBody: case nBrace: case nConcat: case nElse: case nEpilog: case nIf: case nNewfn: case nCbody: case nOrelse: case nPre: case nArgs: case nSwitch: case nMatch: case nVarsub: case nWhile: case nLappend: n = nalloc(offsetof(Node, u[2])); n->u[0].p = va_arg(ap, Node *); n->u[1].p = va_arg(ap, Node *); break; case nForin: n = nalloc(offsetof(Node, u[3])); n->u[0].p = va_arg(ap, Node *); n->u[1].p = va_arg(ap, Node *); n->u[2].p = va_arg(ap, Node *); break; case nPipe: n = nalloc(offsetof(Node, u[4])); n->u[0].i = va_arg(ap, int); n->u[1].i = va_arg(ap, int); n->u[2].p = va_arg(ap, Node *); n->u[3].p = va_arg(ap, Node *); break; case nRedir: case nNmpipe: n = nalloc(offsetof(Node, u[3])); n->u[0].i = va_arg(ap, int); n->u[1].i = va_arg(ap, int); n->u[2].p = va_arg(ap, Node *); break; } n->type = t; va_end(ap); return n; }
/* * Fix the header by glopping all of the expanded names from * the distribution list into the appropriate fields. */ void fixhead(struct header *hp, struct name *tolist) { struct name *np; hp->h_to = NULL; hp->h_cc = NULL; hp->h_bcc = NULL; for (np = tolist; np != NULL; np = np->n_flink) if ((np->n_type & GMASK) == GTO) hp->h_to = cat(hp->h_to, nalloc(np->n_name, np->n_type)); else if ((np->n_type & GMASK) == GCC) hp->h_cc = cat(hp->h_cc, nalloc(np->n_name, np->n_type)); else if ((np->n_type & GMASK) == GBCC) hp->h_bcc = cat(hp->h_bcc, nalloc(np->n_name, np->n_type)); }
/* create node: CONSTANT */ node *constant_n(int value) { node *p; /* allocate size of the node */ p = nalloc(); /* store information */ p->type = constant_t; p->con.value = value; return p; }
/* create node: PRINT */ node *print_n(node *child) { node *p; /* allocate size of the node */ p = nalloc(); /* store information */ p->type = print_t; p->print.child = child; return p; }
/* create node: IF */ node *if_n(node *cond, node *body) { node *p; /* allocate size of the node */ p = nalloc(); /* store information */ p->type = if_t; p->ifno.cond = cond; p->ifno.body = body; return p; }
void array_init(array_t *arr, int elt_size, int alloc) { int node_size = elt_size * alloc + sizeof(memnode_t); node_size += (ARRAY_NODE_SIZE-1); node_size &= ~(ARRAY_NODE_SIZE-1); memnode_t *node = nalloc(node_size - sizeof(memnode_t)); arr->node = node; arr->elt_size = elt_size; arr->elts = node->starts; arr->nelts = 0; arr->alloc = ((void *)node->ends - arr->elts) / elt_size; }
/* create node: ADD */ node *add_n(node *child1, node *child2) { node *p; /* allocate size of the node */ p = nalloc(); /* store information */ p->type = add_t; p->add.child1 = child1; p->add.child2 = child2; return p; }
/* create node: SUBTRACT */ node *subtract_n(node *child1, node *child2) { node *p; /* allocate size of the node */ p = nalloc(); /* store information */ p->type = subtract_t; p->sub.child1 = child1; p->sub.child2 = child2; return p; }
extern List *concat(List *s1, List *s2) { int n1, n2; List *r, *top; if (s1 == NULL) return s2; if (s2 == NULL) return s1; if ((n1 = listnel(s1)) != (n2 = listnel(s2)) && n1 != 1 && n2 != 1) rc_error("bad concatenation"); for (r = top = nnew(List); 1; r = r->n = nnew(List)) { size_t x = strlen(s1->w); size_t y = strlen(s2->w); size_t z = x + y + 1; r->w = nalloc(z); strcpy(r->w, s1->w); strcat(r->w, s2->w); if (s1->m == NULL && s2->m == NULL) { r->m = NULL; } else { r->m = nalloc(z); if (s1->m == NULL) memzero(r->m, x); else memcpy(r->m, s1->m, x); if (s2->m == NULL) memzero(&r->m[x], y); else memcpy(&r->m[x], s2->m, y); r->m[z] = 0; } if (n1 > 1) s1 = s1->n; if (n2 > 1) s2 = s2->n; if (s1 == NULL || s2 == NULL || (n1 == 1 && n2 == 1)) break; } r->n = NULL; return top; }
struct node *nalloc(struct node *p, uint8_t level, uint8_t max) { if (level == max) { return NULL; } struct node *n = malloc(sizeof(struct node)); n->level = level; n->p = p; n->s = malloc(sizeof(struct node) * (n->level + 1)); for (int i = 0; i < n->level + 1; i++) { n->s[i] = nalloc(n, level + 1, max); } return n; }
/* * Fix the header by glopping all of the expanded names from * the distribution list into the appropriate fields. */ void fixhead(struct header *hp, struct name *tolist) { struct name *np; hp->h_to = NULL; hp->h_cc = NULL; hp->h_bcc = NULL; for (np = tolist; np != NULL; np = np->n_flink) { /* Don't copy deleted addresses to the header */ if (np->n_type & GDEL) continue; if ((np->n_type & GMASK) == GTO) hp->h_to = cat(hp->h_to, nalloc(np->n_name, np->n_type)); else if ((np->n_type & GMASK) == GCC) hp->h_cc = cat(hp->h_cc, nalloc(np->n_name, np->n_type)); else if ((np->n_type & GMASK) == GBCC) hp->h_bcc = cat(hp->h_bcc, nalloc(np->n_name, np->n_type)); } }
static void b_cd(char **av) { List *s, nil; char *path = NULL; size_t t, pathlen = 0; if (*++av == NULL) { s = varlookup("home"); *av = (s == NULL) ? "/" : s->w; } else if (av[1] != NULL) { arg_count("cd"); return; } if (isabsolute(*av) || streq(*av, ".") || streq(*av, "..")) { /* absolute pathname? */ if (chdir(*av) < 0) { set(FALSE); uerror(*av); } else set(TRUE); } else { s = varlookup("cdpath"); if (s == NULL) { s = &nil; nil.w = ""; nil.n = NULL; } do { if (s != &nil && *s->w != '\0') { t = strlen(*av) + strlen(s->w) + 2; if (t > pathlen) path = nalloc(pathlen = t); strcpy(path, s->w); if (!streq(s->w, "/")) /* "//" is special to POSIX */ strcat(path, "/"); strcat(path, *av); } else { pathlen = 0; path = *av; } if (chdir(path) >= 0) { set(TRUE); if (interactive && *s->w != '\0' && !streq(s->w, ".")) fprint(1, "%s\n", path); return; } s = s->n; } while (s != NULL); fprint(2, "couldn't cd to %s\n", *av); set(FALSE); } }
int main() { Node node = node_create(NULL, -1, 0); int size; fputs("Dimensiune: ", stdout); scanf("%d", &size); do { puts("[1] Afiseaza"); puts("[2] Aloca"); puts("[3] Elibereaza"); puts("[4] Defragmenteaza"); puts("[0] Iesi"); fputs(">>> ", stdout); int ask; scanf("%d", &ask); if (!ask) { node_free(node, NULL); break; } else if (ask < 1 || ask > 4) puts("Optiune invalida"); else if (ask == 1) { int* cnt = node_print(node); if (*cnt) { *cnt = 0; putchar('\n'); } } else if (ask == 2) { int length; fputs("Lungime: ", stdout); scanf("%d", &length); int offset = nalloc(&node, length, size); if (offset == -1) puts("Nu se poate aloca"); else printf("S-a alocat la adresa %d\n", offset); } else if (ask == 3) { int offset, length; fputs("Adresa: ", stdout); scanf("%d", &offset); fputs("Lungime: ", stdout); scanf("%d", &length); nfree(&node, offset, length); } else if (ask == 4) ndefrag(node); putchar('\n'); } while (1); return 0; }
static DefNode *append(DefNode *pdn, char *def, char *val) { if (pdn) { if (strcmp(pdn->def, def) == 0) { // if the definition exists, replace the former value free(pdn->val); pdn->val = malloc(strlen(val) + 1); strcpy(pdn->val, val); } else { pdn->next = append(pdn->next, def, val); } } else { // if the definition does not exist, add a new definition pdn = nalloc(def, val); } return pdn; }
/* create node: BODY */ node *body_n(node *child) { node *p; /* allocate size of the node */ p = nalloc(); /* allocate size of first child */ if ((p->body.children = malloc(sizeof(child))) == NULL) printf("out of memory"); /* store information */ p->type = body_t; p->body.children[0] = child; p->body.count = 1; return p; }
int addnode (tnode ** root, int * a ) { if (*root==NULL) { tnode * node=nalloc (a); *root= node; return 1; } int res=compare (a,(*root)->matrix,9); if (res==0){ return 0; } if (res<0) { tnode ** z = &((*root)->left); return addnode ( z,a); } else { tnode ** z = &((*root)->right); //puts("pass it"); return addnode ( z,a); } }
/* * === FUNCTION ====================================================================== * Name: get_new_node * Description: apply&init a new alloc_n, return it * just use in this file, static one * ===================================================================================== */ static alloc_n *get_new_node(void *addr, long nbytes, const char *file, int line) { assert(addr_align(addr) == 0); assert(nbytes > 0); int key; alloc_n *node = nalloc(addr, nbytes, file, line); if (node) { node->free = freelist.free; /* alloc_n.free */ freelist.free = node; key = hash(node->addr, htab); node->link = htab[key]->link; /* NULL also works */ htab[key]->link = node; /* add to the start */ } else { FAILURE(); } return node; }
int main(int argc, char **argv) { struct node *nodes = nalloc(NULL, 0, 11); nodes->val = 1; int lev[201]; for (int i = 0; i < 201; i++) { lev[i] = INT_MAX; } tr(nodes->s[0], 0, lev); nfree(nodes); int sum = 0; for (int i = 2; i <= 200; i++) { if (lev[i] != INT_MAX) { sum += lev[i]; } else { sum += 11; /* 191 requires 11 */ } } printf("%d\n", sum); return 0; }
extern List *flatten(List *s) { List *r; size_t step; char *f; if (s == NULL || s->n == NULL) return s; r = nnew(List); f = r->w = nalloc(listlen(s) + 1); r->m = NULL; /* flattened lists come from variables, so no meta */ r->n = NULL; strcpy(f, s->w); f += strlen(s->w); do { *f++ = ' '; s = s->n; step = strlen(s->w); memcpy(f, s->w, step); f += step; } while (s->n != NULL); *f = '\0'; return r; }
/* * Break up a white-space or comma delimited name list so that aliases * can get expanded. Without this, the CC: or BCC: list is broken too * late for alias expansion to occur. */ PUBLIC struct name * lexpand(char *str, int ntype) { char *list; struct name *np = NULL; char *word, *p; list = estrdup(str); word = list; for (word = list; *word; word = p) { word = skip_WSP(word); for (p = word; *p && !is_WSP(*p) && *p != ','; p++) continue; if (*p) *p++ = '\0'; np = cat(np, nalloc(word, ntype)); } free(list); return np; }
/* * Do a shell-like extraction of a line * and make a list of name from it. * Return the list or NULL if none found. */ static struct name * shextract(char *line, int ntype) { struct name *begin, *np, *t; char *argv[MAXARGC]; size_t argc, i; begin = NULL; if (line) { np = NULL; argc = getrawlist(line, argv, (int)__arraycount(argv)); for (i = 0; i < argc; i++) { t = nalloc(argv[i], ntype); if (begin == NULL) begin = t; else np->n_flink = t; t->n_blink = np; np = t; } } return begin; }
hash_t *hash_make(void) { memnode_t *node = nalloc(HASH_NODE_SIZE - sizeof(memnode_t)); if (node == 0) return 0; // Initial node layout: // // memnode_t // hash_t // hash_entry_t *[nr_buckets] // hash_entry_t [] (free) // hash_t *ht = (hash_t *)node->starts; ht->nodes = node; hash_entry_t **buckets = (void *)ht + sizeof(*ht); ht->buckets = buckets; ht->nr_buckets = HASH_BUCKETS; ht->count = 0; ht->free = 0; for (int i = 0; i < HASH_BUCKETS; i++) buckets[i] = 0; hash_entry_t *entry = (void *)(buckets + HASH_BUCKETS); while ((void *)node->ends - (void *)entry >= sizeof(hash_entry_t)) { entry->next = ht->free; ht->free = entry; entry++; } return ht; }
uint64_t counter_add(uint64_t mask) { static uint64_t next_counter_id = 0; uint64_t id = next_counter_id++; if (all_counters +nr_counters +1 > (counter_t *)counters_node->ends) { // overflow, need a bigger node int cur_size = counters_node->index *PAGE_SIZE; memnode_t *new_node = nalloc(cur_size *2 -sizeof(memnode_t)); memcpy((void *)new_node->starts, all_counters, nr_counters *sizeof(counter_t)); nfree(counters_node); counters_node = new_node; all_counters = (counter_t *)new_node->starts; } counter_t *cntr = all_counters +nr_counters; cntr->id = id; cntr->value = 0; cntr->mask = mask; nr_counters++; return id; }
PUBLIC int main(int argc, char *argv[]) { jmp_buf jmpbuf; struct sigaction sa; struct name *to, *cc, *bcc, *smopts; #ifdef MIME_SUPPORT struct name *attach_optargs; struct name *attach_end; #endif char *subject; const char *ef; char nosrc = 0; const char *rc; int Hflag; int i; /* * For portability, call setprogname() early, before * getprogname() is called. */ (void)setprogname(argv[0]); /* * Set up a reasonable environment. * Figure out whether we are being run interactively, * start the SIGCHLD catcher, and so forth. * (Other signals are setup later by sig_setup().) */ (void)sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; sa.sa_handler = sigchild; (void)sigaction(SIGCHLD, &sa, NULL); if (isatty(0)) assign(ENAME_INTERACTIVE, ""); image = -1; /* * Now, determine how we are being used. * We successively pick off - flags. * If there is anything left, it is the base of the list * of users to mail to. Argp will be set to point to the * first of these users. */ rc = NULL; ef = NULL; to = NULL; cc = NULL; bcc = NULL; smopts = NULL; subject = NULL; Hflag = 0; #ifdef MIME_SUPPORT attach_optargs = NULL; attach_end = NULL; while ((i = getopt(argc, argv, ":~EH:INT:a:b:c:dfinr:s:u:v")) != -1) #else while ((i = getopt(argc, argv, ":~EH:INT:b:c:dfinr:s:u:v")) != -1) #endif { switch (i) { case 'T': /* * Next argument is temp file to write which * articles have been read/deleted for netnews. */ Tflag = optarg; if ((i = creat(Tflag, 0600)) < 0) { warn("%s", Tflag); exit(1); } (void)close(i); break; #ifdef MIME_SUPPORT case 'a': { struct name *np; np = nalloc(optarg, 0); if (attach_end == NULL) attach_optargs = np; else { np->n_blink = attach_end; attach_end->n_flink = np; } attach_end = np; break; } #endif case 'u': /* * Next argument is person to pretend to be. */ myname = optarg; (void)unsetenv("MAIL"); break; case 'i': /* * User wants to ignore interrupts. * Set the variable "ignore" */ assign(ENAME_IGNORE, ""); break; case 'd': debug++; break; case 'r': rc = optarg; break; case 's': /* * Give a subject field for sending from * non terminal */ subject = optarg; break; case 'f': /* * User is specifying file to "edit" with Mail, * as opposed to reading system mailbox. * If no argument is given after -f, we read his * mbox file. * * getopt() can't handle optional arguments, so here * is an ugly hack to get around it. */ if ((argv[optind]) && (argv[optind][0] != '-')) ef = argv[optind++]; else ef = "&"; break; case 'H': /* * Print out the headers and quit. */ Hflag = get_Hflag(argv); break; case 'n': /* * User doesn't want to source /usr/lib/Mail.rc */ nosrc++; break; case 'N': /* * Avoid initial header printing. */ assign(ENAME_NOHEADER, ""); break; case 'v': /* * Send mailer verbose flag */ assign(ENAME_VERBOSE, ""); break; case 'I': case '~': /* * We're interactive */ assign(ENAME_INTERACTIVE, ""); break; case 'c': /* * Get Carbon Copy Recipient list */ cc = cat(cc, lexpand(optarg, GCC)); break; case 'b': /* * Get Blind Carbon Copy Recipient list */ bcc = cat(bcc, lexpand(optarg, GBCC)); break; case 'E': /* * Don't send empty files. */ assign(ENAME_DONTSENDEMPTY, ""); break; case ':': /* * An optarg was expected but not found. */ if (optopt == 'H') { Hflag = get_Hflag(NULL); break; } (void)fprintf(stderr, "%s: option requires an argument -- %c\n", getprogname(), optopt); /* FALLTHROUGH */ case '?': /* * An unknown option flag. We need to do the * error message. */ if (optopt != '?') (void)fprintf(stderr, "%s: unknown option -- %c\n", getprogname(), optopt); usage(); /* print usage message and die */ /*NOTREACHED*/ } } for (i = optind; (argv[i]) && (*argv[i] != '-'); i++) to = cat(to, nalloc(argv[i], GTO)); for (/*EMPTY*/; argv[i]; i++) smopts = cat(smopts, nalloc(argv[i], GSMOPTS)); /* * Check for inconsistent arguments. */ if (to == NULL && (subject != NULL || cc != NULL || bcc != NULL)) errx(EXIT_FAILURE, "You must specify direct recipients with -s, -c, or -b."); if (ef != NULL && to != NULL) { errx(EXIT_FAILURE, "Cannot give -f and people to send to."); } if (Hflag != 0 && to != NULL) errx(EXIT_FAILURE, "Cannot give -H and people to send to."); #ifdef MIME_SUPPORT if (attach_optargs != NULL && to == NULL) errx(EXIT_FAILURE, "Cannot give -a without people to send to."); #endif tinit(); /* must be done before loading the rcfile */ input = stdin; mailmode = Hflag ? mm_hdrsonly : to ? mm_sending : mm_receiving; spreserve(); if (!nosrc) load(_PATH_MASTER_RC); /* * Expand returns a savestr, but load only uses the file name * for fopen, so it's safe to do this. */ if (rc == NULL && (rc = getenv("MAILRC")) == NULL) rc = "~/.mailrc"; load(expand(rc)); setscreensize(); /* do this after loading the rcfile */ #ifdef USE_EDITLINE /* * This is after loading the MAILRC so we can use value(). * Avoid editline in mm_hdrsonly mode or pipelines will screw * up. XXX - there must be a better way! */ if (mailmode != mm_hdrsonly) init_editline(); #endif sig_setup(); switch (mailmode) { case mm_sending: (void)mail(to, cc, bcc, smopts, subject, mime_attach_optargs(attach_optargs)); /* * why wait? */ exit(senderr); break; /* XXX - keep lint happy */ case mm_receiving: case mm_hdrsonly: /* * Ok, we are reading mail. * Decide whether we are editing a mailbox or reading * the system mailbox, and open up the right stuff. */ if (ef == NULL) ef = "%"; if (setfile(ef) < 0) exit(1); /* error already reported */ if (value(ENAME_QUIET) == NULL) (void)printf("Mail version %s. Type ? for help.\n", version); if (mailmode == mm_hdrsonly) show_headers_and_exit(Hflag); /* NORETURN */ announce(); (void)fflush(stdout); if (setjmp(jmpbuf) != 0) { /* Return here if quit() fails below. */ (void)printf("Use 'exit' to quit without saving changes.\n"); } commands(); /* Ignore these signals from now on! */ (void)signal(SIGHUP, SIG_IGN); (void)signal(SIGINT, SIG_IGN); (void)signal(SIGQUIT, SIG_IGN); quit(jmpbuf); break; default: assert(/*CONSTCOND*/0); break; } return 0; }
/* This definition is stupid. Think of something better */ SOCKET * NEW(socket) (SOCKET *sk, int type, int domain, int proto, char sr, unsigned int port, const char *hostname, void *ssl_ctx) { /* Object allocation */ iiprintf(SOCKET); SOCKET *s; socket_t *sock; /* Check memory */ if (!sk) { if (!(s = nalloc(sizeof(SOCKET), "socket.object"))) return NULL; if (!(sock = (socket_t *)nalloc(sizeof(socket_t), "socket.socket"))) { free(s); return NULL; } memset(sock, 0, sizeof(socket_t)); } else { s = sk; sock = sk->data; memset(sock, 0, sizeof(socket_t)); } /* All of this can be done with a macro */ sock->buffer = NULL; sock->connection_type = type; sock->domain = domain; sock->protocol = proto; sock->addrsize = sizeof(struct sockaddr); sock->bufsz = 1024; sock->opened = 0; sock->backlog = 500; sock->waittime = 5000; // 3000 microseconds sock->hostname = !hostname ? NULL : (char *)hostname; /* Check port number (clients are zero until a request is made) */ if (port < 0 || port > 65536) { /* Free allocated socket */ vvprintf("Invalid port specified."); return errnull("Invalid port specified."); } else if (!port) sock->port = 0; else sock->port = port; #if 0 /* Service check (part of struct in the future) */ fprintf(stderr, "Checking that port binds to a real service..."); if (!services[port]) sock->service = "UNKNOWN"; else sock->service = (char *)services[port]; #endif /* Set up the address data structure for use as either client or server */ sock->_class = sr; if (sock->_class == 's') { if ((sock->srvaddrinfo = (struct sockaddr_in *)nalloc(sizeof(struct sockaddr_in), "sockaddr.info")) == NULL) return errnull("Could not allocate structure specified."); /* Some type of gethosting must be done */ memset(sock->srvaddrinfo, 0, sizeof(struct sockaddr_in)); struct sockaddr_in *saa = sock->srvaddrinfo; saa->sin_family = AF_INET; saa->sin_port = htons(sock->port); /* A smart string function can decide whether or not this is IPv6 */ (&saa->sin_addr)->s_addr = htonl(INADDR_ANY); } else if (sock->_class == 'c') { /* Set up the addrinfo structure for a future client request. */ struct addrinfo *h; memset(&sock->hints, 0, sizeof(sock->hints)); h = &sock->hints; h->ai_family = sock->domain; h->ai_socktype = sock->connection_type; } #if 0 /* Show the buffer pointer... */ fprintf(stderr, "tcp socket buffer: %p (%s)\n", sock->buffer, sock->_class == 'c' ? "client" : \ sock->_class == 'd' ? "child" : "server"); #endif /* Set up an SSL context if asked. */ if (!ssl_ctx) sock->ssl_ctx = NULL; else sock->ssl_ctx = ssl_ctx; /* Finally, create a socket. */ sock->fd = socket(sock->domain, sock->connection_type, sock->protocol); sock->opened = 1; /* Set timeout, reusable bit and any other options */ struct timeval to; to.tv_sec = 2; to.tv_usec = 0; if (setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, &to, sizeof(to)) == -1) { // sock->free(sock); errsys("Could not reopen socket."); return NULL; } /* Set private data */ s->data = sock; /* Set the socket info as part of the object. */ s->data->urn = NULL; /* Set the URN to NULL */ /* The standard */ s->free = &__free; s->info = &__printf; /* The rest */ s->connect = &__connect; s->bind = &__bind; s->listen = &__listen; s->accept = &__accept; s->shutdown = &__shutdown; s->close = &__close; s->send = &__send; s->recv = &__recv; s->addrinfo = &__addrinfo; s->recvd = &recvd; s->parsed = &parsed; s->release = &__release; return INITIALIZED(s); }
static SOCKET * __accept (SOCKET *self) { /* Use a function pointer to choose the right type of send */ SOCKET *ns, *os; socket_t *od = self->data; /* Allocate memory for object */ // fprintf(stderr, "allocate child object...\n"); if (!(ns = nalloc(sizeof(SOCKET), "socket.childo"))) { fprintf(stderr, "Failed to allocate memory for child object.\n"); return NULL; } /* Allocate memory for this too? */ // fprintf(stderr, "allocate child data...\n"); if (!(ns->data = nalloc(sizeof(socket_t), "socket.childd"))) { fprintf(stderr, "Failed to allocate memory for child data.\n"); free(ns); return NULL; } /* Clone current socket data */ // fprintf(stderr, "clone parent data to child-to-be...\n"); if (!memcpy(ns->data, self->data, sizeof(socket_t))) { fprintf(stderr, "Could not copy original parent socket data.\n"); return NULL; } /* Accept a connection. */ ns->data->fd = accept(od->fd, NULL, NULL); /* If failure occurred, free all and send back. */ if (!ns->data->fd || ns->data->fd == -1) { char *err = (ns->data->fd == -1) ? strerror(errno) : "Lost descriptor."; free(ns->data); free(ns); fprintf(stderr, "Could not accept connection: %s", err); return NULL; } /* Set socket description */ ns->data->_class = 'd'; /* Set methods */ ns->info = &__printf; ns->bind = &__bind; ns->listen = &__listen; ns->shutdown = &__shutdown; ns->close = &__close; ns->send = &__send; ns->recv = &__recv; ns->free = &__free; ns->addrinfo = &__addrinfo; ns->recvd = &recvd; ns->parsed = &parsed; ns->release = &__release; /* Because this is a clone, some functions are not needed */ ns->accept = &__blank; /* Show info */ // fprintf(stderr, "Immediately after allocation.\n"); // ns->info(ns); return ns; }