[前][次][番号順一覧][スレッド一覧]

ruby-changes:23867

From: akr <ko1@a...>
Date: Tue, 5 Jun 2012 19:16:20 +0900 (JST)
Subject: [ruby-changes:23867] akr:r35918 (trunk): * process.c: add comments about async-signal-safe.

akr	2012-06-05 19:16:11 +0900 (Tue, 05 Jun 2012)

  New Revision: 35918

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=35918

  Log:
    * process.c: add comments about async-signal-safe.
    
    * io.c: ditto.

  Modified files:
    trunk/ChangeLog
    trunk/io.c
    trunk/process.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 35917)
+++ ChangeLog	(revision 35918)
@@ -1,3 +1,9 @@
+Tue Jun  5 19:15:14 2012  Tanaka Akira  <akr@f...>
+
+	* process.c: add comments about async-signal-safe.
+
+	* io.c: ditto.
+
 Tue Jun  5 09:25:10 2012  Eric Hodel  <drbrain@s...>
 
 	* io.c:  Edited documentation for IO and File open and new and
Index: io.c
===================================================================
--- io.c	(revision 35917)
+++ io.c	(revision 35918)
@@ -5421,6 +5421,7 @@
 }
 #endif
 
+/* This function should be async-signal-safe. */
 void
 rb_close_before_exec(int lowfd, int maxhint, VALUE noclose_fds)
 {
@@ -5428,7 +5429,7 @@
     int max = max_file_descriptor;
 #ifdef F_MAXFD
     /* F_MAXFD is available since NetBSD 2.0. */
-    ret = fcntl(0, F_MAXFD);
+    ret = fcntl(0, F_MAXFD); /* async-signal-safe */
     if (ret != -1)
         maxhint = max = ret;
 #elif defined(__linux__)
@@ -5441,15 +5442,15 @@
         max = maxhint;
     for (fd = lowfd; fd <= max; fd++) {
         if (!NIL_P(noclose_fds) &&
-            RTEST(rb_hash_lookup(noclose_fds, INT2FIX(fd))))
+            RTEST(rb_hash_lookup(noclose_fds, INT2FIX(fd)))) /* async-signal-safe */
             continue;
 #ifdef FD_CLOEXEC
-	ret = fcntl(fd, F_GETFD);
+	ret = fcntl(fd, F_GETFD); /* async-signal-safe */
 	if (ret != -1 && !(ret & FD_CLOEXEC)) {
-            fcntl(fd, F_SETFD, ret|FD_CLOEXEC);
+            fcntl(fd, F_SETFD, ret|FD_CLOEXEC); /* async-signal-safe */
         }
 #else
-	ret = close(fd);
+	ret = close(fd); /* async-signal-safe */
 #endif
 #define CONTIGUOUS_CLOSED_FDS 20
         if (ret != -1) {
Index: process.c
===================================================================
--- process.c	(revision 35917)
+++ process.c	(revision 35918)
@@ -1048,14 +1048,17 @@
 }
 
 #if defined(HAVE_FORK) && !defined(__native_client__)
+
+/* try_with_sh and exec_with_sh should be async-signal-safe. */
 #define try_with_sh(prog, argv) ((saved_errno == ENOEXEC) ? exec_with_sh((prog), (argv)) : (void)0)
 static void
 exec_with_sh(const char *prog, char **argv)
 {
     *argv = (char *)prog;
     *--argv = (char *)"sh";
-    execv("/bin/sh", argv);
+    execv("/bin/sh", argv); /* async-signal-safe */
 }
+
 #define ARGV_COUNT(n) ((n)+1)
 #else
 #define try_with_sh(prog, argv) (void)0
@@ -1066,6 +1069,7 @@
 #define ALLOC_ARGV_WITH_STR(n, v, s, l) \
     (char **)(((s) = ALLOCV_N(char, (v), ARGV_SIZE(n) + (l)) + ARGV_SIZE(n)) - ARGV_SIZE(n))
 
+/* This function should be async-signal-safe. */
 static int
 proc_exec_v(const char *prog, VALUE argv_str, VALUE envp_str)
 {
@@ -1083,7 +1087,7 @@
 
     if (!prog)
 	prog = argv[0];
-    prog = dln_find_exe_r(prog, 0, fbuf, sizeof(fbuf));
+    prog = dln_find_exe_r(prog, 0, fbuf, sizeof(fbuf)); /* xxx: not async-signal-safe because getenv(), strdup(), etc. */
     if (!prog) {
 	errno = ENOENT;
 	return -1;
@@ -1117,12 +1121,13 @@
 	}
     }
 # endif /* __EMX__ */
-    before_exec();
+    before_exec(); /* async-signal-safe if forked_child is true */
     if (envp_str)
-        execve(prog, argv, (char **)RSTRING_PTR(envp_str));
+        execve(prog, argv, (char **)RSTRING_PTR(envp_str)); /* async-signal-safe */
     else
-        execv(prog, argv);
-    preserving_errno(try_with_sh(prog, argv); after_exec());
+        execv(prog, argv); /* async-signal-safe */
+    preserving_errno(try_with_sh(prog, argv); /* try_with_sh() is async-signal-safe. */
+                     after_exec()); /* after_exec() is not async-signal-safe */
 # if defined(__EMX__) || defined(OS2)
     if (new_argv) {
 	xfree(new_argv[0]);
@@ -1133,6 +1138,7 @@
 #endif
 }
 
+/* This function should be async-signal-safe. */
 static int
 rb_proc_exec_e(const char *str, VALUE envp_str)
 {
@@ -1169,12 +1175,12 @@
             exit(status);
     }
 #else
-    before_exec();
+    before_exec(); /* async-signal-safe if forked_child is true. */
     if (envp_str)
-        execle("/bin/sh", "sh", "-c", str, (char *)NULL, (char **)RSTRING_PTR(envp_str));
+        execle("/bin/sh", "sh", "-c", str, (char *)NULL, (char **)RSTRING_PTR(envp_str)); /* async-signal-safe */
     else
-        execl("/bin/sh", "sh", "-c", str, (char *)NULL);
-    preserving_errno(after_exec());
+        execl("/bin/sh", "sh", "-c", str, (char *)NULL); /* async-signal-safe */
+    preserving_errno(after_exec()); /* xxx: not async-signal-safe because after_exec calls rb_thread_start_timer_thread.  */
 #endif
     return -1;
 #endif	/* _WIN32 */
@@ -2123,6 +2129,7 @@
     return *(int*)b - *(int*)a;
 }
 
