static duk_ret_t pwd_getpwnam(duk_context* ctx) { const char* name; long initsize; char* buf; size_t bufsize; struct passwd pw; struct passwd* rpw; int r; name = duk_require_string(ctx, 0); initsize = sysconf(_SC_GETPW_R_SIZE_MAX); if (initsize <= 0) { bufsize = 4096; } else { bufsize = (size_t) initsize; } buf = NULL; for (;;) { free(buf); buf = malloc(bufsize); if (buf == NULL) { SJS_THROW_ERRNO_ERROR2(ENOMEM); return -42; /* control never returns here */ } r = getpwnam_r(name, &pw, buf, bufsize, &rpw); if (r != ERANGE) { break; } bufsize *= 2; } if (r != 0) { SJS_THROW_ERRNO_ERROR2(r); return -42; /* control never returns here */ } if (rpw == NULL) { free(buf); duk_push_null(ctx); return 1; } else { passwd2obj(ctx, &pw); return 1; } }
/* * Read data from a fd. Args: * - 0: fd * - 1: nread * TODO: * - use buffers */ static duk_ret_t io_read(duk_context* ctx) { int fd; ssize_t r; size_t nread; char* buf; fd = duk_require_int(ctx, 0); nread = duk_require_int(ctx, 1); buf = malloc(nread); if (!buf) { SJS_THROW_ERRNO_ERROR2(ENOMEM); return -42; /* control never returns here */ } r = read(fd, buf, nread); if (r < 0) { SJS_THROW_ERRNO_ERROR(); return -42; /* control never returns here */ } else if (r == 0) { /* EOF */ duk_push_string(ctx, ""); } else { duk_push_lstring(ctx, buf, r); } return 1; }
/* * Read a line from a file. Args: * - 0: FILE * - 1: nread (a number or a Buffer-ish object) */ static duk_ret_t io_fgets(duk_context* ctx) { FILE* f; size_t nread; char* r; char* buf; char* alloc_buf = NULL; f = duk_require_pointer(ctx, 0); if (duk_is_number(ctx, 1)) { nread = duk_require_int(ctx, 1); alloc_buf = malloc(nread); if (!alloc_buf) { SJS_THROW_ERRNO_ERROR2(ENOMEM); return -42; /* control never returns here */ } buf = alloc_buf; } else { buf = duk_require_buffer_data(ctx, 1, &nread); if (buf == NULL || nread == 0) { duk_error(ctx, DUK_ERR_TYPE_ERROR, "invalid buffer"); return -42; /* control never returns here */ } } r = fgets(buf, nread, f); if (r == NULL) { duk_push_string(ctx, ""); } else { if (alloc_buf) { /* return the string we read */ duk_push_string(ctx, r); } else { /* the data was written to the buffer, return how much we read */ duk_push_int(ctx, strlen(r)); } } free(alloc_buf); return 1; }
/* * Write data to a file. Args: * - 0: FILE * - 1: data */ static duk_ret_t io_fwrite(duk_context* ctx) { FILE* f; size_t len, r; const char* buf; f = duk_require_pointer(ctx, 0); if (duk_is_string(ctx, 1)) { buf = duk_require_lstring(ctx, 1, &len); } else { buf = duk_require_buffer_data(ctx, 1, &len); } r = fwrite(buf, 1, len, f); if (ferror(f) || feof(f)) { clearerr(f); SJS_THROW_ERRNO_ERROR2(EIO); return -42; /* control never returns here */ } else { duk_push_int(ctx, r); return 1; } }
/* * Read data from a file. Args: * - 0: FILE * - 1: nread (a number or a Buffer-ish object) */ static duk_ret_t io_fread(duk_context* ctx) { FILE* f; size_t nread, r; char* buf; int create_buf = 0; f = duk_require_pointer(ctx, 0); if (duk_is_number(ctx, 1)) { nread = duk_require_int(ctx, 1); buf = duk_push_dynamic_buffer(ctx, nread); create_buf = 1; } else { buf = duk_require_buffer_data(ctx, 1, &nread); if (buf == NULL || nread == 0) { duk_error(ctx, DUK_ERR_TYPE_ERROR, "invalid buffer"); return -42; /* control never returns here */ } } r = fread(buf, 1, nread, f); if (ferror(f)) { if (create_buf) { duk_pop(ctx); } clearerr(f); SJS_THROW_ERRNO_ERROR2(EIO); return -42; /* control never returns here */ } if (create_buf) { /* return the string we read */ duk_resize_buffer(ctx, -1, r); } else { /* the data was written to the buffer, return how much we read */ duk_push_int(ctx, r); } return 1; }