Стартирайте програма в C _без_ да използвате обвивка

Опитвам се да стартирам приложение на C, но единственият начин, който успях да намеря, който е сравнително лесен за използване, работи така:

system("command here");

Работи, разбира се, но е много бавно (особено когато повтаряте това много). Просто се чудя дали има начин да стартирам програма без да взаимодействам с обвивка, нещо като модул за подпроцес на python.

Чувал съм за execl и бих използвал това (forkпърво, разбира се), но се чудя дали има по-прост начин, който не изисква разклоняване първи.

РЕДАКТИРАНЕ: Искам също така да мога да знам кода за връщане на програмата


person MiJyn    schedule 30.03.2013    source източник
comment
Python, изграден на C, просто ще обгръща тази функционалност. Всичко, което трябва да направите, е да дефинирате своя собствена функция за fork и exec, след което да я използвате, където имате нужда.   -  person Dave    schedule 30.03.2013
comment

Използвам скрипт за валидиране на имейл адрес. Това се основава на валидиране на HTML5 и валидиране на jQuery. Сега забелязах, че имейл адреси като [email protected] са валидирани правилно. Този имейл адрес обаче не е валиден имейл адрес.

Ако проверя синтаксиса на този имейл адрес на чрез този уебсайт: http://cobisi.com/email-validation/validate-address, казва ми, че синтаксисът е неправилен.

Имейл адресите с домейна .c не са валидни, но валидаторът по подразбиране HTML5 и jQuery смята, че имат валиден синтаксис.

Написах малък пример на JSFIDDLE: http://jsfiddle.net/kvALH/

По-долу ще намерите имейл частта от моята проверка на jQuery, която използвам във формуляра.

$('#form-validate').validate({
     rules: {
         email: {
             required: true,
             email: true
         }
     },

Как мога да накарам тази проверка на имейл да работи правилно? Трябва ли да напиша свой собствен валидатор метод за имейл?

Редактиране

Разбирам, че домейн hotmail.c може да е правилен, но tld просто не съществува. Всички tld имат 2 знака или повече, така че се чудя защо валидирането на HTML5 позволява 1 знак в домейна!

Разбирам, че за да реша проблема си, имам нужда от друга проверка, затова използвах регулярния израз от тази тема (Потвърдете имейл адреса в JavaScript?). Добавих метод към проверката на jQuery и това изглежда решава проблема ми.

JSFIDDLE: http://jsfiddle.net/kvALH/1/

jQuery.validator.addMethod("emailCustom", function (value, element, params) {
    var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    return re.test(value);
}, "Please enter a valid email address.");

$('#form-validate').validate({
    rules: {
        email: {
            required: true,
            emailCustom: true
        }
    },

Въпреки това все още смятам, че е странно защо проверката по подразбиране просто изключва този домейн с един символ.

  -  person MiJyn    schedule 30.03.2013
comment
Можете да waitpidWNOHANG, ако искате да сте асинхронни), което ще ви даде статус на изход, след като се затвори.   -  person Dave    schedule 30.03.2013
comment
@Dave, благодаря ти, ще опитам това! :Д   -  person MiJyn    schedule 30.03.2013
comment
(и, за да бъде ясно, pid е това, което получавате от fork, ако сте в основната програма. И получавате 0, ако сте в дъщерната програма)   -  person Dave    schedule 30.03.2013
comment
Не казахте каква операционна система имате, но може да можете да използвате spawn: linux.die .net/man/3/posix_spawnp   -  person Gabe    schedule 30.03.2013
comment
@Gabe, хм, интересно... но наистина не изглежда много хубаво (мисля, че fork/execl би било по-лесно за четене)...   -  person MiJyn    schedule 30.03.2013


Отговори (2)


Ако нито system(), нито popen() предоставя механизма, от който се нуждаете, тогава лесният начин да го направите е с fork() и execv() (или може би execl(), но списъкът с аргументи трябва да бъде фиксиран по време на компилиране, а не променлив, за да го използвате). Наистина ли! Не е трудно да се направят fork() и exec() и всяка алтернатива ще капсулира тази обработка.

Модулът за подпроцес на Python просто крие fork() и exec() за вас зад удобен интерфейс. Това вероятно е подходящо за език от високо ниво като Python. C е език от по-ниско ниво и всъщност не се нуждае от сложността.

Трудният начин да го направите е с posix_spawn(). Трябва да създадете аргументи, за да опишете всички действия, които искате да бъдат извършени в дъщерния елемент между fork() и exec(), което е много по-трудно да се настрои, отколкото просто да направите fork(), да направите промените и след това да използвате exec() в крайна сметка. Това (posix_spawn()) е това, което получавате, когато проектирате кода да създава дъщерен процес, без видимо да използвате fork() и exec() и гарантирате, че може да се справи с почти всяко разумно обстоятелство.

Ще трябва да помислите дали трябва да използвате wait() или waitpid() или вариант за определяне кога детето е завършено. Може да се наложи да обмислите дали да обработите сигнала SIGCHLD (който ще ви уведоми, когато дете умре).

person Jonathan Leffler    schedule 30.03.2013

Както съм сигурен, че вече знаете, system вече използва стратегията fork/exec. Разбирам, че искате да заобиколите обвивката и търсите прост подход, просто казвам, че бихте могли също толкова лесно да напишете функция за обвиване на шаблона fork/exec, както се прави в system. Наистина вероятно би било най-лесно просто да направите това. Алтернатива, както Гейб спомена в коментарите, е posix_spawn.

По-бърза (но очевидно обезсърчена) алтернатива е vfork() / exec, но това обикновено не се препоръчва и е остаряло в най-новите POSIX стандарти.

4.3BSD; POSIX.1-2001 (но означен като ОСТАРЕЛ). POSIX.1-2008 премахва спецификацията на vfork().

Предназначено е да бъде веднага последвано от exec или _exit. В противен случай могат да възникнат всякакви странни грешки, тъй като страниците на виртуалната памет и таблиците на страниците не се дублират (детето използва едни и същи сегменти от данни/купчина/стек). Процесът на родител/извикване блокира до дъщерния execs или _exits. Съвременните реализации на Regular fork имат семантика за копиране при запис, която се доближава до скоростта на vfork, без потенциалните грешки, причинени от семантиката за споделяне на памет на vfork.

Ако искате дори допълнителен контрол върху семантиката на споделяне на паметта и наследяването на процесите и произтичащото от това потенциално ускоряване (и сте на Linux), погледнете clone() (обвивка за системно извикване sys_clone()), на което някои системни извиквания, създаващи процеси, делегират работата си. Не забравяйте внимателно да разресвате всички различни знамена.

Можете да използвате waitpid, за да получите състоянието на изход на процеса.

person Jorge Israel Peña    schedule 30.03.2013
comment
vfork() е странно; правилата за точно използване са много строги; лесно е да го сбъркате. - person Jonathan Leffler; 30.03.2013
comment
@JonathanLeffler Наистина. Надяваме се, че направих това достатъчно ясно на ОП, за да могат по-внимателно да претеглят възможностите си. - person Jorge Israel Peña; 30.03.2013