3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
|
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
|
+
+
+
+
+
+
+
+
+
+
+
|
select_timeout.tv_sec = timeout_val;
select_timeout.tv_usec = 0;
FD_ZERO(&read_fdset);
FD_SET(fd, &read_fdset);
select_ret = select(fd + 1, &read_fdset, NULL, NULL, &select_timeout);
if (select_ret == 0) {
/* On timeout, terminate starting process */
child_pgid = getpgid(child);
if (child_pgid != -1) {
kill(-child_pgid, SIGKILL);
}
Tcl_SetObjResult(interp, Tcl_NewStringObj("timeout", -1));
currtime = time(NULL);
strftime(logmsg, sizeof(logmsg), "[ %b %e %H:%M:%S ", localtime(&currtime));
write(log_fd, logmsg, strlen(logmsg));
snprintf(logmsg, sizeof(logmsg), "Method \"start\" timed out after %i seconds ]\n", (int) timeout_val);
write(log_fd, logmsg, strlen(logmsg));
close(log_fd);
waitpid(child, NULL, WNOHANG);
return(TCL_ERROR);
}
if (select_ret > 0) {
read_ret = read(fd, &child_pgid, sizeof(child_pgid));
} else {
read_ret = -1;
}
/* 4.parent.d. Close read end of pipe */
close(fd);
/* 4.parent.e. Verify read was meaningful */
if (read_ret != sizeof(child_pgid)) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("failed to communicate with started service", -1));
currtime = time(NULL);
strftime(logmsg, sizeof(logmsg), "[ %b %e %H:%M:%S ", localtime(&currtime));
write(log_fd, logmsg, strlen(logmsg));
snprintf(logmsg, sizeof(logmsg), "Method \"start\" failed: communication with started service broken ]\n");
write(log_fd, logmsg, strlen(logmsg));
close(log_fd);
waitpid(child, NULL, WNOHANG);
return(TCL_ERROR);
}
/* 4.parent.f. If the PGID given is actually an error, return error */
if (child_pgid == -1) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("service failed to start", -1));
currtime = time(NULL);
strftime(logmsg, sizeof(logmsg), "[ %b %e %H:%M:%S ", localtime(&currtime));
write(log_fd, logmsg, strlen(logmsg));
snprintf(logmsg, sizeof(logmsg), "Method \"start\" failed ]\n");
write(log_fd, logmsg, strlen(logmsg));
close(log_fd);
waitpid(child, NULL, WNOHANG);
return(TCL_ERROR);
}
/* 4.parent.g. Return PGID to Tcl */
Tcl_SetObjResult(interp, Tcl_NewWideIntObj((Tcl_WideInt) child_pgid));
currtime = time(NULL);
strftime(logmsg, sizeof(logmsg), "[ %b %e %H:%M:%S ", localtime(&currtime));
write(log_fd, logmsg, strlen(logmsg));
snprintf(logmsg, sizeof(logmsg), "Method \"start\" completed, process group = %lu ]\n", (unsigned long) child_pgid);
write(log_fd, logmsg, strlen(logmsg));
close(log_fd);
waitpid(child, NULL, 0);
return(TCL_OK);
}
/* 4.child.a. Close read end of pipe -- we only write to it */
close(fds[0]);
fd = fds[1];
|
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
|
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
|
-
+
|
}
int Tuapi_Init(Tcl_Interp *interp) {
#ifdef USE_TCL_STUBS
const char *tclInitStubs_ret;
/* Initialize Stubs */
tclInitStubs_ret = Tcl_InitStubs(interp, "8.4", 0);
tclInitStubs_ret = Tcl_InitStubs(interp, TCL_PATCH_LEVEL, 0);
if (!tclInitStubs_ret) {
return(TCL_ERROR);
}
#endif
/* Kernel maintenance related commands */
Tcl_CreateObjCommand(interp, "::tuapi::syscall::insmod", tuapi_insmod, NULL, NULL);
|