Cómo implementar readlink a encontrar el camino

El uso de la función readlink utilizado como una solución a ¿Cómo puedo encontrar la ubicación del archivo ejecutable en C?, ¿cómo puedo obtener la ruta de acceso a una matriz de char? Además, ¿las variables buf y bufsize representan y cómo puedo inicializar ellos?

EDIT: estoy tratando de obtener la ruta de acceso de la que actualmente se ejecuta el programa, igual que la pregunta vinculado anteriormente. La respuesta a esa pregunta dice que el uso de readlink("proc/self/exe"). No sé cómo implementar esto en mi programa. He intentado:

char buf[1024];  
string var = readlink("/proc/self/exe", buf, bufsize);  

Esto es obviamente incorrecto.

InformationsquelleAutor a sandwhich | 2011-04-02

4 Kommentare

  1. 37

    Este El uso de la readlink() funcione correctamente para el correcto usos de la readlink función.

    Si usted tiene su camino en un std::string, se podría hacer algo como esto:

    #include <unistd.h>
    #include <limits.h>
    
    std::string do_readlink(std::string const& path) {
        char buff[PATH_MAX];
        ssize_t len = ::readlink(path.c_str(), buff, sizeof(buff)-1);
        if (len != -1) {
          buff[len] = '\0';
          return std::string(buff);
        }
        /* handle error condition */
    }

    Si estás sólo después de una ruta fija:

    std::string get_selfpath() {
        char buff[PATH_MAX];
        ssize_t len = ::readlink("/proc/self/exe", buff, sizeof(buff)-1);
        if (len != -1) {
          buff[len] = '\0';
          return std::string(buff);
        }
        /* handle error condition */
    }

    A utilizar:

    int main()
    {
      std::string selfpath = get_selfpath();
      std::cout << selfpath << std::endl;
      return 0;
    }
    • No, lo siento, creo que no expresé mi frase correctamente. No tengo la ruta, estoy usando readlink(«/proc/self/exe», buf, bufsize); correctamente con el fin de recuperarlo.
    • No entiendo lo que estás diciendo. Por favor, edita tu pregunta para mostrar lo que tiene, y un ejemplo de lo que usted desea.
    • Me acaba de editar una explicación.
    • ok, me pongo más detalles, pero mi respuesta original funcionaba bastante bien con una ruta fija…
    • Ok, gracias. Esto es lo que yo estaba buscando.
    • Sólo para agregar algunos detalles en los que he estado luchando un poco: el get_selfPath() función devuelve la ruta de acceso, incluyendo el nombre del ejecutable. Para obtener la ruta de acceso de quitar el nombre del exe se puede hacer lo siguiente: std::string::size_type t = path.find_last_of("/") y, a continuación,path = path.substr(0,t). No sé por qué en todas partes esta nunca se aclaró lo suficiente;)
    • no es un error en todos.
    • cuál debe ser el valor del argumento de la función do_readlink?
    • No creo que sea una buena idea ser tan arrogante sobre la asignación de 4KiB en la pila como eso. ¿Por qué no un std::vector?
    • no sabía que el «::» en ::readlink obras de C puro libs.
    • No es necesario agregar lío con la adición de un terminador nulo. Acaba de escribir if (len != -1) { return std::string(buff, static_cast<size_t>(len)); }

  2. 4

    Echemos un vistazo a lo que la página del manual dice:

     readlink() places the contents of the symbolic link path in the buffer
     buf, which has size bufsiz.  readlink does not append a NUL character to
     buf.

    ACEPTAR. Debe ser lo suficientemente simple. Dada su búfer de 1024 caracteres:

     char buf[1024];
    
     /* The manpage says it won't null terminate.  Let's zero the buffer. */
     memset(buf, 0, sizeof(buf));
    
     /* Note we use sizeof(buf)-1 since we may need an extra char for NUL. */
     if (readlink("/proc/self/exe", buf, sizeof(buf)-1) < 0)
     {
        /* There was an error...  Perhaps the path does not exist
         * or the buffer is not big enough.  errno has the details. */
        perror("readlink");
        return -1;
     }
    • no debería ser… si (readlink(«/proc/self/exe», buf, sizeof(buf)-1) <0) ?
    • if (readlink(/*...*/)) pruebas para distinto de cero. Menor que 0 es distinto de cero.
    • readlink devuelve >0 en caso de éxito. «En caso de éxito, readlink() devuelve el número de bytes que se coloca en buf. En caso de error, se devuelve -1». linux.die.net/man/2/readlink.
    • Ok. Va a editar luego. Esto es un poco inusual para una syscall. Generalmente 0 es el éxito.
  3. 2

    Aceptado la respuesta es casi correcto, excepto que usted no puede confiar en PATH_MAX porque es

    no garantizada, a ser definido por POSIX si el sistema no la tiene
    límite.

    (De readlink(2) página de manual)

    También, cuando se define, no siempre representan la «verdadera» límite. (Ver http://insanecoding.blogspot.fr/2007/11/pathmax-simply-isnt.html )

    La readlink del manual dar también una manera de hacer que en el enlace :

    El uso de una forma estática de tamaño de búfer podría no proporcionar suficiente espacio para que el
    enlace simbólico contenido. El tamaño requerido para el buffer puede ser
    obtenido de la estadística.st_size valor devuelto por una llamada a lstat(2) en
    en el enlace. Sin embargo, el número de bytes escritos por readlink() y read‐
    linkat() debe ser revisado para asegurarse de que el tamaño de la simbólica
    enlace no aumentó entre las llamadas.

    Sin embargo, en el caso de /proc/self/exe/as para la mayoría de /proc archivos, stat.st_size sería 0. La única solución que veo es para cambiar el tamaño de búfer mientras que no encaja.

    Me sugieren el uso de vector<char> como siga por este propósito:

    std::string get_selfpath()
    {
        std::vector<char> buf(400);
        ssize_t len;
    
        do
        {
            buf.resize(buf.size() + 100);
            len = ::readlink("/proc/self/exe", &(buf[0]), buf.size());
        } while (buf.size() == len);
    
        if (len > 0)
        {
            buf[len] = '\0';
            return (std::string(&(buf[0])));
        }
        /* handle error */
        return "";
    }

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea