tid_t exec(void) { char *args = next_str(); tid_t tid = process_execute(args); if(tid != TID_ERROR){ struct list_elem *e; struct exit_struct *exit = NULL; // TODO this is used at least 3 times for(e = list_begin(&thread_current()->children); e != list_end(&thread_current()->children); e = list_next(e)) { if(tid == list_entry(e, struct exit_struct, elem)->tid){ exit = list_entry(e, struct exit_struct, elem); break; } } sema_down(&exit->running); if(!exit->loaded) { /*list_remove(&exit->elem); free(exit); tid = -1;*/ /* This will always return -1 */ tid = process_wait(tid); } } return tid; }
fs_node_t* fs_path(fs_node_t* node, char* name){ //Copy the name for when we modify it if(strcmp(name, "/") == 0) return node; char* cpy = (char*) kmalloc(strlen(name) + 2); strmov(cpy, name); cpy[strlen(name) + 1] = 1; //Any non-zero character works, solely for next_str name = cpy; char* end = &name[strlen(name)]; //Format for parsing (zero-style parsing) int i, len = strlen(name); for(i = 0; i < len; i++) if(name[i] == '/') name[i] = 0; if(strlen(name) == 0) name = next_str(name); //Iterate down the pathname do{ node = node->holds; while(node != NULL){ if(strcmp(node->name, name) == 0) break; node = node->link; } if(node == NULL){ return NULL; } name = next_str(name); }while((uint) name < (uint) end); kfree(cpy); return node; }
string countAndSay(int n){ string s = "1"; while(--n) s = next_str(s); //n is one-based return s; }
fs_node_t* parse_dir(char* dir){ fs_node_t* node = mk_empty_dnode(); fs_node_t* parent = node; char* fat_buff = (char*) fat_load_full(dir); char* str = prep_str(fat_buff); ASSERT(strcmp(str, "DEEPFAT") == 0); str = next_str(str); ASSERT(strcmp(str, "DEEPDIR") == 0); str = next_str(str); while(strcmp(str, "ENDDIR") != 0){ char* ent = str; str = next_str(ent); fs_node_t* sub; /* vga_puts("\t* creating '"); vga_puts(str); vga_puts("'\n"); */ if(strcmp(ent, "DIR") == 0){ char* name = str; str = next_str(str); sub = parse_dir(fat_name_conv(str)); strmov(sub->name, name); strmov(sub->dos_name, str); fat_dir_t* file = fat_dir_search(fat_name_conv(str)); sub->inode = file->cluster_low; sub->length = file->bytes; sub->flags = FS_DIRECTORY; //Callbacks for basic VFS manipulation sub->open = df_open; sub->close = df_close; sub->readdir = readdir_generic; sub->finddir = df_finddir; } else if(strcmp(ent, "FIL") == 0){ char* name = str; str = next_str(str); sub = mk_empty_fnode(); strmov(sub->dos_name, str); fat_dir_t* file = fat_dir_search(fat_name_conv(str)); strmov(sub->name, name); sub->inode = file->cluster_low; sub->length = file->bytes; } else{ PANIC("bad deepFAT directory entry"); } str = ent; str = next_str(str); str = next_str(str); str = next_str(str); if(parent->holds == NULL){ parent->holds = sub; node = sub; } else{ node->link = sub; node = sub; } } kfree(fat_buff); return parent; }
/* Handles syscalls. Gets the syscall arguments off the stack (including the syscall number) then (either directly or with the aid of helper functions) executes the system call and places any return value into the eax register. Arguments should be parsed as soon as possible and the offset_lock should be held for the least possible amount of time. */ static void syscall_handler (struct intr_frame *f) { int sys_call; uint32_t ret_val = -1; void *arg0, *arg1, *arg2; struct fd_elem **fdt = thread_current()->open_files; /* Acquire lock before manipulating offset */ lock_acquire(&offset_lock); offset = f->esp; sys_call = (int) next_arg(); switch (sys_call) { case SYS_HALT: lock_release(&offset_lock); power_off(); NOT_REACHED (); case SYS_EXIT: arg0 = next_arg();/* exit status */ lock_release(&offset_lock); thread_current()->exit_controler->value = (int) arg0; thread_exit(); NOT_REACHED (); case SYS_EXEC: arg0 = next_str(); /* executable name */ lock_release(&offset_lock); ret_val = syscall_exec((const char *) arg0); break; case SYS_WAIT: arg0 = next_arg(); /* tid */ lock_release(&offset_lock); ret_val = process_wait((tid_t) arg0); break; case SYS_CREATE: arg0 = next_str(); /* File name */ arg1 = next_arg(); /* Size */ lock_release(&offset_lock); lock_acquire(&fs_lock); ret_val = filesys_create((const char *) arg0, (unsigned) arg1); lock_release(&fs_lock); break; case SYS_REMOVE: arg0 = next_str();/* file name */ lock_release(&offset_lock); lock_acquire(&fs_lock); ret_val = filesys_remove((const char *) arg0); lock_release(&fs_lock); break; case SYS_OPEN: arg0 = next_str(); /* file name */ lock_release(&offset_lock); ret_val = syscall_open((const char *) arg0); break; case SYS_FILESIZE: arg0 = next_arg(); /* fd */ lock_release(&offset_lock); lock_acquire(&fs_lock); ret_val = file_length(fdt[(int) arg0]->file); lock_release(&fs_lock); break; case SYS_READ: arg0 = next_arg(); /* fd */ arg1 = next_arg(); /* buffer */ arg2 = next_arg(); /* size */ lock_release(&offset_lock); ret_val = syscall_read((int) arg0, arg1, (unsigned) arg2); break; case SYS_WRITE: arg0 = next_arg(); /* fd */ arg1 = next_arg(); /* buffer */ arg2 = next_arg(); /* size */ lock_release(&offset_lock); ret_val = syscall_write((int) arg0, arg1, (unsigned) arg2); break; case SYS_SEEK: arg0 = next_arg(); /* fd */ arg1 = next_arg(); /* position */ lock_release(&offset_lock); lock_acquire(&fs_lock); file_seek(thread_current()->open_files[(int) arg0]->file, (unsigned) arg1); lock_release(&fs_lock); break; case SYS_TELL: arg0 = next_arg(); /* fd */ lock_release(&offset_lock); lock_acquire(&fs_lock); ret_val = file_tell(fdt[(int) arg0]->file); lock_release(&fs_lock); break; case SYS_CLOSE: arg0 = next_arg(); /* fd */ lock_release(&offset_lock); syscall_close((int) arg0); break; default: /* Invalid system call number. */ lock_release(&offset_lock); ret_val = -1; break; } /* Put return value into eax register and return to normal execution. */ f->eax = ret_val; }
static void syscall_handler (struct intr_frame *f) { /* printf ("system call!\n");//TODO remove thread_exit ();*/ uint32_t ret_val; offset = f->esp; int sys_call = (int) next_arg(); char *tmp; //TODO remove switch (sys_call) { case SYS_HALT: power_off(); NOT_REACHED (); case SYS_EXIT: syscall_exit((int) next_arg()); NOT_REACHED (); case SYS_EXEC: ret_val = exec(); break; case SYS_WAIT: ret_val = process_wait((tid_t) next_arg()); break; case SYS_CREATE: // printf("test\n"); // printf("file_name: %s, size: %d\n", next_str(), next_arg()); tmp = next_str(); ret_val = filesys_create(tmp, next_arg()); break; case SYS_REMOVE: ret_val = filesys_remove(next_str()); break; case SYS_OPEN: next_str(); break; case SYS_FILESIZE: next_arg(); break; case SYS_READ: /* next_arg(); next_arg(); next_arg(); */ ret_val = syscall_read(); break; case SYS_WRITE: //FIXME this is just a temporary function to print to console unil real call is implemented /*if ((int) next_arg() == STDOUT_FILENO) { printf("%s", (char *) next_arg()); }*/ ret_val = syscall_write(); break; case SYS_SEEK: break; case SYS_TELL: break; case SYS_CLOSE: break; default: //TODO print error message break; } f->eax = ret_val; }
static char *get_token_desc(struct wps_token *token, char *buf, int bufsize, struct wps_data *data) { unsigned i; #ifndef HAVE_LCD_BITMAP (void)data; /* kill charcell warning */ #endif bool next = token->next; switch(token->type) { case WPS_NO_TOKEN: snprintf(buf, bufsize, "No token"); break; case WPS_TOKEN_UNKNOWN: snprintf(buf, bufsize, "Unknown token"); break; case WPS_TOKEN_CHARACTER: if (token->value.c == '\n') snprintf(buf, bufsize, "Character '\\n'"); else snprintf(buf, bufsize, "Character '%c'", token->value.c); break; case WPS_TOKEN_STRING: snprintf(buf, bufsize, "String '%s'", (char*)token->value.data); break; case WPS_TOKEN_TRANSLATEDSTRING: snprintf(buf, bufsize, "String ID '%d'", token->value.i); break; #ifdef HAVE_LCD_BITMAP case WPS_TOKEN_ALIGN_LEFT: snprintf(buf, bufsize, "align left"); break; case WPS_TOKEN_ALIGN_CENTER: snprintf(buf, bufsize, "align center"); break; case WPS_TOKEN_ALIGN_RIGHT: snprintf(buf, bufsize, "align right"); break; #endif case WPS_TOKEN_SUBLINE_TIMEOUT: snprintf(buf, bufsize, "subline timeout value: %d", token->value.i); break; case WPS_TOKEN_CONDITIONAL: snprintf(buf, bufsize, "conditional, %d options", token->value.i); break; case WPS_TOKEN_CONDITIONAL_START: snprintf(buf, bufsize, "conditional start, next cond: %d", token->value.i); break; case WPS_TOKEN_CONDITIONAL_OPTION: snprintf(buf, bufsize, "conditional option, next cond: %d", token->value.i); break; case WPS_TOKEN_CONDITIONAL_END: snprintf(buf, bufsize, "conditional end"); break; #ifdef HAVE_LCD_BITMAP case WPS_TOKEN_IMAGE_PRELOAD: snprintf(buf, bufsize, "preload image"); break; case WPS_TOKEN_IMAGE_PRELOAD_DISPLAY: { char subimage = '\0'; char label = token->value.i&0xFF; struct gui_img *img = find_image(label, data); if (img && img->num_subimages > 1) subimage = 'a' + (token->value.i>>8); snprintf(buf, bufsize, "display preloaded image '%c%c'", label, subimage); } break; case WPS_TOKEN_IMAGE_DISPLAY: snprintf(buf, bufsize, "display image"); break; #endif #ifdef HAS_BUTTON_HOLD case WPS_TOKEN_MAIN_HOLD: snprintf(buf, bufsize, "mode hold"); break; #endif #ifdef HAS_REMOTE_BUTTON_HOLD case WPS_TOKEN_REMOTE_HOLD: snprintf(buf, bufsize, "mode remote hold"); break; #endif case WPS_TOKEN_REPEAT_MODE: snprintf(buf, bufsize, "mode repeat"); break; case WPS_TOKEN_PLAYBACK_STATUS: snprintf(buf, bufsize, "mode playback"); break; case WPS_TOKEN_RTC_PRESENT: snprintf(buf, bufsize, "rtc: present?"); break; case WPS_TOKEN_RTC_DAY_OF_MONTH: snprintf(buf, bufsize, "rtc: day of month (01..31)"); break; case WPS_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED: snprintf(buf, bufsize, "rtc: day of month, blank padded ( 1..31)"); break; case WPS_TOKEN_RTC_HOUR_24_ZERO_PADDED: snprintf(buf, bufsize, "rtc: hour (00..23)"); break; case WPS_TOKEN_RTC_HOUR_24: snprintf(buf, bufsize, "rtc: hour ( 0..23)"); break; case WPS_TOKEN_RTC_HOUR_12_ZERO_PADDED: snprintf(buf, bufsize, "rtc: hour (01..12)"); break; case WPS_TOKEN_RTC_HOUR_12: snprintf(buf, bufsize, "rtc: hour ( 1..12)"); break; case WPS_TOKEN_RTC_MONTH: snprintf(buf, bufsize, "rtc: month (01..12)"); break; case WPS_TOKEN_RTC_MINUTE: snprintf(buf, bufsize, "rtc: minute (00..59)"); break; case WPS_TOKEN_RTC_SECOND: snprintf(buf, bufsize, "rtc: second (00..59)"); break; case WPS_TOKEN_RTC_YEAR_2_DIGITS: snprintf(buf, bufsize, "rtc: last two digits of year (00..99)"); break; case WPS_TOKEN_RTC_YEAR_4_DIGITS: snprintf(buf, bufsize, "rtc: year (1970...)"); break; case WPS_TOKEN_RTC_AM_PM_UPPER: snprintf(buf, bufsize, "rtc: upper case AM or PM indicator"); break; case WPS_TOKEN_RTC_AM_PM_LOWER: snprintf(buf, bufsize, "rtc: lower case am or pm indicator"); break; case WPS_TOKEN_RTC_WEEKDAY_NAME: snprintf(buf, bufsize, "rtc: abbreviated weekday name (Sun..Sat)"); break; case WPS_TOKEN_RTC_MONTH_NAME: snprintf(buf, bufsize, "rtc: abbreviated month name (Jan..Dec)"); break; case WPS_TOKEN_RTC_DAY_OF_WEEK_START_MON: snprintf(buf, bufsize, "rtc: day of week (1..7); 1 is Monday"); break; case WPS_TOKEN_RTC_DAY_OF_WEEK_START_SUN: snprintf(buf, bufsize, "rtc: day of week (0..6); 0 is Sunday"); break; #if (CONFIG_CODEC == SWCODEC) case WPS_TOKEN_CROSSFADE: snprintf(buf, bufsize, "crossfade"); break; case WPS_TOKEN_REPLAYGAIN: snprintf(buf, bufsize, "replaygain"); break; #endif #ifdef HAVE_ALBUMART case WPS_TOKEN_ALBUMART_DISPLAY: snprintf(buf, bufsize, "album art display"); break; case WPS_TOKEN_ALBUMART_FOUND: snprintf(buf, bufsize, "%strack album art conditional", next_str(next)); break; #endif #ifdef HAVE_LCD_BITMAP case WPS_TOKEN_IMAGE_BACKDROP: snprintf(buf, bufsize, "backdrop image"); break; case WPS_TOKEN_IMAGE_PROGRESS_BAR: snprintf(buf, bufsize, "progressbar bitmap"); break; case WPS_TOKEN_PEAKMETER: snprintf(buf, bufsize, "peakmeter"); break; #endif case WPS_TOKEN_PROGRESSBAR: snprintf(buf, bufsize, "progressbar"); break; #ifdef HAVE_LCD_CHARCELLS case WPS_TOKEN_PLAYER_PROGRESSBAR: snprintf(buf, bufsize, "full line progressbar"); break; #endif case WPS_TOKEN_TRACK_TIME_ELAPSED: snprintf(buf, bufsize, "time elapsed in track"); break; case WPS_TOKEN_TRACK_ELAPSED_PERCENT: snprintf(buf, bufsize, "played percentage of track"); break; case WPS_TOKEN_PLAYLIST_ENTRIES: snprintf(buf, bufsize, "number of entries in playlist"); break; case WPS_TOKEN_PLAYLIST_NAME: snprintf(buf, bufsize, "playlist name"); break; case WPS_TOKEN_PLAYLIST_POSITION: snprintf(buf, bufsize, "position in playlist"); break; case WPS_TOKEN_TRACK_TIME_REMAINING: snprintf(buf, bufsize, "time remaining in track"); break; case WPS_TOKEN_PLAYLIST_SHUFFLE: snprintf(buf, bufsize, "playlist shuffle mode"); break; case WPS_TOKEN_TRACK_LENGTH: snprintf(buf, bufsize, "track length"); break; case WPS_TOKEN_VOLUME: snprintf(buf, bufsize, "volume"); break; case WPS_TOKEN_METADATA_ARTIST: snprintf(buf, bufsize, "%strack artist", next_str(next)); break; case WPS_TOKEN_METADATA_COMPOSER: snprintf(buf, bufsize, "%strack composer", next_str(next)); break; case WPS_TOKEN_METADATA_ALBUM: snprintf(buf, bufsize, "%strack album", next_str(next)); break; case WPS_TOKEN_METADATA_GROUPING: snprintf(buf, bufsize, "%strack grouping", next_str(next)); break; case WPS_TOKEN_METADATA_GENRE: snprintf(buf, bufsize, "%strack genre", next_str(next)); break; case WPS_TOKEN_METADATA_DISC_NUMBER: snprintf(buf, bufsize, "%strack disc", next_str(next)); break; case WPS_TOKEN_METADATA_TRACK_NUMBER: snprintf(buf, bufsize, "%strack number", next_str(next)); break; case WPS_TOKEN_METADATA_TRACK_TITLE: snprintf(buf, bufsize, "%strack title", next_str(next)); break; case WPS_TOKEN_METADATA_VERSION: snprintf(buf, bufsize, "%strack ID3 version", next_str(next)); break; case WPS_TOKEN_METADATA_ALBUM_ARTIST: snprintf(buf, bufsize, "%strack album artist", next_str(next)); break; case WPS_TOKEN_METADATA_COMMENT: snprintf(buf, bufsize, "%strack comment", next_str(next)); break; case WPS_TOKEN_METADATA_YEAR: snprintf(buf, bufsize, "%strack year", next_str(next)); break; #ifdef HAVE_TAGCACHE case WPS_TOKEN_DATABASE_PLAYCOUNT: snprintf(buf, bufsize, "track playcount (database)"); break; case WPS_TOKEN_DATABASE_RATING: snprintf(buf, bufsize, "track rating (database)"); break; case WPS_TOKEN_DATABASE_AUTOSCORE: snprintf(buf, bufsize, "track autoscore (database)"); break; #endif case WPS_TOKEN_BATTERY_PERCENT: snprintf(buf, bufsize, "battery percentage"); break; case WPS_TOKEN_BATTERY_VOLTS: snprintf(buf, bufsize, "battery voltage"); break; case WPS_TOKEN_BATTERY_TIME: snprintf(buf, bufsize, "battery time left"); break; case WPS_TOKEN_BATTERY_CHARGER_CONNECTED: snprintf(buf, bufsize, "battery charger connected"); break; case WPS_TOKEN_BATTERY_CHARGING: snprintf(buf, bufsize, "battery charging"); break; case WPS_TOKEN_BATTERY_SLEEPTIME: snprintf(buf, bufsize, "sleep timer"); break; case WPS_TOKEN_FILE_BITRATE: snprintf(buf, bufsize, "%sfile bitrate", next_str(next)); break; case WPS_TOKEN_FILE_CODEC: snprintf(buf, bufsize, "%sfile codec", next_str(next)); break; case WPS_TOKEN_FILE_FREQUENCY: snprintf(buf, bufsize, "%sfile audio frequency in Hz", next_str(next)); break; case WPS_TOKEN_FILE_FREQUENCY_KHZ: snprintf(buf, bufsize, "%sfile audio frequency in KHz", next_str(next)); break; case WPS_TOKEN_FILE_NAME: snprintf(buf, bufsize, "%sfile name", next_str(next)); break; case WPS_TOKEN_FILE_NAME_WITH_EXTENSION: snprintf(buf, bufsize, "%sfile name with extension", next_str(next)); break; case WPS_TOKEN_FILE_PATH: snprintf(buf, bufsize, "%sfile path", next_str(next)); break; case WPS_TOKEN_FILE_SIZE: snprintf(buf, bufsize, "%sfile size", next_str(next)); break; case WPS_TOKEN_FILE_VBR: snprintf(buf, bufsize, "%sfile is vbr", next_str(next)); break; case WPS_TOKEN_FILE_DIRECTORY: snprintf(buf, bufsize, "%sfile directory, level: %d", next_str(next), token->value.i); break; #if (CONFIG_CODEC != MAS3507D) case WPS_TOKEN_SOUND_PITCH: snprintf(buf, bufsize, "pitch value"); break; #endif #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD) case WPS_TOKEN_VLED_HDD: snprintf(buf, bufsize, "display virtual HDD LED"); break; #endif case WPS_VIEWPORT_ENABLE: snprintf(buf, bufsize, "enable VP: %c", (char)token->value.i); break; case WPS_TOKEN_BUTTON_VOLUME: snprintf(buf, bufsize, "Volume button timeout: %d", token->value.i); break; case WPS_TOKEN_SETTING: snprintf(buf, bufsize, "Setting value: '%s'", settings[token->value.i].cfg_name); break; case WPS_TOKEN_LANG_IS_RTL: snprintf(buf, bufsize, "lang: is_rtl?"); break; default: for(i=1; i<sizeof(tokens)/sizeof(*token); i++) { if (token->type < tokens[i].start_marker) { snprintf(buf, bufsize, "FIXME: %s + %d\n", tokens[i-1].desc, token->type - tokens[i-1].start_marker); break; } } break; } return buf; }