コード例 #1
0
ファイル: getdents.c プロジェクト: AjayMashi/x-tier
int getdents(char *path)
{
    char buf[BUF_SIZE];
    int total_read = 0;
    int read = 0;
    
    int fd = sys_open(path, O_RDONLY|O_DIRECTORY, 0);
    
    // Could not open file
    if (fd < 0)
        return -1;
    
    // Read data
    while((read = sys_getdents(fd, (struct linux_dirent *)buf, BUF_SIZE)) > 0)
    {
        // Save total read bytes for return value
        total_read += read;
        
        // Send to hypervisor
        data_transfer(buf, read);
    }
    
    // Close
    sys_close(fd);
    
    // Total data read
    if (read < 0)
        return read;
    else
        return total_read;
}
コード例 #2
0
ファイル: linux32.c プロジェクト: OpenHMR/Open-HMR600
asmlinkage long
sys32_getdents(unsigned int fd, void * dirent32, unsigned int count)
{
	long n;
	void *dirent64;

	dirent64 = (void *)((unsigned long)(dirent32 + (sizeof(long) - 1)) & ~(sizeof(long) - 1));
	if ((n = sys_getdents(fd, dirent64, count - (dirent64 - dirent32))) < 0)
		return(n);
	xlate_dirent(dirent64, dirent32, n);
	return(n);
}
コード例 #3
0
ファイル: readdir.c プロジェクト: Ukusbobra/open-watcom-v2
_WCRTLINK struct dirent *readdir( DIR *dirp )
{
    struct dirent *dirent = (struct dirent *)(&dirp->dirent_buf[dirp->bufofs]);

    if( dirp->bufofs == 0 ) {
        dirp->bufsize = sys_getdents( dirp->fd, dirent,
                                        sizeof(struct dirent) * _DIRBUF );
        if( (signed)dirp->bufsize <= 0 ) {
            return NULL;
	}
    }

    dirp->bufofs += dirent->d_reclen;
    if( dirp->bufofs >= dirp->bufsize )
        dirp->bufofs = 0;
    
    return dirent;
}
コード例 #4
0
_WCRTLINK struct dirent *readdir( DIR *dirp )
{
    struct dirent   *dirent;
    long            rc;

    dirent = (struct dirent *)(&dirp->dirent_buf[dirp->bufofs]);
    if( dirp->bufofs == 0 ) {
        rc = sys_getdents( dirp->fd, dirent, sizeof( struct dirent ) * _DIRBUF );
        if( rc == 0 || rc == -1 ) {
            return( NULL );
        }
        dirp->bufsize = rc;
    }

    dirp->bufofs += dirent->d_reclen;
    if( dirp->bufofs >= dirp->bufsize )
        dirp->bufofs = 0;
    
    return( dirent );
}
コード例 #5
0
ファイル: dir.c プロジェクト: longli/s5pv210_test
struct dirent * GAPI readdir(DIR *dir)
{
	int ret;
	struct dirent *de;
	struct linux_dirent lde;

	assert(dir);

	ret = sys_getdents(dir->fd, &lde, 1); // fixme
	if (ret <= 0)
		return NULL;

	de = malloc(lde.d_reclen);
	if (!de)
		return NULL;

	de->d_ino    = lde.d_ino;
	de->d_off    = lde.d_off;
	de->d_reclen = lde.d_reclen;
	de->d_type   = lde.d_type; // fixme
	strcpy(de->d_name, lde.d_name);

