< :the previous in number
^ :the list in numerical order
> :the next in number
P :the previous (in thread)
N :the next (in thread)
|<:the top of this thread
>|:the next thread
^ :the parent (reply-to)
_:the child (an article replying to this)
>:the elder article having the same parent
<:the youger article having the same parent
---:split window and show thread lists
| :split window (vertically) and show thread lists
~ :close the thread frame
.:the index
..:the index of indices
Hi,
At Wed, 18 May 2005 16:20:13 +0900,
Jonathan Paisley wrote in [ruby-talk:143017]:
> > No, it duplicates the argument strings and remains them in the
> > original argv (i.e., pointed from *_NSGetArgv()), but let the
> > entire string area to be pointed by newly allocated argv, which
> > is returned to the caller.
>
> The effect your describe is right, but my point is that set_arg0 (defined
> in ruby.c) needs to operate on the original argv in order to be able to
> change the process name as reported by 'ps'. If set_arg0 sees strdup()-ed
> strings, its changes will have no effect.
Caller's argv is changed but *argv isn't changed. Pointers pointed by
original argv are changed. The pointers are not important.
+-----+-----+-----+-----+-----+
,-- | 0 | 1 | 2 | 3 | 4 | <----- original argv
| +--|--+--|--+--|--+--|--+--|--+
| | | | | |
| V V V V V
,-|- "./argv" "a" "b" "c" NULL <----- original strings
| |
~~|~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| |
| | "./argv" "a" "b" "c" NULL <----- duplicated strings
| | A A A A A
| | | | | | |
| | +--|--+--|--+--|--+--|--+--|--+
| `-> | 0 | 1 | 2 | 3 | 4 | <----- original argv kept
| +-----+-----+-----+-----+-----+ in the runtime internal
|
`--> "./argv" "a" "b" "c" NULL <----- original strings
A A A A A in the system area
| | | | |
+--|--+--|--+--|--+--|--+--|--+
| 0 | 1 | 2 | 3 | 4 | <----- duplicated argv returned
+-----+-----+-----+-----+-----+ to the caller.
$ cat argv.c
#include "ruby.h"
#undef xmalloc
#define xmalloc malloc
void
ruby_sysinit(argc, argv)
int *argc;
char ***argv;
{
int i, n = *argc, len = 0;
char **v1 = *argv, **v2 = ALLOC_N(char*, n + 1);
MEMCPY(v2, v1, char*, n);
v2[n] = 0;
for (i = 0; i < n; ++i) {
v1[i] = strdup(v1[i]);
}
*argv = v2;
}
void
dump_argv(name, argc, argv)
char *name;
int argc;
char **argv;
{
int i;
printf("%s: argc=%d argv=%p\n", name, argc, argv);
for (i = 0; i < argc; ++i) {
char *arg = argv[i];
printf("argv[%d] = %p \"%s\"\n", i, arg, arg);
}
}
int main(argc, argv)
int argc;
char **argv;
{
int origargc = argc;
char **origargv = argv;
dump_argv("before", argc, argv);
ruby_sysinit(&argc, &argv);
dump_argv("after", argc, argv);
dump_argv("original", origargc, origargv);
return 0;
}
$ make argv.o && gcc -o argv argv.o
$ ./argv a b c
before: argc=4 argv=0x61813d80
argv[0] = 0x61813dc8 "./argv"
argv[1] = 0x61813df0 "a"
argv[2] = 0x61813e08 "b"
argv[3] = 0x61813e20 "c"
after: argc=4 argv=0xa050008
argv[0] = 0x61813dc8 "./argv"
argv[1] = 0x61813df0 "a"
argv[2] = 0x61813e08 "b"
argv[3] = 0x61813e20 "c"
original: argc=4 argv=0x61813d80
argv[0] = 0xa0505c0 "./argv"
argv[1] = 0xa0505d0 "a"
argv[2] = 0xa0505e0 "b"
argv[3] = 0xa0505f0 "c"
--
Nobu Nakada