forb_uuid_generate((forb_uuid_t*)server_id->uuid);
}
-void *
-forb_instance_data(const forb_object obj)
+/**
+ *
+ *
+ * @param fd
+ * @param objref
+ *
+ * @return Zero on success, -1 on error.
+ */
+static int
+rewrite_regref(int fd, const char *objref)
{
- return forb_object_instance_data(obj);
+ int ret;
+ int len = strlen(objref);
+ lseek(fd, 0, SEEK_SET);
+ ftruncate(fd, 0);
+
+ while (len > 0) {
+ ret = write(fd, objref, len);
+ if (ret < 0) goto out;
+ len -= ret;
+ objref += ret;
+ }
+ ret = 0; /* Success */
+out:
+ return ret;
+}
+
+/**
+ *
+ *
+ * @param orb
+ * @param fn File name
+ * @param objref string form of the object reference
+ *
+ * @return -1 on error, 0 if reference was replaced and 1 in the
+ * reference is valid.
+ */
+static int
+replace_regref_if_stale(forb_orb orb, const char *fn, const char *objref)
+{
+ int fd, ret = 0;
+ char str[100];
+ forb_object object;
+ forb_orb remote_orb;
+ CORBA_Environment env;
+
+ fd = open(fn, O_RDWR);
+ if (fd < 0) {
+ ret = -1;
+ goto out;
+ }
+ ret = lockf(fd, F_LOCK, 0);
+ if (ret < 0) goto close_err;
+ ret = read(fd, str, sizeof(str)-1);
+ if (ret < 0) goto unlock_err;
+ /* TODO: Check that we have read the whole file */
+
+ str[ret] = '\0';
+ object = forb_string_to_object(orb, str);
+ if (!object) {
+ /* reference is unreadable, so we can replace it */
+ ret = rewrite_regref(fd, objref);
+ /* We are done for now */
+ goto unlock_err;
+ }
+ remote_orb = forb_get_orb_of(object);
+ if (!remote_orb) { /* This shohuld never happen */
+ ret = -1;
+ goto object_release_err;
+ }
+ forb_orb_is_alive(remote_orb, &env);
+ if (env.major == FORB_EX_COMM_FAILURE) {
+ /* Orb is not alive */
+ rewrite_regref(fd, objref);
+ } else {
+ if (forb_exception_occured(&env)) {
+ ul_logerr("%s: unexpected exception: %s\n", __FUNCTION__, forb_strerror(&env));
+ }
+ /* Reference's FORB is alive :-( */
+ ret = 1;
+ }
+
+ forb_object_release(remote_orb);
+object_release_err:
+ forb_object_release(object);
+unlock_err:
+ lockf(fd, F_ULOCK, 0);
+close_err:
+ close(fd);
+out:
+ return ret;
}
if (!f) goto unalloc_err;
objref = forb_object_to_string(object);
- if (!objref) goto unalloc_err;
+ if (!objref) goto unlink_err;
ret = fprintf(f, "%s", objref);
- forb_free(objref);
- if (ret < 0) goto unalloc_err;
+ if (ret < 0) goto free_objref_err;
ret = fclose(f);
- if (ret == EOF) goto unalloc_err;
+ if (ret == EOF) goto free_objref_err;
/* Make the atomic registration in filesystem */
ret = link(fntmp, fn);
- if (ret < 0) {
- /* TODO: If the reference exists, try whether it is
- * still active. */
- goto unlink_err;
+
+ if (ret < 0 && errno == EEXIST) {
+ /* The reference exists. Try whether it is still
+ * active. */
+ if (replace_regref_if_stale(object->orb, fn, objref) != 0) {
+ goto free_objref_err;
+ }
+ ul_logdeb("Stale registration replaced\n");
+ } else if (ret < 0) {
+ goto free_objref_err;
}
+ forb_free(objref);
+
/* Unlink the temporary filename */
unlink(fntmp);
return 0;
+free_objref_err:
+ ret = errno;
+ forb_free(objref);
+ errno = ret;
unlink_err:
ret = errno;
unlink(fntmp);
return -1;
}
+/**
+ * Unregister reference previously registered by
+ * forb_register_reference().
+ *
+ * @param orb forb::orb reference
+ * @param name Name to unregister.
+ *
+ * @return Zero on success, -1 on error.
+ */
int
forb_unregister_reference(forb_orb orb, const char *name)
{
forb_regref_name_t regname;
char fn[100];
char str[100];
- int fd;
+ int fd, ret;
forb_object object;
strncpy(regname, name, FORB_REGREF_NAME_LEN-1);
if (fd < 0) {
return NULL;
}
- read(fd, str, sizeof(str)-1);
- str[sizeof(str)-1] = '\0';
+ ret = read(fd, str, sizeof(str)-1);
+ /* TODO: Check that we have read the whole file */
+ str[ret] = '\0';
object = forb_string_to_object(orb, str);
close(fd);