• Lunes 18 de Noviembre de 2024, 07:44

Autor Tema:  Rutinas En Visual C++  (Leído 4071 veces)

bcasadorodriguez

  • Nuevo Miembro
  • *
  • Mensajes: 12
    • Ver Perfil
Rutinas En Visual C++
« en: Miércoles 17 de Agosto de 2005, 18:55 »
0
Hola, necesito saber si las siguientes funciones que pongo a continuación y  que son de c++ para linux, equivalen a alguna otra en c++ para windows.
Las funciones son:

fork() --> creo que equivale a spawnl()
ioctl()
fstat()
kill() ---> para matar un proceso. no se si es igual que TerminateProcess()
wait() --> creo que equivale a cwait.
fcntl() ---> es para controlar algo de los descriptores de una pipe.

Gracias y espero que puedan ayudarme.

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Rutinas En Visual C++
« Respuesta #1 en: Miércoles 17 de Agosto de 2005, 19:54 »
0
Cita de: "bcasadorodriguez"
Hola, necesito saber si las siguientes funciones que pongo a continuación y  que son de c++ para linux, equivalen a alguna otra en c++ para windows.
Las funciones son:

fork() --> creo que equivale a spawnl()
ioctl()
fstat()
kill() ---> para matar un proceso. no se si es igual que TerminateProcess()
wait() --> creo que equivale a cwait.
fcntl() ---> es para controlar algo de los descriptores de una pipe.

Gracias y espero que puedan ayudarme.
Creo que no existe ninguna funcion que trabaje EXACTAMENTE de la misma forma que fork en Windows, la funcion para crear procesos es CreateProcess.

ioctl sino me equivoco seria equivalente a DeviceIoControl.

fstat la podes usar en VC++, sino podes usar GetFileInformationByHandle por ejemplo.

TerminateProcess mata un proceso efectivamente, necesitas un handle al mismo que podes conseguir con OpenProcess.

Si wait solo espera podes usar Sleep.

Para pipes no hay demasiadas funciones especificas:
http://msdn.microsoft.com/library/default....e_functions.asp

Ya nos contaras que queres hacer exactamente con pipes.

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

Diodo

  • Moderador
  • ******
  • Mensajes: 658
    • Ver Perfil
    • http://www.solocodigo.com
Re: Rutinas En Visual C++
« Respuesta #2 en: Miércoles 17 de Agosto de 2005, 20:49 »
0
Hola

Como bien dice Eternal Idol los servicios de posix relacionados con procesos padre-hijo , no tienen equivalencia en win32

por tanto

Código: Text
  1. fork() --------> No tiene servicio equivalente en win32
  2. ioctl()--------> Mire en un libro que tengo y solo viene para UNIX
  3. fstat--------> tiene 4 servicios equivalentes en win32 segun el uso que se le de:
  4.                     GetFileAttributes (obtiene los atributos de un archivo)
  5.                     GetFileSize (tamaño)
  6.                     GetFileTime (fecha)
  7.                     GetFileType (tipo)
  8. kill -----------> no tiene equivalente en win32
  9. wait ---------->WaitForSingleObject (espera la terminadcion deun proceso)
  10.                      GetExitCodeProcess (obtiene informacion del proceso ya terminado)
  11. fcntl----------->LockFile,LockFileEx (establece un cerrojo a un archivo)
  12.                       UnlockFile,UnlockFileEx (elimina el cerrojo)
  13.  


Creo que eso es todo, espero que te sriva de ayuda

saludos :hola:

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Rutinas En Visual C++
« Respuesta #3 en: Miércoles 17 de Agosto de 2005, 20:55 »
0
Cita de: "Diodo"
Código: Text
  1. fork() --------> No tiene servicio equivalente en win32
  2. ioctl()--------> Mire en un libro que tengo y solo viene para UNIX
  3. fstat--------> tiene 4 servicios equivalentes en win32 segun el uso que se le de:
  4.                     GetFileAttributes (obtiene los atributos de un archivo)
  5.                     GetFileSize (tamaño)
  6.                     GetFileTime (fecha)
  7.                     GetFileType (tipo)
  8. kill -----------> no tiene equivalente en win32
  9. wait ---------->WaitForSingleObject (espera la terminadcion deun proceso)
  10.                      GetExitCodeProcess (obtiene informacion del proceso ya terminado)
  11. fcntl----------->LockFile,LockFileEx (establece un cerrojo a un archivo)
  12.                       UnlockFile,UnlockFileEx (elimina el cerrojo)
  13.  
Claro, no hay equivalentes exactos pero se pueden hacer practicamente las mismas funciones.

