leaf *build(char *expr, hashtab *h) { lstack s; char opr; int i = -1, num; char str[MAX_STR]; leaf *l = NULL, *r = NULL, *tmp = NULL; lstack_init(&s, 1024); while (expr[++i]) { if (is_digit(expr[i])) { num = get_number(expr, &i); l = new_num_leaf(num, INT, NULL, NULL, -1); lpush(&s, l); } else if (is_opr(expr[i])) { lpop(&s, &r); lpop(&s, &l); //Optimization : reducing the amount of registers !! if ((expr[i] == '+' || expr[i] == '*') && l->typ == INT && r->typ != INT) tmp = l, l = r, r = tmp; l = new_num_leaf(expr[i], CHAR, l, r, get_reg_num(l, r)); lpush(&s, l); } else if (is_alpha(expr[i])) { get_string(expr, str, &i); if (search(h, str)) { lpop(&s, &r); r->reg = 1; //Premice to register allocation !!! l = new_str_leaf(str, FUNC, NULL, r, 1); lpush(&s, l); } else //If not a function then a variable identifier ! [extend the grammar] { l = new_str_leaf(str, VAR, NULL, NULL, -1); lpush(&s, l); } } } lstack_free(&s); return l; }
int main(void) { ACData tk = make_token("barf"); ACData n = make_int(3); ACData bs = give_binding(tk,n); ACData tk2 = make_token("frab"); ACData n2 = make_int(-3); ACData bs2 = give_binding(tk2,n2); ACData bs3, bs4; ACData t,l; bs3 = give_overriding(bs,bs2); bs4 = give_disjoint_union(bs3,bs2); print_ac_data(bs3); t = make_tuple(tk,bs3); print_ac_data(t); printf("\n"); l = make_list(tk,bs3); print_ac_data(l); printf("\n"); l = lpush(l,l); print_ac_data(l); printf("\n"); l = lpop(l); print_ac_data(l); printf("\n"); return 0; }
int parse_header(FILE *f, llist *l) { msg_header h; char s[MAX_FBUFFER_SIZE]; if (!feof(f)) { fgets((char *)s, MAX_FBUFFER_SIZE, f); strchop(s); } while ((strcmp(s,"")!=0) && (!feof(f))) { if (strstr(s, "From: ")) { char *tmp = strstr(s,": ")+2; if (tmp) strncpy(h.from, tmp, MAX_HINFO_SIZE); } else if (strstr(s, "Subject: ")) { char *tmp = strstr(s,": ")+2; if (tmp) strncpy(h.subject, tmp, MAX_HINFO_SIZE); } else if (strstr(s, "To: ")) { char *tmp = strstr(s,": ")+2; if (tmp) strncpy(h.to, tmp, MAX_HINFO_SIZE); } else if (strstr(s, "Date: ")) { char *tmp = strstr(s,": ")+2; if (tmp) strncpy(h.date, tmp, MAX_HINFO_SIZE); } fgets((char *)s, MAX_FBUFFER_SIZE, f); strchop(s); } h.body_offset = ftell(f); return(lpush(l, &h)); }
int run_task(task_type_t type, metric_type_t metric, task_option_t *options, char *id) { switch (type) { case PROCESS: return handle_process(metric, options, id); case DIRECTORY: return handle_directory(options, id); case DISK: return handle_disk(metric, options, id); case SWAP: return handle_swap(id); case LOAD: return handle_load(id); case TOTAL: return handle_total(id, metric); default: { // We've been passed an incorrectly initialized task. Shouldn't happen, but handle // for debugging. Plus it gets GCC off my case. task_report_t report; init_task_report(&report, id, type, metric); sprintf(report.message, "FATAL CAUSE INVALID_TASK"); lpush(&reports, &report); return NOTGIOS_GENERIC_ERROR; } } }
void dsend(int idx, dbuf_t * d) { debug(DBG_GLOBAL, 5, "pushing %d bytes for index %d", d->dsize, idx); debug_dump(DBG_GLOBAL, 100, d->buf, d->dsize); lpush(&cdata[idx].xmit_list, d); ufds[idx].events |= POLLOUT; // Will be unlocked by the send mechanism dlock(d); }
/* * Momentary layer */ void layer_momentary(uint8_t pressed, const struct key *key) { const uint8_t usage = pgm_read_byte(&key->usage); if (pressed) { Config.keys.mods.dumb |= pdata8(key, struct mods, req) & ~pdata8(key, struct mods, ign); lpush(usage); } else {
int handle_total(char *id, metric_type_t metric) { task_report_t report; init_task_report(&report, id, PROCESS, metric); int retval; switch (metric) { case MEMORY: retval = total_memory_collect(&report); if (retval == NOTGIOS_UNSUPP_DISTRO) RETURN_UNSUPPORTED_DISTRO(report, id); write_log(LOG_DEBUG, "Task %s: Total memory info collected...\n", id); break; case CPU: retval = total_cpu_collect(&report); if (retval == NOTGIOS_UNSUPP_DISTRO) RETURN_UNSUPPORTED_DISTRO(report, id); write_log(LOG_DEBUG, "Task %s: Total CPU usage collected...\n", id); break; case IO: // This is currently unimplemented. retval = total_io_collect(&report); break; default: // We've been passed a task containing invalid options. Shouldn't happen, but handle it // for debugging. sprintf(report.message, "FATAL CAUSE INVALID_TASK"); lpush(&reports, &report); return NOTGIOS_GENERIC_ERROR; } if (retval == NOTGIOS_UNSUPP_TASK) { write_log(LOG_DEBUG, "Task %s: Received an unsupported task. Removing...\n", id); sprintf(report.message, "FATAL CAUSE UNSUPPORTED_TASK"); lpush(&reports, &report); return NOTGIOS_TASK_FATAL; } write_log(LOG_DEBUG, "Task %s: Enqueuing report an returning...\n", id); lpush(&reports, &report); return NOTGIOS_SUCCESS; }
int redis_list::lpush(const char* key, const char* first_value, ...) { std::vector<const char*> values; values.push_back(first_value); va_list ap; va_start(ap, first_value); const char* value; while ((value = va_arg(ap, const char*)) != NULL) values.push_back(value); va_end(ap); return lpush(key, values); }
void Ardb::WakeBlockedConnCallback(Channel* ch, void* data) { if (NULL != ch) { Context* ctx = (Context*) data; if (-1 != ctx->block->blocking_timer_task_id) { ch->GetService().GetTimer().Cancel(ctx->block->blocking_timer_task_id); ctx->block->blocking_timer_task_id = -1; } if (ctx->block->dest_key.empty()) { ctx->reply.type = REDIS_REPLY_ARRAY; if (!ctx->block->waked_value.empty()) { RedisReply& r1 = ctx->reply.AddMember(); RedisReply& r2 = ctx->reply.AddMember(); fill_str_reply(r1, ctx->block->waked_key.key); fill_str_reply(r2, ctx->block->waked_value); RedisCommandFrame lpop("lpop"); lpop.AddArg(ctx->block->waked_key.key); g_db->m_master.FeedSlaves(ctx->currentDB, lpop); } } else { if (!ctx->block->waked_value.empty()) { fill_str_reply(ctx->reply, ctx->block->waked_value); RedisCommandFrame lpush("lpush"); lpush.AddArg(ctx->block->dest_key); lpush.AddArg(ctx->block->waked_value); g_db->LPush(*ctx, lpush); RedisCommandFrame lpop("lpop"); lpop.AddArg(ctx->block->waked_key.key); g_db->m_master.FeedSlaves(ctx->currentDB, lpop); g_db->m_master.FeedSlaves(ctx->currentDB, lpush); } else { ctx->reply.type = REDIS_REPLY_NIL; } } ch->Write(ctx->reply); g_db->ClearBlockKeys(*ctx); ch->AttachFD(); } }
void timer_enqueue_internal(uint32_t timer_idx, uint32_t msec) { timerwheel_entry_t *timers = (timerwheel_entry_t *) timers_list->buf; uint32_t ticks = (msec * TIMER_WHEEL_TICKS_PER_SEC / 1000); uint32_t next_wheel_idx = (timerwheel_idx + ticks) % TIMER_WHEEL_SIZE; if(ticks >= TIMER_WHEEL_SIZE) { debug(DBG_TIMERS, 0, "%d ticks is bigger than the wheel size", ticks); return; } debug(DBG_TIMERS, 10, "enqueue index %d with interval %d", timer_idx, msec); debug(DBG_TIMERS, 10, "current tw index: %d, ticks from it: %d", timerwheel_idx, ticks); // These two fields are primarily used to remove the timer beforehand, // but rpush is important :) timers[timer_idx].wheel_li = lpush(&timerwheel[next_wheel_idx], (void *) ((long int) timer_idx)); timers[timer_idx].wheel_idx = next_wheel_idx; debug(DBG_TIMERS, 10, "Pushed timer index %d onto wheel index %d", timer_idx, next_wheel_idx); }
/** \brief Set the argument offsets for a function, then kick off compiling * of the function * * \param prevarg - Last argument * \param currfn - Current function */ void setlocvar(SYMBOL *prevarg,SYMBOL *currfn) { int lgh,where; int *iptr; SYMBOL *copyarg; int argnumber; char buffer2[120]; unsigned char tester; lgh = 0; /* Initialise it */ if ( prevarg != NULL && currfn->prototyped == 0 ) { StoreFunctionSignature(prevarg); } argnumber=currfn->prototyped; /* * If we have filled up our number of arguments, then pretend * we don't have any..nasty, nasty */ if (argnumber==(MAXARGS-1)) argnumber=0; else if (argnumber) argnumber=1; /* * Dump some info about defining the function etc */ if (verbose){ toconsole(); outstr("Defining function: "); outstr(currfn->name); nl(); tofile(); } nl();prefix();outname(currfn->name,dopref(currfn));col();nl(); /* print function name */ infunc=1; /* In a function for sure! */ copyarg=prevarg; if ( ( (currfn->flags&SHARED) && makeshare ) || sharedfile ) { /* Shared library definition, offset the stack */ where= 2 +shareoffset; } else where = 2 ; /* If we use frame pointer we preserve previous framepointer on entry * to each function */ #ifdef USEFRAME if (useframe) where+=2; #endif while ( prevarg ) { lgh = 2 ; /* Default length */ /* This is strange, previously double check for ->type */ if ( prevarg->type == LONG && prevarg->ident != POINTER ) lgh=4; if ( prevarg->type == DOUBLE && prevarg->ident != POINTER ) lgh=6; /* Far pointers */ if ( (prevarg->flags&FARPTR)==FARPTR && prevarg->ident == POINTER) lgh=4; prevarg->size=lgh; #ifdef CODSWALLOP /* All pointers are pushed onto the stack for functions as 4 bytes, if * needed, near pointers are padded out to compensate for this by dummy * loading with zero, this allows us to have one set of routines to * cope with this and hence solve a lot of duplication */ if (prevarg->ident == POINTER && lpointer) lgh=4; prevarg->size=lgh; #endif /* * Check the definition against prototypes here... */ if (argnumber) { tester=CalcArgValue(prevarg->type,prevarg->ident,prevarg->flags); if (currfn->args[argnumber] != tester ) { if (currfn->args[argnumber] != PELLIPSES ) { if (currfn->args[argnumber] == 0 ) { warning(W_2MADECL); } else { if ( (currfn->args[argnumber]&PMASKSIGN) == (tester&PMASKSIGN) ) { warning(W_SIGNARG); } else { error(E_ARGMIS1,currfn->name,currfn->prototyped-argnumber+1, ExpandArgValue(tester,buffer2,prevarg->tag_idx) ); error(E_ARGMIS2,ExpandArgValue(currfn->args[argnumber],buffer2, currfn->tagarg[argnumber])); } } } } argnumber++; } iptr = &prevarg->offset.i ; prevarg = prevarg->offset.p ; /* follow ptr to prev. arg */ *iptr = where ; /* insert offset */ where += lgh ; /* calculate next offset */ } #ifdef USEFRAME pushframe(); #endif currfn->handled=YES; if (currfn->prototyped==1 && (currfn->flags®CALL) ) { /* * Fast call routine.. */ if (lgh==2) zpush(); else if (lgh==4) lpush(); else if (lgh==6) dpush(); /* erk, if not matched, dodgy type! */ copyarg->offset.i=-lgh; where=2; } stackargs=where; lstdecl=0; /* Set number of local statics to zero */ if ( statement() != STRETURN ) { if (lstdecl) postlabel(lstlab); lstdecl=0; /* do a statement, but if it's a return, skip */ /* cleaning up the stack */ leave(NO,NO) ; } CleanGoto(); /* Asz80 needs a label at the end to sort out local symbols */ if (asxx) { nl();prefix(); outstr("smce_"); outname(currfn->name,NO); col();nl(); } #ifdef INBUILT_OPTIMIZER generate(); #endif infunc = 0 ; /* not in fn. any more */ }
int handle_process(metric_type_t metric, task_option_t *options, char *id) { int keepalive = 0; uint16_t pid; char *pidfile, *runcmd; task_report_t report; init_task_report(&report, id, PROCESS, metric); // Pull out options. // FIXME: Need to go over this again to make sure all necessary validation of parameters // is performed. for (int i = 0; i < NOTGIOS_MAX_OPTIONS; i++) { task_option_t *option = &options[i]; switch (option->type) { case KEEPALIVE: keepalive = strcmp(option->value, "TRUE") ? 0 : 1; break; case PIDFILE: pidfile = option->value; break; case RUNCMD: runcmd = option->value; break; case EMPTY: // User chose not to specify an option. This is fine, move on. break; default: // We've been passed a task containing invalid options. Shouldn't happen, but handle // it for debugging. sprintf(report.message, "FATAL CAUSE INVALID_TASK"); lpush(&reports, &report); return NOTGIOS_GENERIC_ERROR; } } write_log(LOG_DEBUG, "Task %s: Finished parsing arguments for process task...\n", id); // Figure out process running/not running situation. if (keepalive) { FILE *file = fopen(pidfile, "w+"); if (!file) { // We cannot write to the given pidfile path. Most likely the directory just // doesn't exist, but I'm defining this as an unrecoverable error, so send a message // to the frontend and remove the task. write_log(LOG_ERR, "Task %s: Pidfile inaccessible for keepalive process...\n", id); sprintf(report.message, "FATAL CAUSE NO_PIDFILE"); lpush(&reports, &report); return NOTGIOS_TASK_FATAL; } write_log(LOG_DEBUG, "Task %s: Successfully opened pidfile for keepalive process...\n", id); uint16_t *tmp_pid = hash_get(&children, id); if (tmp_pid) { write_log(LOG_DEBUG, "Task %s: Keepalive Process is already running...\n", id); pid = *tmp_pid; fprintf(file, "%hu", pid); } else { pid = fork(); if (pid) { write_log(LOG_DEBUG, "Task %s: Forked...\n", id); uint16_t *pid_cpy = malloc(sizeof(uint16_t)); *pid_cpy = pid; // Put the new pid into the children hash, update the pidfile, and just make // sure we aren't doing all of this for nothing. int retval = hash_put(&children, id, pid_cpy); fprintf(file, "%hu", pid); if (retval == HASH_FROZEN) return NOTGIOS_IN_SHUTDOWN; } else { int elem = 0; char *args[NOTGIOS_MAX_ARGS]; memset(args, 0, sizeof(char *) * NOTGIOS_MAX_ARGS); // Just sleep for a tiny bit to make sure our pid got into the children table. // No validation has been done on the run command, so, odds are, it won't work // and exec will fail. If so, need to make sure our pid is in the children table // so that the SIGCHLD handler will know what to do with our exit status. sleep(0.1); // Get our base command and arguments. char *path = strtok(runcmd, "\t"), *arg; while ((arg = strtok(NULL, "\t")) && elem < NOTGIOS_MAX_ARGS) args[elem++] = arg; // Moment of truth! execv(path, args); exit(NOTGIOS_EXEC_FAILED); } } fclose(file); } else { uint16_t other_pid; FILE *file = fopen(pidfile, "r"); if (file) { // We can access the file. int retval = fscanf(file, "%hu", &other_pid); fclose(file); write_log(LOG_DEBUG, "Task %s: Got pid for watched process...\n", id); if (retval && retval != EOF) { // We read the pid successfully. retval = kill(other_pid, 0); if (!retval) { // The process is running! write_log(LOG_DEBUG, "Task %s: Watched process is still running...\n", id); pid = other_pid; } else { // The process is not currently running, enqueue a report saying this, then return. write_log(LOG_ERR, "Task %s: Kill revealed watched process is not running...\n", id); sprintf(report.message, "ERROR CAUSE PROC_NOT_RUNNING"); lpush(&reports, &report); return NOTGIOS_SUCCESS; } } else { // The process is not currently running, enqueue a report saying this, then return. write_log(LOG_ERR, "Task %s: Pidfile not formatted correctly for watched process...\n", id); sprintf(report.message, "ERROR CAUSE PROC_NOT_RUNNING"); lpush(&reports, &report); return NOTGIOS_SUCCESS; } } else { // We can't access the file. I'm defining this as an unrecoverable error, so // send a message to the frontend, and then remove the task. write_log(LOG_ERR, "Task %s: Pidfile not accessible for watched process...\n", id); sprintf(report.message, "FATAL CAUSE NO_PIDFILE"); lpush(&reports, &report); return NOTGIOS_TASK_FATAL; } } // Collect metrics. int retval; switch (metric) { case MEMORY: retval = process_memory_collect(pid, &report); if (retval == NOTGIOS_NOPROC && keepalive) { if (check_statm()) { // FIXME: This was written before the child handler was figured out. Could need to revisit this // after implementing the child handler. // Since we're keeping alive, this most likely means that the user gave us an invalid command. // Send an error message, and the frontend will eventually kill the task if necessary. write_log(LOG_ERR, "Task %s: Watched/Keepalive process is not running for collection...\n", id); sprintf(report.message, "ERROR CAUSE PROC_NOT_RUNNING"); } else { // We can't even read from /proc/self/statm, which should be guaranteed to work on any version of // linux that supports statm at all. Let the front end know that we're running on an unsupported // distro. RETURN_UNSUPPORTED_DISTRO(report, id); } } else { write_log(LOG_DEBUG, "Task %s: Memory info collected...\n", id); } break; case CPU: retval = process_cpu_collect(pid, &report); if (retval == NOTGIOS_NOPROC) { if (check_stat()) { write_log(LOG_ERR, "Task %s: Watched/Keepalive process is not running for collection...\n", id); sprintf(report.message, "ERROR CAUSE PROC_NOT_RUNNING"); } else { // We can't even read from /proc/self/stat, which means it either doesn't exist, or we don't // support the format it's using. Either way, we're done. RETURN_UNSUPPORTED_DISTRO(report, id); } } else if (retval == NOTGIOS_UNSUPP_DISTRO) { // Collection function encountered an error condition that suggests we're running on an // unsupported distro. RETURN_UNSUPPORTED_DISTRO(report, id); } else { write_log(LOG_DEBUG, "Task %s: CPU Time collected...\n", id); } break; case IO: // This is currently unimplemented. retval = process_io_collect(pid, &report); break; default: // We've been passed a task containing invalid options. Shouldn't happen, but handle it // for debugging. sprintf(report.message, "FATAL CAUSE INVALID_TASK"); lpush(&reports, &report); return NOTGIOS_GENERIC_ERROR; } if (retval == NOTGIOS_UNSUPP_TASK) { write_log(LOG_DEBUG, "Task %s: Received an unsupported task. Removing..."); sprintf(report.message, "FATAL CAUSE UNSUPPORTED_TASK"); lpush(&reports, &report); return NOTGIOS_TASK_FATAL; } // Enqueue metrics for sending. write_log(LOG_DEBUG, "Task %s: Enqueuing report and returning...\n", id); lpush(&reports, &report); return NOTGIOS_SUCCESS; }
int handle_directory(task_option_t *options, char *id) { char *path = NULL; task_report_t report; init_task_report(&report, id, DIRECTORY, MEMORY); // Pull out options for (int i = 0; i < NOTGIOS_MAX_OPTIONS; i++) { task_option_t *option = &options[i]; switch (option->type) { case PATH: path = option->value; break; case EMPTY: // There's only one option for directory tasks, so this will be the most common branch. break; default: // We've been passed a task containing invalid options. Shouldn't happen, but handle // it for debugging. sprintf(report.message, "FATAL CAUSE INVALID_TASK"); lpush(&reports, &report); return NOTGIOS_GENERIC_ERROR; } } write_log(LOG_DEBUG, "Task %s: Finished parsing arguments for directory task...\n", id); // Perform some error handling on the given path. if (!path) { // The server should take care of making sure this doesn't happen, but the directory option // wasn't sent. write_log(LOG_ERR, "Task %s: Recevied directory task with no path option...\n", id); sprintf(report.message, "FATAL CAUSE TASK_MISSING_OPTIONS"); lpush(&reports, &report); return NOTGIOS_TASK_FATAL; } else if (access(path, F_OK)) { // We can't access the directory for some reason. write_log(LOG_ERR, "Task %s: Cannot access directory...\n", id); if (errno == EACCES || errno == ENOENT) sprintf(report.message, "FATAL CAUSE DIR_NOT_ACCESSIBLE"); else if (errno == ELOOP) sprintf(report.message, "FATAL CAUSE DIR_INFINITE_LOOP"); else if (errno == ENAMETOOLONG) sprintf(report.message, "FATAL CAUSE DIR_NAME_TOO_LONG"); else sprintf(report.message, "FATAL CAUSE UNKNOWN"); lpush(&reports, &report); return NOTGIOS_TASK_FATAL; } // Recursively calculate the directory size. write_log(LOG_DEBUG, "Task %s: Calculating directory size...\n", id); long retval = directory_memory_collect(path); if (retval >= 0) { report.value = (double) retval; report.time_taken = time(NULL); } else if (retval == NOTGIOS_BAD_ACCESS) { write_log(LOG_ERR, "Task %s: Access was refused for a subdirectory...\n", id); sprintf(report.message, "FATAL CAUSE SUBDIR_NOT_ACCESSIBLE"); lpush(&reports, &report); return NOTGIOS_TASK_FATAL; } else if (retval == NOTGIOS_NO_FILES) { write_log(LOG_ERR, "Task %s: Failed to open a file due to too many files being open...\n", id); sprintf(report.message, "ERROR CAUSE TOO_MANY_FILES"); } // Enqueue metrics for sending. write_log(LOG_DEBUG, "Task %s: Enqueuing report and returning...\n", id); lpush(&reports, &report); return NOTGIOS_SUCCESS; }