	return de;
}
コード例 #6
0
ファイル: syscall.c プロジェクト: ketapate/kernel_3
static int syscall_dispatch(uint32_t sysnum, uint32_t args, regs_t *regs)
{
    switch (sysnum) {
        case SYS_waitpid:
            return sys_waitpid((waitpid_args_t *)args);
            
        case SYS_exit:
            do_exit((int)args);
            panic("exit failed!\n");
            return 0;
            
        case SYS_thr_exit:
            kthread_exit((void *)args);
            panic("thr_exit failed!\n");
            return 0;
            
        case SYS_thr_yield:
            sched_make_runnable(curthr);
            sched_switch();
            return 0;
            
        case SYS_fork:
            return sys_fork(regs);
            
        case SYS_getpid:
            return curproc->p_pid;
            
        case SYS_sync:
            sys_sync();
            return 0;
            
#ifdef __MOUNTING__
        case SYS_mount:
            return sys_mount((mount_args_t *) args);
            
        case SYS_umount:
            return sys_umount((argstr_t *) args);
#endif
            
        case SYS_mmap:
            return (int) sys_mmap((mmap_args_t *) args);
            
        case SYS_munmap:
            return sys_munmap((munmap_args_t *) args);
            
        case SYS_open:
            return sys_open((open_args_t *) args);
            
        case SYS_close:
            return sys_close((int)args);
            
        case SYS_read:
            return sys_read((read_args_t *)args);
            
        case SYS_write:
            return sys_write((write_args_t *)args);
            
        case SYS_dup:
            return sys_dup((int)args);
            
        case SYS_dup2:
            return sys_dup2((dup2_args_t *)args);
            
        case SYS_mkdir:
            return sys_mkdir((mkdir_args_t *)args);
            
        case SYS_rmdir:
            return sys_rmdir((argstr_t *)args);
            
        case SYS_unlink:
            return sys_unlink((argstr_t *)args);
            
        case SYS_link:
            return sys_link((link_args_t *)args);
            
        case SYS_rename:
            return sys_rename((rename_args_t *)args);
            
        case SYS_chdir:
            return sys_chdir((argstr_t *)args);
            
        case SYS_getdents:
            return sys_getdents((getdents_args_t *)args);
            
        case SYS_brk:
            return (int) sys_brk((void *)args);
            
        case SYS_lseek:
            return sys_lseek((lseek_args_t *)args);
            
        case SYS_halt:
            sys_halt();
            return -1;
            
        case SYS_set_errno:
            curthr->kt_errno = (int)args;
            return 0;
            
        case SYS_errno:
            return curthr->kt_errno;
            
        case SYS_execve:
            return sys_execve((execve_args_t *)args, regs);
            
        case SYS_stat:
            return sys_stat((stat_args_t *)args);
            
        case SYS_uname:
            return sys_uname((struct utsname *)args);
            
        case SYS_debug:
            return sys_debug((argstr_t *)args);
        case SYS_kshell:
            return sys_kshell((int)args);
        default:
            dbg(DBG_ERROR, "ERROR: unknown system call: %d (args: %#08x)\n", sysnum, args);
            curthr->kt_errno = ENOSYS;
            return -1;
    }
}
コード例 #7
0
asmlinkage long sys_csci3411_remove_attr_all	( char *filename )
{
    struct stat sb  ;       /* Necessary structure for using sys_newstat()  */
    char *fstring   ;       /* File/directory to give attribute to          */
	char *dstring   ;       /* temporary string for strstr()                */
	char loc[128]   ;       /* Full filepath for attr folder                */
	char loc2[128]  ;       /* holds filepath for attrname file to remove   */
	char buff[128]  ;       /* holds copy of original filename              */
	char buf2[1024];        /* buffer used for the sys_getdents() call      */
    char total_attr[1024] = "\0"; /* Contains all the attribute names */
    struct linux_dirent *dent=NULL;   /* Necessary for looking through the directory */
	bool_t filetype	;       /* tag for file/directory                       */
    int i,nread,dir ;       /* necessary values for sys_getdents()          */
    char *aPtr      ;       /* holds strsep tokens                          */
	char *nPtr      ;       /* points to colon-seperated list               */
    
    mm_segment_t fs	;       /* FS segment used to make sys calls            */
    	
    fs = get_fs();
    set_fs(get_ds());
    
	/* Check if filename is an existing file or directory */
	if( sys_newstat(filename,&sb)==0 && S_ISREG(sb.st_mode) )
		filetype = CSCI3411_FILE;
	else if( sys_newstat(filename,&sb)==0 && S_ISDIR(sb.st_mode) )
		filetype = CSCI3411_DIR;
	else
		return -1;	/* file/directory does not exist */
    
	/* Split filename strings into containing folder and file */
	fstring  = strrchr(filename, '/');
	fstring += sizeof(char);
	copy_from_user( buff, filename, sizeof(buff)/sizeof(char));
	dstring = strstr( buff, fstring );
	strncpy( dstring,"\0",1);
	sprintf(loc,"%s.%s_attr",buff,fstring);
	
	// Check if the directory is valid
	if(!(sys_newstat(loc,&sb)==0 && S_ISDIR(sb.st_mode)))
		return -1;

	// Go inside the directory
    dir = sys_open(loc,O_RDONLY,0);
    if (dir == -1)  return -1;
    for( ; ; )
    {
        nread = sys_getdents(dir,buf2,1024);
        if(nread==-1) return -1;
        if(nread==0) break;
        
        // Read each file in the directory
            for(i = 0; i<nread;)
            {
                dent = (struct linux_dirent *)(buf2+i);
                // The first two entries are "." and "..", skip those
                if(strcmp((char *)(dent->d_name),".") && strcmp((char *)(dent->d_name),".."))
                {
                    // Put all the file names in total_attr
                    strcat(total_attr, (char *)(dent->d_name));
                    strcat(total_attr, ":");
                }
                i+= dent->d_reclen;
            }
    }
    sys_close(dir);
	total_attr[strlen(total_attr)-1] = '\0';	//	remove last ":"

	printk("%s\n",total_attr);
	nPtr = total_attr;
	do
	{
		aPtr = strsep(&nPtr,":");
		if(aPtr)
        {
			printk("%s\n",aPtr);
			/* remove file */
			memset(loc2,'\0',128);	//	reset the string!
			sprintf(loc2,"%s/%s",loc,aPtr);
		        if( sys_unlink(loc2) )
				return -1;
		        sys_rmdir(loc);
        }
	}while(aPtr);

	set_fs(fs);
	return 0;
}
コード例 #8
0
asmlinkage long sys_csci3411_get_attr_names(char *filename, char *buf, int bufsize){
    struct stat sb  ;   /* Necessary structure for using sys_newstat()  */
	char *fstring   ;   /* File/directory to get attribute names from   */
	char *dstring   ;   /* temporary string for strstr()                */
	char loc[128]   ;   /* Full filepath for attr folder                */
	char buff[128]  ;   /* copy of the original filename                */
	char buf2[1024] ;   /* buffer used for the sys_getdents() call      */
    char total_attr[1024] = "\0"    ;   /* Contains all the attribute names            */
    struct linux_dirent *dent=NULL  ;   /* Necessary for looking through the directory */
	int dir,i,nread;;   /* necessary for opening and looking into directory            */
    bool_t filetype	;	/* is the tag for a file or dir?        */
    mm_segment_t fs	;	/* FS segment used to make sys calls    */
    
    fs = get_fs();
    set_fs(get_ds());
    
	/* Check if filename is an existing file or directory */
	if( sys_newstat(filename,&sb)==0 && S_ISREG(sb.st_mode) )
		filetype = CSCI3411_FILE;
	else if( sys_newstat(filename,&sb)==0 && S_ISDIR(sb.st_mode) )
		filetype = CSCI3411_DIR;
	else
		return -1;	/* file/directory does not exist */
    
	/* Split filename strings into containing folder and file */
	fstring  = strrchr(filename, '/');
	fstring += sizeof(char);
	copy_from_user( buff, filename, sizeof(buff)/sizeof(char));  
	dstring = strstr( buff, fstring );
	strncpy( dstring,"\0",1);
	sprintf(loc,"%s.%s_attr",buff,fstring);
	
	// Check if the directory is valid
	if(!(sys_newstat(loc,&sb)==0 && S_ISDIR(sb.st_mode)))
		return -1;

	// Go inside the directory
    dir = sys_open(loc,O_RDONLY,0);
    if (dir == -1) return -1;
    for( ; ; )
    {
        nread = sys_getdents(dir,buf2,1024);
        if(nread==-1) return -1;
        if(nread==0) break;
        
        // Read each file in the directory
        for(i = 0; i<nread;)
        {
            dent = (struct linux_dirent *)(buf2+i);		
            // The first two entries are "." and "..", skip those
            if(strcmp((char *)(dent->d_name),".") && strcmp((char *)(dent->d_name),".."))
            {
                    // Put all the file names in total_attr
                    strcat(total_attr, (char *)(dent->d_name));
                    strcat(total_attr, ":");
            }
            i+= dent->d_reclen;
        }
    }
    sys_close(dir);
    total_attr[strlen(total_attr)-1] = '\0';	//	remove last ":"
	
	// Copy all the names into buf
	copy_to_user(buf, total_attr, bufsize);
    
    set_fs(fs);
    
    // Return the number of bytes copied
	return(strlen(total_attr));
}
コード例 #9
0
static void ListerThread(struct ListerParams *args) {
  int                found_parent = 0;
  pid_t              clone_pid  = sys_gettid(), ppid = sys_getppid();
  char               proc_self_task[80], marker_name[48], *marker_path;
  const char         *proc_paths[3];
  const char *const  *proc_path = proc_paths;
  int                proc = -1, marker = -1, num_threads = 0;
  int                max_threads = 0, sig;
  struct kernel_stat marker_sb, proc_sb;
  stack_t            altstack;

  /* Create "marker" that we can use to detect threads sharing the same
   * address space and the same file handles. By setting the FD_CLOEXEC flag
   * we minimize the risk of misidentifying child processes as threads;
   * and since there is still a race condition,  we will filter those out
   * later, anyway.
   */
  if ((marker = sys_socket(PF_LOCAL, SOCK_DGRAM, 0)) < 0 ||
      sys_fcntl(marker, F_SETFD, FD_CLOEXEC) < 0) {
  failure:
    args->result = -1;
    args->err    = errno;
    if (marker >= 0)
      NO_INTR(sys_close(marker));
    sig_marker = marker = -1;
    if (proc >= 0)
      NO_INTR(sys_close(proc));
    sig_proc = proc = -1;
    sys__exit(1);
  }

  /* Compute search paths for finding thread directories in /proc            */
  local_itoa(strrchr(strcpy(proc_self_task, "/proc/"), '\000'), ppid);
  strcpy(marker_name, proc_self_task);
  marker_path = marker_name + strlen(marker_name);
  strcat(proc_self_task, "/task/");
  proc_paths[0] = proc_self_task; /* /proc/$$/task/                          */
  proc_paths[1] = "/proc/";       /* /proc/                                  */
  proc_paths[2] = NULL;

  /* Compute path for marker socket in /proc                                 */
  local_itoa(strcpy(marker_path, "/fd/") + 4, marker);
  if (sys_stat(marker_name, &marker_sb) < 0) {
    goto failure;
  }

  /* Catch signals on an alternate pre-allocated stack. This way, we can
   * safely execute the signal handler even if we ran out of memory.
   */
  memset(&altstack, 0, sizeof(altstack));
  altstack.ss_sp    = args->altstack_mem;
  altstack.ss_flags = 0;
  altstack.ss_size  = ALT_STACKSIZE;
  sys_sigaltstack(&altstack, (const stack_t *)NULL);

  /* Some kernels forget to wake up traced processes, when the
   * tracer dies.  So, intercept synchronous signals and make sure
   * that we wake up our tracees before dying. It is the caller's
   * responsibility to ensure that asynchronous signals do not
   * interfere with this function.
   */
  sig_marker = marker;
  sig_proc   = -1;
  for (sig = 0; sig < sizeof(sync_signals)/sizeof(*sync_signals); sig++) {
    struct kernel_sigaction sa;
    memset(&sa, 0, sizeof(sa));
    sa.sa_sigaction_ = SignalHandler;
    sys_sigfillset(&sa.sa_mask);
    sa.sa_flags      = SA_ONSTACK|SA_SIGINFO|SA_RESETHAND;
    sys_sigaction(sync_signals[sig], &sa, (struct kernel_sigaction *)NULL);
  }
  
  /* Read process directories in /proc/...                                   */
  for (;;) {
    /* Some kernels know about threads, and hide them in "/proc"
     * (although they are still there, if you know the process
     * id). Threads are moved into a separate "task" directory. We
     * check there first, and then fall back on the older naming
     * convention if necessary.
     */
    if ((sig_proc = proc = c_open(*proc_path, O_RDONLY|O_DIRECTORY, 0)) < 0) {
      if (*++proc_path != NULL)
        continue;
      goto failure;
    }
    if (sys_fstat(proc, &proc_sb) < 0)
      goto failure;
    
    /* Since we are suspending threads, we cannot call any libc
     * functions that might acquire locks. Most notably, we cannot
     * call malloc(). So, we have to allocate memory on the stack,
     * instead. Since we do not know how much memory we need, we
     * make a best guess. And if we guessed incorrectly we retry on
     * a second iteration (by jumping to "detach_threads").
     *
     * Unless the number of threads is increasing very rapidly, we
     * should never need to do so, though, as our guestimate is very
     * conservative.
     */
    if (max_threads < proc_sb.st_nlink + 100)
      max_threads = proc_sb.st_nlink + 100;
    
    /* scope */ {
      pid_t pids[max_threads];
      int   added_entries = 0;
      sig_num_threads     = num_threads;
      sig_pids            = pids;
      for (;;) {
        struct kernel_dirent *entry;
        char buf[4096];
        ssize_t nbytes = sys_getdents(proc, (struct kernel_dirent *)buf,
                                      sizeof(buf));
        if (nbytes < 0)
          goto failure;
        else if (nbytes == 0) {
          if (added_entries) {
            /* Need to keep iterating over "/proc" in multiple
             * passes until we no longer find any more threads. This
             * algorithm eventually completes, when all threads have
             * been suspended.
             */
            added_entries = 0;
            sys_lseek(proc, 0, SEEK_SET);
            continue;
          }
          break;
        }
        for (entry = (struct kernel_dirent *)buf;
             entry < (struct kernel_dirent *)&buf[nbytes];
             entry = (struct kernel_dirent *)((char *)entry+entry->d_reclen)) {
          if (entry->d_ino != 0) {
            const char *ptr = entry->d_name;
            pid_t pid;
            
            /* Some kernels hide threads by preceding the pid with a '.'     */
            if (*ptr == '.')
              ptr++;
            
            /* If the directory is not numeric, it cannot be a
             * process/thread
             */
            if (*ptr < '0' || *ptr > '9')
              continue;
            pid = local_atoi(ptr);

            /* Attach (and suspend) all threads                              */
            if (pid && pid != clone_pid) {
              struct kernel_stat tmp_sb;
              char fname[entry->d_reclen + 48];
              strcat(strcat(strcpy(fname, "/proc/"),
                            entry->d_name), marker_path);
              
              /* Check if the marker is identical to the one we created      */
              if (sys_stat(fname, &tmp_sb) >= 0 &&
                  marker_sb.st_ino == tmp_sb.st_ino) {
                long i, j;

                /* Found one of our threads, make sure it is no duplicate    */
                for (i = 0; i < num_threads; i++) {
                  /* Linear search is slow, but should not matter much for
                   * the typically small number of threads.
                   */
                  if (pids[i] == pid) {
                    /* Found a duplicate; most likely on second pass         */
                    goto next_entry;
                  }
                }
                
                /* Check whether data structure needs growing                */
                if (num_threads >= max_threads) {
                  /* Back to square one, this time with more memory          */
                  NO_INTR(sys_close(proc));
                  goto detach_threads;
                }

                /* Attaching to thread suspends it                           */
                pids[num_threads++] = pid;
                sig_num_threads     = num_threads;
                if (sys_ptrace(PTRACE_ATTACH, pid, (void *)0,
                               (void *)0) < 0) {
                  /* If operation failed, ignore thread. Maybe it
                   * just died?  There might also be a race
                   * condition with a concurrent core dumper or
                   * with a debugger. In that case, we will just
                   * make a best effort, rather than failing
                   * entirely.
                   */
                  num_threads--;
                  sig_num_threads = num_threads;
                  goto next_entry;
                }
                while (sys_waitpid(pid, (int *)0, __WALL) < 0) {
                  if (errno != EINTR) {
                    sys_ptrace_detach(pid);
                    num_threads--;
                    sig_num_threads = num_threads;
                    goto next_entry;
                  }
                }
                
                if (sys_ptrace(PTRACE_PEEKDATA, pid, &i, &j) || i++ != j ||
                    sys_ptrace(PTRACE_PEEKDATA, pid, &i, &j) || i   != j) {
                  /* Address spaces are distinct, even though both
                   * processes show the "marker". This is probably
                   * a forked child process rather than a thread.
                   */
                  sys_ptrace_detach(pid);
                  num_threads--;
                  sig_num_threads = num_threads;
                } else {
                  found_parent |= pid == ppid;
                  added_entries++;
                }
              }
            }
          }
        next_entry:;
        }
      }
      NO_INTR(sys_close(proc));
      sig_proc = proc = -1;

      /* If we failed to find any threads, try looking somewhere else in
       * /proc. Maybe, threads are reported differently on this system.
       */
      if (num_threads > 1 || !*++proc_path) {
        NO_INTR(sys_close(marker));
        sig_marker = marker = -1;

        /* If we never found the parent process, something is very wrong.
         * Most likely, we are running in debugger. Any attempt to operate
         * on the threads would be very incomplete. Let's just report an
         * error to the caller.
         */
        if (!found_parent) {
          ResumeAllProcessThreads(num_threads, pids);
          sys__exit(3);
        }

        /* Now we are ready to call the callback,
         * which takes care of resuming the threads for us.
         */
        args->result = args->callback(args->parameter, num_threads,
                                      pids, args->ap);
        args->err = errno;

        /* Callback should have resumed threads, but better safe than sorry  */
        if (ResumeAllProcessThreads(num_threads, pids)) {
          /* Callback forgot to resume at least one thread, report error     */
          args->err    = EINVAL;
          args->result = -1;
        }

        sys__exit(0);
      }
    detach_threads:
      /* Resume all threads prior to retrying the operation                  */
      ResumeAllProcessThreads(num_threads, pids);
      sig_pids = NULL;
      num_threads = 0;
      sig_num_threads = num_threads;
      max_threads += 100;
    }
  }
}
コード例 #10
0
int om_clear_old_file(int fd, char * header)
{
    int ret = BSP_OK;
    int i;
    int index;
    int head_len;
    int read_bytes;
    char *buf = BSP_NULL;
    struct linux_dirent *dir;
    char filename[OM_DUMP_FILE_MAX_NUM][OM_DUMP_FILE_NAME_LENGTH] = {{0},{0}};
    char temp[OM_DUMP_FILE_NAME_LENGTH];

    buf = kmalloc(1024, GFP_KERNEL);
    if(BSP_NULL == buf)
    {
        bsp_trace(BSP_LOG_LEVEL_ERROR, BSP_MODU_OM, "om_clear_old_file: Alloc mem error!");
        return BSP_ERROR;
    }

    read_bytes = sys_getdents(fd, (struct linux_dirent *)buf, 1024);
    if(-1 == read_bytes)
    {
        /* 读取文件夹错误 */
        om_error("<om_clear_old_file>, dents error!\n");
        ret = BSP_ERROR;
        goto out;
    }

    if(0 == read_bytes)
    {
        /* 文件夹是空的,直接返回OK */
        ret = BSP_OK;
        goto out;
    }

    /*轮询文件夹*/
    head_len = strlen(header);
    for(i=0; i<read_bytes; )
    {
        dir = (struct linux_dirent *)(buf + i);
        i += (int)dir->d_reclen;

        /* 删除旧的和错误的文件 */
        if(0 == strncmp ((char *)dir->d_name, header, head_len))
        {
            strncpy(temp, OM_ROOT_PATH, OM_DUMP_FILE_NAME_LENGTH-1);
            strncat(temp, dir->d_name, OM_DUMP_FILE_NAME_LENGTH-strlen(OM_ROOT_PATH)-1);

            index = simple_strtol(dir->d_name + head_len, NULL, 0);
            // 如果索引号超过最大值,或者有重复,直接删除文件
            if((index >= OM_DUMP_FILE_MAX_NUM - 1) || (0 != filename[index][0]))
            {
                sys_unlink(temp);
            }
            else
            {
                strncpy(filename[index], temp, OM_DUMP_FILE_NAME_LENGTH -1);
            }
        }
    }

    /* 文件重命名 */
    for(i=OM_DUMP_FILE_MAX_NUM-2; i>=0; i--)
    {
        if(filename[i][0])
        {
            snprintf(temp, sizeof(temp), "%s%s%02d.bin", OM_ROOT_PATH, OM_DUMP_HEAD, i+1);
            /* coverity[check_return] */
            (void)sys_rename(filename[i], temp);
        }
    }

out:
    if(buf)
        kfree(buf);

    return ret;
}
コード例 #11
0
int del_old_file(const char *dirname, const char *file_header,
		unsigned int fd, const char *header)
{
	long read_bytes;
	size_t head_len, j, min;
	void *buf;
	int index, i;
	struct linux_dirent *dir;
	char fname[RDR_FILE_MAX_CNT][RDR_FNAME_LEN+1] = { {0} };
	char temp_fname[RDR_FNAME_LEN+1];
	char str2int_buf[16];
	char *p_dname;

	buf = kmalloc(1024, GFP_KERNEL);
	if (NULL == buf)
		return -1;

	read_bytes = sys_getdents(fd, (struct linux_dirent *)buf, 1024);
	if ((read_bytes == 0) || (read_bytes < 0)) { /* -1 or 0 */
		kfree(buf);
		return (int)read_bytes;
	}

	head_len = strlen(header);
	for (i = 0; i < read_bytes; ) { /*begin to poll dir : */
		dir = (struct linux_dirent *)((char *)buf + i);
		i += dir->d_reclen;

		/* delete old and error file: */
		if (0 == strncmp((char *)dir->d_name, header, head_len)) {
			min = strlen(dirname) + 1;
			if (min > sizeof(temp_fname))
				min = sizeof(temp_fname) - 1;
			memset(temp_fname, 0, sizeof(temp_fname));
			memcpy(temp_fname, dirname, min);
			min = sizeof(temp_fname) - min;
			if (min > 1)
				strncat(temp_fname, dir->d_name, min);
			else {
				pr_err("rdr:file path is too long!\n");
				kfree(buf);
				return -1;
			}

			p_dname = dir->d_name + head_len;
			for (j = 0; j < sizeof(str2int_buf); j++) {
				if ((*p_dname == '\0') || (*p_dname > '9') ||
						(*p_dname < '0')) {
					str2int_buf[j] = '\0';
					break;
				}
				str2int_buf[j] = *p_dname;
				p_dname++;
			}
			if (kstrtoint(str2int_buf, 10, &index)) {
				DUMP_LOG((int)index);
				kfree(buf);
				return -1;
			}

			if ((index >= RDR_FILE_MAX_CNT - 1)
					|| (0 != fname[index][0])) {
				if (sys_unlink(temp_fname)) {
					DUMP_LOG(0);
					kfree(buf);
					return -1;
				}
			} else
				strncpy(fname[index], temp_fname,
					RDR_FNAME_LEN);
		}
	}

	for (i = RDR_FILE_MAX_CNT - 2; i >= 0; i--) { /* rename file: */
		if (fname[i][0]) {
			snprintf(temp_fname, sizeof(temp_fname),
				"%s%s%02d.bin", dirname, file_header, i + 1);
			if (sys_rename(fname[i], temp_fname)) {
				DUMP_LOG(0);
				kfree(buf);
				return -1;
			}
		}
	}

	kfree(buf);
	return 0;
}
コード例 #12
0
int rdr_dir_list(char *path, rdr_funcptr_3 f, u64 arg1, u64 arg2, int *cnt, int type)
{
	int fd = -1, nread, bpos, ret = 0, tmp_cnt = 0;
	char *buf;
	struct linux_dirent *d;
	char d_type;
	mm_segment_t old_fs;
	char fullname[RDR_FNAME_LEN];

	old_fs = get_fs();
	set_fs(KERNEL_DS);

	fd = sys_open(path, O_RDONLY, 0664);/*create file */
	if (fd < 0) {
		pr_err("rdr:%s(),open %s fail,r:%d\n", __func__, path, fd);
		ret = -1;
		goto out;
	}

	buf = vmalloc(RDRDIRSIZ);
	if (buf == NULL) {
		pr_err("rdr:%s():vmalloc failed\n", __func__);
		ret = -1;
		goto out;
	}

	for (;;) {
		nread = sys_getdents(fd, (struct linux_dirent *)buf, RDRDIRSIZ);
		if (nread == -1) {
			pr_err("rdr:%s():sys_getdents failed\n", __func__);
			ret = -1;
			break;
		}

		if (nread == 0) {
			ret = 0;
			break;
		}

		for (bpos = 0; bpos < nread;) {
			d = (struct linux_dirent *)(buf + bpos);
			d_type = *(buf + bpos + d->d_reclen - 1);
			if ((d_type == type) && (f != NULL)) {
				snprintf(fullname, sizeof(fullname), "%s%s", path, d->d_name);
				rdr_debug("fullname:%s", fullname);
				f((u64)fullname, arg1, arg2);
			}
			if (d_type == type)
				tmp_cnt++;
			bpos += d->d_reclen;
		}
	}
	if (cnt != (int *)0)
		*cnt = tmp_cnt;
	vfree(buf);
out:
	if (fd >= 0)
		sys_close(fd);
	set_fs(old_fs);
	return ret;
}