Commit Graph

315 Commits

Author SHA1 Message Date
Yukihiro "Matz" Matsumoto e0393943f1 mruby-io: add error helper functions to eliminate goto
Add mode_error() and badfd_error() helper functions to replace
goto statements used for error handling. These functions are marked
with mrb_noreturn attribute since they call mrb_raise/mrb_sys_fail
which never return.

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-12 10:25:36 +09:00
Yukihiro "Matz" Matsumoto e636360250 mruby-io: combine variable declaration with initialization 2025-10-26 23:48:38 +09:00
Yukihiro "Matz" Matsumoto 01ab2ffc29 mruby-io: fix buffer overflow in io#ungetc; fix #6647
io_unget_data had two issues that caused crashes with repeated ungetc:

1. Integer underflow in buffer size check: "len > MRB_IO_BUF_SIZE - buf->len"
   could underflow when buf->len was large, bypassing reallocation

2. Short overflow: buf->len could exceed SHRT_MAX after multiple ungetc
   calls, causing integer overflow when cast to short

Fixed by checking buf->len + len against both MRB_IO_BUF_SIZE and
SHRT_MAX before buffer operations.

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-22 14:04:14 +09:00
Yukihiro "Matz" Matsumoto c21604eea6 mruby-io: validate negative length in io#gets; fix #6646
io_gets was passing negative limit values to io_buf_cat without
validation, causing negative-size-param in memcpy detected by ASAN.

Add validation to raise ArgumentError for negative limit values,
consistent with other io methods like io_read.

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-22 12:49:40 +09:00
Yukihiro "Matz" Matsumoto 6043490c0a mruby-io: hoist RARRAY_PTR calls in IO.select loops
Optimizes IO.select by hoisting RARRAY_PTR calls outside loops to avoid
repeated conditional checks in both setup and result processing phases.

Optimized loops:
- Setup phase: 3 loops for read/write/except arrays
- Result phase: 3 loops for read/write/except arrays

Each loop previously called RARRAY_PTR 1-2 times per iteration. With
hoisting, each array pointer is retrieved once per loop instead of once
per iteration, significantly reducing overhead in I/O multiplexing.

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-22 12:06:46 +09:00
Yukihiro "Matz" Matsumoto 2965113052 mruby-io: add helper for int64_t to mrb_value conversion
Fixes MSVC warnings on 32-bit builds when converting st_size (int64_t) to
mrb_int. The helper tries bigint if available, falls back to float, or
raises an error if neither is available.

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-22 12:06:45 +09:00
Yukihiro "Matz" Matsumoto bbf46a4355 mruby-io: raise NotImplementedEerror for FileTest.pipe? on Windows
add Windows guard to FileTest.pipe? to raise NotImplementedError,
consistent with symlink? and socket?. Windows anonymous pipes created
by IO.pipe are not UNIX FIFOs and cannot be detected via stat mode
bits. the test suite expects this exception and handles it with skip.

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-20 08:18:38 +09:00
Yukihiro "Matz" Matsumoto ee5a6705ee mruby-io: fix cross-platform test compatibility for windows
make symlink operations raise notimplementederror on Windows since
symlinks require special privileges and differ significantly from posix.
similarly, filetest.socket? and filetest.symlink? now raise
notimplementederror on Windows since these file types don't exist in
the same way. the file.chmod test now restores write permissions before
deletion, which is required on Windows to delete read-only files.

