//## FILE FILE.new(String path, String mode); static KMETHOD File_new(KonohaContext *kctx, KonohaStack *sfp) { KMakeTrace(trace, sfp); char buffer[K_PATHMAX]; kString *path = sfp[1].asString; const char *systemPath = I18NAPI formatSystemPath(kctx, buffer, sizeof(buffer), kString_text(path), kString_size(path), trace); const char *mode = kString_text(sfp[2].asString); FILE *fp = fopen(systemPath, mode); kFile *file = (kFile *) sfp[0].asObject; if(fp == NULL) { int fault = KLIB DiagnosisFaultType(kctx, kString_GuessUserFault(path)|SystemError, trace); KTraceErrorPoint(trace, fault, "fopen", LogText("filename", kString_text(path)), LogText("mode", mode), LogErrno); KLIB KRuntime_raise(kctx, KException_("IO"), fault, NULL, sfp); } if(mode[0] == 'w' || mode[0] == 'a' || mode[1] == '+') { KTraceChangeSystemPoint(trace, "fopen", LogFileName(kString_text(path)), LogText("mode", mode)); } file->fp = fp; KFieldInit(file, file->PathInfoNULL, path); if(!I18NAPI isSystemCharsetUTF8(kctx)) { if(mode[0] == 'w' || mode[0] == 'a' || mode[1] == '+') { file->writerIconv = I18NAPI iconvUTF8ToSystemCharset(kctx, trace); } else { file->readerIconv = I18NAPI iconvSystemCharsetToUTF8(kctx, trace); } } KReturn(file); }
static kFile* new_File(KonohaContext *kctx, kArray *gcstack, FILE *fp, const char *pathInfo, size_t len, KTraceInfo *trace) { kFile *file = new_(File, fp, gcstack); file->fp = fp; KFieldInit(file, file->PathInfoNULL, KLIB new_kString(kctx, OnField, pathInfo, len, StringPolicy_ASCII|StringPolicy_TEXT)); kFile_Set(ChangeLessStream, file, true); if(!I18NAPI isSystemCharsetUTF8(kctx)) { if(fp == stdin) { file->readerIconv = I18NAPI iconvSystemCharsetToUTF8(kctx, trace); } else { file->writerIconv = I18NAPI iconvUTF8ToSystemCharset(kctx, trace); } } return file; }
//## DIR System.opendir(String path) static KMETHOD System_opendir(KonohaContext *kctx, KonohaStack *sfp) { KMakeTrace(trace, sfp); char buffer[K_PATHMAX]; kString *path = sfp[1].asString; const char *systemPath = PLATAPI formatSystemPath(kctx, buffer, sizeof(buffer), S_text(path), S_size(path), trace); DIR *d = opendir(systemPath); if(d == NULL) { int fault = KLIB DiagnosisFaultType(kctx, kString_guessUserFault(path)|SystemError, trace); KTraceErrorPoint(trace, fault, "opendir", LogText("dirname", S_text(path)), LogErrno); KLIB KonohaRuntime_raise(kctx, EXPT_("IO"), fault, NULL, sfp); } kDir *dir = (kDir *)KLIB new_kObject(kctx, OnStack, KGetReturnType(sfp), (uintptr_t)d); KFieldSet(dir, dir->PathInfoNULL, path); if(!PLATAPI isSystemCharsetUTF8(kctx)) { dir->readerIconv = PLATAPI iconvSystemCharsetToUTF8(kctx, trace); } KReturn(dir); }
static const char *I18N_formatSystemPath(KonohaContext *kctx, char *buf, size_t bufsiz, const char *path, size_t pathsize, KTraceInfo *trace) { size_t newsize; if(!I18NAPI isSystemCharsetUTF8(kctx)) { uintptr_t ic = I18NAPI iconvSystemCharsetToUTF8(kctx, trace); int isTooBig; ICONV_INBUF_CONST char *presentPtrFrom = (ICONV_INBUF_CONST char *)path; // too dirty? ICONV_INBUF_CONST char **inbuf = &presentPtrFrom; char **outbuf = &buf; size_t inBytesLeft = pathsize, outBytesLeft = bufsiz - 1; I18NAPI iconv_i(kctx, ic, inbuf, &inBytesLeft, outbuf, &outBytesLeft, &isTooBig, trace); newsize = (bufsiz - 1) - outBytesLeft; } else { DBG_ASSERT(bufsiz > pathsize); memcpy(buf, path, pathsize); newsize = pathsize; } buf[newsize] = 0; return (const char *)buf; }