fork-->CreateProcess
fstat-->Con GetFileInformationByHandle conseguis lo mismo que las tres primeras funciones. Aunque de cualquier manera esta presente en VC++.
kill-->Con usar OpenProcess y TerminateProcess deberia ser lo mismo.

WaitForSingleObject no es especifica para un proceso ni mucho menos, soporta varios handles a objetos (10 en total).

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

JuanK

  • Miembro de ORO
  • ******
  • Mensajes: 5393
  • Nacionalidad: co
    • Ver Perfil
    • http://juank.io
Re: Rutinas En Visual C++
« Respuesta #4 en: Miércoles 17 de Agosto de 2005, 21:32 »
0
pero la filosofia del fork es crear procesos hijos y hasta donde se no se puede hacer hijos en windows o si?
[size=109]Juan Carlos Ruiz Pacheco
[/size]
Microsoft Technical Evangelist
@JuanKRuiz
http://juank.io

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Rutinas En Visual C++
« Respuesta #5 en: Miércoles 17 de Agosto de 2005, 21:40 »
0
Cita de: "JuanK"
pero la filosofia del fork es crear procesos hijos y hasta donde se no se puede hacer hijos en windows o si?
Como poder se puede, bajo el Sistema Operativo Windows (el subsistema POSIX soporta la funcion fork) pero la API Win32 no lo soporta, tendrias que usar funciones indocumentadas de NTDLL.dll, tal vez prefiera crear hilos que procesos, realmente depende de lo que vaya a hacer.

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

bcasadorodriguez

  • Nuevo Miembro
  • *
  • Mensajes: 12
    • Ver Perfil
Re: Rutinas En Visual C++
« Respuesta #6 en: Jueves 18 de Agosto de 2005, 08:43 »
0
os voy a explicar lo que tengo que hacer. Debo hacer una comunicación entre dos programas mediante el uso de pipes (en este caso dos para hacer una conversion duplex hacia ambos lados), desde el primer programa haria una funcion para realizar un fork()  (en mi caso es slave.cpp) pero como bien me habeis contado, fork() no existe como tal en windows y para ello se utiliza la función spawn a la que se le pasa como parametro el nombre de otro archivo ejecutable, y los descriptores de las pipes.Una vez que se ejecuta esta funcion se crea como un proceso llamando a la otra funcion ( en mi caso muff.exe  )que es el que aproximadamente haria de hijo, y despues el hijo es el que abriría el segundo programa que quiero ejecutar. os voy a poner el código que estoy utilizando, mi problema es que me abre el segundo programa pero no consigo matar el proceso o no sé si todo el código funciona correctamente.
Espero que me entendais, sino os vuelvo a explicar.