all tests already have rescue notimplementederror clauses that skip
gracefully on unsupported platforms.

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-16 23:59:23 +09:00
Yukihiro "Matz" Matsumoto 3d1c4981e7 mruby-io: conditionally compile mrb_lstat for symlink support
only define mrb_lstat when symbolic link macros are available. on
windows/mingw, symlinks are not supported and the function is unused,
causing -Wunused-function warning.

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-16 16:56:42 +09:00
Yukihiro "Matz" Matsumoto f25fadf46c mruby-io: fix const qualifier warnings on msvc
remove const qualifier from variables passed to free functions.
msvc is stricter about const correctness than gcc. variables from
mrb_utf8_from_locale and mrb_locale_from_utf8 are dynamically allocated
and need to be freed, so they should not be const.

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-16 16:10:52 +09:00
Yukihiro "Matz" Matsumoto 610ff67906 HAL: rename functions to mrb_hal_<feature>_<name> convention
rename all HAL functions from mrb_<feature>_hal_<name>() to
mrb_hal_<feature>_<name>() for better grouping and clarity. this makes all
HAL functions immediately identifiable with the mrb_hal_* prefix.

affected gems:
- mruby-task: mrb_task_hal_* -> mrb_hal_task_*
- mruby-io: mrb_io_hal_* -> mrb_hal_io_*
- mruby-socket: mrb_socket_hal_* -> mrb_hal_socket_*
- mruby-dir: mrb_dir_hal_* -> mrb_hal_dir_*

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-16 09:59:03 +09:00
Yukihiro "Matz" Matsumoto 74a5c840f8 mruby-io: fix const qualifier warning in path_gethome
home variable should be const char* to match mrb_io_hal_gethome return type.

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-16 08:00:06 +09:00
Yukihiro "Matz" Matsumoto f81cadfed5 mrbgems: standardize HAL header include patterns
changed from angle brackets to quotes for gem-local HAL headers
(task.h, io_hal.h, socket_hal.h), and removed relative path prefix
from task.h include. this follows the mrbgem build system convention
where gem/include/ is automatically added to the include path.

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-15 18:52:28 +09:00
Yukihiro "Matz" Matsumoto f4dcc3dc3d mruby-io: refactor popen to use HAL functions
eliminates platform-specific popen implementations by using
mrb_io_hal_pipe and mrb_io_hal_spawn_process. removes io_cloexec_pipe,
io_pipe, and io_process_exec functions. io.pipe now also uses
mrb_io_hal_pipe. reduces platform conditionals and improves portability.

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-15 14:17:27 +09:00
Yukihiro "Matz" Matsumoto 74ca22f281 mruby-io: introduce HAL for platform abstraction
separates platform-specific code into hal-posix-io and hal-win-io gems,
making mruby-io platform-independent. HAL interface defined in
mrbgems/mruby-io/include/io_hal.h covers file operations, I/O operations,
and process operations. follows mruby-task dependency pattern where HAL
gems depend on feature gem. ws2_32 library linked in hal-win-io gem.

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-15 11:53:38 +09:00
dearblue 5838de682b Revert File.absolute_path logic
The error was introduced by commit 7b9d1da3fc.
2025-09-19 22:51:09 +09:00
HASUMI Hitoshi 4035e42a39 Fix uninitialized variable in io_gets causing segmentation fault
This patch fixs a critical segmentation fault in `io_gets` function caused by an uninitialized limit variable.

This bug may specifically heppen when:
- MicroRuby with task scheduler, which I'm implementing, enabled

## Root Cause Analysis

When `io_gets` is called without arguments (argc=0), the local variable `limit` remains uninitialized on the stack.
I guess that this uninitialized memory often contains leftover heap addresses from previous stack frames.

### The problematic flow:

1. `mrb_get_args(mrb, "|o?i?", &rs, &rs_given, &limit, &limit_given)` with 0 arguments
2. `limit_given = FALSE` but limit contains garbage heap address
3. Looks like later processing truncates this address, creating invalid pointer 0xffff0000
4. This value gets pushed onto VM stack during string operations
5. Garbage collector attempts to mark 0xffff0000 as valid object pointer
6. SIGSEGV in mrb_gc_mark() at gc.c:748

    ```
    Program received signal SIGSEGV, Segmentation fault.
    0x00005c8bebffa95c in mrb_gc_mark (mrb=0x5c8bec2836c8 <heap_pool+728>, obj=0xffff0000)
        at .../gc.c:748
    748       if (!is_white(obj)) return;
    #1  mark_context_stack (mrb=0x5c8bec2836c8 <heap_pool+728>, c=0x5c8bec2b4a50 <heap_pool+202336>)
        at .../gc.c:555
    555       mrb_gc_mark(mrb, mrb_basic_ptr(v));
    ```

