47
48
static int open_port(Process* p, Eterm name, Eterm settings, int *err_nump);
48
49
static byte* convert_environment(Process* p, Eterm env);
50
static char **convert_args(Eterm);
51
static void free_args(char **);
53
char *erts_default_arg0 = "default";
50
55
BIF_RETTYPE open_port_2(BIF_ALIST_2)
278
283
if (erts_system_profile_flags.runnable_ports && !erts_port_is_scheduled(p)) {
279
284
profile_runnable_port(p, am_active);
281
size = encode_size_struct(BIF_ARG_3, TERM_TO_BINARY_DFLAGS);
286
size = erts_encode_ext_size(BIF_ARG_3);
282
287
if (size > sizeof(port_input))
283
288
bytes = erts_alloc(ERTS_ALC_T_PORT_CALL_BUF, size);
286
if (erts_to_external_format(NULL, BIF_ARG_3, &endp, NULL, NULL) || !endp) {
287
erl_exit(1, "%s, line %d: bad term: %x\n",
288
__FILE__, __LINE__, BIF_ARG_3);
291
erts_encode_ext(BIF_ARG_3, &endp);
291
293
real_size = endp - bytes;
292
294
if (real_size > size) {
336
338
/* Error or a binary without magic/ with wrong magic */
339
result_size = erts_decoded_size(port_resp, ret, 0);
341
result_size = erts_decode_ext_size(port_resp, ret, 0);
340
342
if (result_size < 0) {
343
345
hp = HAlloc(BIF_P, result_size);
344
346
hp_end = hp + result_size;
345
347
endp = port_resp;
346
if ((res = erts_from_external_format(NULL, &hp, &endp, &MSO(BIF_P)))
348
res = erts_decode_ext(&hp, &MSO(BIF_P), &endp);
349
if (res == THE_NON_VALUE) {
350
352
HRelease(BIF_P, hp_end, hp);
627
632
opts.envir = (char *) bytes;
633
} else if (option == am_args) {
635
char **oav = opts.argv;
636
if ((av = convert_args(*tp)) == NULL) {
641
opts.argv[0] = oav[0];
642
oav[0] = erts_default_arg0;
646
} else if (option == am_arg0) {
651
} else if( (n = is_string(*tp)) == 0) {
654
a0 = (char *) erts_alloc(ERTS_ALC_T_TMP,
655
(n + 1) * sizeof(byte));
656
if (intlist_to_buf(*tp, a0, n) != n) {
657
erl_exit(1, "%s:%d: Internal error\n",
661
if (opts.argv == NULL) {
662
opts.argv = erts_alloc(ERTS_ALC_T_TMP,
663
2 * sizeof(char **));
667
if (opts.argv[0] != erts_default_arg0) {
668
erts_free(ERTS_ALC_T_TMP, opts.argv[0]);
628
672
} else if (option == am_cd) {
715
759
if (arity == make_arityval(0)) {
719
if (*tp == am_spawn) { /* A process port */
720
if (arity != make_arityval(2)) {
725
name_buf = (char *) erts_alloc(ERTS_ALC_T_TMP,
726
atom_tab(atom_val(name))->len+1);
727
sys_memcpy((void *) name_buf,
728
(void *) atom_tab(atom_val(name))->name,
729
atom_tab(atom_val(name))->len);
730
name_buf[atom_tab(atom_val(name))->len] = '\0';
731
} else if ((i = is_string(name))) {
732
name_buf = (char *) erts_alloc(ERTS_ALC_T_TMP, i + 1);
733
if (intlist_to_buf(name, name_buf, i) != i)
734
erl_exit(1, "%s:%d: Internal error\n", __FILE__, __LINE__);
763
if (*tp == am_spawn || *tp == am_spawn_driver) { /* A process port */
764
if (arity != make_arityval(2)) {
769
name_buf = (char *) erts_alloc(ERTS_ALC_T_TMP,
770
atom_tab(atom_val(name))->len+1);
771
sys_memcpy((void *) name_buf,
772
(void *) atom_tab(atom_val(name))->name,
773
atom_tab(atom_val(name))->len);
774
name_buf[atom_tab(atom_val(name))->len] = '\0';
775
} else if ((i = is_string(name))) {
776
name_buf = (char *) erts_alloc(ERTS_ALC_T_TMP, i + 1);
777
if (intlist_to_buf(name, name_buf, i) != i)
778
erl_exit(1, "%s:%d: Internal error\n", __FILE__, __LINE__);
783
if (*tp == am_spawn_driver) {
784
opts.spawn_type = ERTS_SPAWN_DRIVER;
786
driver = &spawn_driver;
787
} else if (*tp == am_spawn_executable) { /* A program */
789
* {spawn_executable,Progname}
792
if (arity != make_arityval(2)) {
797
name_buf = (char *) erts_alloc(ERTS_ALC_T_TMP,
798
atom_tab(atom_val(name))->len+1);
799
sys_memcpy((void *) name_buf,
800
(void *) atom_tab(atom_val(name))->name,
801
atom_tab(atom_val(name))->len);
802
name_buf[atom_tab(atom_val(name))->len] = '\0';
803
} else if ((i = is_string(name))) {
804
name_buf = (char *) erts_alloc(ERTS_ALC_T_TMP, i + 1);
805
if (intlist_to_buf(name, name_buf, i) != i)
806
erl_exit(1, "%s:%d: Internal error\n", __FILE__, __LINE__);
811
opts.spawn_type = ERTS_SPAWN_EXECUTABLE;
739
812
driver = &spawn_driver;
740
813
} else if (*tp == am_fd) { /* An fd port */
843
if ((driver != &spawn_driver && opts.argv != NULL) ||
844
(driver == &spawn_driver &&
845
opts.spawn_type != ERTS_SPAWN_EXECUTABLE &&
846
opts.argv != NULL)) {
847
/* Argument vector only if explicit spawn_executable */
770
852
if (driver != &spawn_driver && opts.exit_status) {
774
856
if (IS_TRACED_FL(p, F_TRACE_SCHED_PROCS)) {
775
857
trace_virtual_sched(p, am_out);
779
861
erts_smp_proc_unlock(p, ERTS_PROC_LOCK_MAIN);
820
905
#undef OPEN_PORT_ERROR
908
static char **convert_args(Eterm l)
915
/* We require at least one element in list (argv[0]) */
916
if (is_not_list(l) && is_not_nil(l)) {
920
pp = erts_alloc(ERTS_ALC_T_TMP, (n + 2) * sizeof(char **));
921
pp[i++] = erts_default_arg0;
923
str = CAR(list_val(l));
927
} else if( (n = is_string(str)) == 0) {
928
/* Not a string... */
930
for (j = 1; j < i; ++j)
931
erts_free(ERTS_ALC_T_TMP, pp[j]);
932
erts_free(ERTS_ALC_T_TMP, pp);
935
b = (char *) erts_alloc(ERTS_ALC_T_TMP, (n + 1) * sizeof(byte));
936
pp[i++] = (char *) b;
937
if (intlist_to_buf(str, b, n) != n)
938
erl_exit(1, "%s:%d: Internal error\n", __FILE__, __LINE__);
940
l = CDR(list_val(l));
946
static void free_args(char **av)
951
for (i = 0; av[i] != NULL; ++i) {
952
if (av[i] != erts_default_arg0) {
953
erts_free(ERTS_ALC_T_TMP, av[i]);
956
erts_free(ERTS_ALC_T_TMP, av);
823
960
static byte* convert_environment(Process* p, Eterm env)