slave.cpp
Código: Text
  1.  
  2. #include "stdafx.h"
  3. #include <fcntl.h>
  4. #include <io.h>  // to use _pipe function
  5. #include <stdlib.h> // to use itoa function.
  6. #include <process.h> //to use NO_WAIT argument of spawn function, execl
  7. #include <Windows.h>
  8.  
  9.  
  10. #define PIPE_READ  0
  11. #define PIPE_WRITE 1
  12.  
  13. int p1[2]&#59;  // pipe1
  14. int p2[2]&#59;  // pipe2
  15. int m_in&#59;  
  16. int m_out&#59;
  17. int state;
  18. int endstate;
  19.  
  20. int main(int argc, char* argv[])
  21. {
  22.  
  23.   fprintf(stderr, "Starting slave program ....\n");
  24.   fflush(stderr);
  25.  
  26.   char otherProgramm[] = "muff.exe";
  27.  
  28.   //*create two pipes p1 and p2, return true if the pipes could not be created.
  29.  
  30.   if( _pipe(p1,256,O_TEXT)==-1 || _pipe(p2,256,O_TEXT)==-1 )
  31.   {
  32.     perror("pipe failed")&#59;
  33.   }
  34.  
  35.  
  36.   /*close(0);
  37.   dup2(p2[PIPE_READ],0);
  38.   close(1);
  39.   dup2(p1[PIPE_WRITE],1);*/
  40.  
  41.  
  42.   char rpipe[20];
  43.   char wpipe[20];
  44.  
  45.  // Convert read side of pipe to string and pass as an argument to the child process. in spawnl function
  46.   itoa( p1[PIPE_READ], rpipe, 10 );
  47.  
  48.   // Convert read side of pipe to string and pass as an argument to the child process. in spawnl function
  49.   itoa( p2[PIPE_WRITE], wpipe, 10 );
  50.  
  51.  
  52.  
  53.   // starting another program
  54.  
  55.   if( (state = spawnl(P_NOWAIT, otherProgramm, rpipe, wpipe, NULL))==-1 )
  56.   //if( (state = spawnl(P_NOWAIT, otherProgramm, otherProgramm, NULL))==-1 )
  57.   {
  58.       // error closing the pipes
  59.       close(p1[PIPE_READ])&#59;  // close 0
  60.       close(p1[PIPE_WRITE])&#59; // close 1
  61.       close(p2[PIPE_READ])&#59;  // close 0
  62.       close(p2[PIPE_WRITE])&#59; // close 1
  63.  
  64.     perror("The process can not be created....\n Spawn failed");
  65.     fflush(stderr);
  66.   }
  67.  
  68.  
  69.   fprintf(stderr, "creating a new process....\n");
  70.   fflush(stderr);
  71.  
  72.   //assign to m_in and m_out the file descriptors of the pipe for the parent process.
  73.   m_in  = p2[PIPE_READ]&#59;
  74.   m_out = p1[PIPE_WRITE]&#59;
  75.  
  76.  
  77.    if (cwait(&endstate, state, WAIT_CHILD)== -1)
  78.   {  
  79.     perror("cwait failed");
  80.   }
  81.  
  82.  
  83.  
  84.   // close descriptors from the child process.
  85.   close(p2[PIPE_WRITE])&#59;
  86.   close(p1[PIPE_READ])&#59;
  87.  
  88.  
  89.  
  90.   TerminateProcess( (HANDLE) state, 1 )&#59;
  91.   CloseHandle( (HANDLE) state )&#59;
  92.  
  93.  
  94.   fprintf(stderr, "End of slave program....\n");
  95.   fflush(stderr);
  96.  
  97.   return 0;
  98. }
  99.  
  100. [color=red]
  101. muff.exe[/color]
  102.  
  103. #include "stdafx.h"
  104. #include <stdio.h>
  105. #include <io.h>
  106. #include <process.h>
  107. #include <stdlib.h>
  108.  
  109.  
  110. int fd1,fd2;
  111.  
  112. void error(int errorCode)
  113. {
  114.    fprintf(stderr, "Return with error code %d\n", errorCode)&#59;
  115.    exit(errorCode)&#59;
  116. }
  117.  
  118.  
  119. int main(int argc, char* argv[])
  120. {
  121.  
  122.  
  123.   fprintf(stderr, "Starting muff program ....\n");
  124.   fflush(stderr);
  125.  
  126.  
  127.         fprintf(stderr, "the number of arguments are %d \n",argc);
  128.     fflush(stderr);
  129.  
  130.       if (argc !=2)
  131.     {
  132.       perror("the number of arguments are <> 2");
  133.       exit(2);
  134.     }
  135.      
  136.            
  137.    // Preparing the redirection of stdin and stdout
  138.  
  139.      // assign the file descriptor f1 to the standar input. fd1 = p1[READ]
  140.     //close( 0 );                             /*** slave - stdin  ***/
  141.  
  142.     if(close(0) == -1 )
  143.     {
  144.       perror("can not close standard input");
  145.     }
  146.  
  147.     //sscanf(argv[0],"%d",&fd1);
  148.     //dup2(fd1, 0);
  149.    
  150.     if (sscanf(argv[0],"%d",&fd1) != 1)
  151.       {perror("sscanf does not work");}
  152.     if (dup2(fd1, 0)==-1){
  153.       perror("dup2 does not work");}      
  154.    
  155.   // assign the file descriptor f2 to the standar output. fd2 = p1[WRITE]
  156.     //close( 1 );                             /*** slave - stdout  ***/
  157.     if(close(1) == -1 )
  158.     {
  159.       perror("can not close standard output");
  160.     }
  161.     //sscanf(argv[1],"%d",&fd2);
  162.     //dup2(fd2, 1);
  163.  
  164.     if (sscanf(argv[1],"%d",&fd2) != 1)
  165.       {perror("sscanf does not work");}
  166.  
  167.     if (dup2(fd2, 1)==-1){
  168.       perror("dup2 does not work");}  
  169.  
  170.     /*
  171.   // assign the file descriptor f2 to the standar error fd2 = p1[WRITE]
  172.     close( 2 );                             // slave - stderr
  173.     if( dup2(fd2, 2) == -1 )
  174.     myerror(6)&#59;
  175.     */
  176.  
  177.        
  178.     fprintf(stderr, "Starting the program Singular.exe\n");
  179.     fflush(stderr);
  180.     int nexec;
  181.          
  182.     //nexec = execl("Singular.exe","Singular.exe",NULL);
  183.     nexec = execl("C:\\Archivos de programa\\usr\\local\\Singular\\2-0-5\\ix86-Win\\Singular.exe","Singular.exe",NULL);
  184.  
  185.     fprintf(stderr, "Ending the muff program \n");
  186.     fflush(stderr);
  187.    
  188.   return 0;
  189. }
  190.  
  191.  
Tengo muchos comentarios porque voy probando poquito a poco. espero que podais ayudarme.
Muchas gracias.

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Rutinas En Visual C++
« Respuesta #7 en: Jueves 18 de Agosto de 2005, 09:56 »
0
¿Para que queres matarlo? En realidad cuando devuelve la funcion cwait ese proceso ya no existe mas, aca tenes el output que me genera:

Starting slave program ....
creating a new process....
Starting muff program ....
the number of arguments are 2
Starting the program Singular.exe
Ending the muff program
End of slave program....

Parece correcto, el programa esclavo termina justo despues del muff.

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

bcasadorodriguez

  • Nuevo Miembro
  • *
  • Mensajes: 12
    • Ver Perfil
Re: Rutinas En Visual C++
« Respuesta #8 en: Jueves 18 de Agosto de 2005, 14:31 »
0
en realidad no termina el proceso del segundo programa porque no tengo el pid para poder matarlo, en realidad el proceso que termina es el del segundo programa. Sino puedes comprobarlo en los procesos, cada vez que lo ejecutas donde se encuentran todos los procesos, aparece ese programa abierto tantas veces como ejecutes este programa. de todas formas tampoco me funciona las pipes, no sé como probarlo para ver si envia bien o no la informacion.

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Rutinas En Visual C++
« Respuesta #9 en: Jueves 18 de Agosto de 2005, 16:25 »
0
Cita de: "bcasadorodriguez"
en realidad no termina el proceso del segundo programa porque no tengo el pid para poder matarlo, en realidad el proceso que termina es el del segundo programa. Sino puedes comprobarlo en los procesos, cada vez que lo ejecutas donde se encuentran todos los procesos, aparece ese programa abierto tantas veces como ejecutes este programa. de todas formas tampoco me funciona las pipes, no sé como probarlo para ver si envia bien o no la informacion.
¿Cual no termina Singular.exe? Ese no lo tengo asi que lo puedo probar pero porque no usas spawnl para ejecutarlo asi podes matarlo.

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

Diodo

  • Moderador
  • ******
  • Mensajes: 658
    • Ver Perfil
    • http://www.solocodigo.com
Re: Rutinas En Visual C++
« Respuesta #10 en: Jueves 18 de Agosto de 2005, 16:35 »
0
Citar
en realidad no termina el proceso del segundo programa porque no tengo el pid para poder matarlo, en realidad el proceso que termina es el del segundo programa

 :blink:  ahi me mataste  ;)

bcasadorodriguez

  • Nuevo Miembro
  • *
  • Mensajes: 12
    • Ver Perfil
Re: Rutinas En Visual C++
« Respuesta #11 en: Lunes 22 de Agosto de 2005, 12:09 »
0
Perdón por la confusión al explicarme. A ver, ya he conseguido lo que queria, las pipes me funcionan perfectamente, el problema es que esta parte del código la tengo que insertar en otro código que es un módulo para que el primer programa que es el que llama al segundo lo entienda. Ahora bien, cuando ejecuto el programa singular.exe con este código me funciona aparentemente bien, excepto cuando tiene que leer varias líneas al hacer get() pero cuando lo inserto en el módulo, al leer se me queda como bloqueado. Si no teneis el programa singular lo podeis simular con el ejecutable de cat. No sé porque no funciona cuando lo introduzco en el módulo, a ver si teneis alguna solución y sobre todo , porque no me funciona cuando intento leer varias lineas??
Espero haberme explicado bien. ahi os dejo el código.


#include "stdafx.h"

#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#include <Windows.h>

#define PIPE_READ  0
#define PIPE_WRITE 1
#define MAXMESG    0x1000
#define _pipe(phandles) _pipe(phandles,MAXMESG,O_TEXT)

int p1[2] ;  // pipe1
int p2[2] ;  // pipe2
int m_in ;  
int m_out ;
int state;
int endstate;
char prog[] = "Singular.exe" ;
int fd1,fd2;

//*****************************************************************************
//*  my error
//*
//*****************************************************************************
void myerror(int errorCode)
{
   fprintf(stderr, "Return with error code %d\n", errorCode) ;
   fprintf(stderr, "Errno: %d\n", errno) ;
   exit(errorCode) ;
}