## Solution

I couldn't figure out the exact mechanism of the issue. Anyway, initializing the limit variable to zero could prevent invalid garbage stack memory:

```c
mrb_int limit = 0;  // Explicit initialization
```

## Files Changed

- mrbgems/picoruby-mruby/lib/mruby/mrbgems/mruby-io/src/io.c
2025-08-22 17:37:59 +09:00
Yukihiro "Matz" Matsumoto fbb10cf73d mruby-io: fix incorrect pointer access in io.c
In the Windows-specific code path for IO.popen, the variable 'p'
is a struct, not a pointer. The code was using 'p->klass' to
access a member, which is incorrect and causes a build failure
on Windows. This has been corrected to use the 'klass' argument
directly.

Co-authored-by: Gemini <gemini@google.com>
2025-08-21 10:17:12 +09:00
Yukihiro "Matz" Matsumoto 7e6cdc0285 mruby-io: add filetest call-seq documentation to file test methods
Co-authored-by: Claude <noreply@anthropic.com>
2025-08-19 10:06:18 +09:00
Yukihiro "Matz" Matsumoto 9e8fe00114 mruby-io: migrate File.join to C
Implements File.join in C for better performance, replacing the Ruby
implementation with direct C string manipulation and array processing.
Uses mruby's built-in recursion detection (MRB_RECURSIVE_UNARY_P) for
cleaner and more reliable recursive array handling.

Co-authored-by: Claude <noreply@anthropic.com>
2025-08-19 10:06:18 +09:00
Yukihiro "Matz" Matsumoto 6ee3f00849 mruby-io: migrate File.path to C
Implements File.path in C for better performance, replacing the Ruby
implementation that used kind_of? check with direct C type validation.

Co-authored-by: Claude <noreply@anthropic.com>
2025-08-19 10:06:17 +09:00
Yukihiro "Matz" Matsumoto 786f0aa015 mruby-io: migrate File.extname to C
Implement C version of File.extname for better performance:
- Direct C string processing instead of Ruby basename + rindex
- Efficient path parsing with single pass through string
- Proper handling of edge cases (dotfiles, trailing slashes, etc.)
- Maintains full compatibility with Ruby implementation

Performance improvement:
- Eliminates Ruby method call overhead for basename/rindex
- Direct C string operations vs Ruby string methods
- Faster path processing for file extension extraction

Co-authored-by: Claude <noreply@anthropic.com>
2025-08-19 10:06:17 +09:00
Yukihiro "Matz" Matsumoto 0a8a7bb329 mruby-io: implement ungetbyte in c for improved performance
Moved IO#ungetbyte from Ruby to C implementation to eliminate
boundary crossing overhead and avoid temporary string allocations.
Added io_unget_data helper function to handle raw data operations
efficiently.

Co-authored-by: Claude <noreply@anthropic.com>
2025-08-16 14:39:14 +09:00
Yukihiro "Matz" Matsumoto 89e07d90e2 mruby-io: implement << operator in c for improved performance
Moved IO#<< from Ruby to C implementation to reduce boundary
crossing overhead. Maintains full compatibility with automatic
to_s conversion and proper return value for method chaining.

Co-authored-by: Claude <noreply@anthropic.com>
2025-08-16 13:03:56 +09:00
Yukihiro "Matz" Matsumoto 85ca24622a mruby-io: implement print in c for improved performance
Moved IO#print from Ruby to C implementation to reduce boundary
crossing overhead. Maintains full compatibility with automatic
to_s conversion for all arguments.

Co-authored-by: Claude <noreply@anthropic.com>
2025-08-16 12:43:35 +09:00
Yukihiro "Matz" Matsumoto dd9053d0cf mruby-io: implement puts in c for improved performance
Moved IO#puts from Ruby to C implementation to reduce boundary
crossing overhead. Maintains full compatibility including array
recursion and newline handling.

