GNU/Linux >> Linux Esercitazione >  >> Linux

Come implementare readlink per trovare il percorso

La risposta accettata è quasi corretta, tranne per il fatto che non puoi fare affidamento su PATH_MAX perché lo è

non garantito per essere definito per POSIX se il sistema non ha tale limite.

(Dalla pagina man di readlink(2))

Inoltre, quando è definito non sempre rappresenta il limite "vero". (Vedi http://insanecoding.blogspot.fr/2007/11/pathmax-simply-isnt.html )

La manpage di readlink fornisce anche un modo per farlo su symlink :

L'utilizzo di un buffer di dimensioni statiche potrebbe non fornire spazio sufficiente per il contenuto del collegamento simbolico. La dimensione richiesta per il buffer può essere ottenuta dal valore stat.st_size restituito da una chiamata a lstat(2) sul collegamento. Tuttavia, il numero di byte scritti da readlink() e read‐linkat() dovrebbe essere controllato per assicurarsi che la dimensione del collegamento simbolico non sia aumentata tra le chiamate.

Tuttavia, nel caso di /proc/self/exe/ come per la maggior parte dei file /proc, stat.st_size sarebbe 0. L'unica soluzione rimanente che vedo è ridimensionare il buffer mentre non si adatta.

Suggerisco l'uso di vector<char> come segue per questo scopo:

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 "";
}

Usa correttamente la funzione readlink() per gli usi corretti di readlink funzione.

Se hai il tuo percorso in un std::string , potresti fare qualcosa del genere:

#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 */
}

Se cerchi solo un percorso prestabilito:

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 */
}

Per usarlo:

int main()
{
  std::string selfpath = get_selfpath();
  std::cout << selfpath << std::endl;
  return 0;
}

Diamo un'occhiata a cosa dice la manpage:

 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.

OK. Dovrebbe essere abbastanza semplice. Dato il tuo buffer di 1024 caratteri:

 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;
 }

Linux
  1. Come scoprire se il disco è SSD o HDD in Linux

  2. Come utilizzare il comando trova di Linux per trovare i file

  3. come trovare il percorso HADOOP_HOME su Linux?

  4. Come trovare il file manager predefinito?

  5. Come trovo l'UUID di un filesystem

Come trovare il numero di porta di un servizio in Linux

Come trovare l'indirizzo IP di una macchina virtuale KVM

Come trovare la dimensione totale di una directory in Linux

Come trovare file con il comando fd in Linux

Come trovare l'elenco dei repository installati in Linux

Come configurare il percorso JAVA_HOME in Debian 11