+/* This function should be async-signal-safe when _save_ is not Qnil. */
 static int
 run_exec_dup2(VALUE ary, VALUE save, char *errmsg, size_t errmsg_buflen)
 {
@@ -2137,7 +2144,7 @@
     } *pairs = 0;
 
     n = RARRAY_LEN(ary);
-    pairs = (struct fd_pair *)malloc(sizeof(struct fd_pair) * n);
+    pairs = (struct fd_pair *)malloc(sizeof(struct fd_pair) * n); /* xxx: not async-signal-safe */
     if (pairs == NULL) {
         ERRMSG("malloc");
         return -1;
@@ -2153,7 +2160,7 @@
 
     /* sort the table by oldfd: O(n log n) */
     if (!RTEST(save))
-        qsort(pairs, n, sizeof(struct fd_pair), intcmp);
+        qsort(pairs, n, sizeof(struct fd_pair), intcmp); /* hopefully async-signal-safe */
     else
         qsort(pairs, n, sizeof(struct fd_pair), intrcmp);
 
@@ -2162,7 +2169,7 @@
         int newfd = pairs[i].newfd;
         struct fd_pair key, *found;
         key.oldfd = newfd;
-        found = bsearch(&key, pairs, n, sizeof(struct fd_pair), intcmp);
+        found = bsearch(&key, pairs, n, sizeof(struct fd_pair), intcmp); /* hopefully async-signal-safe */
         pairs[i].num_newer = 0;
         if (found) {
             while (pairs < found && (found-1)->oldfd == newfd)
@@ -2179,14 +2186,14 @@
     for (i = 0; i < n; i++) {
         long j = i;
         while (j != -1 && pairs[j].oldfd != -1 && pairs[j].num_newer == 0) {
-            if (save_redirect_fd(pairs[j].newfd, save, errmsg, errmsg_buflen) < 0)
+            if (save_redirect_fd(pairs[j].newfd, save, errmsg, errmsg_buflen) < 0) /* async-signal-safe */
                 goto fail;
-            ret = redirect_dup2(pairs[j].oldfd, pairs[j].newfd);
+            ret = redirect_dup2(pairs[j].oldfd, pairs[j].newfd); /* async-signal-safe */
             if (ret == -1) {
                 ERRMSG("dup2");
                 goto fail;
             }
-            rb_update_max_fd(pairs[j].newfd);
+            rb_update_max_fd(pairs[j].newfd); /* async-signal-safe but don't need to call it in a child process. */
             pairs[j].oldfd = -1;
             j = pairs[j].older_index;
             if (j != -1)
@@ -2202,14 +2209,14 @@
         if (pairs[i].oldfd == pairs[i].newfd) { /* self cycle */
 #ifdef F_GETFD
             int fd = pairs[i].oldfd;
-            ret = fcntl(fd, F_GETFD);
+            ret = fcntl(fd, F_GETFD); /* async-signal-safe */
             if (ret == -1) {
                 ERRMSG("fcntl(F_GETFD)");
                 goto fail;
             }
             if (ret & FD_CLOEXEC) {
                 ret &= ~FD_CLOEXEC;
-                ret = fcntl(fd, F_SETFD, ret);
+                ret = fcntl(fd, F_SETFD, ret); /* async-signal-safe */
                 if (ret == -1) {
                     ERRMSG("fcntl(F_SETFD)");
                     goto fail;
@@ -2220,7 +2227,7 @@
             continue;
         }
         if (extra_fd == -1) {
-            extra_fd = redirect_dup(pairs[i].oldfd);
+            extra_fd = redirect_dup(pairs[i].oldfd); /* async-signal-safe */
             if (extra_fd == -1) {
                 ERRMSG("dup");
                 goto fail;
@@ -2228,7 +2235,7 @@
             rb_update_max_fd(extra_fd);
         }
         else {
-            ret = redirect_dup2(pairs[i].oldfd, extra_fd);
+            ret = redirect_dup2(pairs[i].oldfd, extra_fd); /* async-signal-safe */
             if (ret == -1) {
                 ERRMSG("dup2");
                 goto fail;
@@ -2239,7 +2246,7 @@
         j = pairs[i].older_index;
         pairs[i].older_index = -1;
         while (j != -1) {
-            ret = redirect_dup2(pairs[j].oldfd, pairs[j].newfd);
+            ret = redirect_dup2(pairs[j].oldfd, pairs[j].newfd); /* async-signal-safe */
             if (ret == -1) {
                 ERRMSG("dup2");
                 goto fail;
@@ -2250,21 +2257,22 @@
         }
     }
     if (extra_fd != -1) {
-        ret = redirect_close(extra_fd);
+        ret = redirect_close(extra_fd); /* async-signal-safe */
         if (ret == -1) {
             ERRMSG("close");
             goto fail;
         }
     }
 
-    free(pairs);
+    free(pairs); /* xxx: not async-signal-safe */
     return 0;
 
   fail:
-    free(pairs);
+    free(pairs); /* xxx: not async-signal-safe */
     return -1;
 }
 
+/* This function should be async-signal-safe. */
 static int
 run_exec_close(VALUE ary, char *errmsg, size_t errmsg_buflen)
 {
@@ -2274,7 +2282,7 @@
     for (i = 0; i < RARRAY_LEN(ary); i++) {
         VALUE elt = RARRAY_PTR(ary)[i];
         int fd = FIX2INT(RARRAY_PTR(elt)[0]);
-        ret = redirect_close(fd);
+        ret = redirect_close(fd); /* async-signal-safe */
         if (ret == -1) {
             ERRMSG("close");
             return -1;
@@ -2283,6 +2291,7 @@
     return 0;
 }
 
+/* This function should be async-signal-safe when _save_ is not Qnil. */
 static int
 run_exec_open(VALUE ary, VALUE save, char *errmsg, size_t errmsg_buflen)
 {
@@ -2297,7 +2306,7 @@
         int flags = NUM2INT(RARRAY_PTR(param)[1]);
         int perm = NUM2INT(RARRAY_PTR(param)[2]);
         int need_close = 1;
-        int fd2 = redirect_open(path, flags, perm);
+        int fd2 = redirect_open(path, flags, perm); /* async-signal-safe */
         if (fd2 == -1) {
             ERRMSG("open");
             return -1;
@@ -2310,9 +2319,9 @@
                 need_close = 0;
             }
             else {
-                if (save_redirect_fd(fd, save, errmsg, errmsg_buflen) < 0)
+                if (save_redirect_fd(fd, save, errmsg, errmsg_buflen) < 0) /* async-signal-safe */
                     return -1;
-                ret = redirect_dup2(fd2, fd);
+                ret = redirect_dup2(fd2, fd); /* async-signal-safe */
                 if (ret == -1) {
                     ERRMSG("dup2");
                     return -1;
@@ -2322,7 +2331,7 @@
             i++;
         }
         if (need_close) {
-            ret = redirect_close(fd2);
+            ret = redirect_close(fd2); /* async-signal-safe */
             if (ret == -1) {
                 ERRMSG("close");
                 return -1;
@@ -2332,6 +2341,7 @@
     return 0;
 }
 
+/* This function should be async-signal-safe when _save_ is not Qnil. */
 static int
 run_exec_dup2_child(VALUE ary, VALUE save, char *errmsg, size_t errmsg_buflen)
 {
@@ -2343,9 +2353,9 @@
         int newfd = FIX2INT(RARRAY_PTR(elt)[0]);
         int oldfd = FIX2INT(RARRAY_PTR(elt)[1]);
 
-        if (save_redirect_fd(newfd, save, errmsg, errmsg_buflen) < 0)
+        if (save_redirect_fd(newfd, save, errmsg, errmsg_buflen) < 0) /* async-signal-safe */
             return -1;
-        ret = redirect_dup2(oldfd, newfd);
+        ret = redirect_dup2(oldfd, newfd); /* async-signal-safe */
         if (ret == -1) {
             ERRMSG("dup2");
             return -1;
@@ -2356,6 +2366,7 @@
 }
 
 #ifdef HAVE_SETPGID
+/* This function should be async-signal-safe when _save_ is not Qnil. */
 static int
 run_exec_pgroup(VALUE obj, VALUE save, char *errmsg, size_t errmsg_buflen)
 {
@@ -2373,15 +2384,16 @@
     }
     pgroup = NUM2PIDT(obj);
     if (pgroup == 0) {
-        pgroup = getpid();
+        pgroup = getpid(); /* async-signal-safe */
     }
-    ret = setpgid(getpid(), pgroup);
+    ret = setpgid(getpid(), pgroup); /* async-signal-safe */
     if (ret == -1) ERRMSG("setpgid");
     return ret;
 }
 #endif
 
 #if defined(HAVE_SETRLIMIT) && defined(RLIM2NUM)
+/* This function should be async-signal-safe when _save_ is not Qnil. */
 static int
 run_exec_rlimit(VALUE ary, VALUE save, char *errmsg, size_t errmsg_buflen)
 {
@@ -2408,7 +2420,7 @@
         }
         rlim.rlim_cur = NUM2RLIM(RARRAY_PTR(elt)[1]);
         rlim.rlim_max = NUM2RLIM(RARRAY_PTR(elt)[2]);
-        if (setrlimit(rtype, &rlim) == -1) {
+        if (setrlimit(rtype, &rlim) == -1) { /* hopefully async-signal-safe */
             ERRMSG("setrlimit");
             return -1;
         }
@@ -2441,6 +2453,7 @@
 }
 #endif
 
+/* This function should be async-signal-safe when _s_ is not NULL. */
 int
 rb_run_exec_options_err(const struct rb_exec_arg *e, struct rb_exec_arg *s, char *errmsg, size_t errmsg_buflen)
 {
@@ -2462,7 +2475,7 @@
 #ifdef HAVE_SETPGID
     obj = rb_ary_entry(options, EXEC_OPTION_PGROUP);
     if (RTEST(obj)) {
-        if (run_exec_pgroup(obj, soptions, errmsg, errmsg_buflen) == -1)
+        if (run_exec_pgroup(obj, soptions, errmsg, errmsg_buflen) == -1) /* async-signal-safe */
             return -1;
     }
 #endif
@@ -2470,7 +2483,7 @@
 #if defined(HAVE_SETRLIMIT) && defined(RLIM2NUM)
     obj = rb_ary_entry(options, EXEC_OPTION_RLIMIT);
     if (!NIL_P(obj)) {
-        if (run_exec_rlimit(obj, soptions, errmsg, errmsg_buflen) == -1)
+        if (run_exec_rlimit(obj, soptions, errmsg, errmsg_buflen) == -1) /* not async-signal-safe */
             return -1;
     }
 #endif
@@ -2501,14 +2514,14 @@
     obj = rb_ary_entry(options, EXEC_OPTION_UMASK);
     if (!NIL_P(obj)) {
         mode_t mask = NUM2MODET(obj);
-        mode_t oldmask = umask(mask); /* never fail */
+        mode_t oldmask = umask(mask); /* never fail */ /* async-signal-safe */
         if (!NIL_P(soptions))
             rb_ary_store(soptions, EXEC_OPTION_UMASK, MODET2NUM(oldmask));
     }
 
     obj = rb_ary_entry(options, EXEC_OPTION_DUP2);
     if (!NIL_P(obj)) {
-        if (run_exec_dup2(obj, soptions, errmsg, errmsg_buflen) == -1)
+        if (run_exec_dup2(obj, soptions, errmsg, errmsg_buflen) == -1) /* xxx: not async-signal-safe */
             return -1;
     }
 
@@ -2517,7 +2530,7 @@
         if (!NIL_P(soptions))
             rb_warn("cannot close fd before spawn");
         else {
-            if (run_exec_close(obj, errmsg, errmsg_buflen) == -1)
+            if (run_exec_close(obj, errmsg, errmsg_buflen) == -1) /* async-signal-safe */
                 return -1;
         }
     }
@@ -2525,19 +2538,19 @@
 #ifdef HAVE_FORK
     obj = rb_ary_entry(options, EXEC_OPTION_CLOSE_OTHERS);
     if (obj != Qfalse) {
-        rb_close_before_exec(3, FIX2INT(obj), e->redirect_fds);
+        rb_close_before_exec(3, FIX2INT(obj), e->redirect_fds); /* async-signal-safe */
     }
 #endif
 
     obj = rb_ary_entry(options, EXEC_OPTION_OPEN);
     if (!NIL_P(obj)) {
-        if (run_exec_open(obj, soptions, errmsg, errmsg_buflen) == -1)
+        if (run_exec_open(obj, soptions, errmsg, errmsg_buflen) == -1) /* async-signal-safe */
             return -1;
     }
 
     obj = rb_ary_entry(options, EXEC_OPTION_DUP2_CHILD);
     if (!NIL_P(obj)) {
-        if (run_exec_dup2_child(obj, soptions, errmsg, errmsg_buflen) == -1)
+        if (run_exec_dup2_child(obj, soptions, errmsg, errmsg_buflen) == -1) /* async-signal-safe */
             return -1;
     }
 
@@ -2549,7 +2562,7 @@
                          hide_obj(rb_str_new2(cwd)));
             xfree(cwd);
         }
-        if (chdir(RSTRING_PTR(obj)) == -1) {
+        if (chdir(RSTRING_PTR(obj)) == -1) { /* async-signal-safe */
             ERRMSG("chdir");
             return -1;
         }
@@ -2564,6 +2577,7 @@
     return rb_run_exec_options_err(e, s, NULL, 0);
 }
 
+/* This function should be async-signal-safe. */
 int
 rb_exec_err(const struct rb_exec_arg *e, char *errmsg, size_t errmsg_buflen)
 {
@@ -2574,15 +2588,15 @@
 # define sargp NULL
 #endif
 
-    if (rb_run_exec_options_err(e, sargp, errmsg, errmsg_buflen) < 0) {
+    if (rb_run_exec_options_err(e, sargp, errmsg, errmsg_buflen) < 0) { /* not async-signal-safe because run_exec_dup2. */
         return -1;
     }
 
     if (e->use_shell) {
-	rb_proc_exec_e(prog, e->envp_str);
+	rb_proc_exec_e(prog, e->envp_str); /* not async-signal-safe because after_exec. */
     }
     else {
-        proc_exec_v(prog, e->argv_str, e->envp_str);
+        proc_exec_v(prog, e->argv_str, e->envp_str); /* async-signal-safe not checked */
     }
 #if !defined(HAVE_FORK)
     preserving_errno(rb_run_exec_options_err(sargp, NULL, errmsg, errmsg_buflen));
@@ -2614,6 +2628,7 @@
 }
 
 #ifdef HAVE_FORK
+/* This function should be async-signal-safe but rb_thread_atfork_before_exec is not checked. */
 static int
 rb_exec_atfork(void* arg, char *errmsg, size_t errmsg_buflen)
 {

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]