Co-authored-by: Claude <noreply@anthropic.com>
2025-08-16 12:25:42 +09:00
Yukihiro "Matz" Matsumoto 857a1b3a0d mruby-io: refactor write buffer preparation logic
Extract buffer adjustment logic from io_write into reusable helper
function io_prepare_write. This prepares for implementing io_puts
in C while maintaining consistency in write operations.

Co-authored-by: Claude <noreply@anthropic.com>
2025-08-16 12:10:44 +09:00
Yukihiro "Matz" Matsumoto 01226c8fc9 mruby-io: refactor io_s_popen for readability
This commit refactors the `io_s_popen` function to improve readability
and maintainability. The function has been broken down into smaller,
more manageable functions, and the platform-specific code has been
separated.

Co-authored-by: Gemini <gemini@google.com>
2025-08-14 10:53:10 +09:00
Yukihiro "Matz" Matsumoto f8ee815468 mruby-io: fix bug in fd_write
The previous implementation of fd_write had a bug that caused it to
repeatedly write the entire string instead of the remaining portion.
This commit fixes the bug and improves the performance of writing
large strings.

Co-authored-by: Gemini <gemini@google.com>
2025-08-14 10:53:10 +09:00
Yukihiro "Matz" Matsumoto 07b803e28a docs: replace xml-style markup with markdown in comments
Replace XML-style markup tags in comments with markdown equivalents:
- <code>...</code> to `...` (inline code)
- <tt>...</tt> to `...` (teletype/monospace)
- <i>...</i> to *...* (italics/emphasis)
- +...+ to `...` (parameter/variable references)

Updated 80+ files across core source, headers, mrbgems, and libraries
to use consistent markdown formatting in documentation comments.
Handled edge cases including special characters like <=> operators.

Co-authored-by: Atlassian Rovo Dev
2025-08-14 10:52:49 +09:00
Yukihiro "Matz" Matsumoto 7b9d1da3fc mruby-io: add comprehensive call-seq documentation for all Ruby and C methods
Added complete call-seq documentation for the entire mruby-io gem across
both Ruby and C implementations:

## Ruby Methods (mrblib/) - 50 methods documented:

### Kernel Module (kernel.rb):
- Backtick operator: shell command execution with output capture
- open: unified file/subprocess opening with pipe support
- p: debug output with inspect formatting and multiple argument handling
- print/puts/printf: output methods with proper formatting and separators
- gets/readline/readlines: input methods with various line handling options

### File Constants (file_constants.rb):
- FNM_* constants: file name matching flags for glob and fnmatch operations
  with detailed explanations of case sensitivity, escaping, and pattern behavior

### IO Class (io.rb):
Class methods:
- IO.open: creates IO objects with automatic resource management
- IO.popen: subprocess communication with pipe handling
- IO.pipe: creates connected pipe endpoints for IPC
- IO.read: convenience method for reading entire files

Instance methods:
- Stream positioning: pos=, rewind, tell with proper seeking behavior
- Iteration: each, each_byte, each_char with enumerator support
- Output: puts, print, printf with formatting and newline handling
- Utility: hash, <<, ungetbyte with proper stream manipulation
- Global streams: STDIN/STDOUT/STDERR and $stdin/$stdout/$stderr

### File Class (file.rb):
Instance methods:
- Constructor: handles both file paths and file descriptors
- Timestamps: atime, ctime, mtime with proper Time object conversion
- Inspection: inspect method for debugging file objects

Class methods:
- Path utilities: join with cross-platform separator handling
- File iteration: foreach with block and enumerator support
- FileTest delegation: complete set of file type and existence checks
  (directory?, exist?, file?, pipe?, size, socket?, symlink?, zero?)
- Path manipulation: extname for extension extraction, path for conversion

## C Methods (src/) - 25 methods documented:

