X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=cygwin%2Fcygwin.c;h=21ec98cd6e8cced24bc00684568084c28506edc2;hb=eda4663d0f345e78f0a82529a08f3aa28c98ff2c;hp=db1c426ea1fb3687e3da160c54e61a1faae06ed2;hpb=b4bcd66247e5bc9051bd228e0f63bc1a5ffcf2a7;p=p5sagit%2Fp5-mst-13.2.git diff --git a/cygwin/cygwin.c b/cygwin/cygwin.c index db1c426..21ec98c 100644 --- a/cygwin/cygwin.c +++ b/cygwin/cygwin.c @@ -9,6 +9,10 @@ #include #include +#include +#include +#include +#include /* * pp_system() implemented via spawn() @@ -18,20 +22,18 @@ static int do_spawnvp (const char *path, const char * const *argv) { - dTHXo; + dTHX; Sigsave_t ihand,qhand; int childpid, result, status; - rsignal_save(SIGINT, SIG_IGN, &ihand); - rsignal_save(SIGQUIT, SIG_IGN, &qhand); + rsignal_save(SIGINT, (Sighandler_t) SIG_IGN, &ihand); + rsignal_save(SIGQUIT, (Sighandler_t) SIG_IGN, &qhand); childpid = spawnvp(_P_NOWAIT,path,argv); if (childpid < 0) { status = -1; - if(ckWARN(WARN_EXEC)) { - dTHR; - Perl_warner(aTHX_ WARN_EXEC,"Can't spawn \"%s\": %s", + if(ckWARN(WARN_EXEC)) + Perl_warner(aTHX_ packWARN(WARN_EXEC),"Can't spawn \"%s\": %s", path,Strerror (errno)); - } } else { do { result = wait4pid(childpid, &status, 0); @@ -47,7 +49,7 @@ do_spawnvp (const char *path, const char * const *argv) int do_aspawn (SV *really, void **mark, void **sp) { - dTHXo; + dTHX; int rc; char **a,*tmps,**argv; STRLEN n_a; @@ -58,10 +60,10 @@ do_aspawn (SV *really, void **mark, void **sp) while (++mark <= sp) if (*mark) - *a++ = SvPVx(*mark, n_a); + *a++ = SvPVx((SV *)*mark, n_a); else *a++ = ""; - *a = Nullch; + *a = (char*)NULL; if (argv[0][0] != '/' && argv[0][0] != '\\' && !(argv[0][0] && argv[0][1] == ':' @@ -80,8 +82,9 @@ do_aspawn (SV *really, void **mark, void **sp) int do_spawn (char *cmd) { - dTHXo; - char **a,*s,*metachars = "$&*(){}[]'\";\\?>|<~`\n"; + dTHX; + char const **a; + char *s,*metachars = "$&*(){}[]'\";\\?>|<~`\n"; const char *command[4]; while (*cmd && isSPACE(*cmd)) @@ -119,7 +122,7 @@ do_spawn (char *cmd) return do_spawnvp("sh",command); } - New (1303,PL_Argv,(s-cmd)/2+2,char*); + Newx (PL_Argv,(s-cmd)/2+2,const char*); PL_Cmd=savepvn (cmd,s-cmd); a=PL_Argv; for (s=PL_Cmd; *s;) { @@ -130,7 +133,7 @@ do_spawn (char *cmd) if (*s) *s++='\0'; } - *a=Nullch; + *a = (char*)NULL; if (!PL_Argv[0]) return -1; @@ -138,27 +141,239 @@ do_spawn (char *cmd) } /* see also Cwd.pm */ -static XS(Cygwin_cwd) { dXSARGS; char *cwd; - if(items != 0) + /* See http://rt.perl.org/rt3/Ticket/Display.html?id=38628 + There is Cwd->cwd() usage in the wild, and previous versions didn't die. + */ + if(items > 1) Perl_croak(aTHX_ "Usage: Cwd::cwd()"); - if((cwd = getcwd(NULL, 0))) { + if((cwd = getcwd(NULL, -1))) { ST(0) = sv_2mortal(newSVpv(cwd, 0)); - safesysfree(cwd); + free(cwd); +#ifndef INCOMPLETE_TAINTS + SvTAINTED_on(ST(0)); +#endif XSRETURN(1); } XSRETURN_UNDEF; } +XS(XS_Cygwin_pid_to_winpid) +{ + dXSARGS; + dXSTARG; + pid_t pid, RETVAL; + + if (items != 1) + Perl_croak(aTHX_ "Usage: Cygwin::pid_to_winpid(pid)"); + + pid = (pid_t)SvIV(ST(0)); + + if ((RETVAL = cygwin_internal(CW_CYGWIN_PID_TO_WINPID, pid)) > 0) { + XSprePUSH; PUSHi((IV)RETVAL); + XSRETURN(1); + } + XSRETURN_UNDEF; +} + +XS(XS_Cygwin_winpid_to_pid) +{ + dXSARGS; + dXSTARG; + pid_t pid, RETVAL; + + if (items != 1) + Perl_croak(aTHX_ "Usage: Cygwin::winpid_to_pid(pid)"); + + pid = (pid_t)SvIV(ST(0)); + + if ((RETVAL = cygwin32_winpid_to_pid(pid)) > 0) { + XSprePUSH; PUSHi((IV)RETVAL); + XSRETURN(1); + } + XSRETURN_UNDEF; +} + +XS(XS_Cygwin_win_to_posix_path) +{ + dXSARGS; + int absolute_flag = 0; + STRLEN len; + int err; + char *pathname, *buf; + + if (items < 1 || items > 2) + Perl_croak(aTHX_ "Usage: Cygwin::win_to_posix_path(pathname, [absolute])"); + + pathname = SvPV(ST(0), len); + if (items == 2) + absolute_flag = SvTRUE(ST(1)); + + if (!len) + Perl_croak(aTHX_ "can't convert empty path"); + buf = (char *) safemalloc (len + 260 + 1001); + + if (absolute_flag) + err = cygwin_conv_to_full_posix_path(pathname, buf); + else + err = cygwin_conv_to_posix_path(pathname, buf); + if (!err) { + ST(0) = sv_2mortal(newSVpv(buf, 0)); + safefree(buf); + XSRETURN(1); + } else { + safefree(buf); + XSRETURN_UNDEF; + } +} + +XS(XS_Cygwin_posix_to_win_path) +{ + dXSARGS; + int absolute_flag = 0; + STRLEN len; + int err; + char *pathname, *buf; + + if (items < 1 || items > 2) + Perl_croak(aTHX_ "Usage: Cygwin::posix_to_win_path(pathname, [absolute])"); + + pathname = SvPV(ST(0), len); + if (items == 2) + absolute_flag = SvTRUE(ST(1)); + + if (!len) + Perl_croak(aTHX_ "can't convert empty path"); + buf = (char *) safemalloc(len + 260 + 1001); + + if (absolute_flag) + err = cygwin_conv_to_full_win32_path(pathname, buf); + else + err = cygwin_conv_to_win32_path(pathname, buf); + if (!err) { + ST(0) = sv_2mortal(newSVpv(buf, 0)); + safefree(buf); + XSRETURN(1); + } else { + safefree(buf); + XSRETURN_UNDEF; + } +} + +XS(XS_Cygwin_mount_table) +{ + dXSARGS; + struct mntent *mnt; + + if (items != 0) + Perl_croak(aTHX_ "Usage: Cygwin::mount_table"); + /* => array of [mnt_dir mnt_fsname mnt_type mnt_opts] */ + + setmntent (0, 0); + while ((mnt = getmntent (0))) { + AV* av = newAV(); + av_push(av, newSVpvn(mnt->mnt_dir, strlen(mnt->mnt_dir))); + av_push(av, newSVpvn(mnt->mnt_fsname, strlen(mnt->mnt_fsname))); + av_push(av, newSVpvn(mnt->mnt_type, strlen(mnt->mnt_type))); + av_push(av, newSVpvn(mnt->mnt_opts, strlen(mnt->mnt_opts))); + XPUSHs(sv_2mortal(newRV_noinc((SV*)av))); + } + endmntent (0); + PUTBACK; +} + +XS(XS_Cygwin_mount_flags) +{ + dXSARGS; + char *pathname; + char flags[260]; + + if (items != 1) + Perl_croak(aTHX_ "Usage: Cygwin::mount_flags(mnt_dir|'/cygwin')"); + + pathname = SvPV_nolen(ST(0)); + + /* TODO: Check for cygdrive registry setting, + * and then use CW_GET_CYGDRIVE_INFO + */ + if (!strcmp(pathname, "/cygdrive")) { + char user[260]; + char system[260]; + char user_flags[260]; + char system_flags[260]; + + cygwin_internal (CW_GET_CYGDRIVE_INFO, user, system, user_flags, + system_flags); + + if (strlen(user) > 0) { + sprintf(flags, "%s,cygdrive,%s", user_flags, user); + } else { + sprintf(flags, "%s,cygdrive,%s", system_flags, system); + } + + ST(0) = sv_2mortal(newSVpv(flags, 0)); + XSRETURN(1); + + } else { + struct mntent *mnt; + setmntent (0, 0); + while ((mnt = getmntent (0))) { + if (!strcmp(pathname, mnt->mnt_dir)) { + strcpy(flags, mnt->mnt_type); + if (strlen(mnt->mnt_opts) > 0) { + strcat(flags, ","); + strcat(flags, mnt->mnt_opts); + } + break; + } + } + endmntent (0); + ST(0) = sv_2mortal(newSVpv(flags, 0)); + XSRETURN(1); + } +} + +XS(XS_Cygwin_is_binmount) +{ + dXSARGS; + char *pathname; + + if (items != 1) + Perl_croak(aTHX_ "Usage: Cygwin::is_binmount(pathname)"); + + pathname = SvPV_nolen(ST(0)); + + ST(0) = boolSV(cygwin_internal(CW_GET_BINMODE, pathname)); + XSRETURN(1); +} + void init_os_extras(void) { - char *file = __FILE__; dTHX; + char *file = __FILE__; + void *handle; newXS("Cwd::cwd", Cygwin_cwd, file); + newXSproto("Cygwin::winpid_to_pid", XS_Cygwin_winpid_to_pid, file, "$"); + newXSproto("Cygwin::pid_to_winpid", XS_Cygwin_pid_to_winpid, file, "$"); + newXSproto("Cygwin::win_to_posix_path", XS_Cygwin_win_to_posix_path, file, "$;$"); + newXSproto("Cygwin::posix_to_win_path", XS_Cygwin_posix_to_win_path, file, "$;$"); + newXSproto("Cygwin::mount_table", XS_Cygwin_mount_table, file, ""); + newXSproto("Cygwin::mount_flags", XS_Cygwin_mount_flags, file, "$"); + newXSproto("Cygwin::is_binmount", XS_Cygwin_is_binmount, file, "$"); + + /* Initialize Win32CORE if it has been statically linked. */ + handle = dlopen(NULL, RTLD_LAZY); + if (handle) { + void (*pfn_init)(pTHX); + pfn_init = (void (*)(pTHX))dlsym(handle, "init_Win32CORE"); + if (pfn_init) + pfn_init(aTHX); + dlclose(handle); + } }