Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

misc. buglets #3797

Closed
vicuna opened this issue Sep 24, 2005 · 2 comments
Closed

misc. buglets #3797

vicuna opened this issue Sep 24, 2005 · 2 comments
Labels

Comments

@vicuna
Copy link

vicuna commented Sep 24, 2005

Original bug ID: 3797
Reporter: administrator
Status: closed
Resolution: fixed
Priority: normal
Severity: minor
Category: ~DO NOT USE (was: OCaml general)

Bug description

Bonjour,

quelques bricoles, en vrac :

  • String.index_from et String.rindex_from peuvent lancer l'exception
    Invalid_argument mais ce n'est pas indiqué dans la documentation

  • String.index_from s (String.length s) c lance Not_found et non pas
    Invalid_argument, c'est un peu surprenant

  • int_of_string et float_of_string n'ont pas le même comportement
    vis-à-vis des espaces en début de chaîne :
    ,----
    | # float_of_string " 0" ;;
    | - : float = 0.
    | # int_of_string " 0" ;;
    | Exception: Failure "int_of_string".
    `----
    (par contre les deux échouent s'il y a des espaces en fin de chaîne)

  • float_of_string utilise strtod() et donc reconnaît les flottants en
    notation hexadecimale (qui est assez intéressante vu qu'il n'y a pas
    d'arrondis lors d'une conversion float -> string suivi de string ->
    float). Malheureusement il n'y a pas de moyen de réaliser l'opération
    float -> string en caml. Le printf en C utilise le format %a pour ça
    mais c'est déjà utilisé en caml.

  • d'ailleurs caml_float_of_string et caml_float_of_substring (dans
    float.c) ont une potentielle fuite de mémoire (patch en attachement).

  • la fonction Unix.establish_server a quelques problèmes. La socket
    acceptant les connections est transmise aux fils forkés. Du coup, on
    ne peut pas relancer le serveur si un fils tourne encore (bind:
    address already in use ...). Il faudrait fermer cette socket avant
    d'exécuter server_fun. Ensuite le accept() et le waitpid() ne sont pas
    protégés contre l'interruption par des signaux.

--
Olivier


Index: byterun/floats.c

RCS file: /caml/ocaml/byterun/floats.c,v
retrieving revision 1.48
diff -u -r1.48 floats.c
--- byterun/floats.c 22 Sep 2005 14:21:50 -0000 1.48
+++ byterun/floats.c 24 Sep 2005 13:02:22 -0000
@@ -127,11 +127,15 @@
if (c != '_') *dst++ = c;
}
*dst = 0;

  • if (dst == buf) caml_failwith("float_of_string");
  • if (dst == buf) goto fail;
    d = strtod((const char *) buf, &end);
  • if (end != dst) goto fail;
    if (buf != parse_buffer) caml_stat_free(buf);
  • if (end != dst) caml_failwith("float_of_string");
    return caml_copy_double(d);
  • fail:
  • if (buf != parse_buffer) caml_stat_free(buf);
  • caml_failwith("float_of_string");
    }

CAMLprim value caml_float_of_string(value vs)
@@ -150,11 +154,15 @@
if (c != '_') *dst++ = c;
}
*dst = 0;

  • if (dst == buf) caml_failwith("float_of_string");
  • if (dst == buf) goto fail;
    d = strtod((const char *) buf, &end);
  • if (end != dst) goto fail;
    if (buf != parse_buffer) caml_stat_free(buf);
  • if (end != dst) caml_failwith("float_of_string");
    return caml_copy_double(d);
  • fail:
  • if (buf != parse_buffer) caml_stat_free(buf);
  • caml_failwith("float_of_string");
    }

CAMLprim value caml_int_of_float(value f)


Index: otherlibs/unix/unix.ml

RCS file: /caml/ocaml/otherlibs/unix/unix.ml,v
retrieving revision 1.63
diff -u -r1.63 unix.ml
--- otherlibs/unix/unix.ml 24 Mar 2005 17:20:53 -0000 1.63
+++ otherlibs/unix/unix.ml 24 Sep 2005 13:32:01 -0000
@@ -919,11 +919,18 @@
bind sock sockaddr;
listen sock 5;
while true do

  • let (s, caller) = accept sock in
  • (* The "double fork" trick, the process which calls server_fun will not
  •   leave a zombie process *)
    
  • match fork() with
  •   0 -> if fork() <> 0 then exit 0; (* The son exits, the grandson works *)
    
  • match
  •  try Some (accept sock) 
    
  •  with Unix_error (EINTR, _, _) -> None
    
  • with
  • | None -> ()
  • | Some (s, caller) ->
  • (* The "double fork" trick, the process which calls server_fun will not
  •  leave a zombie process *)
    
  • match fork() with
  • 0 -> 
    
  •   if fork() <> 0 then exit 0; (* The son exits, the grandson works *)
    
  •   close sock ;
           ignore(try_set_close_on_exec s);
           let inchan = in_channel_of_descr s in
           let outchan = out_channel_of_descr s in
    

@@ -933,6 +940,6 @@
close_in inchan;
*)
exit 0

  • | id -> close s; ignore(waitpid [] id) (* Reclaim the son *)
  • | id -> close s; ignore(waitpid_non_intr id) (* Reclaim the son *)
    done


@vicuna
Copy link
Author

vicuna commented Oct 12, 2005

Comment author: administrator

Bonjour Olivier,

Merci pour les "bricoles".

  • String.index_from s (String.length s) c lance Not_found et non pas
    Invalid_argument, c'est un peu surprenant

Non, non, c'est mûrement réfléchi: c'est comme chercher dans la
chaîne vide (à partir de la position 0).

  • int_of_string et float_of_string n'ont pas le m=EAme comportement
    vis-=E0-vis des espaces en d=E9but de cha=EEne :

Là, on est tributaire de ce que fait l'implémentation sous-jacente de
strtod().

  • float_of_string utilise strtod() et donc reconna=EEt les flottants en
    notation hexadecimale (qui est assez int=E9ressante vu qu'il n'y a pas
    d'arrondis lors d'une conversion float -> string suivi de string ->
    float). Malheureusement il n'y a pas de moyen de r=E9aliser l'op=E9ration
    float -> string en caml. Le printf en C utilise le format %a pour =E7a
    mais c'est d=E9j=E0 utilis=E9 en caml.

J'ai l'impression que le %a dans les formats de printf() ne fait pas
partie des standards C. Si tu en as un besoin majeur, ça peut
s'obtenir via

external format_float: string -> float -> string = "caml_format_float"
let hex_string_of_float f = format_float "%a" f

Mais s'il s'agit d'écrire et de relire des flottants sans perte de
précision, le passage via int64 (Int64.bits_of_float,
Int64.float_of_bits) est sûrement plus portable.

  • d'ailleurs caml_float_of_string et caml_float_of_substring (dans
    float.c) ont une potentielle fuite de m=E9moire (patch en attachement).

Bien vu, je corrige.

  • la fonction Unix.establish_server a quelques probl=E8mes. La socket
    acceptant les connections est transmise aux fils fork=E9s. Du coup, on
    ne peut pas relancer le serveur si un fils tourne encore (bind:
    address already in use ...). Il faudrait fermer cette socket avant
    d'ex=E9cuter server_fun. Ensuite le accept() et le waitpid() ne sont pas
    prot=E9g=E9s contre l'interruption par des signaux.

Je corrige aussi.

  • Xavier Leroy

@vicuna
Copy link
Author

vicuna commented Oct 12, 2005

Comment author: administrator

Patches merged in 3.09. XL, 2005-10-12

@vicuna vicuna closed this as completed Oct 12, 2005
@vicuna vicuna added the bug label Mar 19, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant