system() 함수 return value 가 무엇을 의미하는 지 알고 싶어요.

nuel의 이미지

웹상에서 웹서버를 컨트롤 하는 중에 system()함수를 사용하게 되었는데요.

웹에서 실행을 시켜보면 알 수 없는 리턴값인 11만 계속해서 출력하고 있습니다.

...
        int retval = 0;
 
	printf("Content-type:text/html \n\n");
 
	printf("test"); 
 
	retval = system("pwd");
	printf("<br><br>pwd =%d\n <br>", retval); 
 
...
------------------
result :
test
pwd =11
 
-------------------

혹시 system() 함수의 리턴값 11이 무엇을 의미하는지 아시는 분 계신가요? ㅜ

김동수의 이미지

system 함수의 리턴값은 -1, 0, 127 그리고, 앞의 세가지가 아닌 다른 값으로 분류됩니다.
127은 shell invoke 에러
-1은 생겨먹은 그대로 "무언가 에러"
인자를 NULL 로 주었을시
0은 shell 이용 불가
그외 다른 반환값은 실행된 프로그램의 return 값입니다. 값이 11로 나온다면, pwd 의 코드에서 return 11 이 하고 있는 것입니다^^;

-------------------------------------
김동수 - Prototype for Evolution

김동수 - Prototype for Evolution

nuel의 이미지

윽.. 제가 pwd의 실행 예제만 올리고 말씀을 안드렸네요.;
pwd 실행은 간단한 예제로 올려본 것이고 제가 만든 스크립트 및 cgi 프로그램을 통해서
리턴값을 지정해주어도 결과는 같았습니다.
심지어. system(""); NULL값으로 주어도 리턴값은 11로 찍히네요;
에러도 아닌것이 더욱 답답한 심정입니다..OTL

vacancy의 이미지


man-page에
setuid나 setgid 권한이 있는 프로그램에서의
system()의 사용에 대한 경고가 짤막히 있네요.

웹서버라니 권한과 관련된 무언가가 있을듯도 한데;
한번 확인해보세요. ;;

ktd2004의 이미지

수행한 명령의 실제 return 값을 얻기 위해서는 WEXITSTATUS로 한번 걸러주어야 한다고 알고 있습니다.

ret = system("...");
if( ret == 127) {
    printf("can't execute /bin/sh!\n");
} else if(ret == -1) {
    printf("fork error!\n");
} else {
    printf("return value : %d\n", WEXITSTATUS(ret));
}
nuel의 이미지

답변 감사합니다.
setuid setgid를 지우고 해도 같은 현상입니다;

아!~ WEXITSTATUS를 통해 출력해보니 0 값을 리턴합니다.
하지만 전혀출력되지가 않아 동작하는지는 알 수가 없네요.;
다른 글을 참고해서 fflush(stdout); 구문을 추가해봤지만
웹상에서 출력이 되지가 않습니다.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
 
int main(int argc, char *argv[])
{
        int retval = 0;
        printf("Content-type:text/html \n\n");
 
        fflush(stdout);
	retval = system("/.../web/cgi-bin/test");
	printf("<br><br>pwd = %d\n <br>", WEXITSTATUS(retval)); 
 
        return 0;	
 }
 
결과:
retval = 0
 
---test---
#include <stdio.h>
 
main()
{
     printf("test OK!");
 
}

이렇게 단순한 프로그램 조차..되지가 않네요.
리턴값이 0 이라면..대체 왜 이런건지..더욱 미궁속으로 빠지는 듯한..OTL

Hyun의 이미지

fork 후 exec 계열을 호출해 보심이 어떨까요?


나도 세벌식을 씁니다
nuel의 이미지

어찌된 일인지..fork()를 실행하면 자식 프로세스는 생성이 안되는 듯 합니다.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/types.h>
 
int main(int argc, char *argv[])
{       
 
         int retval = 0;
	char *args[2];
	pid_t pid;
	pid = fork();
	if( pid == -1 )
	{
		fprintf(stderr, 
		"%s : failed to fork()\n", 
		strerror(errno));
		exit(13);
	}
	else if(pid == 0)
	{
		printf("PID %ld : Child started, parent is %ld.\n", 
		(long)getpid(), /*our pid*/
		(long)getppid()); /*parent pid*/
 
		args[0] = "/bin/pwd";	
	    args[1] = NULL;		
	    retval = execv("/bin/pwd", args) ;
	    printf("retval = %d\n", WEXITSTATUS(retval)) ;
	}
	else
	{
		printf("PID %ld : started child PID %ld.\n", 
		(long)getpid(), /*our pid*/
		(long)pid); /*child's pid*/
	}
         sleep(1);
	return 0;
 
 }
 
결과값:
 
PID 954 : started child PID 955.

자식 프로세스인 PID 955 는 시작이 되지가 않네요.
정상 동작 한다면
"PID 955 : Child started, parent is 954." 를 출력해야 하건만...OTZ

ymir의 이미지

return 값 11 이면, WIFSIGNALED() 로 평가했을 때 1이 나오는군요.
WTERMSIG() 로 찍어보면, 11 (SIGSEGV) 입니다.
혹시 모르니, 이 부분도 확인해 보심이...?

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

nuel의 이미지

감사합니다!~ 참고하여 실행해 본 결과,

WEXITSTATUS = 0  // 자식 프로세스가 정상적으로 종료되면 자식 프로세스의 종료 코드를 반환 
WIFSIGNALED = 1  // 자식 프로세스가 시그널에 의해 비정상적으로 종료되면 참
WIFEXITED = 0 // 자식 프로세스가 정상 종료 되면 참
WTERMSIG = 11 // WIFSIGNALED 가 참을 리턴할 경우 종료를 야기한 시그널의 번호를 리턴

위 결과로 미루어 볼 때 자식 프로세스가 비정상적으로 종료되었으며 종료를 야기한 시그널의 번호가 11이라는 말이 되네요.
과연 시그널 번호 11은;;

//윽 그렇군요.ㅎ 갯수를 번호로 수정하였습니다.^^; 감사합니다.

cinsk의 이미지


먼저, 비정상적으로 동작한다고 생각되면, Web server의 error_log를 살펴보시기 바랍니다.

그리고, CGI에서 system()을 써서 외부 명령을 실행하고, 그 결과를 출력하는 것은 별로 바람직하지 않습니다. 차라리, popen()을 쓰는 게 더 나아 보입니다.

그리고 바로 위에(nuel님), WTERMSIG()는 시그널 갯수(number of signals)를 알려주는 것이 아니라, 시그널 번호(signal number)를 알려주는 매크로입니다. 시그널 번호와 실제 내용은 "man 7 signal"하면 나옵니다.

그리고, 입력이 따로 필요없어보이니, CGI를 만들고 command-line에서 직접 실행해도 같은 결과가 나오는지 확인해보기 바랍니다.

--
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://www.cinsk.org/cfaqs/

nuel의 이미지

알려주신대로 검색해보니
세크먼트 에러임을 알 수 있었습니다.

Signal        Value        Action      Comment
----------------------------------------------------------------
SIGSEGV         11          Core       Invalid memory reference  

하지만 command-line(직접 cgi 파일을 실행하면 잘됩니다.)과 웹에서 실행하는 것과 어떤 차이로
이런 문제가 발생하는지는 감을 못잡겠네요. 웹서버는 GoAhead 서버입니다.

김수환의 이미지

system() 함수는 실행 후에 나오는 결과를 알 수 없는 반면
popen() 함수 실행으로 원하는 값을 얻을 수 있을 것입니다. ^^

김수환의 이미지

system() 함수는 실행 후에 나오는 결과를 알 수 없는 반면
popen() 함수 실행으로 원하는 값을 얻을 수 있을 것입니다. ^^

bushi의 이미지

10여년 만에 새로 달린 댓들에 덧글을 더 달아보자면,

CGI 는 stdout 을 사용합니다.
그러므로, system() 으로 뭔가를 정상적으로 실행했고, 그 뭔가가 stdout 으로 출력을 내보냈다면, CGI 서버 쪽에서 받을 수 있습니다.
stdout 에 대해 딱히 뭔가 처리를 해주는 것도 없고, 단순히 parent 의 file desriptor 가 커널 수준에서 복사되는 걸 그대로 두거든요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.