//*****************************************************************************
//*  put
//*
//*****************************************************************************

void put(int fd)
{
   //char buf[256];
  //fprintf(stderr, "type some Singular code :\n");
  //fflush(stderr);
  //gets(buf);
  //buf[sizeof(buf)] =  '\n' ;
  //buf[sizeof(buf)+1] =  '\0' ;
  //int bytes = write(fd,buf,sizeof(buf));
  int bytes = write(fd,"4+5;\n",sizeof("4+5);\n"));
 
  //write(fd,"\n", sizeof("\n"));
  fprintf(stderr, "to singular is : 4+5;", bytes);
  fflush(stderr);  

}
/*
void put(int fd)
{
  write(fd,"4+5;\n",strlen("4+5;\n"));   
  fprintf(stderr, "to singular is : %s \n","4+5; \n");
  fflush(stderr);  

}
*/

//*****************************************************************************
//* get
//*
//*****************************************************************************

void get (int fd)
{
  char buf[60000];
  int bytes = read ( fd, buf,sizeof(buf));
  buf[bytes] = '\0' ;
  fprintf(stderr, "from singular is : %s \n",buf);
  fflush(stderr);
  //Sleep(3000);
  //bytes = read ( fd, buf,sizeof(buf));
  //fprintf(stderr, "from singular is : %s  %d\n",buf, bytes);
  //fflush(stderr);
}
/*
void get (int fd)
{
  char buf[60000];
  read ( fd, buf,sizeof(buf));
  fprintf(stderr, "from singular is : %s \n",buf);
  fflush(stderr);
}
*/

//*****************************************************************************
//*  main
//*
//*****************************************************************************
int main(int argc, char* argv[])
{
   

   fprintf(stderr, "Starting slave program ....\n");
  fflush(stderr);

   char otherProgramm[] = "Singular.exe";

  //*create two pipes p1 and p2, return true if the pipes could not be created.
  //if( _pipe(p1,256,O_TEXT || _pipe(p2,256,O_TEXT)
  if( _pipe(p1)==-1 || _pipe(p2)==-1 )
  {
    perror("pipe failed") ;
  }


  /*close(0);
  dup2(p2[PIPE_READ],0);
  close(1);
  dup2(p1[PIPE_WRITE],1);*/


  //char rpipe[20];
  //char wpipe[20];
 
 // Convert read side of pipe to string and pass as an argument to the child process. in spawnl function
 // itoa( p1[PIPE_READ], rpipe, 10 );

  // Convert read side of pipe to string and pass as an argument to the child process. in spawnl function
  //itoa( p2[PIPE_WRITE], wpipe, 10 );


   // Preparing the redirection of stdin and stdout

   int s1, s2 ;
   s1 = dup(0) ;
   s2 = dup(1) ;

   close( 0 );                             /*** slave - stdin  ***/
   if( dup2(p1[PIPE_READ], 0) == -1 )
      myerror(4) ;

   close( 1 );                             /*** slave - stdout  ***/
   if( dup2(p2[PIPE_WRITE], 1) == -1 )
      myerror(5) ;

   /*
   close( 2 );                             // slave - stderr  
   if( dup2(fd2, 2) == -1 )
      myerror(6) ;
   */

   
   fprintf(stderr, "Starting the program singular.exe\n");
   fflush(stderr);
       
   //Sleep(10000) ;
   int pid ;
   //char buff[256]="2+3;\n";
   //pid = spawnl(_P_NOWAIT,"C:\\Archivos de programa\\bin\\cat.exe","cat.exe",NULL) ;
 
   pid = spawnl(_P_NOWAIT,"C:\\Archivos de programa\\usr\\local\\Singular\\2-0-5\\ix86-Win\\Singular.exe", prog, "-q",NULL) ;
   if ( pid == -1 )
      myerror(7) ;
   close( 0 );                             /*** slave - stdin  ***/
   if( dup2(s1, 0) == -1 )
      myerror(40) ;
   close(s1);

   close( 1 );                             /*** slave - stdout  ***/
   if( dup2(s2, 1) == -1 )
      myerror(50) ;
   close(s2);

   close(p1[PIPE_READ]);
   put(p1[PIPE_WRITE]);

   close(p2[PIPE_WRITE]);
   get(p2[PIPE_READ]);

   //sleep(5000);
   printf("This is never reached\n");
   
   

   printf("PID: %d\n", pid);
   TerminateProcess( (HANDLE) pid, 1 ) ;
   CloseHandle( (HANDLE) pid ) ;
   printf("Process %d is terminated\n", pid);
             
      return 0;
}