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
|
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);
return(TCL_ERROR);
}
if (select_ret > 0) {
read_ret = read(fd, &child_pgid, sizeof(child_pgid));
}
/* 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);
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);
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);
return(TCL_OK);
}
/* 4.child.a. Close read end of pipe -- we only write to it */
close(fds[0]);
fd = fds[1];
|
>
>
>
>
>
>
>
>
>
>
>
|
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];
|