function [in, out, pid] = popen2 (command, args) in = -1; out = -1; pid = -1; if (nargin == 1 || nargin == 2) if (nargin == 1) args = ""; endif if (ischar (command)) [stdin_pipe, stdin_status] = pipe (); [stdout_pipe, stdout_status] = pipe (); if (stdin_status == 0 && stdout_status == 0) pid = fork (); if (pid == 0) ## In the child. fclose (nth (stdin_pipe, 2)); fclose (nth (stdout_pipe, 1)); dup2 (nth (stdin_pipe, 1), stdin); fclose (nth (stdin_pipe, 1)); dup2 (nth (stdout_pipe, 2), stdout); fclose (nth (stdout_pipe, 2)); if (exec (command, args) < 0) error ("popen2: unable to start process `%s'", command); exit (0); endif elseif (pid) ## In the parent. fclose (nth (stdin_pipe, 1)); fclose (nth (stdout_pipe, 2)); %if (fcntl (nth (stdout_pipe, 1), F_SETFL, O_NONBLOCK) < 0) % error ("popen2: error setting file mode"); %else in = nth (stdin_pipe, 2); out = nth (stdout_pipe, 1); %endif elseif (pid < 0) error ("popen2: fork failed -- unable to create child process"); endif else error ("popen2: pipe creation failed"); endif else error ("popen2: file name must be a string"); endif else usage ("[in, out, pid] = popen2 (command, args)"); endif endfunction
Se puede incluir dentro de los programas de Octave, pues Octave permite redefinir las funciones.
Para comunicarse con Octave se seguirán los siguientes pasos:[out,in,pid]=popen2("widgetserver"); if(pid<0) printf("Error widgetserver couldn't be executed\n"); exit(1); endLo que se ha hecho es abrir las comunicaciones con el Widgetserver. En el caso de que el programa widgetserver no se encuentre, se muestra un mensaje de error. En el caso de que no funcione correctamente, se puede usar la implementación de popen2 mostrada anteriormente.
fprintf(out, "<window:frame>\n"); fprintf(out, " <title:Sombrero/>\n"); fprintf(out, " <p>\n"); fprintf(out, " <label:l1>\n"); fprintf(out, " Number of grids\n"); fprintf(out, " </label>\n"); fprintf(out, " <lineedit:w0>\n"); fprintf(out, " <text: 20/>\n"); fprintf(out, " </lineedit>\n"); fprintf(out, " </p>\n"); fprintf(out, " <html:ht1>\n"); fprintf(out, " Draws sombrero function\n"); fprintf(out, " </html>\n"); fprintf(out, " <p>\n"); fprintf(out, " <button:ok>\n"); fprintf(out, " <listen: clicked/>\n"); fprintf(out, " <text>\n"); fprintf(out, " Ok\n"); fprintf(out, " </text>\n"); fprintf(out, " </button>\n"); fprintf(out, " <button:cancel>\n"); fprintf(out, " <listen: clicked/>\n"); fprintf(out, " <text>\n"); fprintf(out, " Cancel\n"); fprintf(out, " </text>\n"); fprintf(out, " </button>\n"); fprintf(out, " </p>\n"); fprintf(out, "</window>\n"); fflush(out);Se envía la ventana que se tiene que mostrar. El fflush(out) es importante para poder enviar los datos..Es mucho más cómodo escribir la ventana en un fichero y enviarla después leyendo el fichero.
%Event loop while( isstr ( line=fgets(in) ) ) % Se procesan los eventos para cerrar la ventana if( ( length(line)>=15 && strcmp(substr(line,1,16),'*clicked: cancel') ) || ( length(line)>=13 && strcmp(substr(line,1,13),'*close: frame') ) ) fprintf(out, "<quit/>\n"); fflush(out); break; end; % Se debe haber hecho click sobre el botón de Ok. % Se lee la línea de texto. fprintf(out, "<lineedit:w0>\n"); fprintf(out, " <getText/>\n"); fprintf(out, "</lineedit>\n"); fflush(out); line=fgets(in); w0=fgets(in); %Se dibuja el sombrero sombrero(eval(w0)); endEste era el bucle de eventos, se van leyendo, línea a línea los datos que envía el Widgetserver y se procesan.
fclose(in); fclose(out); % Fin del programaEn el fichero ej_sombrero.m se puede encontrar el ejemplo anterior.