### Core IO Operations (io.c):
- File descriptor management: fileno with proper error handling
- Stream state: closed?, eof?, sync/sync= for buffering control
- Process management: pid for pipe process tracking
- Resource management: close_on_exec?/close_on_exec= for FD_CLOEXEC handling

### Reading Operations:
- Character reading: getc, readchar with EOF handling differences
- Byte reading: getbyte, readbyte with integer conversion
- Buffer reading: read with length and output buffer support
- Stream manipulation: ungetc for character pushback

### System Operations:
- IO multiplexing: IO.select for monitoring multiple streams
- Constructor: IO.new for creating IO objects from file descriptors
- Stream flushing: flush for forcing output to OS

Co-authored-by: Atlassian Rovo Dev
2025-08-14 10:52:48 +09:00
Yukihiro "Matz" Matsumoto b7e3b2be72 fix io file time accessor typo 2025-07-18 15:00:44 +09:00
Yukihiro "Matz" Matsumoto ae39a9e56f mruby-io (mrb_file_basename): add type cast to fix mixed signedness 2025-06-25 17:47:48 +09:00
John Bampton 383cd6a936 misc: fix spelling word case 2025-06-25 10:46:23 +10:00
Yukihiro Matz Matsumoto dcd661efb8 File.basename: add support for suffix removal and enhance tests 2025-06-23 22:49:43 +00:00
Yukihiro "Matz" Matsumoto 35fafe57fb mruby-io: make IO#initialize_copy private 2025-06-16 12:42:22 +09:00
Yukihiro "Matz" Matsumoto 29964b3ba7 mruby-io (mrb_file_size): add check for MRB_32BIT and MRB_INT64 2025-04-14 22:09:33 +09:00
John Bampton b1d910f6f4 mrbgems: fix spelling 2025-04-04 15:05:13 +10:00
Yukihiro "Matz" Matsumoto b8351d6191 mruby-io/file.c: use ptrdiff_t for pointer difference 2025-03-24 22:30:53 +09:00
Yukihiro "Matz" Matsumoto 4aae7be949 mruby-io (path_gethome): move local variable declarations 2025-03-24 14:03:13 +09:00
Yukihiro "Matz" Matsumoto a33426da15 mruby-io (mrb_file_s_chmod): check string type before casting 2025-03-23 20:04:25 +09:00
Yukihiro "Matz" Matsumoto 11f6251d23 mruby-io (mrb_file_basename): fixed a silly mistake 2025-03-22 13:01:38 +09:00
Yukihiro "Matz" Matsumoto aa06aff50d mruby-io/file.c: use mrb_sys_fail instead of mrb_raise (w/ errno info) 2025-03-22 11:02:05 +09:00
Yukihiro "Matz" Matsumoto f3b79fcc23 mruby-io (mrb_file_s_readlink): increase buffer size linearly 2025-03-21 19:34:05 +09:00
Yukihiro "Matz" Matsumoto ca693dec30 mruby-io (mrb_file_s_readlink): when rc == bufsize, rc never be -1 2025-03-21 19:31:12 +09:00
Yukihiro "Matz" Matsumoto 9e315af2a5 mruby-io (mrb_file_basename): fixed wrong strncmp usage 2025-03-21 10:37:05 +09:00
Yukihiro "Matz" Matsumoto 90d4805f5b mruby-io (mrb_file_realpath): use mrb_str_cat instead of mrb_str_append 2025-03-20 22:04:49 +09:00
Yukihiro "Matz" Matsumoto 5bc391e170 mruby-io (mrb_file_basename): use mrb_str_cat() instead of snprintf(3) 2025-03-20 22:03:30 +09:00
Yukihiro "Matz" Matsumoto dbafada7be mruby-io (mrb_file_basename): use "z" specifier for mrb_get_args() 2025-03-20 13:39:38 +09:00
Yukihiro "Matz" Matsumoto 96113a2ed9 mruby-io: define File.absolute_path method; ref #6482 2025-03-08 11:12:12 +09:00