Chinaunix首页 | 论坛 | 博客
  • 博客访问: 498758
  • 博文数量: 223
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2145
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-01 10:23
个人简介

该坚持的时候坚持,该妥协的时候妥协,该放弃的时候放弃

文章分类

全部博文(223)

文章存档

2017年(56)

2016年(118)

2015年(3)

2014年(46)

我的朋友

分类: C/C++

2014-09-09 22:07:41

main函数
/**********************************************************************
 *           main
 */
int main( int argc, char *argv[] )
{
    char error[1024];
    int i;
判断是否有这个环境,是否在运行
    if (!getenv( "WINELOADERNOEXEC" ))  /* first time around */
    {
        static char noexec[] = "WINELOADERNOEXEC=1";
如果没有就可以运行wine,设置成1.
        putenv( noexec );
确认命令格式,对--help和--version做出解释
        check_command_line( argc, argv );
确认运行前的进程,资源情况
        if (pre_exec())
        {
初始化运行所需要的环境,库环境,数据的环境
            wine_init_argv0_path( argv[0] );
确认相关文件是否正确,是否存在,载入文件运行
            wine_exec_wine_binary( NULL, argv, getenv( "WINELOADER" ));
如果能载入程序,并正常退出。程序不会到这里
            fprintf( stderr, "wine: could not exec the wine loader\n" );
强制退出
            exit(1);
        }
    }

#ifndef __APPLE__
    if (wine_main_preload_info)
#endif
    {
        for (i = 0; wine_main_preload_info[i].size; i++)
            reserve_area( wine_main_preload_info[i].addr, wine_main_preload_info[i].size );
    }

    wine_init( argc, argv, error, sizeof(error) );
    fprintf( stderr, "wine: failed to initialize: %s\n", error );
    exit(1);
}

main函数中的check_command_line
[main() >check_command_line()]
static void check_command_line( int argc, char *argv[] )
{
提示的相关信息
    static const char usage[] =
        "Usage: wine PROGRAM [ARGUMENTS...]   Run the specified program\n"
        "       wine --help                   Display this help and exit\n"
        "       wine --version                Output version information and exit";
参数不够
    if (argc <= 1)
    {
        fprintf( stderr, "%s\n", usage );
        exit(1);
}
如果是--help
    if (!strcmp( argv[1], "--help" ))
    {
        printf( "%s\n", usage );
        exit(0);
}
如果是--version
    if (!strcmp( argv[1], "--version" ))
    {
        printf( "%s\n", wine_get_build_id() );
        exit(0);
    }
}

check_command_line函数手中的wine_get_build_id
[main() >check_command_line()>wine_get_build_id()]
const char *wine_get_build_id(void)
{
这里wine_build = “1.7.21”...
    extern const char wine_build[];
    return wine_build;
}





