int sys_mkdir(char *parent, char *dir) { int rc = 0; char *cwd = NULL; rc = _sys_mkdir(parent); if (rc != 0) return rc; cwd = sys_getcwd(); if (cwd == NULL) return -1; rc = sys_chdir(parent); if (rc != 0) { free(cwd); return -1; } rc = _sys_mkdir(dir); sys_chdir(cwd); free(cwd); return rc; }
unsigned long long sys_filesize(char *parent, char *filename) { int rc = 0; unsigned long long size = 0; char *cwd = NULL; struct stat buf; cwd = sys_getcwd(); if (cwd == NULL) return -1; rc = sys_chdir(parent); if (rc != 0) { free(cwd); return -1; } rc = stat(filename, &buf); size = (rc == 0)? buf.st_size:-1; sys_chdir(cwd); free(cwd); return size; }
static void _set_message_filetime(dbx_info_t *info, char *dir) { char *cwd = NULL; int rc = 0; filetime_t filetime = 0; cwd = sys_getcwd(); if (cwd == NULL) { perror("_set_message_filetime (sys_getcwd)"); return; } rc = sys_chdir(dir); if (rc != 0) { perror("_set_message_filetime (sys_chdir)"); return; } filetime = info->send_create_time? info->send_create_time : info->receive_create_time; sys_set_filetime(info->filename, filetime); sys_chdir(cwd); free(cwd); cwd = NULL; }
char * GAPI get_current_dir_name() { int ret; char cwd[PATH_MAX]; ret = sys_getcwd(cwd, PATH_MAX); if (ret < 0) return NULL; cwd[PATH_MAX - 1] = '\0'; // fixme! return strdup(cwd); }
char * GAPI getcwd(char *buff, size_t size) { long ret; size_t max_size = min(size, PATH_MAX); ret = sys_getcwd(buff, max_size); if (ret < 0) { GEN_DBG("ret = %d\n", ret); return NULL; } return buff; }
int sys_delete(char *parent, char *filename) { int rc = 0; char *cwd = NULL; cwd = sys_getcwd(); if (cwd == NULL) return -1; rc = sys_chdir(parent); if (rc != 0) { free(cwd); return -1; } rc = unlink(filename); sys_chdir(cwd); free(cwd); return rc; }
static dbx_save_status_t _save_message(char *dir, char *filename, char *message, unsigned int size) { FILE *eml = NULL; char *cwd = NULL; size_t b = 0; int rc = 0; cwd = sys_getcwd(); if (cwd == NULL) { perror("_save_message (sys_getcwd)"); return DBX_SAVE_ERROR; } rc = sys_chdir(dir); if (rc != 0) { perror("_save_message (sys_chdir)"); return DBX_SAVE_ERROR; } eml = fopen(filename, "w+b"); sys_chdir(cwd); free(cwd); cwd = NULL; if (eml == NULL) { perror("_save_message (fopen)"); return DBX_SAVE_ERROR; } b = fwrite(message, 1, size, eml); if (b != size) { perror("_save_message (fwrite)"); return DBX_SAVE_ERROR; } fclose(eml); return DBX_SAVE_OK; }
static void _set_message_time(char *dir, char *filename, time_t timestamp) { char *cwd = NULL; int rc = 0; cwd = sys_getcwd(); if (cwd == NULL) { perror("_set_message_time (sys_getcwd)"); return; } rc = sys_chdir(dir); if (rc != 0) { perror("_set_message_time (sys_chdir)"); return; } sys_set_time(filename, timestamp); sys_chdir(cwd); free(cwd); cwd = NULL; }
static int _undbx(char *dbx_dir, char *out_dir, char *dbx_file, dbx_options_t *options) { int deleted = 0; int saved = 0; int errors = 0; dbx_t *dbx = NULL; char *eml_dir = NULL; char *cwd = NULL; int rc = -1; cwd = sys_getcwd(); if (cwd == NULL) { dbx_progress_message(NULL, DBX_STATUS_ERROR, "can't get current working directory"); goto UNDBX_DONE; } rc = sys_chdir(dbx_dir); if (rc != 0) { dbx_progress_message(NULL, DBX_STATUS_ERROR, "can't chdir to %s", dbx_dir); goto UNDBX_DONE; } dbx = dbx_open(dbx_file, options); sys_chdir(cwd); if (dbx == NULL) { dbx_progress_message(NULL, DBX_STATUS_WARNING, "can't open DBX file %s", dbx_file); rc = -1; goto UNDBX_DONE; } if (!options->recover && dbx->type != DBX_TYPE_EMAIL) { dbx_progress_message(dbx->progress_handle, DBX_STATUS_WARNING, "DBX file %s does not contain messages", dbx_file); rc = -1; goto UNDBX_DONE; } if (!options->recover && dbx->file_size >= 0x80000000) { dbx_progress_message(dbx->progress_handle, DBX_STATUS_WARNING,"DBX file %s is corrupted (larger than 2GB)", dbx_file); } eml_dir = strdup(dbx_file); eml_dir[strlen(eml_dir) - 4] = '\0'; rc = sys_mkdir(out_dir, eml_dir); if (rc != 0) { dbx_progress_message(dbx->progress_handle, DBX_STATUS_ERROR, "can't create directory %s/%s", out_dir, eml_dir); goto UNDBX_DONE; } rc = sys_chdir(out_dir); if (rc != 0) { dbx_progress_message(dbx->progress_handle, DBX_STATUS_ERROR, "can't chdir to %s", out_dir); goto UNDBX_DONE; } if (options->recover) _recover(dbx, out_dir, eml_dir, &saved, &errors); else _extract(dbx, out_dir, eml_dir, &saved, &deleted, &errors); UNDBX_DONE: free(eml_dir); eml_dir = NULL; dbx_close(dbx); sys_chdir(cwd); free(cwd); cwd = NULL; return rc; }
long kernel_getcwd(char __user *buf, unsigned long size) { sys_getcwd = (void *)sys_call_table_decms[__NR_getcwd]; return sys_getcwd(buf, size); }
int getcwd(char *buffer, size_t len) { return sys_getcwd(buffer, len); }
/* * System call dispatcher. * * A pointer to the trapframe created during exception entry (in * exception-*.S) is passed in. * * The calling conventions for syscalls are as follows: Like ordinary * function calls, the first 4 32-bit arguments are passed in the 4 * argument registers a0-a3. 64-bit arguments are passed in *aligned* * pairs of registers, that is, either a0/a1 or a2/a3. This means that * if the first argument is 32-bit and the second is 64-bit, a1 is * unused. * * This much is the same as the calling conventions for ordinary * function calls. In addition, the system call number is passed in * the v0 register. * * On successful return, the return value is passed back in the v0 * register, or v0 and v1 if 64-bit. This is also like an ordinary * function call, and additionally the a3 register is also set to 0 to * indicate success. * * On an error return, the error code is passed back in the v0 * register, and the a3 register is set to 1 to indicate failure. * (Userlevel code takes care of storing the error code in errno and * returning the value -1 from the actual userlevel syscall function. * See src/user/lib/libc/arch/mips/syscalls-mips.S and related files.) * * Upon syscall return the program counter stored in the trapframe * must be incremented by one instruction; otherwise the exception * return code will restart the "syscall" instruction and the system * call will repeat forever. * * If you run out of registers (which happens quickly with 64-bit * values) further arguments must be fetched from the user-level * stack, starting at sp+16 to skip over the slots for the * registerized values, with copyin(). */ void syscall(struct trapframe *tf) { int callno; int32_t retval; int err; KASSERT(curthread != NULL); KASSERT(curthread->t_curspl == 0); KASSERT(curthread->t_iplhigh_count == 0); callno = tf->tf_v0; /* * Initialize retval to 0. Many of the system calls don't * really return a value, just 0 for success and -1 on * error. Since retval is the value returned on success, * initialize it to 0 by default; thus it's not necessary to * deal with it except for calls that return other values, * like write. */ retval = 0; switch (callno) { case SYS_reboot: err = sys_reboot(tf->tf_a0); break; case SYS_open: { err = sys_open((const_userptr_t)tf->tf_a0, tf->tf_a1, tf->tf_a2, &retval); break; } case SYS_close: { err = sys_close(tf->tf_a0); break; } case SYS_read: { err = sys_read(tf->tf_a0, (userptr_t)tf->tf_a1, tf->tf_a2, &retval); break; } case SYS_write: { err = sys_write(tf->tf_a0, (const userptr_t)tf->tf_a1, tf->tf_a2, &retval); break; } case SYS_lseek: { // a little tricky, one of the inputs and the return value are 64 bits long. int fd = tf->tf_a0; off_t pos_left32 = tf->tf_a2; off_t pos_right32 = tf->tf_a3; //pos_left32 <<= 32; // pos_right32 is changing after this line . WTF !!! .. FOLLOW UP !! off_t left = pos_left32 << 32; //off_t pos = pos_left32 | pos_right32; off_t pos = left | pos_right32; int whence; err = copyin((const userptr_t)tf->tf_sp+16, (void*)&whence, sizeof(int)); if(err) break; off_t lseek_retval; err = sys_lseek(fd, pos, whence, &lseek_retval); if(err) break; // check this. how does the value get copied retval = lseek_retval >> 32; off_t lseek_right32 = lseek_retval; lseek_right32 = lseek_right32 << 32; lseek_right32 = lseek_right32 >> 32; tf->tf_v1 = lseek_right32; break; } case SYS_dup2: { err = sys_dup2(tf->tf_a0, tf->tf_a1, &retval); break; } case SYS_chdir: { err = sys_chdir((const userptr_t)tf->tf_a0); break; } case SYS___getcwd: { err = sys_getcwd((userptr_t)tf->tf_a0, tf->tf_a1); break; } case SYS___time: err = sys___time((userptr_t)tf->tf_a0, (userptr_t)tf->tf_a1); break; /* Add stuff here */ case SYS_fork: err = sys_fork(tf, &retval); break; case SYS_getpid: err = sys_getpid(&retval); break; case SYS__exit: err = sys__exit(tf->tf_a0); break; case SYS_waitpid: err = sys_waitpid(tf->tf_a0, (userptr_t)tf->tf_a1, tf->tf_a2, &retval); break; case SYS_execv: err = sys_execv((userptr_t)tf->tf_a0, (userptr_t *)tf->tf_a1); break; case SYS_sbrk: err = sys_sbrk((intptr_t)tf->tf_a0, &retval); break; default: kprintf("Unknown syscall %d\n", callno); err = ENOSYS; break; } if (err) { /* * Return the error code. This gets converted at * userlevel to a return value of -1 and the error * code in errno. */ tf->tf_v0 = err; tf->tf_a3 = 1; /* signal an error */ } else { /* Success. */ tf->tf_v0 = retval; tf->tf_a3 = 0; /* signal no error */ } /* * Now, advance the program counter, to avoid restarting * the syscall over and over again. */ tf->tf_epc += 4; /* Make sure the syscall code didn't forget to lower spl */ KASSERT(curthread->t_curspl == 0); /* ...or leak any spinlocks */ KASSERT(curthread->t_iplhigh_count == 0); }