qcom_msm8916_64_android5.0/sources/qcom/bootable/recovery/updater/install.c
Value* SymlinkFn(const char* name, State* state, int argc, Expr* argv[]) {
    if (argc == 0) {
        return ErrorAbort(state, "%s() expects 1+ args, got %d", name, argc);
    }
    char* target;
    target = Evaluate(state, argv[0]);
    if (target == NULL) return NULL;

    char** srcs = ReadVarArgs(state, argc-1, argv+1);
    if (srcs == NULL) {
        free(target);
        return NULL;
    }

    int bad = 0;
    int i;
    for (i = 0; i < argc-1; ++i) {
        if (unlink(srcs[i]) < 0) {
            if (errno != ENOENT) {
                printf("%s: failed to remove %s: %s\n",
                        name, srcs[i], strerror(errno));
                ++bad;
            }
        }
        if (make_parents(srcs[i])) {
            printf("%s: failed to symlink %s to %s: making parents failed\n",
                    name, srcs[i], target);
            ++bad;
        }
        if (symlink(target, srcs[i]) < 0) {
            printf("%s: failed to symlink %s to %s: %s\n",
                    name, srcs[i], target, strerror(errno));
            ++bad;
        }
        free(srcs[i]);
    }
    free(srcs);
    if (bad) {
        return ErrorAbort(state, "%s: some symlinks failed", name);
    }
    return StringValue(strdup(""));
}
// symlink target src1 src2 ...
//    unlinks any previously existing src1, src2, etc before creating symlinks.
symlink target src1 src2
unlinks any previously existing src1, src2, etc before creating symlinks.
symlink target src1 src2 unlinks any previously existing src1 src2 etc before creating symlinks .
Value* SymlinkFn(const char* name, State* state, int argc, Expr* argv[]) {
    if (argc == 0) {
        return ErrorAbort(state, "%s() expects 1+ args, got %d", name, argc);
    }
    char* target;
    target = Evaluate(state, argv[0]);
    if (target == NULL) return NULL;
    char** srcs = ReadVarArgs(state, argc-1, argv+1);
    if (srcs == NULL) {
        free(target);
        return NULL;
    }
    int bad = 0;
    int i;
    for (i = 0; i < argc-1; ++i) {
        if (unlink(srcs[i]) < 0) {
            if (errno != ENOENT) {
                printf("%s: failed to remove %s: %s\n",
                        name, srcs[i], strerror(errno));
                ++bad;
            }
        }
        if (make_parents(srcs[i])) {
            printf("%s: failed to symlink %s to %s: making parents failed\n",
                    name, srcs[i], target);
            ++bad;
        }
        if (symlink(target, srcs[i]) < 0) {
            printf("%s: failed to symlink %s to %s: %s\n",
                    name, srcs[i], target, strerror(errno));
            ++bad;
        }
        free(srcs[i]);
    }
    free(srcs);
    if (bad) {
        return ErrorAbort(state, "%s: some symlinks failed", name);
    }
    return StringValue(strdup(""));
}
Value * SymlinkFn ( const char * name , State * state , int argc , Expr * argv [ ] ) { if ( argc == 0 ) { return ErrorAbort ( state , " " , name , argc ) ; } char * target ; target = Evaluate ( state , argv [ 0 ] ) ; if ( target == NULL ) return NULL ; char * * srcs = ReadVarArgs ( state , argc - 1 , argv + 1 ) ; if ( srcs == NULL ) { free ( target ) ; return NULL ; } int bad = 0 ; int i ; for ( i = 0 ; i < argc - 1 ; ++ i ) { if ( unlink ( srcs [ i ] ) < 0 ) { if ( errno != ENOENT ) { printf ( " \n " , name , srcs [ i ] , strerror ( errno ) ) ; ++ bad ; } } if ( make_parents ( srcs [ i ] ) ) { printf ( " \n " , name , srcs [ i ] , target ) ; ++ bad ; } if ( symlink ( target , srcs [ i ] ) < 0 ) { printf ( " \n " , name , srcs [ i ] , target , strerror ( errno ) ) ; ++ bad ; } free ( srcs [ i ] ) ; } free ( srcs ) ; if ( bad ) { return ErrorAbort ( state , " " , name ) ; } return StringValue ( strdup ( " " ) ) ; }
symlink target src1 src2 ...
unlinks any previously existing src1, src2, etc before creating symlinks.
symlink target src1 src2 ... unlinks any previously existing src1 src2 etc before creating symlinks .