main中的pre_exec
[main() >pre_exec()]
static int pre_exec(void)
{
    int temp;
确认不使用pthread
check_threading();
要求小于2G
check_vmsplit( &temp );
设置最大使用资源
    set_max_limit( RLIMIT_AS );
    return 1;
}
main中的wine_init_argv0_path
[main() >wine_init_argv0_path()]
/* initialize the argv0 path */初始化argv0路径
void wine_init_argv0_path( const char *argv0 )
{
    const char *basename;
char *libdir;
basename是从路径中提取wine
    if (!(basename = strrchr( argv0, '/' ))) basename = argv0;
else basename++;
bindir是wine所在的路径
bindir = get_runtime_exedir();
判断wine路径是否存在和相同路径下wineserver是否存在
    if (bindir && !is_valid_bindir( bindir ))
{
如果wine路径下没有wineserver,说明还在源文件下。于是到server目录下找到wineserver,到dlls目录下找到ntdll.dll.so。此时build_dir是源文件目录,如"/home/chen/下载/wine-1.7.21"
        build_dir = running_from_build_dir( bindir );
清空bindir
        free( bindir );
        bindir = NULL;
}
这里找lib文件的目录,如"/home/chen/下载/wine-1.7.21/loader/../libs/wine"
libdir = get_runtime_libdir();
    if (libdir && !bindir && !build_dir)
    {
        build_dir = running_from_build_dir( libdir );
        if (!build_dir) bindir = build_path( libdir, LIB_TO_BINDIR );
    }
    if (!libdir && !bindir && !build_dir)
    {
        bindir = get_runtime_argvdir( argv0 );
        if (bindir && !is_valid_bindir( bindir ))
        {
            build_dir = running_from_build_dir( bindir );
            free( bindir );
            bindir = NULL;
        }
}
这里argv0_name为”loader/wine”
    if (build_dir)
    {
        argv0_name = build_path( "loader/", basename );
    }
    else
    {
        if (libdir) dlldir = build_path( libdir, LIB_TO_DLLDIR );
        else if (bindir) dlldir = build_path( bindir, BIN_TO_DLLDIR );
        if (bindir) datadir = build_path( bindir, BIN_TO_DATADIR );
        argv0_name = xstrdup( basename );
    }
free( libdir );
函数结束后只有build_dir还存放着wine的路径,如"/home/chen/下载/wine-1.7.21"
}
main中的wine_exec_wine_binary
[main() >wine_exec_wine_binary()]
void wine_exec_wine_binary( const char *name, char **argv, const char *env_var )
{
    const char *path, *pos, *ptr;
int use_preloader;
name为”loader/wine”
    if (!name) name = argv0_name;  /* no name means default loader */
#ifdef linux
    use_preloader = !strendswith( name, "wineserver" );
#else
    use_preloader = 0;
#endif
linux下use_preloader = 1,这个use_preloader在preloader_exec用来判断
    if ((ptr = strrchr( name, '/' )))
    {
        /* if we are in build dir and name contains a path, try that */
这里ptr有值,build_dir也有值,判断后进入。其他的判断应该也差不多,都是为了进preloader_exec函数。
        if (build_dir)
        {
            argv[0] = build_path( build_dir, name );
            preloader_exec( argv, use_preloader );
            free( argv[0] );
        }
        name = ptr + 1;  /* get rid of path */
    }
    /* first, bin directory from the current libdir or argv0 */
    if (bindir)
    {
        argv[0] = build_path( bindir, name );
        preloader_exec( argv, use_preloader );
        free( argv[0] );
    }
    /* then specified environment variable */
    if (env_var)
    {
        argv[0] = (char *)env_var;
        preloader_exec( argv, use_preloader );
    }
    /* now search in the Unix path */
    if ((path = getenv( "PATH" )))
    {
        argv[0] = xmalloc( strlen(path) + strlen(name) + 2 );
        pos = path;
        for (;;)
        {
            while (*pos == ':') pos++;
            if (!*pos) break;
            if (!(ptr = strchr( pos, ':' ))) ptr = pos + strlen(pos);
            memcpy( argv[0], pos, ptr - pos );
            strcpy( argv[0] + (ptr - pos), "/" );
            strcat( argv[0] + (ptr - pos), name );
            preloader_exec( argv, use_preloader );
            pos = ptr;
        }
        free( argv[0] );
    }
    /* and finally try BINDIR */
    argv[0] = build_path( BINDIR, name );
    preloader_exec( argv, use_preloader );
    free( argv[0] );
}
wine_exec_wine_binary中的preloader_exec
/* exec a binary using the preloader if requested; helper for wine_exec_wine_binary */
static void preloader_exec( char **argv, int use_preloader )
{
    if (use_preloader)
    {
        static const char preloader[] = "wine-preloader";
        static const char preloader64[] = "wine64-preloader";
        char *p, *full_name;
        char **last_arg = argv, **new_argv;
这里p和之前basename一样,是”wine”
        if (!(p = strrchr( argv[0], '/' ))) p = argv[0];
        else p++;
        full_name = xmalloc( p - argv[0] + sizeof(preloader64) );
        memcpy( full_name, argv[0], p - argv[0] );
        if (strendswith( p, "64" ))
            memcpy( full_name + (p - argv[0]), preloader64, sizeof(preloader64) );
        else
            memcpy( full_name + (p - argv[0]), preloader, sizeof(preloader) );
到这里full_name是wine(或64)-preloader的路径了
        /* make a copy of argv */
last_arg存放着argv,现在又扩展了.last_arg是在argv后面的部分,last_arg[-2]是argv[0]
        while (*last_arg) last_arg++;
last_arg-argv=2,又加了2,分配了×argv的空间,new_argv有4个×argv的空间
        new_argv = xmalloc( (last_arg - argv + 2) * sizeof(*argv) );
从new_argv[1]开始把argv内容复制进去大小为3个×argv,
        memcpy( new_argv + 1, argv, (last_arg - argv + 1) * sizeof(*argv) );
这里new_argv[0]是full_name的路径,new_argv就依次有full_name,argv的内容了
        new_argv[0] = full_name;
execv中运行的是wine-preloader,new_argv中又三个参数:wine-preloader(带路径),wine(带路径),notepad.exe。没有kthread了
        execv( full_name, new_argv );
        free( new_argv );
        free( full_name );
}
use_preloader=0就直接运行
    execv( argv[0], argv );
}
阅读(1080) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~