aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/erl_bif_port.c
diff options
context:
space:
mode:
authorDan Gudmundsson <[email protected]>2013-03-25 12:44:20 +0100
committerDan Gudmundsson <[email protected]>2013-06-03 12:46:47 +0200
commit75763bd57338b3efe8300ece094aacc8e1a7a467 (patch)
tree9ef4f74a15157183c67d5545085e453982ff46d4 /erts/emulator/beam/erl_bif_port.c
parentc97ac1a34971ce60bd36519e7ea51db2456217df (diff)
downloadotp-75763bd57338b3efe8300ece094aacc8e1a7a467.tar.gz
otp-75763bd57338b3efe8300ece094aacc8e1a7a467.tar.bz2
otp-75763bd57338b3efe8300ece094aacc8e1a7a467.zip
erts: Change erlang:open_port spawn to handle unicode
Previously only 'spawn_executable' handled unicode input. Also change 'cd' option to always handle unicode. Update open_port documentation and tests
Diffstat (limited to 'erts/emulator/beam/erl_bif_port.c')
-rw-r--r--erts/emulator/beam/erl_bif_port.c69
1 files changed, 17 insertions, 52 deletions
diff --git a/erts/emulator/beam/erl_bif_port.c b/erts/emulator/beam/erl_bif_port.c
index 109c54fd7f..5b26e53c9f 100644
--- a/erts/emulator/beam/erl_bif_port.c
+++ b/erts/emulator/beam/erl_bif_port.c
@@ -784,43 +784,29 @@ open_port(Process* p, Eterm name, Eterm settings, int *err_typep, int *err_nump)
goto badarg;
}
- if (*tp == am_spawn || *tp == am_spawn_driver) { /* A process port */
+ if (*tp == am_spawn || *tp == am_spawn_driver || *tp == am_spawn_executable) { /* A process port */
+ int encoding;
if (arity != make_arityval(2)) {
goto badarg;
}
name = tp[1];
- if (is_atom(name)) {
- name_buf = (char *) erts_alloc(ERTS_ALC_T_TMP,
- atom_tab(atom_val(name))->len+1);
- sys_memcpy((void *) name_buf,
- (void *) atom_tab(atom_val(name))->name,
- atom_tab(atom_val(name))->len);
- name_buf[atom_tab(atom_val(name))->len] = '\0';
- } else if ((i = is_string(name))) {
- name_buf = (char *) erts_alloc(ERTS_ALC_T_TMP, i + 1);
- if (intlist_to_buf(name, name_buf, i) != i)
- erl_exit(1, "%s:%d: Internal error\n", __FILE__, __LINE__);
- name_buf[i] = '\0';
- } else {
+ encoding = erts_get_native_filename_encoding();
+ /* Do not convert the command to utf-16le yet, do that in win32 specific code */
+ /* since the cmd is used for comparsion with drivers names and copied to port info */
+ if (encoding == ERL_FILENAME_WIN_WCHAR) {
+ encoding = ERL_FILENAME_UTF8;
+ }
+ if ((name_buf = erts_convert_filename_to_encoding(name, NULL, 0, ERTS_ALC_T_TMP,0,1, encoding, NULL))
+ == NULL) {
goto badarg;
}
+
if (*tp == am_spawn_driver) {
opts.spawn_type = ERTS_SPAWN_DRIVER;
+ } else if (*tp == am_spawn_executable) {
+ opts.spawn_type = ERTS_SPAWN_EXECUTABLE;
}
- driver = &spawn_driver;
- } else if (*tp == am_spawn_executable) { /* A program */
- /*
- * {spawn_executable,Progname}
- */
-
- if (arity != make_arityval(2)) {
- goto badarg;
- }
- name = tp[1];
- if ((name_buf = erts_convert_filename_to_native(name, NULL, 0, ERTS_ALC_T_TMP,0,1, NULL)) == NULL) {
- goto badarg;
- }
- opts.spawn_type = ERTS_SPAWN_EXECUTABLE;
+
driver = &spawn_driver;
} else if (*tp == am_fd) { /* An fd port */
int n;
@@ -861,29 +847,8 @@ open_port(Process* p, Eterm name, Eterm settings, int *err_typep, int *err_nump)
}
if (edir != NIL) {
- /* A working directory is expressed differently if spawn_executable, i.e. Unicode is handles
- for spawn_executable... */
- if (opts.spawn_type != ERTS_SPAWN_EXECUTABLE) {
- Eterm iolist;
- DeclareTmpHeap(heap,4,p);
- int r;
-
- UseTmpHeap(4,p);
- heap[0] = edir;
- heap[1] = make_list(heap+2);
- heap[2] = make_small(0);
- heap[3] = NIL;
- iolist = make_list(heap);
- r = erts_iolist_to_buf(iolist, (char*) dir, MAXPATHLEN);
- UnUseTmpHeap(4,p);
- if (ERTS_IOLIST_TO_BUF_FAILED(r)) {
- goto badarg;
- }
- opts.wd = (char *) dir;
- } else {
- if ((opts.wd = erts_convert_filename_to_native(edir, NULL, 0, ERTS_ALC_T_TMP,0,1,NULL)) == NULL) {
- goto badarg;
- }
+ if ((opts.wd = erts_convert_filename_to_native(edir, NULL, 0, ERTS_ALC_T_TMP,0,1,NULL)) == NULL) {
+ goto badarg;
}
}
@@ -961,11 +926,11 @@ static char **convert_args(Eterm l)
int n;
int i = 0;
Eterm str;
- /* We require at least one element in list (argv[0]) */
if (is_not_list(l) && is_not_nil(l)) {
return NULL;
}
n = list_length(l);
+ /* We require at least one element in argv[0] + NULL at end */
pp = erts_alloc(ERTS_ALC_T_TMP, (n + 2) * sizeof(char **));
pp[i++] = erts_default_arg0;
while (is_list(l)) {