banner

[Rule] Rules  [Home] Main Forum  [Portal] Portal  
[Members] Member Listing  [Statistics] Statistics  [Search] Search  [Reading Room] Reading Room 
[Register] Register  
[Login] Loginhttp  | https  ]
 
Forum Index Thảo luận hệ điều hành *nix code C  XML
  [Question]   code C 03/10/2010 14:22:49 (+0700) | #1 | 222049
[Avatar]
panfider
Member

[Minus]    0    [Plus]
Joined: 12/05/2010 01:51:04
Messages: 448
Offline
[Profile] [PM] [Email]
bạn nào kiểm ra giùm hàm get_list_exec
trả về con trỏ char ** danh sách các command nhưng không hiểu tại sao nó segment fault
Code:
#include <dirent.h>
#include <string.h>
#include <unistd.h>
#include <malloc.h>
/*
    cut a string by sep character, 
    return a pointer of array string
*/
char **str2arword(const char *str,char sep){
  if(str==NULL) return NULL;
  char *path=str;
  size_t len=strlen(path);
  size_t frag=0,r=0,count=0,msize;
  char **vpath;
  /*first count how many*/
  while(*path)	if(*path++==sep) frag++;
  vpath=(char **)malloc( (frag+2)*sizeof(char*)+len+1 );
  path=str;
  vpath[r]=vpath+frag+2;
  while(*path){
	*(vpath[r]+count++)=*path++;
	if(*path==sep) {
	  *(vpath[r]+count)=NULL;
	  vpath[r+1]=vpath[r]+count+1;
	  count=0,path++,r++;
	}
  }
  vpath[r+1]=NULL;
  return vpath;
}

/*23:00
    get a list of file exec in PATH environment variable
*/
char **get_list_exec(const char *epath){
  #define MAX_NUMBER_POINTER    512
  char *path = epath;
  char **vcpt = 0;
  size_t r=0,len=0,item=0,count=1;
  char **vret=(char **)malloc(sizeof(char *)*MAX_NUMBER_POINTER);
  struct dirent *dent;
  DIR *dirp;
  if(vret==NULL) return -1;
  if(epath==NULL) path = getenv("PATH");
  vcpt = str2arword(path,':');
  /*in this loop I got the total len of all string and number of item*/
  while(vcpt[r]){
    dirp= opendir(vcpt[r]);
    if(dirp==NULL) goto end_loop;
    while( dent=readdir(dirp) ) {
      if( (strcmp(dent->d_name,".")) &&  strcmp(dent->d_name,"..") )
        if((dent->d_type==DT_REG)||(dent->d_type==DT_LNK)){
          char buf[512]; /*form a canonical name*/
          strcpy(buf,vcpt[r]);strcat(buf,dent->d_name);
          if(! access(buf,X_OK))
          {
              size_t len1 = strlen(dent->d_name);
              char *get = malloc(len1+1);
              if(get==NULL) return -1;
              strcpy(get,dent->d_name);
              vret[item]=get;
              len +=len1;
              item++;
          }
        }
      if(item>=MAX_NUMBER_POINTER){
        count++;
        void *tmp=malloc(sizeof(char *)*MAX_NUMBER_POINTER*count);
        if(tmp==NULL) return -1;
        memcpy(tmp,vret,sizeof(char *)*MAX_NUMBER_POINTER*(count-1));
        free(vret);
        vret=(char **)tmp;
      }
    }
    closedir(dirp);
    end_loop:;
    r++;
  }
  /*when i go here len and item are reserve for make string*/
  vret[item]=0;
  return vret;
}
[Unix] live free or die
[Up] [Print Copy]
  [Question]   code C 04/10/2010 12:25:14 (+0700) | #2 | 222102
StarGhost
Elite Member

[Minus]    0    [Plus]
Joined: 29/03/2005 20:34:22
Messages: 662
Location: The Queen
Offline
[Profile] [PM]
Bạn phải đưa ví dụ lên đây là trong trường hợp input thế nào bị segfault, thì việc debug dễ hơn nhiều.
Mind your thought.
[Up] [Print Copy]
  [Question]   code C 04/10/2010 13:57:56 (+0700) | #3 | 222115
[Avatar]
panfider
Member

[Minus]    0    [Plus]
Joined: 12/05/2010 01:51:04
Messages: 448
Offline
[Profile] [PM] [Email]
Code:
/*phần include ở trên và code ở trên*/

/*
  this is main 
*/
int main(){
  char **vpt=get_list_exec(0);
  int r=0;
  while(vpt[r]){
     printf("%s ",vpt[r]);
  }

}

hàm này rất có lợi, nếu nó chạy tốt smilie
nếu kết hợp với hàm which dưới đây
Code:
/*find cmd in path and return malloc string */
char *which(const char *word){
  char **vpath=str2arword(getenv("PATH"),':');
  char buf[266],*rpt=0;
  size_t r=0;
  while(vpath[r]){
        strcpy(buf,vpath[r]);strcat(buf,"/");
        strcat(buf,word);
        if(access(buf,F_OK)==0) {
          rpt=(char *)malloc(strlen(buf));
          if(rpt)  strcpy(rpt,buf);
          return rpt;
        }
        r++;
  }
  free((void *)vpath);
  return NULL;
}

hàm này chạy tốt, trả về đường dẫn của một lệnh Unix, giống lệnh which của *nix
ví dụ: char *lenh=which("ls"); thì trả về lenh "/bin/ls"
[Unix] live free or die
[Up] [Print Copy]
  [Question]   code C 04/10/2010 16:01:22 (+0700) | #4 | 222130
StarGhost
Elite Member

[Minus]    0    [Plus]
Joined: 29/03/2005 20:34:22
Messages: 662
Location: The Queen
Offline
[Profile] [PM]
Mình không rõ segfault chỗ nào vì mình ko gặp, nhưng mình cho rằng cách dùng variable "item" của bạn không chuẩn. Bạn xem lại chỗ "if (item >= MAX_NUMBER_POINTER)".

p/s: mình thấy bạn "chào hàng" trong mục xin việc nhiệt tình thế mà mấy chỗ debug đơn giản vậy ko làm được là sao? Thêm nữa, với lối coding vậy ai mà dám thuê bạn code đây?
Mind your thought.
[Up] [Print Copy]
  [Question]   code C 04/10/2010 17:44:47 (+0700) | #5 | 222135
[Avatar]
panfider
Member

[Minus]    0    [Plus]
Joined: 12/05/2010 01:51:04
Messages: 448
Offline
[Profile] [PM] [Email]
bạn test có in ra được list các lệnh không ?
vì mỗi item tương đương một con trỏ có kích thước sizeof(char *),
vì mình không muốn duyệt qua một thư mục nhiều lần nên mình buf một vùng nhớ cho 512 con trỏ,
nếu số item đang quét lớn hơn thì malloc mới, copy và free cũ,
[Unix] live free or die
[Up] [Print Copy]
[digg] [delicious] [google] [yahoo] [technorati] [reddit] [stumbleupon]
Go to: 
 Users currently in here 
1 Anonymous

Powered by JForum - Extended by HVAOnline
 hvaonline.net  |  hvaforum.net  |  hvazone.net  |  hvanews.net  |  vnhacker.org
1999 - 2013 © v2012|0504|218|