STATIC mp_obj_t socket_makefile(size_t n_args, const mp_obj_t *args) { // TODO: CPython explicitly says that closing returned object doesn't close // the original socket (Python2 at all says that fd is dup()ed). But we // save on the bloat. mp_obj_socket_t *self = MP_OBJ_TO_PTR(args[0]); mp_obj_t *new_args = alloca(n_args * sizeof(mp_obj_t)); memcpy(new_args + 1, args + 1, (n_args - 1) * sizeof(mp_obj_t)); new_args[0] = MP_OBJ_NEW_SMALL_INT(self->fd); return mp_builtin_open(n_args, new_args, (mp_map_t*)&mp_const_empty_map); }
STATIC void handle_op(mp_obj_webrepl_t *self) { // Handle operations not requiring opened file switch (self->hdr.type) { case GET_VER: { static char ver[] = {MICROPY_VERSION_MAJOR, MICROPY_VERSION_MINOR, MICROPY_VERSION_MICRO}; write_webrepl(self->sock, ver, sizeof(ver)); self->hdr_to_recv = sizeof(struct webrepl_file); return; } } // Handle operations requiring opened file mp_obj_t open_args[2] = { mp_obj_new_str(self->hdr.fname, strlen(self->hdr.fname)), MP_OBJ_NEW_QSTR(MP_QSTR_rb) }; if (self->hdr.type == PUT_FILE) { open_args[1] = MP_OBJ_NEW_QSTR(MP_QSTR_wb); } self->cur_file = mp_builtin_open(2, open_args, (mp_map_t*)&mp_const_empty_map); #if 0 struct mp_stream_seek_t seek = { .offset = self->hdr.offset, .whence = 0 }; int err; mp_uint_t res = file_stream->ioctl(self->cur_file, MP_STREAM_SEEK, (uintptr_t)&seek, &err); assert(res != MP_STREAM_ERROR); #endif write_webrepl_resp(self->sock, 0); if (self->hdr.type == PUT_FILE) { self->data_to_recv = self->hdr.size; check_file_op_finished(self); } else if (self->hdr.type == GET_FILE) { self->data_to_recv = 1; } } STATIC mp_uint_t _webrepl_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode); STATIC mp_uint_t webrepl_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode) { mp_uint_t out_sz; do { out_sz = _webrepl_read(self_in, buf, size, errcode); } while (out_sz == -2); return out_sz; }
STATIC void handle_op(mp_obj_webrepl_t *self) { mp_obj_t open_args[2] = { mp_obj_new_str(self->hdr.fname, strlen(self->hdr.fname), false), MP_OBJ_NEW_QSTR(MP_QSTR_rb) }; if (self->hdr.type == PUT_FILE) { open_args[1] = MP_OBJ_NEW_QSTR(MP_QSTR_wb); } self->cur_file = mp_builtin_open(2, open_args, (mp_map_t*)&mp_const_empty_map); const mp_stream_p_t *file_stream = mp_get_stream_raise(self->cur_file, MP_STREAM_OP_READ | MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL); #if 0 struct mp_stream_seek_t seek = { .offset = self->hdr.offset, .whence = 0 }; int err; mp_uint_t res = file_stream->ioctl(self->cur_file, MP_STREAM_SEEK, (uintptr_t)&seek, &err); assert(res != MP_STREAM_ERROR); #endif write_webrepl_resp(self->sock, 0); if (self->hdr.type == PUT_FILE) { self->data_to_recv = self->hdr.size; } else if (self->hdr.type == GET_FILE) { byte readbuf[2 + 256]; int err; // TODO: It's not ideal that we block connection while sending file // and don't process any input. while (1) { mp_uint_t out_sz = file_stream->read(self->cur_file, readbuf + 2, sizeof(readbuf) - 2, &err); assert(out_sz != MP_STREAM_ERROR); readbuf[0] = out_sz; readbuf[1] = out_sz >> 8; DEBUG_printf("webrepl: Sending %d bytes of file\n", out_sz); write_webrepl(self->sock, readbuf, 2 + out_sz); if (out_sz == 0) { break; } } write_webrepl_resp(self->sock, 0); self->hdr_to_recv = sizeof(struct webrepl_file); } }