Changeset 3621 in MondoRescue for branches/3.3/mindi-busybox/libbb/vfork_daemon_rexec.c
- Timestamp:
- Dec 20, 2016, 4:07:32 PM (7 years ago)
- Location:
- branches/3.3
- Files:
-
- 1 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/3.3/mindi-busybox/libbb/vfork_daemon_rexec.c
r3232 r3621 70 70 71 71 #if ENABLE_FEATURE_PREFER_APPLETS 72 static jmp_buf die_jmp; 73 static void jump(void) 74 { 75 /* Special case. We arrive here if NOFORK applet 76 * calls xfunc, which then decides to die. 77 * We don't die, but jump instead back to caller. 78 * NOFORK applets still cannot carelessly call xfuncs: 79 * p = xmalloc(10); 80 * q = xmalloc(10); // BUG! if this dies, we leak p! 81 */ 82 /* | 0x100 allows to pass zero exitcode (longjmp can't pass 0). 83 * This works because exitcodes are bytes, 84 * run_nofork_applet() ensures that by "& 0xff" */ 85 longjmp(die_jmp, xfunc_error_retval | 0x100); 86 } 87 72 88 struct nofork_save_area { 73 89 jmp_buf die_jmp; 90 void (*die_func)(void); 74 91 const char *applet_name; 75 92 uint32_t option_mask32; 76 int die_sleep;77 93 uint8_t xfunc_error_retval; 78 94 }; … … 80 96 { 81 97 memcpy(&save->die_jmp, &die_jmp, sizeof(die_jmp)); 98 save->die_func = die_func; 82 99 save->applet_name = applet_name; 100 save->option_mask32 = option_mask32; 83 101 save->xfunc_error_retval = xfunc_error_retval; 84 save->option_mask32 = option_mask32;85 save->die_sleep = die_sleep;86 102 } 87 103 static void restore_nofork_data(struct nofork_save_area *save) 88 104 { 89 105 memcpy(&die_jmp, &save->die_jmp, sizeof(die_jmp)); 106 die_func = save->die_func; 90 107 applet_name = save->applet_name; 108 option_mask32 = save->option_mask32; 91 109 xfunc_error_retval = save->xfunc_error_retval; 92 option_mask32 = save->option_mask32;93 die_sleep = save->die_sleep;94 110 } 95 111 … … 100 116 101 117 save_nofork_data(&old); 102 103 applet_name = APPLET_NAME(applet_no);104 118 105 119 xfunc_error_retval = EXIT_FAILURE; … … 134 148 argc++; 135 149 136 /* Special flag for xfunc_die(). If xfunc will "die" 137 * in NOFORK applet, xfunc_die() sees negative 138 * die_sleep and longjmp here instead. */ 139 die_sleep = -1; 140 150 /* If xfunc "dies" in NOFORK applet, die_func longjmp's here instead */ 151 die_func = jump; 141 152 rc = setjmp(die_jmp); 142 153 if (!rc) { … … 145 156 char *tmp_argv[argc+1]; 146 157 memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); 158 applet_name = tmp_argv[0]; 147 159 /* Finally we can call NOFORK applet's main() */ 148 160 rc = applet_main[applet_no](argc, tmp_argv); 149 } else { /* xfunc died in NOFORK applet */ 150 /* in case they meant to return 0... */ 151 if (rc == -2222) 152 rc = 0; 161 } else { 162 /* xfunc died in NOFORK applet */ 153 163 } 154 164
Note:
See TracChangeset
for help on using the changeset viewer.