I have these lines that break and throws error at 439 memcpy(&path[0] strlen("ls /proc/"),pid,1);
This is the code
void get_pid()
{
char line[1000];
FILE *cmd = popen("pidof a.out", "r");
fgets(line, 100, cmd);
pid_t pid = strtoul(line, NULL, 10);
char *path=malloc(sizeof(char)*100);
memset(path,0,100);
memcpy(path,"ls /proc/",strlen("ls /proc/"));
memcpy(&path[0] strlen("ls /proc/"),pid,1);
system(path);
free(path);
return;
}
is there any neat way of accomplish I just to execute ls command the way I am trying it just takes /proc/ and concat with pid I got from system(pidof) Actually I need to get into ls /proc/my_pid=pid/fd/ and find socket fd. there is only one socket file in /proc/pid/fd/ directory
How to do it in C
Actually this line is trouble maker
memcpy(&path[0] strlen("ls /proc/"),pid,1);
I am just taking the address of first character plusing it with strlen and then write with mcmcpy just 1. But obviously the above is wrong since my second parameter to memcpy is type int which is 4 byte and it expect char pointer which is 8 bytes. Can I cast it may be but I need to do it the correct way in C. Can anyone please help
CodePudding user response:
It is generally recommended to thing of what you are trying to do and what type are the data.
You first use popen to extract the result of the command pidof a.out. fgets will give you a string ending with a newline. Just replace that last character with a null
...
fgets(line, 100, cmd);
line[strlen(line) -1] = '\0';
You later want to concatenate that value to another string... It is useless to convert it to a pid_t only to convert it back to a string (unless you want to control that the format it correct).
Furthermore, the memxxx functions are recommended to process arbitrary character array that could contain null characters. Here you only handle null terminated strings, so you should use the strxxx functions.
Finally unless you want to experiment with it, using dynamic allocation for a fixed size array is non idiomatic... What you want is:
char path[100] = "ls /proc/";
That is enough to get an array of 100 characters initialized with the content of "ls /proc" followed by null characters.
Just concatenate your initial string:
strcat(path, line);
system(path);
Anyway, this is still poor code, because you should never rely on input data and should always test that what you get is what you expected, but I'll keep that for another answer...
CodePudding user response:
There are a number of ways to go about finding the pid of the current process and then getting a directory listing of the process directory -- but you are making it harder than need be.
Most compiles provide the POSIX function getpid() which will retrieve the current process pid. To determine how many characters are needed for the combined "ls /proc/" and pid, just use the old snprinf() trick with the buffer NULL and the number of chars set to 0 and snprintf() will return the length that would be required to hold the completed string, e.g.
len = snprintf (NULL, 0, "ls /proc/%d", pid); /* determine len req'd */
With the length, you can allocate len 1 bytes and then use sprintf() to fill the string, e.g.
if (!(path = malloc (len 1))) { /* allocate len 1 */
perror ("malloc-path");
return;
}
sprintf (path, "ls /proc/%d", pid); /* create path */
All that remains is making your system() call. Putting it altogether, you can do:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
void get_pid ()
{
char *path;
int len;
pid_t pid = getpid(); /* get pid of current proc */
len = snprintf (NULL, 0, "ls /proc/%d", pid); /* determine len req'd */
if (!(path = malloc (len 1))) { /* allocate len 1 */
perror ("malloc-path");
return;
}
sprintf (path, "ls /proc/%d", pid); /* create path */
system (path); /* list contents of process directory */
free (path); /* free path */
}
int main () {
get_pid();
}
(note: for your use you can avoid the length checking and dynamic allocations simply be declaring path as a fixed-size array, e.g. char path[128]; would more than suffice, then you can simply call sprintf() and create the desired string)
The version using a fixed-size path simplifies to:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
void get_pid ()
{
char path[128]; /* fixed buffer to hold final string */
pid_t pid = getpid(); /* get pid of current proc */
sprintf (path, "ls /proc/%d", pid); /* create path */
system (path); /* list contents of process directory */
}
int main () {
get_pid();
}
Either way is fine.
Example Use/Output
Running the code does provide a listing of the current process directory, e.g.
$ ./bin/lsprocpid
attr coredump_filter fdinfo make-it-fail mountstats oom_score_adj sched stat timerslack_ns
auxv cpuset gid_map map_files net pagemap schedstat statm uid_map
cgroup cwd io maps ns patch_state sessionid status wchan
clear_refs environ latency mem numa_maps personality setgroups syscall
cmdline exe limits mountinfo oom_adj projid_map smaps task
comm fd loginuid mounts oom_score root stack timers
This is probably one of the more concise ways to approach it. There are many ways with strcat(), etc, but when you need to mix numbers and text in a printf() like format-string, then using sprintf() to create the combined string is about as simple way as you have.
Look things over and let me know if you have further questions.
